干翻 nio ,王炸 io_uring 来了 ,史上最详细说明及最全图解!!

Image
大趋势:全链路异步化,性能提升10倍+ 随着业务的发展,微服务应用的流量越来越大,使用到的资源也越来越多。 在微服务架构下,大量的应用都是 SpringCloud 分布式架构,这种架构总体上是 全链路同步模式 。 全链路同步模式 不仅造成了资源的极大浪费,并且在流量发生激增波动的时候,受制于系统资源而无法快速的扩容。 全球后疫情时代,降本增效是大背景。如何降本增效?一条好的路径: 全链路同步模式  ,升级为  全链路异步模式 。 全链路异步模式 改造 具体的内容,请参考尼恩的深度文章: 全链路异步,让你的 SpringCloud 性能优化10倍+ 先回顾一下全链路同步模式架构图 全链路同步模式  ,如何升级为  全链路异步模式 , 就是一个一个 环节的异步化。 40岁老架构师尼恩,持续深化自己的3高架构知识宇宙,当然首先要去完成一次牛逼的 全链路异步模式 微服务实操,下面是尼恩的实操过程、效果、压测数据(性能足足提升10倍多)。 全链路异步模式 改造 具体的内容,请参考尼恩的深度文章: 全链路异步,让你的 SpringCloud 性能优化10倍+ 并且,上面的文章,作为尼恩 全链路异步的架构知识,收录在《 尼恩Java面试宝典 》V52版的架构专题中 注:本文以 PDF 持续更新,最新尼恩 架构笔记、面试题 的PDF文件,请从这里获取: 语雀 或者 码云 全链路异步化的最终目标 全链路异步化的最终目标,如下图所示: 应用层:编程模型的异步化 框架层:IO线程的异步化 OS层:IO模型的异步化 一:应用层:编程模型的异步化 这个请大家去看 尼恩的 《 响应式 圣经 PDF 》电子书 随着 云原生时代的到来, 底层的 组件编程 越来越 响应式、流化, 从命令式 编程转换到 响应式 编程,在非常多的场景 ,是大势所趋。 而响应式编程, 学习曲线很大, 大家需要多看,多实操。 二:框架层:IO线程的异步化 这个大家 都选择 具有异步 回调功能的 异步线程模型,如 Reactor 线程模型 这个是面试的绝对重点 IO的王者组件,Netty框架,整体就是一个 Reactor 线程模型 实现 也是非常核心的知识,这里不做展开,请大家去看尼恩的畅销书《Java 高并发核心编程卷 1 加强版》。 三:OS层:IO模型的异步化 目前的一个最大难题,是IO模型的异步化。 注意,Netty

net.ipv4.ip_local_port_range 的值究竟影响了啥,和UDP connect之间的关系是什么?

前言

网上关于 net.ipv4.ip_local_port_range 的值的效果众说纷纭(下面所说的连接都假定使用的是相同的协议(都是 TCP 或 UDP)):

  • 大部分文章都说这个值决定了客户端的一个 ip 可用的端口数量,即一个 ip 最多只能创建 60K 多一点的连接(1025-65535),如果要突破这个限制需要客户端机器绑定多个 ip。
  • 还有部分文章说的是这个值决定的是 socket 四元组中的本地端口数量,即一个 ip 对同一个目标 ip+port 最多可以创建 60K 多一点连接,只要目标 ip 或端口不一样就可以使用相同的本地端口,不一定需要多个客户端 ip 就可以突破端口数量限制。

文档 中的介绍也很模糊:

ip_local_port_range - 2 INTEGERS
    Defines the local port range that is used by TCP and UDP to
    choose the local port. The first number is the first, the
    second the last local port number.
    If possible, it is better these numbers have different parity.
    (one even and one odd values)
    The default values are 32768 and 60999 respectively.

下面就通过TCP来做一些实验来确认这个选项的实际效果。

实验环境:

$ uname -a
Linux vagrant 4.15.0-29-generic #31-Ubuntu SMP Tue Jul 17 15:39:52 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

相同目标 ip 和相同目标端口下的端口数量限制

先设置 ip_local_port_range 的值为非常小的范围:

$ echo "61000 61001" | sudo tee /proc/sys/net/ipv4/ip_local_port_range
61000 61001

$ cat /proc/sys/net/ipv4/ip_local_port_range
61000       61001

然后对相同 ip 和端口发送 tcp 请求。创建两个连接,达到最大端口数量限制:

$ nohup nc 123.125.114.144 80 -v &
[1] 16196
$ nohup: ignoring input and appending output to 'nohup.out'

$ nohup nc 123.125.114.144 80 -v &
[2] 16197
$ nohup: ignoring input and appending output to 'nohup.out'

$ ss -ant |grep 10.0.2.15:61
ESTAB   0        0                10.0.2.15:61001       123.125.114.144:80
ESTAB   0        0                10.0.2.15:61000       123.125.114.144:80

然后再创建第三个连接,此时预期应该会失败,因为超出的端口数量现在:

vagrant@vagrant:~$ nc 123.125.114.144 80 -v
nc: connect to 123.125.114.144 port 80 (tcp) failed: Cannot assign requested address

可以看到确实如预期的失败了。

相同目标 ip 不同目标端口

下面看看相同目标 ip 不同目标端口是否可以突破这个端口限制:

$ nohup nc 123.125.114.144 443 -v &
[3] 16215
$ nohup: ignoring input and appending output to 'nohup.out'

$ nohup nc 123.125.114.144 443 -v &
[4] 16216
$ nohup: ignoring input and appending output to 'nohup.out'

$ ss -ant |grep 10.0.2.15:61
ESTAB   0        0                10.0.2.15:61001       123.125.114.144:443
ESTAB   0        0                10.0.2.15:61001       123.125.114.144:80
ESTAB   0        0                10.0.2.15:61000       123.125.114.144:443
ESTAB   0        0                10.0.2.15:61000       123.125.114.144:80

可以看到相同目标 ip 不同目标端口下,每个目标端口都有一个独立的端口限制,即,相同源 ip 的源端口是可以相同的。

按照推测这两个目标端口应该只能创建四个连接,下面试试看:

$ ss -ant |grep 10.0.2.15:61
ESTAB   0        0                10.0.2.15:61001       123.125.114.144:443
ESTAB   0        0                10.0.2.15:61001       123.125.114.144:80
ESTAB   0        0                10.0.2.15:61000       123.125.114.144:443
ESTAB   0        0                10.0.2.15:61000       123.125.114.144:80

$ nc 123.125.114.144 443 -v
nc: connect to 123.125.114.144 port 443 (tcp) failed: Cannot assign requested address

确实是不能再创建连接了,因为每个目标端口都达到了 ip_local_port_range 的限制。

多个目标 ip 相同目标端口

下面看一下多个目标 ip 相同目标端口下的情况:

$ nohup nc 220.181.57.216 80 -v &
[5] 16222
$ nohup: ignoring input and appending output to 'nohup.out'

$ nohup nc 220.181.57.216 80 -v &
[6] 16223
$ nohup: ignoring input and appending output to 'nohup.out'

$ nc 220.181.57.216 80 -v
nc: connect to 220.181.57.216 port 80 (tcp) failed: Cannot assign requested address

$ ss -ant |grep :80
SYN-SENT  0        1               10.0.2.15:61001       220.181.57.216:80
SYN-SENT  0        1               10.0.2.15:61000       220.181.57.216:80
SYN-SENT  0        1               10.0.2.15:61001      123.125.114.144:80
SYN-SENT  0        1               10.0.2.15:61000      123.125.114.144:80

可以看到,每个目标 ip 都有独立的 ip_local_port_range 限制。

多个目标 ip 不同目标端口

下面看一下多个目标 ip 相同不同端口下的情况,按照前面的经验两个 ip 加两个端口应该只能创建 8 个连接

$ nohup nc 123.125.114.144 80 -v &

$ nohup nc 123.125.114.144 80 -v &

$ nc 123.125.114.144 80 -v
nc: connect to 123.125.114.144 port 80 (tcp) failed: Cannot assign requested address

$ nohup nc 123.125.114.144 443 -v &

$ nohup nc 123.125.114.144 443 -v &

$ nc 123.125.114.144 443 -v
nc: connect to 123.125.114.144 port 443 (tcp) failed: Cannot assign requested address

$ nohup nc 220.181.57.216 80 -v &

$ nohup nc 220.181.57.216 80 -v &

$ nc 220.181.57.216 80 -v
nc: connect to 220.181.57.216 port 80 (tcp) failed: Cannot assign requested address

$ nohup nc 220.181.57.216 443 -v &

$ nohup nc 220.181.57.216 443 -v &

$ nc 220.181.57.216 443 -v
nc: connect to 220.181.57.216 port 443 (tcp) failed: Cannot assign requested address

$ ss -ant |grep 10.0.2.15:61
SYN-SENT  0        1               10.0.2.15:61001       220.181.57.216:80
ESTAB     0        0               10.0.2.15:61001      123.125.114.144:443
ESTAB     0        0               10.0.2.15:61000       220.181.57.216:443
SYN-SENT  0        1               10.0.2.15:61000       220.181.57.216:80
SYN-SENT  0        1               10.0.2.15:61001      123.125.114.144:80
ESTAB     0        0               10.0.2.15:61000      123.125.114.144:443
SYN-SENT  0        1               10.0.2.15:61000      123.125.114.144:80
ESTAB     0        0               10.0.2.15:61001       220.181.57.216:443

可以看到确实如预期的只能创建8个连接。

但是UDP的行为与上面的TCP的行为是不同的,UDP 使用同一个源IP同一个源端口与同一目的IP不同目的端口进行connect的时候,是无法进行connect操作的,会提示“connect failed: Resource temporarily unavailable”

比如:

ipa:porta -> ipb:portb

ipa:porta -> ipb:portc



Comments

Popular posts from this blog

便宜好用又稳定的VPN-桔子云,性价比极高!

V2rayN 电脑客户端如何在 win7/win10/win11上 实现全局代理

IOS小火箭/Shadowsocks无需AppleID即可在线安装!