php socket keepalive,linux keepalive探测对应用层socket api的影响
問(wèn)題
大部分人都知道tcp的keepalive. 假設(shè)讀者知道keepalive會(huì)如何觸發(fā). 這篇文章想討論keepalive觸發(fā)后, 對(duì)socket使用者的影響.
keepalive設(shè)置
修改/etc/sysctl.conf
ubuntu# vim /etc/sysctl.conf
ubuntu# sysctl -p
fs.file-max = 131072
net.ipv4.tcp_keepalive_time = 10
net.ipv4.tcp_keepalive_intvl = 5
net.ipv4.tcp_keepalive_probes = 3
驗(yàn)證
ubuntu# sysctl -a | grep keepalive
net.ipv4.tcp_keepalive_intvl = 5
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_time = 10
tcp_server.py
import socket
import sys
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_address = ('localhost', 22345)
sock.bind(server_address)
sock.listen(1)
connection, client_address = sock.accept()
while True:
data = connection.recv(1024)
print("data", data)
tcp_client.py
import socket
import sys
import time
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
server_address = ('localhost', 22345)
sock.connect(server_address)
time.sleep(999999999)
可以看到, 因?yàn)閠cp_client開(kāi)啟了SO_KEEPALIVE, 所以tcp_client主動(dòng)往tcp_server發(fā)起KEEPALIVE探測(cè).
若tcp_server開(kāi)啟SO_KEEPALIVE, 則是tcp_server往tcp_client發(fā)送KEEPALIVE探測(cè).
如果tcp_server/tcp_client都開(kāi)啟KEEPALIVE, 則會(huì)雙向探測(cè).
對(duì)應(yīng)用層socket api的影響
準(zhǔn)備工作
為了模擬keepalive生效的情況, 用docker模擬斷網(wǎng)線(xiàn)的情況.
準(zhǔn)備好安裝有docker, python, vim, tcpdump的ubuntu鏡像, 創(chuàng)建好docker 網(wǎng)絡(luò).
跑起來(lái), 修改heartbeat設(shè)置.
ubuntu# sudo docker run -it \
--volume=//home/enjolras/code_repo/python/keepalive_test://home/enjolras/code_repo/python/keepalive_test \
--detach=true \
--name=tcp_server \
--privileged=true \
--network=multi-host-network \
ubuntu_with_python
08f89dcff3547bb15c7aed975dfa5a0821e4d0246d6d812e02fd1470f3cef6c3
ubuntu# sudo docker run -it \
--volume=//home/enjolras/code_repo/python/keepalive_test://home/enjolras/code_repo/python/keepalive_test \
--detach=true \
--name=tcp_client \
--privileged=true \
--network=multi-host-network \
ubuntu_with_python
對(duì)阻塞式send/recv的影響
tcp_server
import socket
import sys
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_address = ('0.0.0.0', 22345)
sock.bind(server_address)
sock.listen(1)
connection, client_address = sock.accept()
connection.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
data = connection.recv(1024)
print("data", data)
tcp_client
import socket
import sys
import time
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
server_address = ('tcp_server', 22345)
sock.connect(server_address)
time.sleep(999999999)
send/recv會(huì)以異常/錯(cuò)誤碼方式得知 heartbeat 檢測(cè)到的鏈接斷開(kāi).
可以看到, tcp_server/tcp_client互發(fā)心跳.
root@0b3f1ee81446:/# tcpdump -i any port 22345
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
12:29:34.491239 IP tcp_client.multi-host-network.57130 > 0b3f1ee81446.22345: Flags [S], seq 2347845399, win 28200, options [mss 1410,sackOK,TS val 951128354 ecr 0,nop,wscale 7], length 0
12:29:34.491279 IP 0b3f1ee81446.22345 > tcp_client.multi-host-network.57130: Flags [S.], seq 1169988006, ack 2347845400, win 27960, options [mss 1410,sackOK,TS val 2298965862 ecr 951128354,nop,wscale 7], length 0
12:29:34.491299 IP tcp_client.multi-host-network.57130 > 0b3f1ee81446.22345: Flags [.], ack 1, win 221, options [nop,nop,TS val 951128354 ecr 2298965862], length 0
12:29:44.666952 IP 0b3f1ee81446.22345 > tcp_client.multi-host-network.57130: Flags [.], ack 1, win 219, options [nop,nop,TS val 2298976038 ecr 951128354], length 0
12:29:44.666969 IP tcp_client.multi-host-network.57130 > 0b3f1ee81446.22345: Flags [.], ack 1, win 221, options [nop,nop,TS val 951138530 ecr 2298965862], length 0
12:29:44.666978 IP 0b3f1ee81446.22345 > tcp_client.multi-host-network.57130: Flags [.], ack 1, win 219, options [nop,nop,TS val 2298976038 ecr 951128354], length 0
12:29:44.666987 IP tcp_client.multi-host-network.57130 > 0b3f1ee81446.22345: Flags [.], ack 1, win 221, options [nop,nop,TS val 951138530 ecr 2298976038], length 0
12:29:54.907019 IP 0b3f1ee81446.22345 > tcp_client.multi-host-network.57130: Flags [.], ack 1, win 219, options [nop,nop,TS val 2298986278 ecr 951138530], length 0
12:29:54.907054 IP tcp_client.multi-host-network.57130 > 0b3f1ee81446.22345: Flags [.], ack 1, win 221, options [nop,nop,TS val 951148770 ecr 2298976038], length 0
12:29:54.907059 IP tcp_client.multi-host-network.57130 > 0b3f1ee81446.22345: Flags [.], ack 1, win 221, options [nop,nop,TS val 951148770 ecr 2298976038], length 0
12:29:54.907062 IP 0b3f1ee81446.22345 > tcp_client.multi-host-network.57130: Flags [.], ack 1, win 219, options [nop,nop,TS val 2298986278 ecr 951138530], length 0
將tcp_server/tcp_client斷網(wǎng).
ubuntu# docker network disconnect multi-host-network tcp_client
可以看到tcp_server在連續(xù)3個(gè)探測(cè)包沒(méi)有回復(fù)后, 往tcp_client發(fā)了一個(gè)RST.
12:31:47.547010 IP tcp_client.multi-host-network.57130 > 0b3f1ee81446.22345: Flags [.], ack 1, win 221, options [nop,nop,TS val 951261408 ecr 2299088676], length 0
12:31:47.547019 IP 0b3f1ee81446.22345 > tcp_client.multi-host-network.57130: Flags [.], ack 1, win 219, options [nop,nop,TS val 2299098916 ecr 951251168], length 0
12:31:47.547061 IP tcp_client.multi-host-network.57130 > 0b3f1ee81446.22345: Flags [.], ack 1, win 221, options [nop,nop,TS val 951261408 ecr 2299098916], length 0
12:31:57.787226 IP 0b3f1ee81446.22345 > tcp_client.multi-host-network.57130: Flags [.], ack 1, win 219, options [nop,nop,TS val 2299109156 ecr 951261408], length 0
12:32:02.906612 IP 0b3f1ee81446.22345 > tcp_client.multi-host-network.57130: Flags [.], ack 1, win 219, options [nop,nop,TS val 2299114276 ecr 951261408], length 0
12:32:08.026829 IP 0b3f1ee81446.22345 > tcp_client.multi-host-network.57130: Flags [.], ack 1, win 219, options [nop,nop,TS val 2299119396 ecr 951261408], length 0
12:32:13.146776 IP 0b3f1ee81446.22345 > tcp_client.multi-host-network.57130: Flags [R.], seq 1, ack 1, win 219, options [nop,nop,TS val 2299124516 ecr 951261408], length 0
可以看到, 在心跳機(jī)制檢測(cè)到socket狀態(tài)異常后, 會(huì)通過(guò)異常/錯(cuò)誤碼等方式通知調(diào)用者.
3f1ee81446:/home/enjolras/code_repo/python/keepalive_test# python tcp_serv
Traceback (most recent call last):
File "tcp_server.py", line 11, in
data = connection.recv(1024)
socket.error: [Errno 110] Connection timed out
對(duì)select的影響
tcp_server
import socket
import sys
import select
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_address = ('0.0.0.0', 22345)
sock.bind(server_address)
sock.listen(1)
connection, client_address = sock.accept()
connection.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
readable, writable, exeptional = select.select([connection], [], [])
print("readable", readable, writable, exeptional)
data = connection.recv(1024)
print("data", data)
對(duì)套接字select返回可讀事件.
3f1ee81446:/home/enjolras/code_repo/python/keepalive_test# python tcp_serv
('readable', [], [], [])
Traceback (most recent call last):
File "tcp_server.py", line 14, in
data = connection.recv(1024)
socket.error: [Errno 110] Connection timed out
對(duì)epoll的影響
不做實(shí)驗(yàn), 應(yīng)該和select一致.
結(jié)論
heartbeat檢測(cè)到tcp鏈接斷開(kāi)后, 會(huì)以可讀事件方式通知應(yīng)用層. 若無(wú)tcp heartbeat, 也無(wú)應(yīng)用層heartbeat, 應(yīng)用層無(wú)法得知鏈接的真實(shí)狀態(tài).
總結(jié)
以上是生活随笔為你收集整理的php socket keepalive,linux keepalive探测对应用层socket api的影响的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: python rest api_Pyth
- 下一篇: mysql5.7 for linux7,