Linux(服务器编程):百万并发服务器系统参数调优
一、本文目的
- 在编写服务器时 , 如果服务器的设计初衷是要可以承担百万、千万的客户端连接 , 那么默认的情况下 , Linux操作系统提供的相关配置参数(比如说进程可分配的文件数目等)是不能够满足我们的程序需求的 , 因此需要自己调整系统的相关参数
- 对于服务器并发的概念 , 下面几点是错误的定义:
- ①服务器处理客户端请求的数量:没有时间、空间等限制 , 因此不能作为并发的概念
- ②单位时间内 , 能够处理请求的数量:这也是不正确的定义 , 因为这个定义是针对于服务器吞吐量(qps)的 , 而不是并发
- 其他等......
- 下面几点组成在一起可以作为服务器“并发”的概念:
- ①服务器能够同时承担的客户端数量(最基本要求)
- ②能处理指定数量以上的相应请求
- ③能够对数据库进行操作
- ④有磁盘的操作
- ⑤CPU的占用率最好不要超过60%
- ⑥内存占用率最好不要超过80%
实现单机百万连接丨优化三次握手四次挥手
揭秘百万并发服务器的奥秘
文章插图
要C/C++ Linux服务器架构师学习资料后台私信“1”获取(资料包括C/C++ , Linux , golang技术 , Nginx , ZeroMQ , MySQL , Redis , fastdfs , MongoDB , ZK , 流媒体 , CDN , P2P , K8S , Docker , TCP/IP , 协程 , DPDK , ffmpeg等) , 免费分享二、本文环境搭建
- 本文准备了两份代码 , 作为测试环境:
- reactor.c:作为服务端 , 采用单进程reactor模式编写 , 持续接收客户端的连接 , 并且与客户端有数据的读写(recv()、send())
- mul_port_client_epoll.c:作为客户端 , 会向reactor.c服务端发起不超过340000的客户端连接 , 并且每个客户端都会与服务端有数据的读写(recv()、send())
- Github源码链接参阅:
// reactor.c// 源码链接: #include #include #include #include #include #include #include #include #include #include#define BUFFER_LENGTH4096#define MAX_EPOLL_EVENTS 1024#define SERVER_PORT8888 typedef int NCALLBACK(int ,int, void*); struct ntyevent { int fd;int events;void *arg;int (*callback)(int fd, int events, void *arg); int status;char buffer[BUFFER_LENGTH]; int length; long last_active;}; struct ntyreactor { int epfd;struct ntyevent *events;}; int recv_cb(int fd, int events, void *arg);int send_cb(int fd, int events, void *arg);int nty_event_set(struct ntyevent *ev, int fd, NCALLBACK callback, void *arg) { ev->fd = fd; ev->callback = callback; ev->events = 0; ev->arg = arg; ev->last_active = time(NULL);return 0;} int nty_event_add(int epfd, int events, struct ntyevent *ev) {struct epoll_event ep_ev = {0, {0}}; ep_ev.data.ptr = ev; ep_ev.events = ev->events = events;int op; if (ev->status == 1) {op = EPOLL_CTL_MOD; } else {op = EPOLL_CTL_ADD;ev->status = 1; }if (epoll_ctl(epfd, op, ev->fd,return -1; }return 0;} int nty_event_del(int epfd, struct ntyevent *ev) {struct epoll_event ep_ev = {0, {0}}; if (ev->status != 1) { return -1; }ep_ev.data.ptr = ev; ev->status = 0; epoll_ctl(epfd, EPOLL_CTL_DEL, ev->fd,return 0;} int recv_cb(int fd, int events, void *arg) { struct ntyreactor *reactor = (struct ntyreactor*)arg; struct ntyevent *ev = reactor->events + fd;int len = recv(fd, ev->buffer, BUFFER_LENGTH, 0); nty_event_del(reactor->epfd, ev);if (len > 0) {ev->length = len;ev->buffer[len] = '\0';printf("C[%d]:%s\n", fd, ev->buffer);nty_event_set(ev, fd, send_cb, reactor);nty_event_add(reactor->epfd, EPOLLOUT, ev);} else if (len == 0) {close(ev->fd); printf("[fd=%d] pos[%ld], closed\n", fd, ev-reactor->events);} else { //if(errno == EAGAIN || errno == EWOULDBLOCK) // continue; return 0;close(ev->fd); printf("recv[fd=%d] error[%d]:%s\n", fd, errno, strerror(errno));}return len;} int send_cb(int fd, int events, void *arg) {struct ntyreactor *reactor = (struct ntyreactor*)arg; struct ntyevent *ev = reactor->events + fd;int len = send(fd, ev->buffer, ev->length, 0); if (len > 0) { printf("send[fd=%d], [%d]%s\n", fd, len, ev->buffer);nty_event_del(reactor->epfd, ev);nty_event_set(ev, fd, recv_cb, reactor);nty_event_add(reactor->epfd, EPOLLIN, ev);} else {close(ev->fd);nty_event_del(reactor->epfd, ev); printf("send[fd=%d] error %s\n", fd, strerror(errno)); }return len;} int accept_cb(int fd, int events, void *arg) { struct ntyreactor *reactor = (struct ntyreactor*)arg; if (reactor == NULL) return -1; struct sockaddr_in client_addr; socklen_t len = sizeof(client_addr); int clientfd; if ((clientfd = accept(fd, (struct sockaddr*) return -1; }int i = 0; do { for (i = 0;i
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Git服务器配置错误导致日产汽车源码在网上泄露
- 机器人|万州区举办“中国梦科技梦”机器人编程大赛
- Linux Kernel 5.10.5发布:禁用FBCON加速滚动特性
- Linux 5.11开始围绕PCI Express 6.0进行早期准备
- Fedora正在寻求协助 希望加快Linux 5.10 LTS内核测试进度
- Linux Mint 20.1 Ulyssa稳定版已确定延期至2021年初发布
- 英特尔Xe GPU在Linux 5.11上的性能表现不错
- MIPS架构厂商日渐式微 Linux报告其漏洞遭遇困难
- 手把手配置HLS流媒体服务器
- 2020年科技十大“翻车”现场:谷歌服务器真的有点累了……