so_reuseport linux,Linux 最新SO_REUSEPORT特性

1、前言

昨天总结了一下Linux下网络编程“惊群”现象,给出Nginx处理惊群的方法,使用互斥锁。为例发挥多核的优势,目前常见的网络编程模型就是多进程或多线程,根据accpet的位置,分为如下场景:

(1)单进程或线程创建socket,并进行listen和accept,接收到连接后创建进程和线程处理连接

(2)单进程或线程创建socket,并进行listen,预先创建好多个工作进程或线程accept()在同一个服务器套接字、

f3993a5f7bdd40a32811108f991c24cb.png                      

146161e752d096edb51a182eaf4971aa.png

这两种模型解充分发挥了多核CPU的优势,虽然可以做到线程和CPU核绑定,但都会存在:

单一listener工作进程胡线程在高速的连接接入处理时会成为瓶颈

多个线程之间竞争获取服务套接字

缓存行跳跃

很难做到CPU之间的负载均衡

随着核数的扩展,性能并没有随着提升

Linux kernel 3.9带来了SO_REUSEPORT特性,可以解决以上大部分问题。

2、SO_REUSEPORT解决了什么问题

SO_REUSEPORT支持多个进程或者线程绑定到同一端口,提高服务器程序的性能,解决的问题:

允许多个套接字 bind()/listen() 同一个TCP/UDP端口

每一个线程拥有自己的服务器套接字

在服务器套接字上没有了锁的竞争

内核层面实现负载均衡

安全层面,监听同一个端口的套接字只能位于同一个用户下面

其核心的实现主要有三点:

扩展 socket option,增加 SO_REUSEPORT 选项,用来设置 reuseport。

修改 bind 系统调用实现,以便支持可以绑定到相同的 IP 和端口

修改处理新建连接的实现,查找 listener 的时候,能够支持在监听相同 IP 和端口的多个 sock 之间均衡选择。

有了SO_RESUEPORT后,每个进程可以自己创建socket、bind、listen、accept相同的地址和端口,各自是独立平等的。让多进程监听同一个端口,各个进程中accept socket fd不一样,有新连接建立时,内核只会唤醒一个进程来accept,并且保证唤醒的均衡性。

3、测试代码

include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define IP "127.0.0.1"

#define PORT 8888

#define WORKER 4

#define MAXLINE 4096

int worker(int i)

{

struct sockaddr_in address;

bzero(&address, sizeof(address));

address.sin_family = AF_INET;

inet_pton( AF_INET, IP, &address.sin_addr);

address.sin_port = htons(PORT);

int listenfd = socket(PF_INET, SOCK_STREAM, );

assert(listenfd >= );

int val =;

/*set SO_REUSEPORT*/

if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(val))<0) {

perror("setsockopt()");

}

int ret = bind(listenfd, (struct sockaddr*)&address, sizeof(address));

assert(ret != -);

ret = listen(listenfd, );

assert(ret != -);

while () {

printf("I am worker %d, begin to accept connection.\n", i);

struct sockaddr_in client_addr;

socklen_t client_addrlen = sizeof( client_addr );

int connfd = accept( listenfd, ( struct sockaddr* )&client_addr, &client_addrlen );

if (connfd != -) {

printf("worker %d accept a connection success. ip:%s, prot:%d\n", i, inet_ntoa(client_addr.sin_addr), client_addr.sin_port);

} else {

printf("worker %d accept a connection failed,error:%s", i, strerror(errno));

}

char buffer[MAXLINE];

int nbytes = read(connfd, buffer, MAXLINE);

printf("read from client is:%s\n", buffer);

write(connfd, buffer, nbytes);

close(connfd);

}

return ;

}

int main()

{

int i = ;

for (i = ; i < WORKER; i++) {

printf("Create worker %d\n", i);

pid_t pid = fork();

/*child process */

if (pid == ) {

worker(i);

}

if (pid < ) {

printf("fork error");

}

}

/*wait child process*/

while (wait(NULL) != )

;

if (errno == ECHILD) {

fprintf(stderr, "wait error:%s\n", strerror(errno));

}

return ;

}

我的测试机器内核版本为:

cd5ca39980ff999cbe78813c2715ca0e.png

测试结果如下所示:

2fb6fcc949f9903f87e8e0a709a3c7f7.png

399536ff18feeeb081c58178dc1f28de.png

32a4a1706b68e9e8e96352a96ec811a6.png

从结果可以看出,四个进程监听相同的IP和port。

4、参考资料

http://lists.dragonflybsd.org/pipermail/users/2013-July/053632.html

http://www.blogjava.net/yongboy/archive/2015/02/12/422893.html

http://m.blog.chinaunix.net/uid-10167808-id-3807060.html

Atitit&period;linux&&num;160&semi;内核&&num;160&semi;新特性&&num;160&semi;新功能

Atitit.linux 内核 新特性 新功能 1.  Linux 3.2内核新特性 2012-02-12 22:41:471 1.1. EXT4:支持更大的块2 1.2. BTRFS:更快的数据清理 ...

SQL2043N 与 linux的randomize&lowbar;va&lowbar;space特性

自从数据库服务器从redhat4.6升级到redhat5.5之后,在使用TSM备份的时候偶尔会出现SQL2043N  查看错误: [db2inst1@limt ~]$ db2 ? SQL2043N S ...

linux的bash特性

Shell本身是应用程序,是用户与操作系统之间完成交互式操作的一个接口程序,为用户提供简化的操作. Bourne Again Shell,简称bash,是Linux系统中默认的shell程序. Bas ...

linux基础02-bash特性

Linux的行结束符是:[$] Windows的行结束符是:[$+回车] 目录管理:ls.cd.pwd.mkdir.rmdir.tree 文件管理:touch.stat.file.rm.cp.mv.n ...

linux bash基本特性

一.bash 基础特性 (1)命令历史的功能 history: 环境变量 HISTSIZE:命令历史记录的条数 HISTFILE: ~/.bash_history 每个用户都有自己独立的命令历史文件 ...

&lbrack;转&rsqb;linux最新分区方案

FROM : http://www.cnblogs.com/chenlulouis/archive/2009/08/27/1554983.html 我的服务器是500G.最重要的是/var分区一定要大 ...

支持 Windows 10 最新 PerMonitorV2 特性的 WPF 多屏高 DPI 应用开发

Windows 10 自 1703 开始引入第二代的多屏 DPI 机制(PerMonitor V2),而 WPF 框架可以支持此第二代的多屏 DPI 机制. 本文将介绍 WPF 框架利用第二代多屏 D ...

Linux bash基础特性二

shell脚本的组成部分 shebang 各种命令组合 编程变量种类 本地变量: 仅仅在当前的shell生效 环境变量: 在当前和子shell生效 局部变量: shell进程某代码片段 位置变量: $ ...

Linux bash基础特性一

命令别名 alias cdnet=”cd /etc/sysconfig/network-scripts” 针对用户的别名: “~/.bashrc” 针对系统的别名:”/etc/bashrc” 重读配置 ...

随机推荐

oracle 11g ORA-12541&colon; TNS&colon; 无监听程序 &lpar;DBD ERROR&colon; OCIServerAttach&rpar;

From :http://www.cnblogs.com/wangyt223/archive/2012/12/11/2812931.html em无法浏览,同时监听起不来.同时他的监听服务还是正常的, ...

268&period; Missing Number

Given an array containing n distinct numbers taken from 0, 1, 2, ..., n, find the one that is missin ...

Windows平台下为Python添加MySQL支持

到Python官网下载MySQL-python-1.2.5.win32-py2.7.exe 安装MySQL-python-1.2.5.win32-py2.7 附 64位MySQL-python下载地址 ...

转&colon;JavaScript函数式编程(一)

转:JavaScript函数式编程(一) 一.引言 说到函数式编程,大家可能第一印象都是学院派的那些晦涩难懂的代码,充满了一大堆抽象的不知所云的符号,似乎只有大学里的计算机教授才会使用这些东西.在曾经 ...

C&num;&comma;记录--一个方法中&comma;完成对数据增删改操作

实际应用中,一般不会使用delete彻底的删除数据,大多都是逻辑删除 为了不把本文写成小作文,举个小栗子吧 表 A,deletestate为置删除字段,int类型,值为0和1 表中五条数据 查询 se ...

解决sublime text3 中文字符乱码

前言 由于系统编码问题导致的中文乱码解决,linux和windows解决方式都一样. 流程 linux下两步都需要,windows下只需要第二步. 1.在package install中搜索安装:co ...

python发送html格式的邮件

python发邮件 #!/usr/bin/python # -*- coding: UTF-8 -*- import smtplib from email.mime.text import MIMET ...

【摘】50个jQuery代码段帮助你成为一个更好的JavaScript开发者

今 天的帖子会给你们展示50个jQuery代码片段,这些代码能够给你的JavaScript项目提供帮助.其中的一些代码段是从jQuery1.4.2才 开始支持的做法,另一些则是真正有用的函数或方法,他 ...

ps查看CPU和内存占用前10的进程

内存增序 ps aux --sort rss 内存减序 ps aux --sort -rss cpu增序 ps auxw --sort=%cpu cpu减序 ps auxw --sort=-%cpu ...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值