重学TCP协议(12)SO_REUSEADDR、SO_REUSEPORT、SO_LINGER

1. SO_REUSEADDR

假如服务端出现故障,主动断开连接以后,需要等 2 个 MSL 以后才最终释放这个连接,而服务重启以后要绑定同一个端口,默认情况下,操作系统的实现都会阻止新的监听套接字绑定到这个端口上。启用 SO_REUSEADDR 套接字选项可以解除这个限制。

2. SO_REUSEPORT

默认情况下,一个 IP、端口组合只能被一个套接字绑定,Linux 内核从 3.9 版本开始引入一个新的 socket 选项 SO_REUSEPORT,又称为 port sharding,允许多个套接字监听同一个IP 和端口组合。

2.1 多进程网络模型

  • 主进程 + 多个 worker 子进程监听相同的端口(导致惊群问题)

image.png

  • 多进程 + REUSEPORT

2.2 惊群问题

多进程/多线程同时监听同一个套接字,当有网络事件发生时,所有等待的进程/线程同时被唤醒,但是只有其中一个进程/线程可以处理该网络事件,其它的进程/线程获取失败重新进入休眠。

2.3 accept系统调用的惊群问题

在Linux 2.6之前,会出现惊群问题。而在后面的版本中,引入了WQ_FLAG_EXCLUSIVE 选项解决了 accept 调用的惊群问题。

2.4 epoll系统调用的惊群问题

image.png

当有新的网络事件发生时,阻塞在 epoll_wait 的多个进程同时被唤醒。在这种情况下,epoll 的惊群还是存在的。

2.5 SO_REUSEPORT原理

内核为处于 LISTEN 状态的 socket 分配了大小为 32 哈希桶。监听的端口号经过哈希算法运算打散到这些哈希桶中,相同哈希的端口采用拉链法解决冲突。

  1. 当收到客户端的 SYN 握手报文以后,会根据目标端口号的哈希值计算出哈希冲突链表

  2. 对于设置了 SO_REUSEPORT 选项的 socket 经过二次哈希找到对应的 SO_REUSEPORT group,从中随机选择一个进行处理。

image.png

2.6 SO_REUSEPORT作用

  • 内核有数据到来的时候就会把请求均衡的分给不同的socket,也就是不同的线程了,这样内核可以自动的做到负载均衡
  • 支持滚动升级
  1. 新启动一个新版本 v2 ,监听同一个端口,与 v1 旧版本一起处理请求。
  2. 发送信号给 v1 版本的进程,让它不再接受新的请求
  3. 等待一段时间,等 v1 版本的用户请求都已经处理完毕时,v1 版本的进程退出,留下 v2 版本继续服务

2.7 SO_REUSEPORT安全性

出于安全性考虑,防止端口劫持

  • 只有effective-user-id相同的服务器进程才能监听同一ip:port
  • 只有第一个启动的进程启用了 SO_REUSEPORT 选项,后面启动的进程才可以绑定同一个端口。

3. SO_LINGER

设置函数close()关闭TCP连接时的行为。缺省close()的行为是,如果有数据残留在socket发送缓冲区中则系统将继续发送这些数据给对方,等待被确认,然后返回。

SO_LINGER选项使用如下结构:

struct linger {int l_onoff;int l_linger;
};
  1. l_onoff为0,则该选项关闭,l_linger的值被忽略,close()用上述缺省方式关闭连接。
  2. l_onoff非0,l_linger为0,close()用下面的a方式关闭连接。
  3. l_onoff非0,l_linger非0,close()用下面的b方式关闭连接。
  • a.立即关闭该连接,通过发送RST分组(而不是用正常的FIN|ACK|FIN|ACK四个分组)来关闭该连接。至于发送缓冲区中如果有未发送完的数据,则丢弃。主动关闭一方的TCP状态则跳过TIMEWAIT,直接进入CLOSED。

  • b.将连接的关闭设置一个超时。如果socket发送缓冲区中仍残留数据,进程进入睡眠,内核进入定时状态去尽量去发送这些数据。

    在超时之前,如果所有数据都发送完且被对方确认,内核用正常的FIN|ACK|FIN|ACK四个分组来关闭该连接,close()成功返回。

    如果超时之时,数据仍然未能成功发送及被确认,用上述a方式来关闭此连接。close()返回EWOULDBLOCK。

参考文章

深入理解 TCP 协议:从原理到实战

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/390843.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

残疾科学家_数据科学与残疾:通过创新加强护理

残疾科学家Could the time it takes for you to water your houseplants say something about your health? Or might the amount you’re moving around your neighborhood reflect your mental health status?您给植物浇水所需的时间能否说明您的健康状况? 还是…

POJ 3660 Cow Contest [Floyd]

POJ - 3660 Cow Contest http://poj.org/problem?id3660 N (1 ≤ N ≤ 100) cows, conveniently numbered 1..N, are participating in a programming contest. As we all know, some cows code better than others. Each cow has a certain constant skill rating that is un…

Linux 网络相关命令

1. telnet 1.1 检查端口是否打开 执行 telnet www.baidu.com 80,粘贴下面的文本(注意总共有四行,最后两行为两个空行) telnet [domainname or ip] [port]例如: telnet www.baidu.com 80 如果这个网络连接可达&…

JSON.parseObject(String str)与JSONObject.parseObject(String str)的区别

一、首先来说说fastjson fastjson 是一个性能很好的 Java 语言实现的 JSON 解析器和生成器,来自阿里巴巴的工程师开发。其主要特点是: ① 快速:fastjson采用独创的算法,将parse的速度提升到极致,超过所有基于Java的jso…

jQuery Ajax POST方法

Sends an asynchronous http POST request to load data from the server. Its general form is:发送异步http POST请求以从服务器加载数据。 其一般形式为: jQuery.post( url [, data ] [, success ] [, dataType ] )url : is the only mandatory parameter. This…

spss23出现数据消失_改善23亿人口健康数据的可视化

spss23出现数据消失District Health Information Software, or DHIS2, is one of the most important sources of health data in low- and middle-income countries (LMICs). Used by 72 different LMIC governments, DHIS2 is a web-based open-source platform that is used…

01-hibernate注解:类级别注解,@Entity,@Table,@Embeddable

Entity Entity:映射实体类 Entity(name"tableName") name:可选,对应数据库中一个表,若表名与实体类名相同,则可以省略。 注意:使用Entity时候必须指定实体类的主键属性。 第一步:建立实体类: 分别…

leetcode 1707. 与数组中元素的最大异或值

题目 给你一个由非负整数组成的数组 nums 。另有一个查询数组 queries ,其中 queries[i] [xi, mi] 。 第 i 个查询的答案是 xi 和任何 nums 数组中不超过 mi 的元素按位异或(XOR)得到的最大值。换句话说,答案是 max(nums[j] XO…

MySQL基础入门学习【2】数据类型

数据类型:指列、存储过程参数、表达式和局部变量的数据特征,它决定了数据的存储格式,代表了不同的信息类型 (1) 整型(按存储范围分类):TINYINT(1字节) SAMLLINT(2字节&am…

昆西·拉森的净资产是多少?

People ask me how much I get paid all the time. It comes up on podcast interviews, Quora questions, and face-to-face discussions.人们问我,我一直得到多少报酬。 它来自播客访谈,Quora问题和面对面的讨论。 And people search this question a…

COVID-19研究助理

These days scientists, researchers, doctors, and medical professionals face challenges to develop answers to their high priority scientific questions.如今,科学家,研究人员,医生和医学专家面临着挑战,无法为其高度优先…

Node.js umei图片批量下载Node.js爬虫1.00

这个爬虫在abaike爬虫的基础上改改图片路径和下一页路径就出来了,代码如下: // // umei图片批量下载Node.js爬虫1.00 // 2017年11月13日 //// 内置http模块 var httprequire("http");// 内置文件处理模块,用于创建目录和图片文件 v…

交通银行信息技术管理部副总经理张漫丽:交通银行“大数据+人工智能”应用研究...

文 | 交通银行信息技术管理部副总经理张漫丽 大数据隐含着巨大的社会、经济、科研价值,已引起了各行各业的高度重视。如果能通过人工智能技术有效地组织和使用大数据,将对社会经济和科学研究发展产生巨大的推动作用,同时也孕育着前所未有的机…

安软件一劳永逸_如何克服一劳永逸地公开演讲的恐惧

安软件一劳永逸If you’re like most people, the idea of public speaking terrifies you (it terrifies me too). So how do you get over those jitters, get up on stage, and give an amazing talk? First, a disclaimer: this article is purely about your stage prese…

Go语言实战 : API服务器 (8) 中间件

为什么需要中间件 我们可能需要对每个请求/返回做一些特定的操作,比如 记录请求的 log 信息在返回中插入一个 Header部分接口进行鉴权 这些都需要一个统一的入口。这个功能可以通过引入 middleware 中间件来解决。Go 的 net/http 设计的一大特点是特别容易构建中间…

缺失值和异常值的识别与处理_识别异常值-第一部分

缺失值和异常值的识别与处理📈Python金融系列 (📈Python for finance series) Warning: There is no magical formula or Holy Grail here, though a new world might open the door for you.警告 : 这里没有神奇的配方或圣杯,尽管…

SQL Server 常用分页SQL

今天无聊和朋友讨论分页,发现网上好多都是错的。网上经常查到的那个Top Not in 或者Max 大部分都不实用,很多都忽略了Order和性能问题。为此上网查了查,顺带把2000和2012版本的也补上了。 先说说网上常见SQL的错误或者说局限问题 12345select…

Word中摘要和正文同时分栏后,正文跑到下一页,怎么办?或Word分栏后第一页明明有空位后面的文字却自动跳到第二页了,怎么办?...

问题1:Word中摘要和正文同时分栏后,正文跑到下一页,怎么办?或Word分栏后第一页明明有空位后面的文字却自动跳到第二页了,怎么办? 答:在word2010中,菜单栏中最左侧选“文件”->“选…

leetcode 664. 奇怪的打印机(dp)

题目 有台奇怪的打印机有以下两个特殊要求: 打印机每次只能打印由 同一个字符 组成的序列。 每次可以在任意起始和结束位置打印新字符,并且会覆盖掉原来已有的字符。 给你一个字符串 s ,你的任务是计算这个打印机打印它需要的最少打印次数。…

SQL数据类型说明和MySQL语法示例

SQL数据类型 (SQL Data Types) Each column in a database table is required to have a name and a data type. 数据库表中的每一列都必须具有名称和数据类型。 An SQL developer must decide what type of data that will be stored inside each column when creating a tab…