tcp 连接数上限突破

连接数上限条件

文件句柄的限制

一个tcp连接就需要占用一个文件描述符,一旦文件描述符用完,新的连接就会返回给我们错误是:Can’topen so many files。linux系统出于安全角度的考虑,在多个维度对于可打开的文件描述符进行了限制,通常是系统限制、用户限制、进程限制。

限制维度描述查看默认修改
系统(fs.file-max)限制整个系统的文件句柄个数cat /proc/sys/fs/file-max-编辑 /etc/sysctl.conf 文件,加入:
fs.file-max=1000000
然后执行sysctl -p命令使其生效
进程(fs.nr_open)限制系统单个进程可打开的最大文件件句柄数量cat /proc/sys/fs/nr_open-编辑 /etc/sysctl.conf 文件,加入:
fs.nr_open=1000000
然后执行sysctl -p命令使其生效
用户进程(nofile)限制每个用户的进程可打开的最大文件句柄数量ulimit -n-临时修改:ulimit -n 1000000
永久修改:编辑 /etc/security/limits.conf 文件:
* soft nofile 55000
* hard nofile 55000
上面修改对所有用户生效。
注意!!!:hard nofile 一定要比 fs.nr_open 要小,否则可能导致用户无法登陆。

端口限制

操作系统采用 <客户端IP : 客户端端口> : <服务端IP : 服务端端口> 四元组来标识一条TCP连接。

端口范围

一个IP的端口范围是1024-65535。

查看方法
$ sysctl net.ipv4.ip_local_port_range

$ cat /proc/sys/net/ipv4/ip_local_port_range
修改方法

临时修改:

# 临时修改方法1
$ echo 1024 65535 > /proc/sys/net/ipv4/ip_local_port_range# 临时修改方法2
$ sysctl -w net.ipv4.ip_local_port_range="1024 64000"

永久修改:
编辑 /etc/sysctl.conf 文件,在其中加入:

net.ipv4.ip_local_port_range = 1024 65535

连接突破限制方法

服务端一般不会存在端口限制的问题,服务端开一个listen端口,只要文件句柄没达上限,就可以建立连接。
针对客户端的端口限制,有下面的方法:

  • 服务器端只开启一个进程,然后使用很多个客户端进程绑定不同的客户端 ip 来连接
  • 服务器开启多个进程,这样客户端就可以只使用一个 ip 即可

supervisor控制的程序

CentOS上使用系统自带的supervisor,使用systemd启动supervisord的服务。被supervisor管理、启动的进程,并不会使用 /etc/security/limits.conf 中配置的 nofile 数值,继承的是systemd对应的限制。

在supervisord 的配置文件 /etc/supervisor.conf中调整

检查 supervisord 的配置文件 /etc/supervisor.conf 中,会发现一个 minfds 的参数设置了 nofile 限制,默认为 1024。

[supervisord]minfds=100000                 ; (min. avail startup file descriptors;default 1024)
minprocs=100000                ; (min. avail process descriptors;default 200)

minprocs 参数,minprocs 对应的是 rlimit 中的 nproc, nproc 代表一个进程最多可以创建的线程数。

在启动.service文件里面修改对应的限制

$ vim /usr/lib/systemd/system/supervisord.service
[Unit]
Description=Process Monitoring and Control Daemon
After=network.target[Service]
Type=forking
LimitCORE=infinity
LimitNOFILE=100000 
LimitNPROC=100000
ExecStart=/usr/bin/supervisord -c /etc/supervisord.conf
ExecReload=/usr/bin/supervisorctl reload
ExecStop=/usr/bin/supervisorctl shutdown[Install]
WantedBy=multi-user.target

重新加载

$ systemctl daemon-reload
$ systemctl restart supervisord.service

nginx 连接突破上限

首先参考上面的内容调整文件句柄数量。其次创建子网卡,将请求分配到不同的 ip上,最后调整nginx配置。

创建子网卡

ifconfig eth0:0 192.168.1.11/24 up
ifconfig eth0:1 192.168.1.12/24 up
ifconfig eth0:2 192.168.1.13/24 up
ifconfig eth0:3 192.168.1.14/24 up
ifconfig eth0:4 192.168.1.15/24 up
ifconfig eth0:5 192.168.1.16/24 up
ifconfig eth0:6 192.168.1.17/24 up
ifconfig eth0:7 192.168.1.18/24 up
ifconfig eth0:8 192.168.1.19/24 up
ifconfig eth0:9 192.168.1.10/24 up
ifconfig eth0:10 192.168.1.20/24 up
ifconfig eth0:11 192.168.1.21/24 up
ifconfig eth0:12 192.168.1.22/24 up
ifconfig eth0:13 192.168.1.23/24 up
ifconfig eth0:14 192.168.1.24/24 up

调整nginx配置

  1. 修改Nginx最大打开文件数为 100w
worker_rlimit_nofile 1000000;
  1. 修改Nginx事件处理模型
events {use epoll;worker_connections 1000000;
}

3.配置应用请求
后端 go应用程序监听在 9505 端口,nginx中配置 upstream

upstream go-ws {server 127.0.0.1:9505;keepalive 128;
}location /ws {proxy_redirect off;proxy_bind $split_ip;proxy_pass http://go-ws;proxy_bind $spl_set_header X-Forwarded-For $proxy_add_x_forwarded_for;# WebSocket 支持的核心配置proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection $http_connection;proxy_intercept_errors on;client_max_body_size 20m;}#将请求分配到不同ip上
split_clients "$remote_addr$remote_port" $split_ip {10%  192.168.1.11;10%  192.168.1.12;10%  192.168.1.13;10%  192.168.1.14;10%  192.168.1.15;10%  192.168.1.16;10%  192.168.1.17;10%  192.168.1.18;10%  192.168.1.19;10%  192.168.1.20;10%  192.168.1.21;10%  192.168.1.22;10%  192.168.1.23;10%  192.168.1.24;*    192.168.1.10;
}

如果句柄数并未达到100万就报http: Accept error: accept tcp [::]:9505: accept4: too many open files; retrying in 40ms

尝试调整 supervisorctl句柄数据试试。

netty 连接数设置

netty中跟连接数相关的参数是ChannelOption.SO_BACKLOG,对应的是tcp/ip协议, listen函数 中的 backlog 参数,用来初始化服务端可连接队列。

linux内核中的两个队列

在linux系统内核中维护了两个队列:syns queue和accept queue

服务端处理客户端连接请求是顺序处理的,所以同一时间只能处理一个客户端连接,多个客户端来的时候,服务端将不能处理的客户端连接请求放在队列中等待处理。

  • syns queue:保存一个SYN已经到达,但三次握手还没有完成的连接。

    用于保存半连接状态的请求,其大小通过/proc/sys/net/ipv4/tcp_max_syn_backlog指定,一般默认值是512。不过这个设置有效的前提是系统的syncookies功能被禁用。

    互联网常见的TCP SYN FLOOD恶意DOS攻击方式就是建立大量的半连接状态的请求,然后丢弃,导致syns queue不能保存其它正常的请求。

  • accept queue:保存三次握手已完成,内核正等待进程执行accept的调用的连接。

    用于保存全连接状态的请求,其大小通过/proc/sys/net/core/somaxconn指定。

    在使用listen函数时,内核会根据传入的backlog参数与系统参数somaxconn,取二者的较小值。

注意:

  • 如果未设置或所设置的值小于1,Java将使用默认值50。
  • 如果accpet queue队列满了,server将发送一个ECONNREFUSED错误信息Connection refused到client。

ChannelOption.SO_BACKLOG

服务器TCP内核 内维护了两个队列,称为A(未连接队列)和B(已连接队列)

如果A+B的长度大于Backlog时,新的连接就会被TCP内核拒绝掉。

如果backlog过小,就可能出现Accept的速度跟不上,A,B队列满了,就会导致客户端无法建立连接。

另外 backlog对程序的连接数没影响,但是影响的是还没有被Accept取出的连接。

在netty实现中,backlog默认通过NetUtil.SOMAXCONN指定;在ServerBootstrap中使用option()方法设置SO_BACKLOG参数,该参数表示等待接受的连接队列的最大长度。示例代码如下:

ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).option(ChannelOption.SO_BACKLOG, 100) // 设置最大连接数为100.childHandler(new MyChannelInitializer());

TCP的连接状态 (SYN, FIN, ACK, PSH, RST, URG)

SYN 表示建立连接
FIN 表示关闭连接
ACK 表示响应
PSH 表示有 DATA数据传输
RST 表示连接重置。

参考

用Netty实现单机百万TCP长连接
让Netty Linux 突破100万的连接量
netty怎么设置最大连接数
单机器如何实现Nginx百万并发连接
linux - 文件句柄的限制,你知道吗?
实践单机实现百万连接
supervisord 中的 open files 数量限制
superversior 常用操作命令supervisorctl
Netty ChannelOption.SO_BACKLOG配置

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

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

相关文章

unityAB包管理(远程下载)

1.AB包生成脚本 using UnityEngine; using UnityEditor; using System.IO; using System; using System.Collections.Generic;/// <summary> /// AB包创建 /// </summary> public class CreateAssetBundles : MonoBehaviour {public static string BuildAssetBund…

ARM 汇编指令:(五)CMP指令

目录 1.CMP比较指令 2.指令条件码 cond 1.CMP比较指令 CMP指令是计算机指令集中的一种比较指令&#xff0c;用于比较两个操作数的大小关系或相等性&#xff0c;并根据比较结果设置或更新条件码寄存器&#xff08;或程序状态字&#xff09;的标志位。 指令格式&#xff1a;C…

VUE内盘期货配资软件源码国际外盘二合一

开发一个Vue内盘期货配资软件源码&#xff0c;同时兼容国际外盘二合一的功能&#xff0c;是一个复杂且专业的任务&#xff0c;涉及前端Vue.js框架的使用、后端服务器处理、数据库管理、实时交易接口对接等多个方面。下面是一些关于开发此类软件的基本指导和考虑因素&#xff1a…

富格林:洞悉暗箱手法可信策略远离

富格林悉知&#xff0c;在现货黄金中&#xff0c;揭秘很多投资者都是奔着盈利来的&#xff0c;因此学习正规盈利出金技能是必不可少的。但一些投资者在进入市场后并不注意技能的提升&#xff0c;只是一味的看中盈利&#xff0c;这样的做单导致被诱导暗箱亏损的不少&#xff0c;…

什么是同城上门预约按摩系统,上门预约平台有哪些功能?

随着互联网技术的发展&#xff0c;人们的生活方式发生了很大的变化。在日常生活中&#xff0c;大家都习惯使用手机来订餐、购物、家政服务等&#xff0c;这也为我们的生活带来了很大的便利。而同城按摩小程序作为一种新兴的按摩预约方式&#xff0c;受到了越来越多人的欢迎。下…

轻松上手MacOS:HomeBrew安装全指南

轻松上手MacOS&#xff1a;HomeBrew安装全指南 你是否曾为在MacOS上安装软件而烦恼&#xff1f;是否想要一个既强大又简单的包管理器来简化你的安装过程&#xff1f;HomeBrew正是你所需要的工具。作为MacOS上的包管理器&#xff0c;HomeBrew让安装软件变得像数123一样容易。在…

机器视觉检测设备的组成要素

机器视觉检测设备是一种先进的自动化检测技术工具&#xff0c;它利用光学、图像处理和计算机硬件及软件技术模拟并扩展人类的视觉功能&#xff0c;以实现对产品或目标物体进行自动化的尺寸测量、缺陷检测、表面质量评估、颜色识别、形状匹配以及位置判断等功能。这种设备通常包…

GettingStartedwithLLVMCoreLibraries书籍

Getting Started with LLVM Core Libraries 参考1 LLVM是构架编译器(compiler)的框架系统&#xff0c;以C编写而成&#xff0c;用于优化以任意程序语言编写的程序的编译时间(compile-time)、链接时间(link-time)、运行时间(run-time)以及空闲时间(idle-time)&#xff0c;对开…

c/c++| 常规 |sizeof 、strlen

总结来说 &#xff0c;sizeof 查看内存给对象分配的空间大小&#xff0c;不仅仅是普通的内置变量&#xff0c;还包括用户自定义变量、结构体、类对象 然后strlen 是查看字符串的实际长度大小&#xff0c;注意它不会计算那个结束符’\0’

重生奇迹MU攻击防御技能石哪里掉

在《重生奇迹MU》中&#xff0c;攻击和防御技能石可以从以下途径获得&#xff1a; 1.怪物掉落&#xff1a;你可以通过击败怪物获得攻击和防御技能石&#xff0c;不同的怪物掉落不同的石头。你可以在各个地图的怪物掉落表中查看特定怪物掉落的技能石。 2.商店购买&#xff1a;…

【教程】APP加固的那些小事

摘要 APP加固是保护APP代码逻辑的重要手段&#xff0c;通过隐藏、混淆、加密等操作提高软件的逆向成本&#xff0c;降低被破解的几率&#xff0c;保障开发者和用户利益。本文将介绍APP加固常见失败原因及解决方法&#xff0c;以及处理安装出现问题的情况和资源文件加固策略选择…

eclipse报: cvc-elt.1: Cannot find the declaration of element

eclipse报: cvc-elt.1: Cannot find the declaration of element 这个错误通常出现在XML文件中&#xff0c;它表示XML解析器在尝试解析XML文件时找不到某个元素的声明。这通常是因为XML文件引用的DTD&#xff08;文档类型定义&#xff09;或XSD&#xff08;XML Schema定义&…

怎么查看电脑是不是固态硬盘?简单几个步骤判断

随着科技的发展&#xff0c;固态硬盘&#xff08;Solid State Drive&#xff0c;简称SSD&#xff09;已成为现代电脑的标配。相较于传统的机械硬盘&#xff0c;固态硬盘在读写速度、稳定性和耐用性等方面都有显著优势。但是&#xff0c;对于不熟悉电脑硬件的用户来说&#xff0…

3D地图在BI大屏中的应用实践

前言 随着商业智能的不断发展&#xff0c;数据可视化已成为一项重要工具&#xff0c;有助于用户更好地理解数据和分析结果。其中&#xff0c;3D地图作为一种可视化工具&#xff0c;已经在BI大屏中得到了广泛地应用。 3D地图通过将地理信息与数据相结合&#xff0c;以更加直观…

3. git 回退代码版本

在Git中&#xff0c;如果你想要将某个分支的代码回退到上一个版本&#xff0c;你可以使用 git revert 或者 git reset 命令。 这两个命令有不同的用途和效果&#xff0c;因此你需要根据你的具体需求来选择合适的命令。 使用 git revert git revert 命令用于创建一个新的提交&…

【Linux】Shell编程【一】

shell是一个用 C 语言编写的程序&#xff0c;它是用户使用 Linux 的桥梁。Shell 既是一种命令语言&#xff0c;又是一种程序设计语言。 Shell 是指一种应用程序&#xff0c;这个应用程序提供了一个界面&#xff0c;用户通过这个界面访问操作系统内核的服务。 Shell属于内置的…

【C++ 学习】程序内存分布

文章目录 1. C 内存分布的引入 1. C 内存分布的引入 ① 栈又叫堆栈&#xff1a;非静态局部变量/函数参数/返回值等等&#xff0c;栈是向下增长的。 ② 内存映射段&#xff1a;是高效的I/O映射方式&#xff0c;用于装载一个共享的动态内存库。用户可使用系统接口创建共享共享内存…

Java异常处理神器:Guava Throwables类

Guava由Google开发&#xff0c;它提供了大量的核心Java库&#xff0c;例如&#xff1a;集合、缓存、原生类型支持、并发库、通用注解、字符串处理和I/O操作等。这些功能在日常的Java开发中超级常用&#xff0c;而且Guava的设计哲学是简洁高效&#xff0c;这让咱们的代码不仅更加…

[Django 0-1] Core.Checks 模块

Checks 源码分析 Django 的 checks 模块提供了一系列的检查函数&#xff0c;用于检查 Django 项目的配置是否正确。 文件结构 . ├── __init__.py ├── async_checks.py ├── caches.py ├── compatibility │ ├── __init__.py │ └── django_4_0.py ├─…

【知识库系统】使用SpringSecurity进行身份认证

一、理论知识部分 SpringSecurity 的官网文档地址&#xff1a;SpringSecurity 这里以24年3月份的 6.2.2 版本为例&#xff0c;记录一下学习过程。 1. SpringSecurity 是基于 Servlet Filters 的&#xff0c;而 Servlet Filters 中的流程如下&#xff1a;首先由客户端 Client…