摘要:套接字端口共享选项允许多个套接字监听同一个绑定的网络地址和端口,这样一来内核就可以将外部的请求连接负载均衡到这些套接字上来。致谢感谢在英特尔工作的卢英奇和,他们每个人各自贡献了使得套接字端口共享生效的解决方案。
英文原文地址:Socket Sharding in NGINX Release 1.9.1
译者:UPYUN CDN 开发工程师 其实不想走
NGINX 1.9.1 发布版本中引入了一个新的特性 —— 允许套接字端口共享,该特性适用于大部分最新版本的操作系统,其中也包括 DragonFly BSD 和内核 3.9 以后的 Linux 操作系统。套接字端口共享选项允许多个套接字监听同一个绑定的网络地址和端口,这样一来内核就可以将外部的请求连接负载均衡到这些套接字上来。(对于 NGINX Plus 的用户来说,该特性将会在年底发布的版本 7 中得到支持)
实际上很多潜在的用户希望使用端口重用功能。其他服务也可以简单的进行热更新升级「NGINX 支持 多种方式 的热更新」。对于 NGINX 来说,打开该选项可以通过在特定场景下减少连接锁竞争而提高性能。
如下图所示,在该选项没有生效的前提下,一个多带带的监听套接字会通知所有的工作进程,每个进程则会试图争抢接管某个连接:
当该选项生效时,这个时候对于每个网络地址和端口就会有多个监听套接字,每个工作进程对应一个套接字,内核会决定由哪个监听套接字(也就是决定哪个工作进程)接管进来的连接。这个特性可以减少进程与进程之间为接收连接产生的锁竞争而提高多核系统的性能。但是,如果当一个工作进程处于阻塞操作时,这个时候不仅会影响已经被该进程接收的连接,还会阻塞由系统准备分配给该进程的连接请求:
配置套接字共享如下面配置所示,可以通过在 listen 指令后添加新的参数 reuseport 来为 HTTP 或者 TCP(流模块)打开套接字端口共享功能:
对于套接字来说,添加 reuseport 参数也就等于禁止了 accept_mutex 指令了,因为 mutex 对于 reuseport 来说是多余的,不过对于那些不希望使用套接字端口共享特性的端口来说,我们则有必要设置 accept_mutex。
reuseport 性能压力测试我通过运行 wrk 压测工具来压测一个跑在 36 核亚马逊实例上并开启 4 个工作进程的 NGINX。为了减少网络对于测试结果的影响,我们的客户端和 NGINX 都是运行在本地的,并且 NGINX 只返回 OK 字符串而不返回文件。我对比了三个不同的配置,一个是默认的(等同于 accept_mutex on),另一个是 accept_mutex off,还有一个则是 reuseport。正如下图所示,使用 reuseport 后每秒能处理的请求数比其他的两个增加了 2-3 倍,并且同时减少了平均延迟和平均延迟的标准差。
我还尝试客户端和 NGINX 分别运行在不同的主机上跑相关的压力测试,但这一次 NGINX 返回的是一个 HTML 文件。正如下表所示,与上图的结果类似,使用端口重用能减少请求的处理延迟,并且延迟标准差减少的更加明显(大概是 10 倍)。其他结果(并没有在下表中显示)则更加让人欣喜。通过端口重用,请求的压力被各个工作进程均衡掉,而在默认条件下(也就是 accept_mutex 打开),一些工作进程会得到比较高的负载,而在 accept_mutex 关闭的时候,所有的进程都会显示负载比较高。
在上述的压力测试中,请求的频率很高但是每个请求并不需要复杂的处理。其他一些初步的测试也表明端口重用特性在网络流量匹配的时候最能提高性能。(该参数并不能在邮件模块的上下文监听指令中生效,因为邮件的网络流量并不能匹配这个特性)。我们建议你在使用 reuseport 这个指令前先在你的 NGINX 实例上进行性能测试,而不是全部的 NGINX 实例都使用。对于测试 NGINX 的一些小提示,可以参考 Konstantin Pavlov 在 2014 NGINX 大会上的演讲。
致谢感谢在英特尔工作的卢英奇和 Sepherosa Ziehau,他们每个人各自贡献了使得套接字端口共享生效的解决方案。NGINX 开发小组合并了他们俩的想法从而创造出目前看来比较理想的解决方案。
原文链接:http://io.upyun.com/2015/07/20/nginx-socket-sharding/
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/39186.html
摘要:常规的网络应用设计都是为每个连接分配一个线程或进程。深入理解进程每个进程都是用配置进行初始化的,并且由主进程提供了一组监听套接字。套接字上发生事件后,进程开始进行处理监听套接字上的事件意味着有个客户端发起了一盘新的象棋游戏。 NGINX在web性能上的表现尤为出众,这完全得益于其设计方式,许多web和应用服务器都是基于线程或进程这种简单的架构,NGINX用了一种精妙的事件驱动架构,在现...
摘要:而对于堆内存,通常需要程序员进行管理。我们通常说的内存管理亦是只堆空间内存管理。内存管理整体可以分为个部分,第一部分是常规的内存池,用于进程平时所需的内存管理第二部分是共享内存的管理。将内存块按照的整数次幂进行划分最小为最大为。 施洪宝 一. 概述 应用程序的内存可以简单分为堆内存,栈内存。对于栈内存而言,在函数编译时,编译器会插入移动栈当前指针位置的代码,实现栈空间的自管理。而对于...
摘要:而对于堆内存,通常需要程序员进行管理。二内存池管理说明本部分使用的版本为具体源码参见文件实现使用流程内存池的使用较为简单可以分为步,调用函数获取指针。将内存块按照的整数次幂进行划分最小为最大为。 运营研发团队 施洪宝 一. 概述 应用程序的内存可以简单分为堆内存,栈内存。对于栈内存而言,在函数编译时,编译器会插入移动栈当前指针位置的代码,实现栈空间的自管理。而对于堆内存,通常需要程序...
阅读 1016·2021-11-22 15:33
阅读 3301·2021-11-08 13:20
阅读 1272·2021-09-22 10:55
阅读 2005·2019-08-29 11:08
阅读 720·2019-08-26 12:24
阅读 3011·2019-08-23 17:15
阅读 2142·2019-08-23 16:12
阅读 1873·2019-08-23 16:09