so_reuserport分析

一、创建服务端程序

/root/server.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import socket

s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)

HostPort = ('0.0.0.0', 9000)
s.bind(HostPort)
s.listen(5)

while True:
    print('server socket waiting...')
    obj,addr = s.accept()
    print('socket object:',obj)
    print('client info:',addr)
    obj.close()

二、执行四次server.py

nohup /root/server.py &
nohup /root/server.py &
nohup /root/server.py &
nohup /root/server.py &

三、查看端口情况

root@iZt4nacmsod7zffqkrrcj8Z:~# lsof -i:9000
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
python3 18474 root    3u  IPv4  69937      0t0  TCP *:9000 (LISTEN)
python3 18475 root    3u  IPv4  69946      0t0  TCP *:9000 (LISTEN)
python3 18476 root    3u  IPv4  69955      0t0  TCP *:9000 (LISTEN)
python3 18477 root    3u  IPv4  69964      0t0  TCP *:9000 (LISTEN)

可见,有四个进程已经同时监听端口9000

四、查看inode情况

9000转换为12进制为2328,查看文件/proc/net/tcp

# cat /proc/net/tcp | grep ":2328" | awk '{print $2,$10}'
00000000:2328 78145
00000000:2328 78136
00000000:2328 78127
00000000:2328 78118

可以看出,虽然4个进程监听的是同一个端口,但是对应到inode确是不同的。内核在网络协议栈到虚拟文件系统的期间,做了负载均衡的策略。这样,也可以完美解决nginx很久以前的惊群问题。

五、附上/proc/net/tcp字段说明

推荐阅读更多精彩内容