单机下能不能让我们的网络应用支持百万连接?可以,但是有很多的工作要做 。而且要考虑到单机的系统资源消耗能否支撑百万并发
文章插图
一、操作系统优化首先就是要突破操作系统的限制 。
在linux平台上,无论编写客户端程序还是服务端程序,在进行高并发TCP连接处理时,最高的并发数量都要受到系统对用户单一进程同时可打开文件数量的限制(这是因为系统为每个TCP连接都要创建一个socket句柄,每个socket句柄同时也是一个文件句柄) 。
可使用ulimit命令查看系统允许当前用户进程打开的文件数限制:$ ulimit -n 1024
这表示当前用户的每个进程最多允许同时打开1024个文件,这1024个文件中还得除去每个进程必然打开的标准输入,标准输出,标准错误,服务器监听 socket,进程间通讯的unix域socket等文件,那么剩下的可用于客户端socket连接的文件数就只有大概1024-10=1014个左右 。也就是说缺省情况下,基于Linux的通讯程序最多允许同时1014个TCP并发连接 。
对于想支持更高数量的TCP并发连接的通讯处理程序,就必须修改Linux对当前用户的进程同时打开的文件数量 。
修改单个进程打开最大文件数限制的最简单的办法就是使用ulimit命令:$ ulimit –n 1000000
如果系统回显类似于"Operation not permitted"之类的话,说明上述限制修改失败,实际上是因为在中指定的数值超过了Linux系统对该用户打开文件数的软限制或硬限制 。因此,就需要修改Linux系统对用户的关于打开文件数的软限制和硬限制 。
软限制(soft limit):是指Linux在当前系统能够承受的范围内进一步限制用户同时打开的文件数;
硬限制(hardlimit):是根据系统硬件资源状况(主要是系统内存)计算出来的系统最多可同时打开的文件数量 。
第一步,修改/etc/security/limits.conf文件,在文件中添加如下行:
* soft nofile 1000000* hard nofile 1000000
'*'号表示修改所有用户的限制;soft或hard指定要修改软限制还是硬限制;1000000则指定了想要修改的新的限制值,即最大打开文件数(请注意软限制值要小于或等于硬限制) 。修改完后保存文件 。
第二步,修改/etc/pam.d/login文件,在文件中添加如下行:
session required /lib/security/pam_limits.so
这是告诉Linux在用户完成系统登录后,应该调用pam_limits.so模块来设置系统对该用户可使用的各种资源数量的最大限制(包括用户可打开的最大文件数限制),而pam_limits.so模块就会从/etc/security/limits.conf文件中读取配置来设置这些限制值 。修改完后保存此文件 。第三步,查看Linux系统级的最大打开文件数限制,使用如下命令:
[root@VM_0_15_centos ~]# cat /proc/sys/fs/file-max98566
这表明这台Linux系统最多允许同时打开(即包含所有用户打开文件数总和)98566个文件,是Linux系统级硬限制,所有用户级的打开文件数限制都不应超过这个数值 。通常这个系统级硬限制是Linux系统在启动时根据系统硬件资源状况计算出来的最佳的最大同时打开文件数限制,如果没有特殊需要,不应该修改此限制,除非想为用户级打开文件数限制设置超过此限制的值 。如何修改这个系统最大文件描述符的限制呢?修改sysctl.conf文件
vi /etc/sysctl.conf # 在末尾添加 fs.file_max = 1000000 # 立即生效 sysctl -p
二、Netty调优1、设置合理的线程数对于线程池的调优,主要集中在用于接收海量设备TCP连接、TLS握手的 Acceptor线程池( Netty通常叫 boss NioEventLoop Group)上,以及用于处理网络数据读写、心跳发送的1O工作线程池(Nety通常叫 work Nio EventLoop Group)上 。对于Nety服务端,通常只需要启动一个监听端口用于端侧设备接入即可,但是如果服务端集群实例比较少,甚至是单机(或者双机冷备)部署,在端侧设备在短时间内大量接入时,需要对服务端的监听方式和线程模型做优化,以满足短时间内(例如30s)百万级的端侧设备接入的需要 。
服务端可以监听多个端口,利用主从 Reactor线程模型做接入优化,前端通过SLB做4层门7层负载均衡 。
主从 Reactor线程模型特点如下:服务端用于接收客户端连接的不再是一个单独的NO线程,而是一个独立的NIO线程池; Acceptor接收到客户端TCP连接请求并处理后(可能包含接入认证等),将新创建的 Socketchanne注册到I/O线程池(subReactor线程池)的某个IO线程,由它负责 Socketchannel的读写和编解码工作; Acceptor线程池仅用于客户端的登录、握手和安全认证等,一旦链路建立成功,就将链路注册到后端 sub reactor线程池的IO线程,由IO线程负责后续的IO操作 。
推荐阅读
- 招聘|如何面试管理人员
- 高档礼品盒如何设计呢
- 餐厨垃圾应该如何处理
- 如何辨别汽车太阳膜优劣
- 如何选购好普洱茶,如何选购祁门红茶
- 如何开启手机定位 手机怎么开启定位系统?
- 绿茶粉的功效与作用,如何挑选绿茶粉
- 安化黑茶的动人传说,如何鉴别黑茶的优劣
- 如何挑选购物袋呢
- 白毫银针如何储存,白毫银针十不采