板凳--------第60章 SOCKET:服务器设计

60.1 迭代型和并发型服务器 1016

1.迭代型: 服务器每次只处理一个客户端,只有当完全处理完一个客户端的请求后才会去处理下一个客户端。只适用于快速处理客户端请求的场景,因为每个客户端都必须等待,直到前面所有的客户端都处理完了服务器才能继续服务下一个客户端。
2.并发型: 服务器能够同时处理多个客户端的请求。适用于每个请求都需要大量处理时间,或是当客户端和服务器在进行扩展对话中需要来回传递信息的场景。本章重点

60.2 迭代型UDP echo服务器 1016

#include <syslog.h>
#include "id_echo.h"
#include "become_daemon.h"
int
main(int argc, char *argv[])
{int sfd;ssize_t numRead;socklen_t len;struct sockaddr_storage claddr;char buf[BUF_SIZE];char addrStr[IS_ADDR_STR_LEN];if (becomeDaemon(0) == -1)errExit("becomeDaemon");sfd = inetBind(SERVICE, SOCK_DGRAM, NULL);if (sfd == -1) {syslog(LOG_ERR, "Could not create server socket (%s)", strerror(errno));exit(EXIT_FAILURE);}/* Receive datagrams and return copies to senders */for (;;) {len = sizeof(struct sockaddr_storage);numRead = recvfrom(sfd, buf, BUF_SIZE, 0,(struct sockaddr *) &claddr, &len);if (numRead == -1)errExit("recvfrom");if (sendto(sfd, buf, numRead, 0, (struct sockaddr *) &claddr, len)!= numRead)syslog(LOG_WARNING, "Error echoing response to %s (%s)",inetAddressStr((struct sockaddr *) &claddr, len,addrStr, IS_ADDR_STR_LEN),strerror(errno));}
}
#include "id_echo.h"int
main(int argc, char *argv[])
{int sfd, j;size_t len;ssize_t numRead;char buf[BUF_SIZE];if (argc < 2 || strcmp(argv[1], "--help") == 0)usageErr("%s host msg...\n", argv[0]);/* Construct server address from first command-line argument */sfd = inetConnect(argv[1], SERVICE, SOCK_DGRAM);if (sfd == -1)fatal("Could not connect to server socket");/* Send remaining command-line arguments to server as separate datagrams */for (j = 2; j < argc; j++) {len = strlen(argv[j]);if (write(sfd, argv[j], len) != len)fatal("partial/failed write");numRead = read(sfd, buf, BUF_SIZE);if (numRead == -1)errExit("read");printf("[%ld bytes] %.*s\n", (long) numRead, (int) numRead, buf);}exit(EXIT_SUCCESS);
}

(base) wannian07@wannian07-PC:~/Desktop/std/linux_prog_interface$ gcc id_echo_cl.c -o id_echo_cl error_functions.c become_daemon.c inet_sockets.c
(base) wannian07@wannian07-PC:~/Desktop/std/linux_prog_interface$ gcc id_echo_cl.c -o id_echo_cl error_functions.c become_daemon.c inet_sockets.c

在这里插入图片描述

60.3 并发型TCP echo服务器 1019

客户端发送无限量数据给服务器,适合并发型,使多个客户端能够同时得到服务
1.服务器调用becomeDaemon()成为一个守护进程
2.为使程序更小,使用Internet域套接字函数库
3.服务器为每个客户端传教一个子进程,确保不会出现僵尸进程。通过信号SIGCHLD安装信号处理例程来实现
4.服务器主体部分由for()循环组成,接受客户端的连接,通过fork()传教子进程。子进程调用handleRequest()处理客户端,父进程在for()循环下接受下一个客户端连接。
5.每次调用fork()后,监听套接字和连接套接字都在子进程中得到复制。
在这里插入图片描述

6.每个子进程在处理完一个客户端后终止。
客户端:

#include "inet_sockets.h"
#include "tlpi_hdr.h"#define BUF_SIZE 100int
main(int argc, char *argv[])
{int sfd;ssize_t numRead;char buf[BUF_SIZE];if (argc != 2 || strcmp(argv[1], "--help") == 0)usageErr("%s host\n", argv[0]);sfd = inetConnect(argv[1], "echo", SOCK_STREAM);if (sfd == -1)errExit("inetConnect");switch (fork()) {case -1:errExit("fork");case 0:             /* Child: read server's response, echo on stdout */for (;;) {numRead = read(sfd, buf, BUF_SIZE);if (numRead <= 0)                   /* Exit on EOF or error */break;printf("%.*s", (int) numRead, buf);}exit(EXIT_SUCCESS);default:            /* Parent: write contents of stdin to socket */for (;;) {numRead = read(STDIN_FILENO, buf, BUF_SIZE);if (numRead <= 0)                   /* Exit loop on EOF or error */break;if (write(sfd, buf, numRead) != numRead)fatal("write() failed");}/* Close writing channel, so server sees EOF */if (shutdown(sfd, SHUT_WR) == -1)errExit("shutdown");exit(EXIT_SUCCESS);}
}

服务器:

#include <signal.h>
#include <syslog.h>
#include <sys/wait.h>
#include "become_daemon.h"
#include "inet_sockets.h"       /* Declarations of inet*() socket functions */
#include "tlpi_hdr.h"#define SERVICE "echo"          /* Name of TCP service */
#define BUF_SIZE 4096static void             /* SIGCHLD handler to reap dead child processes */
grimReaper(int sig)
{int savedErrno;             /* Save 'errno' in case changed here */savedErrno = errno;while (waitpid(-1, NULL, WNOHANG) > 0)continue;errno = savedErrno;
}/* Handle a client request: copy socket input back to socket */static void
handleRequest(int cfd)
{char buf[BUF_SIZE];ssize_t numRead;while ((numRead = read(cfd, buf, BUF_SIZE)) > 0) {if (write(cfd, buf, numRead) != numRead) {syslog(LOG_ERR, "write() failed: %s", strerror(errno));exit(EXIT_FAILURE);}}if (numRead == -1) {syslog(LOG_ERR, "Error from read(): %s", strerror(errno));exit(EXIT_FAILURE);}
}int
main(int argc, char *argv[])
{int lfd, cfd;               /* Listening and connected sockets */struct sigaction sa;if (becomeDaemon(0) == -1)errExit("becomeDaemon");/* Establish SIGCHLD handler to reap terminated child processes */sigemptyset(&sa.sa_mask);sa.sa_flags = SA_RESTART;sa.sa_handler = grimReaper;if (sigaction(SIGCHLD, &sa, NULL) == -1) {syslog(LOG_ERR, "Error from sigaction(): %s", strerror(errno));exit(EXIT_FAILURE);}lfd = inetListen(SERVICE, 10, NULL);if (lfd == -1) {syslog(LOG_ERR, "Could not create server socket (%s)", strerror(errno));exit(EXIT_FAILURE);}for (;;) {cfd = accept(lfd, NULL, NULL);  /* Wait for connection */if (cfd == -1) {syslog(LOG_ERR, "Failure in accept(): %s", strerror(errno));exit(EXIT_FAILURE);}/* Handle each client request in a new child process */switch (fork()) {case -1:syslog(LOG_ERR, "Can't create child (%s)", strerror(errno));close(cfd);                 /* Give up on this client */break;                      /* May be temporary; try next client */case 0:                         /* Child */close(lfd);                 /* Unneeded copy of listening socket */handleRequest(cfd);_exit(EXIT_SUCCESS);default:                        /* Parent */close(cfd);                 /* Unneeded copy of connected socket */break;                      /* Loop to accept next connection */}}
}

(base) wannian07@wannian07-PC:~/Desktop/std/linux_prog_interface$ gcc is_echo_cl.c -o is_echo_cl error_functions.c become_daemon.c inet_sockets.c
(base) wannian07@wannian07-PC:~/Desktop/std/linux_prog_interface$ gcc is_echo_sv.c -o is_echo_sv error_functions.c become_daemon.c inet_sockets.c

60.4 并发型服务器的其他设计方案 1021

https://www.bilibili.com/read/cv28123863/
TCP多进程并发服务器(进程池版本)&TCP多进程并发服务器(动态创建进程版本)
在这里插入图片描述

TCP多线程并发服务器(进程池版本)&TCP多线程并发服务器(动态创建进程版本)

在这里插入图片描述

https://www.bilibili.com/read/cv28123863/

在服务器上预先创建进程或线程
1.服务器程序在启动阶段(即在任何客户端请求到来之前)就立刻预先创建好一定数量的子进程(或线程),而不是针对每个客户端来创建一个新的子进程(或线程)。这些子进程构成了一种服务池(server pool)
2.服务池中的每个子进程一次只处理一个客户端。在处理完客户端请求后,子进程并不会终止,而是获取下一个待处理的客户端继续处理,如此类推。
3.服务器应用中仔细地管理子进程。服务池应该足够大,以确保能充分响应客户端的请求。 a. 服务器父进程必须对未占用的子进程加以监视,服务器处于负载高峰期时增加服务池的大小,这样就总会有足够多的子进程存在,从而可以立刻服务于新的客户端请求。
b. 负载下降了,那么应该相应地降低服务池的大小,因为过多的空余进程会降低系统的整体性能。
c. 服务池中的子进程必须遵循某些协议,使得它们能以独占的方式选择一个客户端连接。
d. 服务池中的每个子进程在监听描述符的 accept()调用上阻塞就足够了。
e. 服务器父进程在创建任何子进程之前先创建监听套接字, 然后每个子进程在 fork()调用中继承该套接字的文件描述符。当一个新的客户端连接到来时,只有其中一个子进程能完成 accept()调用。
f. 由于 accept()在一些老式的实现中并不是一个原子化的系统调用,因此可能需要通过一些互斥技术(例如文件锁)来支持,以确保每次只有一个子进程可以执行 accept()调用
在单个进程中处理多个客户端
设计让单个服务器进程来处理多个客户端, 必须采用一种能允许单个进程同时监视多个文件描述符上 I/O 事件的 I/O 模型(I/O 多路复用、信号驱动 I/O 或者 epoll)。
在设计单进程服务器时,服务器进程必须做一些通常由内核来处理的调度任务。在每个客户端一个服务器进程地解决方案中,依靠内核来确保每个服务器进程能公平地访问到服务器主机的资源。用单个服务器进程来处理多个客户端时,服务器进程必须自行确保一个或多个客户端不会霸占服务器,从而使其他的客户端处于饥饿状态。
采用服务器集群
使用多个服务器系统—服务器集群(server farm)。构建服务器集群最简单的一种方法是 DNS 轮转负载共享(DNS round-robin load sharing)(或负载分发, load distribution),一个地区的域名权威服务器将同一个域名映射到多个 IP地址上(即,多台服务器共享同一个域名)。后续对 DNS 服务器的域名解析请求将以循环轮转的方式以不同的顺序返回这些 IP 地址。
优势: DNS 循环轮转的是成本低,而且容易实施。
问题1、是远端 DNS 服务器上所执行的缓存操作, 这意味着今后位于某个特定主机(或一组主机)上的客户端发出的请求会绕过循环轮转 DNS 服务器,并总是由同一个服务器来负责处理。
问题2、循环轮转 DNS 并没有任何内建的用来确保达到良好负载均衡(不同的客户端在服务器上产生的负载不同)或者是确保高可用性的机制(如果其中一台服务器宕机或者运行的服务器 程序崩溃了怎么办?)。
服务器亲和性(server affinity),确保来自同一个客户端的请求序列能够全部定向到同一台服务器上,这样由服务器维护的任何有关客户端状态的信息都能保持准确。
服务器负载均衡(server load balancing)由一台负载均衡服务器将客户端请求路由到服务器集群中的其中一个成员上。(为了确保高可用性,可能还会有一台备用的服务器。一旦负载均衡主服务器崩溃,备用服务器就立刻接管主服务器的任务。)这消除了由远端 DNS 缓存所引起的问题,因为服务器集群只对外提供了一个单独的 IP 地址(也就是负载均衡服务器的 IP 地址)。负载均衡服务器结合一些算法来衡量或计算服务器负载(可能是根据服务器集群的成员所提供的量值),并智能化地将负载分发到集群中的各个成员之上。负载均衡服务器也会自动检测集群中失效的成员(如果需要,还会自动检测新增加的服务器成员)。最后,负载均衡服务器可能还会提供对服务器亲和力的支持。
https://www.jb51.net/article/122310.htm
服务器负载均衡的基本功能和实现原理

60.5 inetd( Internet 超级服务器)守护进程

/etc/services , 列出了系统中服务项目,大部分服务器进程通常只是等待着偶尔发送过来的连接请求或数据报, 等待。服务器进程会占用内核进程表中的槽位,会占用一些内存和交换空间,对系统产生负载。
守护进程 inetd 用来消除运行大量非常用服务器进程的需要。好处:
1.与其为每个服务运行一个单独的守护进程,现在只用一个进程—inetd 守护进程—就可以监视一组指定的套接字端口,并按照需要启动其他的服务。因此可降低系统上运行的进程数量。
2.inetd 简化了启动其他服务的编程工作。因为由 inetd 执行的一些步骤通常在所有的网络服务启动时都会用到。 由于 inetd 监管着一系列的服务,可按照需要启动其他的服务,因此 inetd 有时候也被称为 Internet 超级服务器。
inetd 守护进程所做的操作
inetd 守护进程通常在系统启动时运行。 inetd 执行如下步骤:
1.对于在配置文件/etc/inetd.conf 中指定的每项服务, inetd 都会创建一个恰当类型的套接字(即流式套接字或数据报套接字),然后绑定到指定的端口号上。此外,每个 TCP套接字都会通过 listen()调用允许客户端发来连接。
2.通过 select()调用, inetd 对前一步中创建的所有套接字进行监视,看是否有数据报或请求连接发送过来
3.select()调用进入阻塞态,直到一个 UDP 套接字上有数据报可读或者 TCP 套接字上收到了连接请求。在 TCP 连接中, inetd 在进入下一个步骤之前会先为连接执行 accept()调用。
4.要启动这个套接字上指定的服务, inted 调用 fork()创建一个新的进程, 然后通过 exec()启动服务器程序。在执行 exec()前,子进程执行如下的步骤。
(a)除了用于 UDP 数据报和接受 TCP 连接的文件描述符外,将其他所有从父进程继 承而来的文件描述符都关闭。
(b)在文件描述符 0、 1 和 2 上复制套接字文件描 述符,并关闭套接字文件描述符本身(因为已经不需要它了)。完成这一步之后, 启动的服务器进程就能通过这三个标准的文件描述符同套接字通信了。
(c)为启动的服务器进程设定用户和组 ID,设定的值可在 /etc/inetd.conf 中的相应条目找到。
5.第 3 步中,如果在 TCP 套接字上接受了一个连接, inetd 就关闭这个连接套接字。
6.inetd 服务跳转回第 2 步继续执行。
/etc/inetd.conf 文件
inetd 守护进程的操作由一个配置文件来控制,通常是/etc/inetd.conf。该文件中的每一行都描述了一种由 inetd 处理的服务
echo 服务: /etc/inetd.conf 文件中的每一行都由以下字段组成,由空格来将它们分隔开。
1.服务名称(service name):指定了一项服务的名称,这项服务可在/etc/services 文件中找到。结合协议字段(protocol),就可以通过查找/etc/services 文件以确定 inetd 应该为这项服务监视哪一个端口号。
2.套接字类型(Socket type):该字段指定了这项服务所用的套接字类型—流式 套接字(stream)还是数据报套接字(dgram)。
3.协议( protocol):该字段指定了这个套接字所使用的协议。这个字段可以包含文件 /etc/protocols 中所列出的任何 Internet 协议,所有的服务都会指定 tcp或 udp。
4. 标记(flags):该字段的内容要么是 wait,要么是 nowait。这个字段指明了由 inetd 启 动的服务器(暂时的)是否会接管用于该服务的套接字。如果启动的服务器需要管理 这个套接字,那么该字段被指定为 wait。这将导致 inetd 把这个套接字从它所监视的文件描述符集合中移除,直到这个服务器 程序退出为止。
5.登录名( login name):该字段由/etc/passwd 中的用户名部分组成,还可以在其后 紧跟一个句号以及一个/etc/group 中的组名称。这些名称确定了运行的服务器程 序的用户 ID 和组 ID。
6.服务器程序(server program):该字段指定了被执行的服务器程序的路径名。
7.服务器程序参数(server program arguments):该字段指定了一个或多个参数,参数之间由空格符分隔。当执行服务器程序时,这些参数就作为程序的参数列表。在被执行的服务器程序中, 第一个参数对应于 argv[0], 通常和服务器程序名称的基础部分相同。 下一个参数对应于 argv[1],以此类推。
由 inetd 调用的流式套接字(TCP)服务器通常都被设计为只处理一个单独的客户端连接,处理完后就终止, 把监听其他连接的任务留给了 inetd。 修改了/etc/inetd.conf 文件后,需要发送一个 SIGHUP 信号给 inetd,请求它重新读取配置文件
inetd 可以简化服务器程序的编程工作,并发型(通常是 TCP)服务器。这是因为 inetd 已经帮它所调用的服务器程序完成了以下步骤。
1.执行所有和套接字相关的初始化工作,调用 socket()、 bind()以及 listen()(针对 TCP服务器)。
2.对于一个 TCP 服务,为新到来的连接执行 accept()操作。
3.创建一个新的进程来处理到来的 UDP 数据报或者是 TCP 连接。自动将调用的服务器进程设置为守护进程。 inetd 通过 fork()处理所有与进程创建相关的细节,通过 SIGCHLD 信号处理例程清除所有退出的子进程。
4.将代表 UDP 套接字或 TCP 连接套接字的文件描述符复制到标准文件描述符 0、 1 和2 上,并关闭所有其他的文件描述符(因为它们并不会在调用的服务器进程中用到)。
5.执行服务器程序。
在/etc/inetd.conf 文件中创建如下的条目,使得 inetd 可以调用该服务器程序

#include <syslog.h>
#include "tlpi_hdr.h"
#define BUF_SIZE 4096
int
main(int argc, char *argv[])
{char buf[BUF_SIZE];ssize_t numRead;while ((numRead = read(STDIN_FILENO, buf, BUF_SIZE)) > 0) {if (write(STDOUT_FILENO, buf, numRead) != numRead) {syslog(LOG_ERR, "write() failed: %s", strerror(errno));exit(EXIT_FAILURE);}}if (numRead == -1) {syslog(LOG_ERR, "Error from read(): %s", strerror(errno));exit(EXIT_FAILURE);}exit(EXIT_SUCCESS);
} 

60.6 总结

https://www.cnblogs.com/wangbin2188/tag/Linux/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/31088.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一键批量复制至指定文件夹,轻松实现同名文件覆盖,数据管理更高效!

在数字化时代&#xff0c;文件的管理与复制是每位电脑用户都不可避免的日常工作。你是否曾因为大量文件的复制与更新而焦头烂额&#xff1f;是否曾因为同名文件的冲突而不知所措&#xff1f;别担心&#xff0c;现在&#xff0c;我们为您带来高效文件复制管理的秘诀&#xff0c;…

【管理咨询宝藏132】国际顶级咨询公司战略组织运营报告套装

本报告首发于公号“管理咨询宝藏”&#xff0c;如需阅读完整版报告内容&#xff0c;请查阅公号“管理咨询宝藏”。 【管理咨询宝藏132】国际顶级咨询公司战略&组织&运营报告套装 【格式】PDF版本 【关键词】德勤、罗兰贝格、外资咨询、战略规划、组织管控、运营提升、…

HNU操作系统2022期中考试试卷及参考答案

一、&#xff08;20分&#xff0c;每小题5分&#xff09;简答题 &#xff08;1&#xff09;通过多任务共享实现的虚拟化CPU与通常虚拟机&#xff08;VMware等&#xff09;里所使用的虚拟化技术有什么不一样&#xff1f; 多任务共享实现的虚拟化CPU通常指的是在操作系统层面&am…

证书速览|CCSK云计算安全知识认证

随着云计算技术的发展&#xff0c;现在越来越多的企业感受到云的好处&#xff0c;把业务逐渐转移到云上。上云是大势所趋&#xff0c;也是现今企业发展的实际需要。 这就意味着企业会更青睐于具备云安全专业知识、技能与经验的人员。 CCSK 云计算安全知识认证&#xff0c;是由…

【学习笔记】Maven高级01:POM深入了解

文章目录 一、POM的四个层次超级POM父POM当前POM有效POM(effective pom) 二、属性的声明和引用使用 mvn help:evaluate查看属性通过Maven访问系统属性1、访问Java系统属性2、访问系统属性4、访问系统环境变量5、访问project属性访问一级标签访问子标签访问标签列表 6、访问全局…

c++里 父类私有的虚函数,也是可以被子类重写和继承的。但父类私有的普通函数,子类无法直接使用

谢谢 。今天看课本上有这么个用法&#xff0c;特测试一下。这样就也可以放心的把父类的私有函数列为虚函数了&#xff0c;或者说把父类的虚函数作为私有函数了。 再补充一例&#xff1a;

2024-06月 | 维信金科 | 风控数据岗位推荐,高收入岗位来袭!

今日推荐岗位&#xff1a;策略分析经理/分析专家、贷前、中策略分析、风控模型分析。 风控部门是金融业务的核心部门&#xff0c;而从事风控行业的人即称之为风险管理者。是大脑&#xff0c;是最最最重要的部门之一。今日推荐岗位的核心技能分布如下&#xff1a; 简历发送方式…

如何使用ChatGPT辅助设计工作

文章目录 设计师如何使用ChatGPT提升工作效率&#xff1f;25个案例告诉你&#xff01;什么是 prompt&#xff1f;咨询信息型 prompt vs 执行任务 prompt编写出色 prompt 的基本思路撰写 prompt 的案例和技巧1、将 ChatGPT 视作专业人士2、使用 ChatGPT 创建表单3、使用 ChatGPT…

人工智能产品经理,行业巨头争夺的稀缺人才

前言 在当今这个由数据驱动的时代&#xff0c;人工智能&#xff08;AI&#xff09;正迅速成为推动各行各业创新的核心力量。随着行业巨头纷纷布局人工智能领域&#xff0c;对于专业人才的需求也日益增长。特别是人工智能产品经理这一岗位&#xff0c;缺口高达6.8万&#xff0c…

如何用Vue3打造一个引人注目的3D雷达图

本文由ScriptEcho平台提供技术支持 项目地址&#xff1a;传送门 ApexCharts 雷达图&#xff1a;可视化多系列数据 应用场景介绍 雷达图是一种可视化多变量数据的多边形图表&#xff0c;每个变量表示雷达图上的一条射线&#xff0c;射线的长度表示变量的值。雷达图广泛用于展…

【ajax核心01】ajax底层原理

一:XMLHttpRequest对象 节选自MDN网站 XMLHttpRequest&#xff08;XHR&#xff09;对象用于与服务器交互。通过 XMLHttpRequest 可以在不刷新页面的情况下请求特定 URL&#xff0c;获取数据。这允许网页在不影响用户操作的情况下&#xff0c;更新页面的局部内容。XMLHttpReque…

东芝-Soft Limit 报警及其解决办法

灵感来源与生活,在生活中总能有意想不到的惊喜,下面来看看小编今天的惊喜!!! 今天不知道怎么了,有人来找就说是机器人坏了,一直报警,重启关机回原点也没有用。 意外到来,只能使用手柄将控制器打手动,来看看报警显示什么。 下面就看到了这,我靠第一次看见,只能看看手…

JavaWeb之JSON、AJAX

JSON 什么是JSON&#xff1a;JSON: JavaScript Object Notation JS对象简谱 , 是一种轻量级的数据交换格式(JavaScript提供) 特点 [{"name":"周珍珍", "age":18},{"name":"李淑文","age":20}]数据是以键值对形式…

后端不提供文件流接口,前台js使用a标签实现当前表格数据(数组非blob数据)下载成Excel

前言&#xff1a;开发过程中遇到的一些业务场景&#xff0c;如果第三方不让使用&#xff0c;后端不提供接口&#xff0c;就只能拿到table数据(Array)&#xff0c;实现excel文件下载。 废话不多说&#xff0c;直接上代码&#xff0c;方法后续自行封装即可&#xff1a; functio…

微观时空结构和虚数单位的关系

回顾虚数单位的定义&#xff0c; 其中我们把称为周期&#xff08;的绝大部分&#xff09;&#xff0c;称为微分&#xff0c;0称为原点或者起点&#xff08;意味着新周期的开始&#xff09;&#xff0c;由此我们用序数的概念反过来构建了基数的概念。 周期和单位显然具有倍数关…

在Maven工程中手动配置并测试SpringBoot(巨详)

本篇博客承继自博客&#xff1a; 在IDEA 2024.1.3 (Community Edition)中创建Maven项目_idea2024.1.3如何创建maven项目-CSDN博客 配置POM文件 打开工程中的pom.xml文件&#xff0c;先向其中写入 <parent><groupId>org.springframework.boot</groupId><…

大厂的 404 页面都长啥样?看到最后一个,我笑了~

每天浏览各大网站&#xff0c;难免会碰到404页面啊。你注意过404页面么&#xff1f;猿妹搜罗来了下面这些知名网站的404页面&#xff0c;以供大家欣赏&#xff0c;看看哪个网站更有创意&#xff1a; 腾讯 网易 淘宝 百度 新浪微博 新浪 京东 优酷 腾讯视频 搜狐 携程 去哪儿 今…

深度解析RocketMq源码-持久化组件(四) CommitLog

1.绪论 commitLog是rocketmq存储的核心&#xff0c;前面我们介绍了mappedfile、mappedfilequeue、刷盘策略&#xff0c;其实commitlog的核心组件我们基本上已经介绍完成。 2.commitLog的组成 commitLog的核心其实就是MqppedFilequeue&#xff0c;它本质上就是多个mappedFile…

web中间件漏洞-weblogic漏洞-弱口令war包上传

web中间件漏洞-weblogic漏洞-弱口令war包上传 弱口令war包上传 制作war包 jar cvf ma.war.(最后的.代表打包当前目录) 弱口令weblogic/weblogic123 点击部署后、一直点击下一步 访问webshell

传输大文件之镭速自动清理过期文件

电子文档的普及无疑极大地便利了我们的工作与生活&#xff0c;但随之而来的是如何有效管理这些日益增多的文件。企业面临着存储空间紧张、文件传输复杂、敏感信息泄露等挑战。自动化文件清理的需求日益凸显&#xff0c;这不仅关乎个人对高效工作环境的追求&#xff0c;更是企业…