rabbitmq最大连接数(Socket Descriptors)(转)

2024-03-16 10:32

本文主要是介绍rabbitmq最大连接数(Socket Descriptors)(转),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

RabbitMQ自带了显示能够接受的最大连接数,有2种比较直观的方式:
1. rabbitmqctl命令。

1
2
3
4
5
6
7
8
9
10
11
12
<span style="color: rgb(102, 102, 102);">n$ </span>rabbitmqctl status
Status of node <span style="color: rgb(255, 0, 0);">'rabbit@10-101-17-13'</span> ...
<span style="color: rgb(122, 8, 116); "><strong>[</strong></span><span style="color: rgb(122, 8, 116); "><strong>{</strong></span>pid,23658<span style="color: rgb(122, 8, 116); "><strong>}</strong></span>,......<span style="color: rgb(122, 8, 116); "><strong>{</strong></span>file_descriptors,<span style="color: rgb(122, 8, 116); "><strong>[</strong></span><span style="color: rgb(122, 8, 116); "><strong>{</strong></span>total_limit,924<span style="color: rgb(122, 8, 116); "><strong>}</strong></span>,<span style="color: rgb(122, 8, 116); "><strong>{</strong></span>total_used,10<span style="color: rgb(122, 8, 116); "><strong>}</strong></span>,<span style="color: rgb(122, 8, 116); "><strong>{</strong></span>sockets_limit,829<span style="color: rgb(122, 8, 116); "><strong>}</strong></span>,<span style="color: rgb(122, 8, 116); "><strong>{</strong></span>sockets_used,10<span style="color: rgb(122, 8, 116); "><strong>}</strong></span><span style="color: rgb(122, 8, 116); "><strong>]</strong></span><span style="color: rgb(122, 8, 116); "><strong>}</strong></span>,......
<span style="color: rgb(122, 8, 116); "><strong>]</strong></span>
...done.

2. rabbitmq_management WebUI插件。

本文关注当RabbitMQ可用连接数耗尽时客户端的影响以及如何增加最大连接数默认值。

RabbitMQ的socket连接数(socket descriptors)是文件描述符(file descriptors,fd)的一个子集。也就是说,RabbitMQ能同时打开的最大连接数和最大文件句柄数(文件系统,管道)都是受限于操作系统关于文件描述符数量的设置,两者是此消彼长的关系。初始时,可用socket描述符与可用fd数量的比率大概在0.8-0.9左右,这个值并不固定,当socket描述符有剩余时,RabbitMQ会使用尽量多的文件描述符用于磁盘文件读写。随着服务器建立越来越多的socket连接,文件句柄开始回收,数量减少。总之,RabbitMQ会优先将文件描述符用于建立socket连接,宁可牺牲频繁打开/关闭文件带来的磁盘操作性能损耗,这种取舍很容易理解,作为网络服务器,当然优先保障网络吞吐率了。因此,对于高并发连接数的多队列读写时,队列性能会稍微差那么一点,比如用RabbitMQ做RPC。

当服务器建立的socket连接已经达到限制(sockets_limit)时,服务器不再接受新连接。这里要区分清楚,RabbitMQ不再接收的是AMQP连接,而不是传输层的TCP连接,通过简单抓包分析即可清楚流程:

1
2
3
4
5
6
7
8
$ <span style="color: rgb(194, 12, 185); "><strong>sudo</strong></span> tcpdump host 10.101.17.13 and port 5672
17:24:12.214186 IP 10.101.17.166.56925 <span style="font-weight: bold;">></span> 10.101.17.13.amqp: Flags <span style="color: rgb(122, 8, 116); "><strong>[</strong></span>S<span style="color: rgb(122, 8, 116); "><strong>]</strong></span>, <span style="color: rgb(194, 12, 185); "><strong>seq</strong></span> 3319779561, win 65535, options <span style="color: rgb(122, 8, 116); "><strong>[</strong></span>mss 1368,<span style="color: rgb(194, 12, 185); "><strong>nop</strong></span>,wscale 5,<span style="color: rgb(194, 12, 185); "><strong>nop</strong></span>,<span style="color: rgb(194, 12, 185); "><strong>nop</strong></span>,TS val 1006381554 ecr 0,sackOK,eol<span style="color: rgb(122, 8, 116); "><strong>]</strong></span>, length 0
17:24:12.214231 IP 10.101.17.13.amqp <span style="font-weight: bold;">></span> 10.101.17.166.56925: Flags <span style="color: rgb(122, 8, 116); "><strong>[</strong></span>S.<span style="color: rgb(122, 8, 116); "><strong>]</strong></span>, <span style="color: rgb(194, 12, 185); "><strong>seq</strong></span> 1636058035, ack 3319779562, win 14480, options <span style="color: rgb(122, 8, 116); "><strong>[</strong></span>mss 1460,sackOK,TS val 24529834 ecr 1006381554,<span style="color: rgb(194, 12, 185); "><strong>nop</strong></span>,wscale 5<span style="color: rgb(122, 8, 116); "><strong>]</strong></span>, length 0
17:24:12.218795 IP 10.101.17.166.56925 <span style="font-weight: bold;">></span> 10.101.17.13.amqp: Flags <span style="color: rgb(122, 8, 116); "><strong>[</strong></span>.<span style="color: rgb(122, 8, 116); "><strong>]</strong></span>, ack 1, win 4110, options <span style="color: rgb(122, 8, 116); "><strong>[</strong></span><span style="color: rgb(194, 12, 185); "><strong>nop</strong></span>,<span style="color: rgb(194, 12, 185); "><strong>nop</strong></span>,TS val 1006381560 ecr 24529834<span style="color: rgb(122, 8, 116); "><strong>]</strong></span>, length 0
17:24:12.243184 IP 10.101.17.166.56925 <span style="font-weight: bold;">></span> 10.101.17.13.amqp: Flags <span style="color: rgb(122, 8, 116); "><strong>[</strong></span>P.<span style="color: rgb(122, 8, 116); "><strong>]</strong></span>, <span style="color: rgb(194, 12, 185); "><strong>seq</strong></span> 1:9, ack 1, win 4110, options <span style="color: rgb(122, 8, 116); "><strong>[</strong></span><span style="color: rgb(194, 12, 185); "><strong>nop</strong></span>,<span style="color: rgb(194, 12, 185); "><strong>nop</strong></span>,TS val 1006381583 ecr 24529834<span style="color: rgb(122, 8, 116); "><strong>]</strong></span>, length 8
17:24:12.243201 IP 10.101.17.13.amqp <span style="font-weight: bold;">></span> 10.101.17.166.56925: Flags <span style="color: rgb(122, 8, 116); "><strong>[</strong></span>.<span style="color: rgb(122, 8, 116); "><strong>]</strong></span>, ack 9, win 453, options <span style="color: rgb(122, 8, 116); "><strong>[</strong></span><span style="color: rgb(194, 12, 185); "><strong>nop</strong></span>,<span style="color: rgb(194, 12, 185); "><strong>nop</strong></span>,TS val 24529841 ecr 1006381583<span style="color: rgb(122, 8, 116); "><strong>]</strong></span>, length 0
17:24:22.247907 IP 10.101.17.166.56925 <span style="font-weight: bold;">></span> 10.101.17.13.amqp: Flags <span style="color: rgb(122, 8, 116); "><strong>[</strong></span>F.<span style="color: rgb(122, 8, 116); "><strong>]</strong></span>, <span style="color: rgb(194, 12, 185); "><strong>seq</strong></span> 9, ack 1, win 4110, options <span style="color: rgb(122, 8, 116); "><strong>[</strong></span><span style="color: rgb(194, 12, 185); "><strong>nop</strong></span>,<span style="color: rgb(194, 12, 185); "><strong>nop</strong></span>,TS val 1006391550 ecr 24529841<span style="color: rgb(122, 8, 116); "><strong>]</strong></span>, length 0
17:24:22.284914 IP 10.101.17.13.amqp <span style="font-weight: bold;">></span> 10.101.17.166.56925: Flags <span style="color: rgb(122, 8, 116); "><strong>[</strong></span>.<span style="color: rgb(122, 8, 116); "><strong>]</strong></span>, ack 10, win 453, options <span style="color: rgb(122, 8, 116); "><strong>[</strong></span><span style="color: rgb(194, 12, 185); "><strong>nop</strong></span>,<span style="color: rgb(194, 12, 185); "><strong>nop</strong></span>,TS val 24532352 ecr 1006391550<span style="color: rgb(122, 8, 116); "><strong>]</strong></span>, length 0

line 2-4是TCP握手包,成功建立TCP连接。line 5开始客户端向服务器端发送AMQP协议头字符串“AMQP0091”,共8个字节,开始AMQP握手。line 6是服务器回给客户端的ack包,但未发送AMQP connection.start方法,导致客户端一直等到超时(line 7-8),发送FIN包关闭TCP连接。至此,AMQP连接建立失败。

从客户端(Java SDK)来看上述这个过程,客户端通过ConnectionFactory实例的newConnection()方法创建一条AMQP连接。在网络层,它首先通过java.net.Socket与服务器建立一条TCP连接,发送协议协商字符串“AMQP0091”,然后启动MainLoop线程,通过封装的Frame实例来循环读取帧(readFrame()),注意readFrame()方法可能会有一个SocketTimeoutException的超时异常,这个超时时间是由socket实例setSoTimeout方法写入,默认是10s,由AMQConnection.HANDSHAKE_TIMEOUT常量指定。当超时发生在AMQP连接握手阶段时,就抛出一个SocketTimeoutException异常,发生在其他阶段(除心跳超时)时,什么都不做继续下一个循环:

1
2
3
4
[java]  view plain copy
  1. Caused by<span style="color:#339933">:</span> java.<span style="color:#006633">net</span>.<span style="color:#006633">SocketTimeoutException</span><span style="color:#339933">:</span> Timeout during <span style="color:#003399">Connection</span> negotiation  
  2.  at com.<span style="color:#006633">rabbitmq</span>.<span style="color:#006633">client</span>.<span style="color:#006633">impl</span>.<span style="color:#006633">AMQConnection</span>.<span style="color:#006633">handleSocketTimeout</span><span style="color:#009900">(</span>AMQConnection...  
  3.  <span style="color:#006633">at</span> com.<span style="color:#006633">rabbitmq</span>.<span style="color:#006633">client</span>.<span style="color:#006633">impl</span>.<span style="color:#006633">AMQConnection</span>.<span style="color:#006633">access</span>$500<span style="color:#009900">(</span>AMQConnection.<span style="color:#006633">java</span><span style="color:#339933">:</span><span style="color:#cc66cc">59</span><span style="color:#009900">)</span>  
  4.  at com.<span style="color:#006633">rabbitmq</span>.<span style="color:#006633">client</span>.<span style="color:#006633">impl</span>.<span style="color:#006633">AMQConnection</span>$MainLoop.<span style="color:#006633">run</span><span style="color:#009900">(</span>AMQConnection.<span style="color:#006633">java</span><span style="color:#339933">:</span><span style="color:#cc66cc">541</span><span style="color:#009900">)</span>  

这里的socket读取超时很容易跟连接超时搞混。连接超时由ConnectionFactory实例的setConnectionTimeout()方法指定,对应着网络层Socket实例connect()方法中的timeout参数,指的是完成TCP三次握手的超时时间;而读取超时是从socket中读取字节流的等待时间,前文已经说过,由Socket实例的setSoTimeout()指定。这在各种网络库中应该很常见,比如HttpClient。

私以为这种情况下更好的设计是应该由RabbitMQ主动断开与客户端的TCP连接,减少客户端等待时间。

最后一个问题,如何增加RabbitMQ的能够同时打开的连接数。通过前文可知,最大并发连接数由此进程可打开的最大文件描述符数量(乘以一个比例系数)决定,因此只要增加单个进程可打开的文件描述符数量即可。有几个常规方法,按作用范围可以归纳为以下几类:

1. 进程级别。在启动脚本rabbitmq-server中加入ulimit -n 10240命令(假设将最大文件描述符数量设置为10240,下同),相当于在shell中执行,由此shell进程fork出来的进程都能继承这个配置。

2. 用户级别。修改/etc/security/limits.conf文件,添加以下配置,重新登录生效:

1
2
user    soft    nofile    10240
user    hard    nofile    10240

3. 系统级别。

1
<span style="color: rgb(102, 102, 102);"># </span><span style="color: rgb(122, 8, 116); "><strong>echo</strong></span> 10240 <span style="font-weight: bold;">></span> <span style="font-weight: bold;">/</span>proc<span style="font-weight: bold;">/</span>sys<span style="font-weight: bold;">/</span>fs<span style="font-weight: bold;">/</span>file-max

上述设置只是针对proc文件系统,相当于修改了操作系统的运行时参数,重启后失效。要想永久生效,需要修改/etc/sysctl.conf文件,加入配置项fs.file-max=10240。

一个进程能打开的最大文件描述符数量受限于上述三个级别配置中的最小值。理论上,系统级别的配置数值必须要大于用户级别,用户级别的要大于进程级别的,只有这样配置才是安全的,否则进程容易因为打开文件数量问题受到来自操作系统的种种限制。操作系统为什么要限制可打开的文件描述符数量?为了系统安全。因为文件描述符本质上是一种内存中的数据结构,如果不加以限制,很容易被进程无意或恶意耗尽内存,比如fork bomb。

这篇关于rabbitmq最大连接数(Socket Descriptors)(转)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/815188

相关文章

微服务架构之使用RabbitMQ进行异步处理方式

《微服务架构之使用RabbitMQ进行异步处理方式》本文介绍了RabbitMQ的基本概念、异步调用处理逻辑、RabbitMQ的基本使用方法以及在SpringBoot项目中使用RabbitMQ解决高并发... 目录一.什么是RabbitMQ?二.异步调用处理逻辑:三.RabbitMQ的基本使用1.安装2.架构

Springboot使用RabbitMQ实现关闭超时订单(示例详解)

《Springboot使用RabbitMQ实现关闭超时订单(示例详解)》介绍了如何在SpringBoot项目中使用RabbitMQ实现订单的延时处理和超时关闭,通过配置RabbitMQ的交换机、队列和... 目录1.maven中引入rabbitmq的依赖:2.application.yml中进行rabbit

如何提高Redis服务器的最大打开文件数限制

《如何提高Redis服务器的最大打开文件数限制》文章讨论了如何提高Redis服务器的最大打开文件数限制,以支持高并发服务,本文给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录如何提高Redis服务器的最大打开文件数限制问题诊断解决步骤1. 修改系统级别的限制2. 为Redis进程特别设置限制

SpringBoot整合Canal+RabbitMQ监听数据变更详解

《SpringBoot整合Canal+RabbitMQ监听数据变更详解》在现代分布式系统中,实时获取数据库的变更信息是一个常见的需求,本文将介绍SpringBoot如何通过整合Canal和Rabbit... 目录需求步骤环境搭建整合SpringBoot与Canal实现客户端Canal整合RabbitMQSp

poj 3723 kruscal,反边取最大生成树。

题意: 需要征募女兵N人,男兵M人。 每征募一个人需要花费10000美元,但是如果已经招募的人中有一些关系亲密的人,那么可以少花一些钱。 给出若干的男女之间的1~9999之间的亲密关系度,征募某个人的费用是10000 - (已经征募的人中和自己的亲密度的最大值)。 要求通过适当的招募顺序使得征募所有人的费用最小。 解析: 先设想无向图,在征募某个人a时,如果使用了a和b之间的关系

poj 3258 二分最小值最大

题意: 有一些石头排成一条线,第一个和最后一个不能去掉。 其余的共可以去掉m块,要使去掉后石头间距的最小值最大。 解析: 二分石头,最小值最大。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <c

poj 2175 最小费用最大流TLE

题意: 一条街上有n个大楼,坐标为xi,yi,bi个人在里面工作。 然后防空洞的坐标为pj,qj,可以容纳cj个人。 从大楼i中的人到防空洞j去避难所需的时间为 abs(xi - pi) + (yi - qi) + 1。 现在设计了一个避难计划,指定从大楼i到防空洞j避难的人数 eij。 判断如果按照原计划进行,所有人避难所用的时间总和是不是最小的。 若是,输出“OPETIMAL",若

poj 2135 有流量限制的最小费用最大流

题意: 农场里有n块地,其中约翰的家在1号地,二n号地有个很大的仓库。 农场有M条道路(双向),道路i连接着ai号地和bi号地,长度为ci。 约翰希望按照从家里出发,经过若干块地后到达仓库,然后再返回家中的顺序带朋友参观。 如果要求往返不能经过同一条路两次,求参观路线总长度的最小值。 解析: 如果只考虑去或者回的情况,问题只不过是无向图中两点之间的最短路问题。 但是现在要去要回

poj 2594 二分图最大独立集

题意: 求一张图的最大独立集,这题不同的地方在于,间接相邻的点也可以有一条边,所以用floyd来把间接相邻的边也连起来。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <sta

poj 3422 有流量限制的最小费用流 反用求最大 + 拆点

题意: 给一个n*n(50 * 50) 的数字迷宫,从左上点开始走,走到右下点。 每次只能往右移一格,或者往下移一格。 每个格子,第一次到达时可以获得格子对应的数字作为奖励,再次到达则没有奖励。 问走k次这个迷宫,最大能获得多少奖励。 解析: 拆点,拿样例来说明: 3 2 1 2 3 0 2 1 1 4 2 3*3的数字迷宫,走两次最大能获得多少奖励。 将每个点拆成两个