什么是 TCP Fast Open
TCP Fast Open 簡稱 TFO谎痢,其目的是縮短 TCP 三次握手的時間磕昼。通過加入 cookie,在握手階段就可以傳輸數(shù)據(jù)包节猿,從而將三次握手的延時降低到最低票从。比較適用于網(wǎng)絡(luò)延時比較長的場景。
TCP Fast Open 流程
首次請求
- 客戶端發(fā)送 syn,并且字段里面請求 cookie (tfo request)
- 服務(wù)端發(fā)送 syn+ack以及cookie
- 客戶端保存cookie并發(fā)送ack
- 客戶端發(fā)送數(shù)據(jù)
后續(xù)請求
- 客戶端發(fā)送 syn纫骑、數(shù)據(jù)以及 cookie
- 服務(wù)端驗證 cookie 并發(fā)送 syn+ack
- 服務(wù)端不必等客戶端ack開始發(fā)送數(shù)據(jù)
- 客戶端發(fā)送 ack
延時分析
假設(shè)單程延時為 t蝎亚,如果沒有用 TFO,那么需要三次握手后才會開始發(fā)送數(shù)據(jù)先馆,即發(fā)送數(shù)據(jù)延時至少為 2t发框,而用了 TFO,發(fā)送數(shù)據(jù)延時就是0煤墙。當然從用戶體驗來看梅惯,從發(fā)起請求到接收到服務(wù)端發(fā)送過來數(shù)據(jù)的延時分別是4t和2t。
TFO 的一些問題
由于帶了 cookie 有些防火墻認為數(shù)據(jù)包異常仿野,在這種環(huán)境下用起來就會有問題铣减。有報告說某些4G網(wǎng)絡(luò)就有這種問題。
TCP Fast Open 實踐
系統(tǒng)層面
echo 3 > /proc/sys/net/ipv4/tcp_fastopen
其中1表示啟用客戶端(sendto)脚作,2表示啟用服務(wù)端(bind)葫哗,3表示兩者都啟用。
客戶端代碼
#!/usr/bin/env python
import socket
import sys
MSG_FASTOPEN = 0x20000000
host = sys.argv[1]
print("connecting to host {} ...".format(host))
addr = (host, 8000)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 以 Fast Open 方式發(fā)送數(shù)據(jù)球涛,不需要 connect
s.sendto("hello!", MSG_FASTOPEN, addr)
print s.recv(1000)
服務(wù)端代碼
import socket
TCP_FASTOPEN = 23
def listen():
connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connection.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 設(shè)置 TCP Fast Open 隊列
connection.setsockopt(socket.SOL_TCP, TCP_FASTOPEN, 5)
connection.bind(('0.0.0.0', 8000))
connection.listen(10)
while True:
current_connection, address = connection.accept()
while True:
data = current_connection.recv(2048)
if data:
current_connection.send(data)
print data
current_connection.close()
break
if __name__ == "__main__":
try:
listen()
except KeyboardInterrupt:
pass
軟件配置
在 haproxy 中劣针,如果要啟用 TCP Fast Open,那么需要在 bind 中顯式指定亿扁。譬如:
bind 0.0.0.0:12345 tfo
參考鏈接
https://tools.ietf.org/html/rfc7413
https://lwn.net/Articles/508865/