socket so_reuseport提高服务端性能
来源:互联网 发布:去哪里下无损音乐 知乎 编辑:程序博客网 时间:2024/05/29 02:25
以前就在国外的论坛接触过 SO_REUSEPORT,这两天朋友群又在传播nginx 1.9 reuseport多进程监听参数。 那咱们简单说下 SO_REUSEPORT的应用场景, 为什么会用他? 然而在讲解SO_REUSEPORT之前,需要先说下我们常用的网络模型。
文章写得不太严谨, 请砖家拍砖,另外标注下原文地址, http://xiaorui.cc/?p=2413
当前Linux网络应用程序问题
运行在Linux系统上网络应用程序,为了利用多核的优势,一般使用以下比较典型的多进程/多线程服务器模型:
单线程listen/accept,多个工作线程接收任务分发,虽CPU的工作负载不再是问题,但会存在:
单线程listener,在处理高速率海量连接时,一样会成为瓶颈
CPU缓存行丢失套接字结构(socket structure)现象严重
所有工作线程都accept()在同一个服务器套接字上呢,一样存在问题:
多线程访问server socket锁竞争严重
高负载下,线程之间处理不均衡,有时高达3:1不均衡比例
导致CPU缓存行跳跃(cache line bouncing)
在繁忙CPU上存在较大延迟
上面模型虽然可以做到线程和CPU核绑定,但都会存在:
单一listener工作线程在高速的连接接入处理时会成为瓶颈
缓存行跳跃
很难做到CPU之间的负载均衡
随着核数的扩展,性能并没有随着提升
比如HTTP CPS(Connection Per Second)吞吐量并没有随着CPU核数增加呈现线性增长:
Linux kernel 3.9带来了SO_REUSEPORT特性,可以解决以上大部分问题
在多核时代,一般使用以下比较典型的多进程/多线程服务器模型。
首先需要单线程listen一个端口上,然后由多个工作进程/线程去accept()在同一个服务器套接字上。
第一个性能瓶颈,单线程listener,在处理高速率海量连接时,一样会成为瓶颈
第二个性能瓶颈,多线程访问server socket锁竞争严重。
那么怎么解决? 这里先别扯什么分布式调度,集群xxx的 , 就拿单机来说问题。在 Linux kernel 3.9带来了SO_REUSEPORT特性,她可以解决上面(单进程listen,多工作进程accept() )的问题.
看图说话,对比SO_REUSADDR的模型,我想你应该看懂SO_REUSEPORT是个什么东西了。 SO_REUSEPORT是 支持多个进程或者线程绑定到同一端口,提高服务器程序的吞吐性能,具体来说解决了下面的几个问题:
允许多个套接字 bind()/listen() 同一个TCP/UDP端口
每一个线程拥有自己的服务器套接字
在服务器套接字上没有了锁的竞争,因为每个进程一个服务器套接字
内核层面实现负载均衡
安全层面,监听同一个端口的套接字只能位于同一个用户下面
我这边用python做了一个关于python SO_REUSEPORT服务端测试. 测试之前,已经要确定你的linux内核版本是3.9, 在mac下进行so_reuseport测试,貌似不会提示端口被绑定,但是后启动的进程会阻塞.
file: reuseport.py
Python
import socketimport os#xiaorui.ccs = socket.socket(socket.AF_INET, socket.SOCK_STREAM)s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)s.bind(('0.0.0.0', 1234))s.listen(1)while True: conn, addr = s.accept() print('Connected to {}'.format(os.getpid())) data = conn.recv(1024) conn.send(data) conn.close()
importsocketimportos#xiaorui.ccs=socket.socket(socket.AF_INET,socket.SOCK_STREAM)s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEPORT,1)s.bind(('0.0.0.0',1234))s.listen(1) whileTrue: conn,addr=s.accept() print('Connected to {}'.format(os.getpid())) data=conn.recv(1024) conn.send(data) conn.close()
开始测试 reuseport.py
Python
nohup python reuseport.py &nohup python reuseport.py &nohup python reuseport.py &nohup python reuseport.py &nohup python reuseport.py &
nohup pythonreuseport.py&nohup pythonreuseport.py&nohup pythonreuseport.py&nohup pythonreuseport.py&nohup pythonreuseport.py&
使用nc测试
Python
echo 'xiaorui.cc' | nc localhost 1234
echo'xiaorui.cc'|nclocalhost1234
有些文章说,在python下多进程绑定同一个端口,也就是有人常说的prefork,他其实也是单个进程去listen监听端口,剩余的worker去accept获取用户请求而已. 如果想用python实现真正的多进程绑定在多一个端口,那只能是用so_reuseport模式 。
其实用python开发支持SO_REUSEPORT的服务端有个大好处,不用写多进程,多线程了.. 算是一个偷懒的方法。 我自己觉得python离 SO_REUSEPORT真实提高socket性能的应用场景比较的远,就python这性能…. 倒是可以迅速的提高socket开发效率..
另外标注下,SO_REUSEADDR和SO_REUSEPORT的区别
SO_REUSEADDR提供如下四个功能:
SO_REUSEADDR允许启动一个监听服务器并捆绑其众所周知端口,即使以前建立的将此端口用做他们的本地端口的连接仍存在。这通常是重启监听服务器时出现,若不设置此选项,则bind时将出错。
SO_REUSEADDR允许在同一端口上启动同一服务器的多个实例,只要每个实例捆绑一个不同的本地IP地址即可。对于TCP,我们根本不可能启动捆绑相同IP地址和相同端口号的多个服务器。
SO_REUSEADDR允许单个进程捆绑同一端口到多个套接口上,只要每个捆绑指定不同的本地IP地址即可。这一般不用于TCP服务器。
SO_REUSEADDR允许完全重复的捆绑:当一个IP地址和端口绑定到某个套接口上时,还允许此IP地址和端口捆绑到另一个套接口上。一般来说,这个特性仅在支持多播的系统上才有,而且只对UDP套接口而言(TCP不支持多播)。
SO_REUSEPORT选项有如下语义:
此选项允许完全重复捆绑,但仅在想捆绑相同IP地址和端口的套接口都指定了此套接口选项才行。
如果被捆绑的IP地址是一个多播地址,则SO_REUSEADDR和SO_REUSEPORT等效。
学习SO_REUSEPORT时,参考的文章:
http://www.blogjava.net/yongboy/archive/2015/02/12/422893.html
http://www.cnblogs.com/mydomain/archive/2011/08/23/2150567.html
- socket so_reuseport提高服务端性能
- socket选项 SO_REUSEPORT
- socket新特性之SO_REUSEPORT
- socket选项--SO_LINGER,SO_REUSEADDR(SO_REUSEPORT)
- 提高 Linux 上 socket 性能
- 提高Linux上socket 性能
- 提高 Linux 上 socket 性能
- 提高 Linux 上 socket 性能
- 提高 Linux 上 socket 性能
- 提高 Linux 上 socket 性能
- 提高 Linux 上 socket 性能
- 提高 Linux 上 socket 性能
- 提高 Linux 上 socket 性能
- 提高 Linux 上 socket 性能
- 提高 Linux 上 socket 性能
- 提高 Linux 上 socket 性能
- 提高 Linux 上 socket 性能
- 提高 Linux 上 socket 性能
- Runtime优雅的解决UIButton多次点击(重复点击)
- android WindowManager解析与骗取QQ密码案例分析
- Git自学(一)Git简介
- 【Flume】flume中sink到hdfs,文件系统频繁产生文件,文件滚动配置不起作用?
- Hive 安装及元数据库配置
- socket so_reuseport提高服务端性能
- LeetCode P137:single number
- VisualStudio安装加载等待CSS特效
- 常用的JS设计模式
- 浙大PAT甲级 1061
- XListView上拉加载下拉刷新
- RasGetCredentials
- 22
- sql server如何直接在表中修改数据