/***********************************************************

* Author : Samson

* Date : 07/14/2015

* Test platform:

* gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2

* GNU bash, 4.3.11(1)-release (x86_64-pc-linux-gnu)

* Nginx version:

* Nginx 1.6.2

* Nginx 1.8.0

* *********************************************************/

GNU Linux高并发性能优化方案

在GNU Linux系统中,影响连接个数的因素主是由于单个进程能够打开的最大文件数、port数量决定的;而一个基于tcp的server的并发,除了上文说过的两个因素外,还有由于基本的tcp连接的非常多属性,而问题最大的则是连接断开后的连接会在TIME_WAIT状态一直存在60秒,这就造成了在大量高并发的情况下当连接为此TIME_WAIT状态时没有可用连接。

1、改动port号范围:

默认范围:

cat /proc/sys/net/ipv4/ip_local_port_range

32768 61000

众所周知,port号的范围为0~65535,知名port号介于1~255之间。256~1023之间的port号通常都是由系统占用,所以我们须要很多其他能够使用的port号的话,那么就须要改动系统中对port使用范围变量;

改动方法:

1)、echo “1024 65535” > /proc/sys/net/ipv4/ip_local_port_range

2)、在/etc/sysctl.conf中进行例如以下的设置:

net.ipv4.ip_local_port_range=1024 65535

然后运行: sysctl -p 对这些设置进行生效;

3)、直接使用命令进行系统变量的优化

sysctl -w net.ipv4.ip_local_port_range=1024 65535

若port不够用的时候报错信息

若没有空暇的port能够使用时。将会报错。如:

connect() to ip:80 failed (99: Cannot assign requested address)

注意:

改动了port的范围后。若是有多个服务在一台设备上时。若是先被其他服务先行启动将另外的服务的“众所周知”的port给占用了,那么这个问题就比較不太优点理,在这种情况下,对于须要监听的服务进行先行启动,将服务要使用的“众所周知”的port先行占用。就不会发生比較麻烦的情况了。

2、改动系统全部进程能够打开的文件数:

cat /proc/sys/fs/file-max

203466

若要改动的话:

echo 403466 > /proc/sys/fs/file-max

3、对于处理TIME_WAIT的问题,通过设置下面两项能够极大地提高并发

在进行了通信完毕后,完毕通信的连接差点儿相同在秒级间就进行了回收,经測试,再使用netstat -ntp,都不会再看到刚才使用的连接,可是在官方文档中说明了(Default value is 0. It should not be changed without advice/request of technical experts.)使用这两种方式须要非常慎重;例如以下(改动方法请參看上面的改动方式):

net.ipv4.tcp_tw_reuse = 1

//表示开启重用。同意将TIME-WAIT sockets又一次用于新的TCP连接,默觉得0,表示关闭;

net.ipv4.tcp_tw_recycle = 1

//表示开启TCP连接中TIME-WAIT sockets的高速回收,默觉得0,表示关闭。

由于以上两项在官方文档中有这种描写叙述”It should not be changed without advice/request of technical experts.“,也即是说,这两项在某些情况下会产生负作用或影响。

可能出现的影响:

net.ipv4.tcp_tw_recycle是与net.ipv4.tcp_timestamps是密切相关的,而net.ipv4.tcp_timestamps默认是开启的,当tcp_tw_recycle和tcp_timestamps同一时候打开时会激活TCP的一种隐藏属性:缓存连接的时间戳。

60秒内,同一源IP的兴许请求的时间戳小于缓存中的时间戳,内核就会丢弃该请求。

什么样的场景会使时间戳会小于缓存中的时间戳呢?

相似的故障场景:

多个client通过一个NAT訪问一台server,由于NAT仅仅改IP地址信息,但不会改变timestamp(TCP的时间戳不是系统时间。而是系统启动的时间uptime。所以两台机器的的TCP时间戳一致的可能性非常小)。那么就会出现请求被丢弃的情况,所以非常easy造成连接失败的情况。

server上开启了tcp_tw_recycle用于TIME_WAIT的高速回收故障现象和分析步骤:

1) 通过NAT出口的多个client常常请求Webserver无响应;

2) 在server抓包,发现服务端能够收到client的SYN请求。可是没有回应SYN,ACK,也就是说内核直接将包丢弃了。

解决方法:

1) 关闭服务其端的tcp_timestamps。故障能够解决,可是这么做存在安全和性能隐患。强烈建议不关闭此变量;

2) 关闭tcp_tw_recycle,故障也能够解决。推荐NAT环境下的机器不要开启该选项;

3)调整网络拓扑避免NAT的这种相似的情况。

4)client使用同一个NTP服务进行时间同步。使时间同步避免timestamp差异;

其他优化參数

net.ipv4.tcp_fin_timeout = 30

//表示假设套接字由本端要求关闭。这个參数决定了它保持在FIN-WAIT-2状态的时间。

net.ipv4.tcp_keepalive_time = 1200

//表示当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时,改为20分钟。

net.ipv4.tcp_max_tw_buckets = 5000

//表示系统同一时候保持TIME_WAIT套接字的最大数量,假设超过这个数字,

//TIME_WAIT套接字将立马被清除并打印警告信息。默觉得180000,改为5000。

//对于Apache、Nginx等server,上几行的參数能够非常好地降低TIME_WAIT套接字数量。

//此值和/proc/sys/net/ipv4/tcp_max_syn_backlog是一样的,也是对listen()函数中的backlog參数的限制,依照文档中的说明,应该最好是设置成和/proc/sys/net/ipv4/tcp_max_syn_backlog一样的值,此值的默认值是128:

cat /proc/sys/net/core/somaxconn

128

net.core.somaxconn = 40000

//指定未完毕连接队列的最大长度,默觉得1024个,是对socket的listen()函数中的backlog数量的限制,若server过载能够增大此值;

cat /proc/sys/net/ipv4/tcp_max_syn_backlog

1024

net.ipv4.tcp_max_syn_backlog = 40000

4、调整每一个进程最大打开文件描写叙述符限制

调整文件描写叙述符限制:

$ ulimit -n

1024

改动此值。ulimit -n 4096

$vi /etc/security/limits.conf

//Setting Shell Limits for File Descriptors

*soft nofile 8192

*hard nofile 8192

这二者的差别,在/etc/security/limits.conf配置文件里配置好后,进行重新启动后再次使用ulimit -n将得到的值是8192.

5、通过又一次编译内核代码降低TCP连接的TIME-WAIT时间

在内核代码中的include/net/tcp.h文件里。TIME-WAIT的定义例如以下:

//#define TCP_TIMEWAIT_LEN (60*HZ) /* how long to wait to destroy TIME-WAIT

* state, about 60 seconds */

能够通过改动TCP_TIMEWAIT_LEN的值。来加快连接的释放;改动后,内核进行编译后进行替换。

Nginx的配置与系统环境变量间的关系

系统默认的是1024。若在Nginx的配置文件里,配置了worker_connections 4096;后,再启动时,会出现这种一个警告:

nginx: [warn] 4096 worker_connections exceed open file resource limit: 1024

Nginx中的这些和系统变量有关的,是依据系统中的配置而进行设置的。若大于了系统变量的范围的话,不会生效,会被默认成系统的值,如每一个worker进行能够打开的文件数量就被默认成系统的值1024;

注意:

改动内核变量是有风险的,最好是在測试环境进行測试通过。再将配置平移到生产环境。

REF:

IPV4和IPV6的内核參数各项的意义及取值:

https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt

关于/proc文件夹下的主要项的介绍:

http://man7.org/linux/man-pages/man5/proc.5.html

GNU Linux高并发性能优化方案的更多相关文章

  1. 用Netty开发中间件:高并发性能优化

    用Netty开发中间件:高并发性能优化 最近在写一个后台中间件的原型,主要是做消息的分发和透传.因为要用Java实现,所以网络通信框架的第一选择当然就是Netty了,使用的是Netty 4版本.Net ...

  2. 用Netty开发中间件:高并发性能优化(转)

    用Netty开发中间件:高并发性能优化 最近在写一个后台中间件的原型,主要是做消息的分发和透传.因为要用Java实现,所以网络通信框架的第一选择当然就是Netty了,使用的是Netty 4版本.Net ...

  3. SpringCloud高并发性能优化

    1. SpringCloud高并发性能优化 1.1. 前言 当系统的用户量上来,每秒QPS上千后,可能就会导致系统的各种卡顿,超时等情况,这时优化操作不可避免 1.2. 优化步骤 第一步:优化大SQL ...

  4. 高并发&性能优化(二)------系统监控工具使用

    上一篇主要从总体介绍了高并发&性能优化的相关思路和方法,本篇主要介绍系统监控工具. [CPU查看工具] ------top命令(性能) 进入top命令后,按1即可看到每核CPU的运行指标与详细 ...

  5. Java 架构师+高并发+性能优化+Spring boot大型分布式项目实战

    视频课程内容包含: 高级 Java 架构师包含:Spring boot.Spring cloud.Dubbo.Redis.ActiveMQ.Nginx.Mycat.Spring.MongoDB.Zer ...

  6. 高并发&性能优化(一)------总体介绍

    [开篇词] 本文主要通过一些经典的高并发场景,以及一些基本的运维工具来讲述一些关于高并发以及性能优化相关的内容,主要包括性能瓶颈的定位,性能调优的思路和技巧等. [性能的衡量指标] ?什么是性能 性能 ...

  7. 大型php网站性能和并发访问优化方案(转载自php中文网)

               网站性能优化对于大型网站来说非常重要,一个网站的访问打开速度影响着用户体验度,网站访问速度慢会造成高跳出率,小网站很好解决,那对于大型网站由于栏目多,图片和图像都比较庞大,那该怎 ...

  8. 大型php网站性能和并发访问优化方案

    网站性能优化对于大型网站来说非常重要,一个网站的访问打开速度影响着用户体验度,网站访问速度慢会造成高跳出率,小网站很好解决,那对于大型网站由于栏目多,图片和图像都比较庞大,那该怎么进行整体性能优化呢? ...

  9. DedeCMS数据负载性能优化方案简单几招让你提速N倍

    前文介绍了DedeCMS栏目列表页实现完美分页的方法,避免了大部分重复栏目标题对搜索引擎的影响,对SEO更有利.今天,分享一下DedeCMS数据负载性能优化的方法. 接触织梦也有三年多时间了,对它可谓 ...

随机推荐

  1. 椭圆曲线加密算法(ECC)原理和C++实现源码(摘录)

    /* 1.用户A选定一条适合加密的椭圆曲线Ep(a,b)(如:y2=x3+ax+b),并取椭圆曲线上一点,作为基点G. 2.用户A选择一个私有密钥k,并生成公开密钥K=kG. 3.用户A将Ep(a,b ...

  2. latex不能识别eps图片

    latex中可以使用.eps的图片,许多文档都介绍了怎么引用这种格式的图片,但没有给出使用过程中的注意事项.我在使用MIKTEX的时候,latex文档中引入.eps图片遇到了这样的问题.编译的时候显示 ...

  3. LINUX下使用NC反弹CMDSHELL提权

    很多时候linux拿到shell了,然后在菜刀或Shell里执行简单命令不允许!说明权限很死或者被管理禁止了!这里我已NC将SHELL反弹回本地提权!先看下linux内核 2.6.18-194.11. ...

  4. python scikit-learn选择正确估算器

    下图摘自官方文档 链接 http://scikit-learn.org/stable/tutorial/machine_learning_map/index.html

  5. SQL 备份还原单个表

    如果只想备份或恢复单个表而不想备份或恢复整个数据库的话,往往有以下方法: 1.在Sql server2000 中可以使用DTS来将该表的数据导出成另外的文件格式.当需要恢复时,可以将该文件中数据再通过 ...

  6. os.waitpid()无法获取sys.exit()退出时的status code

    [目的] 父进程使用os.waitpid()等待子进程退出,并检测子进程的exit code,以决定是否重启子进程. (常见的应用场景是:子进程接收外部命令,收到"stop"时退出 ...

  7. C# 继承实现父类方法、重写、重载

    继承是派生类(子类)去实现(重写<override>.重构<new>)基类(父类)的方法或属性.从而获取在派生类中要实现的功能. 子类调用父类构造方法,在父类中有个实现姓名和年 ...

  8. java中的序列化和反序列化学习笔记

    须要序列化的Person类: package cn.itcast_07; import java.io.Serializable; /* * NotSerializableException:未序列化 ...

  9. 关于Objective-c和Java下DES加密保持一致的方式

    转载自:http://www.cnblogs.com/janken/archive/2012/04/05/2432930.html 最近做了一个移动项目,是有服务器和客户端类型的项目,客户端是要登录才 ...

  10. VS2013编译boost1.55库

    1. 官网下载最新的Boost库,我的是1.55 2. 在使用vs2013编译boost-1.55.0之前,先要给boost做下修改: boost_1_55_0\boost\intrusive\det ...