Несколько процессов прослушивают один и тот же порт; как это возможно?
Несколько процессов прослушивают один и тот же порт. Но, насколько я знаю, только один процесс может прослушивать порт. Возможно ли (как?), Что несколько процессов могут прослушивать один и тот же порт?
$ 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
экземпляры могут использовать отдельные ядра ЦП и работать (полу) независимо. Входящее соединение будет передано в режим ожидания 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)
-ing поток, который распределяет соединения, или имеет несколько потоков, которые конкурируют сaccept(2)
из той же розетки.
Также проверьте SO_ATTACH_REUSEPORT_CBPF
а также SO_ATTACH_REUSEPORT_EBPF
там.
Изменить: я нашел эту статью (от 3 мая 2017 года); кажется, поддерживает мое предположение:
А пока новое и намного лучше
SO_REUSEPORT
Реализация была перенесена в ядро Linux 3.9, что позволило разумно распределить нагрузку по нескольким сокетам. HAProxy может немедленно извлечь выгоду из этого нового улучшения.Но это пришло с проблемой [...]
Не беспокойся о проблеме. В статье описаны обходные пути и решение. Вы можете найти это интересным, если вам нравятся такие вещи.