多个进程正在监听同一个端口。但据我所知,只有一个进程可以监听一个端口。多个进程可以监听同一个端口吗(如何实现?)?
$ sudo lsof -n -i :80 | grep LISTEN
haproxy 2039 root 4u IPv4 12874 0t0 TCP *:http (LISTEN)
haproxy 2042 root 4u IPv4 12898 0t0 TCP *:http (LISTEN)
haproxy 2045 root 4u IPv4 12923 0t0 TCP *:http (LISTEN)
pstree
输出:
init
├─acpid -c /etc/acpi/events -s /var/run/acpid.socket
├─atd
├─cron
├─dbus-daemon --system --fork
├─dhclient -1 -v -pf /run/dhclient.eth0.pid -lf /var/lib/dhcp/dhclient.eth0.leases eth0
├─docker -d
│ └─6*[{docker}]
├─getty -8 38400 tty4
├─getty -8 38400 tty5
├─getty -8 38400 tty2
├─getty -8 38400 tty3
├─getty -8 38400 tty6
├─getty -8 38400 tty1
├─getty -8 38400 ttyS0
├─haproxy -f /etc/haproxy/haproxy.cfg
├─haproxy -f /etc/haproxy/haproxy.cfg
├─haproxy -f /etc/haproxy/haproxy.cfg
haproxy配置:
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
user ubuntu
group ubuntu
daemon
defaults
log global
mode http
option httplog
option dontlognull
contimeout 5000
clitimeout 50000
srvtimeout 50000
listen appname 0.0.0.0:80
mode http
stats enable
stats uri /haproxy?stats
balance roundrobin
option httpclose
option forwardfor
server lamp1 172.31.20.0:81 check
server lamp2 172.31.20.1:81 check
答案1
这是可能的。目标是并行处理多个传入连接。多个haproxy
实例可能使用单独的 CPU 核心并(半)独立工作。传入连接将被传递到空闲haproxy
(如果可用)而不是排队到繁忙的连接。
我猜 haproxy
用途SO_REUSEPORT
。man 7 socket
解释此选项如下:
SO_REUSEPORT
(自 Linux 3.9 起)允许将多个
AF_INET
套接字AF_INET6
绑定到相同的套接字地址。在调用bind(2)
套接字之前,必须在每个套接字(包括第一个套接字)上设置此选项。为了防止端口劫持,绑定到同一地址的所有进程都必须具有相同的有效 UID。此选项可用于 TCP 和 UDP 套接字。对于 TCP 套接字,此选项允许通过为每个线程使用不同的侦听器套接字来改善多线程服务器中的负载分配。与使用单个线程分配连接或使用多个线程竞争同一套接字的
accept(2)
传统技术相比,这提供了更好的负载分配。accept(2)
accept(2)
也检查SO_ATTACH_REUSEPORT_CBPF
一下SO_ATTACH_REUSEPORT_EBPF
那里。
编辑:我发现本文(日期为2017年5月3日);它似乎支持了我的猜测:
同时,
SO_REUSEPORT
Linux 内核 3.9 引入了新的、更好的实现,允许将负载智能地分布在多个套接字上。HAProxy 可以立即从这一新改进中受益。但它带来了一个问题[...]
不用担心这个问题。本文介绍了解决方法和解决方案。如果你对这类东西感兴趣,你可能会觉得它很有趣。