LVS - Keepalived 實現 L4 高可用負載均衡器
LVS 負載均衡器
LVS 是一種開源的 L4 TCP/UDP 負載均衡器,本質是一個 Linux Kernel Module,所以稱爲 Linux Virtual Server(Linux 虛擬服務器)。LVS 的目標是使用 LB 技術和集羣技術來實現一個具有良好可伸縮性(Scalability)、可靠性(Reliability)和可管理性(Manageability)的 “Virtual Server“。
部署架構
三層部署架構:
-
負載調度器層:客戶端請求流量入口,需要嚴格保障該層面的高可用性,以獲取良好的可靠性。
-
服務器集羣層:客戶端請求應答單元,需要儘量保證該層面的無狀態性,以獲得更好的可伸縮性。
-
共享存儲池層:邏輯上集中的數據存儲池,用於支撐服務器集羣的無狀態性。
基本概念
Server 類型:
-
DS(Director Server,流量調度服務器):是充當 LB 流量入口的服務器,負責負載均衡策略的執行和流量分發。所以也稱爲 FE(前端服務器)。
-
RS(Real Server,真實服務器):真正用於處理請求流量的服務器,也稱爲 BE(後端服務器)。
-
VS(Virtual Server,虛擬服務器):VS 是由 DS 和 RS 組合構成的一個邏輯概念,VS 最終通過一個 VIP 對外部 Clients 提供服務。
IP 類型:
-
VIP(Virtual IP,虛擬 IP 地址):VS 向外部 Client 提供服務的 IP 地址。
-
DIP(Director IP,直連 IP 地址):Director Server 向內部與 RS 進行通信的 IP 地址。
-
RIP(Real IP,真實 IP 地址):RS 與 DS 互通的 IP 地址。
-
CIP(Client IP,客戶端的 IP 地址)。
軟件架構
LVS 的軟件架構比較簡單,只有 2 個模塊:
-
ipvsadm(用戶態指令行工具):用於管理集羣服務及集羣中的 RS 節點;
-
ipvs(內核態轉發模塊):工作在 iptables 的 INPUT 鏈上,提供 L4 流量轉發和策略執行。
用戶通過 ipvsadm 添加規則,再由 ipvs 來實現功能。
運行原理
LVS-NAT 模式
模式特徵:
-
Client REQ 的 dstIP 是 VIP,srcIP 是 CIP,dstPort 是 VPort,srcPort 是隨機分配的 CPort;
-
DS 根據 LB Policy 選擇一個 RS;
-
L3 層 NAT:
-
Ingress:DS 將 Client REQ 的 dstIP 轉換爲 RIP,srcIP 仍然爲 CIP。
-
Egress:DS 將 RESP 的 srcIP 轉換爲 VIP,dstIP 仍然爲 CIP。
- L4 層 PAT:
-
Ingress:DS 將 Client REQ 的 dstPort 轉換爲 RPort,srcPort 仍然爲 CPort。
-
Egress:DS 將 RESP 的 srcPort 轉換爲 VPort,dstPort 仍然爲 CPort。
- RS 的 Default Gateway 必須指向 DIP,這樣 dstIP 爲 CIP 才能進入 DS 轉發。
模式缺點:DS 會成爲帶寬和高性能的瓶頸,RS 彈性伸縮性有限。
LVS-TUN 模式
從上述 LVS-NAT 模式的特徵可知,其瓶頸的關鍵在於頻繁的 IP 和 Port 編輯。在改良的 LVS-TUN 模式中,DS 爲了避免對 Original Packet 的編輯而引入了 IP Tunneling 技術。因此也稱爲透明模式。
簡而言之,LVS-TUN 模式在 DS 和 RS 之間建立了 IP Tunnel,Client REQ 會在 Tunnel 中傳輸而無需修改。前提是所有的 RSs 都掛載了 VIP,這樣 RS 才能接收 REQ。也因此 RS 能夠直接將 REQ 的 srcIP(CIP)和 dstIP(VIP)反轉構成一個 RESP 並直接返回給 Client 而繞開 DS 的轉發。這使得整個流量路徑看起來就像是一個 “三角形狀 ",所以也被稱爲非對稱性網絡。
由於一般的網絡服務場景中,RESP 往往要不 REQ 的 Size 更大,所以三角流量的 LVS-TUN 模式相較於 LVS-NAT 模式集羣系統的最大吞吐量可以提高 10 倍。
模式特性:
-
Client REQ 不會被編輯,但會封裝上 OuterIP 層,實現 IP Tunnel;
-
不支持 PAT;
-
RS 除了擁有常規的 RIP 之外,都會綁定同一個 VIP,一般配置到 lo 網絡接口上(作爲 VIP 接口)。RS VIP 是實現三角流量的關鍵。
-
RS 的 Default Gateway 爲前端 Router,RESP 不經過 DS。
模式缺點:
-
要求 RS 支持 IP Tunneling 技術,對 RS OS 有侵入性。
-
IP Tunneling 增加了 OuterIP 封裝層,也帶來了一定的報文處理開銷。
-
對物理組網具有較高的設計和部署要求。
LVS-DR
LVS-DR(Direct Routing)模式的網絡流量模型與 LVS-TUN 模式類似,都是三角流量模型。但核心區別在於 LVS-TUN 是基於 L3 IP 技術實現的,而 LVS-DR 是基於 L2 技術實現的。所以,LVS-DR 沒有 IP Tunneling 的開銷,也不對 RS 具有侵入性。
模式特性:
-
要求 DS(DIP/MAC)和 RS(RIP/MAC)處於同一個 L2 LAN 中;
-
所有 RS 都配置了一個 lo VIP,同時所有的 RS 會抑制 lo 接口響應 ARP 請求(RS 和 DS 處於同一個 LAN),保證 Client REQ 經過前端 Router 之後必須先進入 DS 而不是 RS;
-
DS 會通過改寫 L2 Frame 的 dstMAC 爲 RS-MAC,來實現將 Client REQ 轉發給 RS,並且由 RS 將 RESP 直接發送給 Client,無需經過 DS;
-
RS 的 Default Gateway 爲前端 Router,RESP 不經過 DS;
-
不支持 PAT;
模式缺點:必須處於同一個 LAN,集羣規模受限。
負載均衡算法
靜態負載均衡
-
rr(round robin,輪詢 ):把每次來自客戶端的請求輪流分配到後端真實服務器。它無需記錄當前所有連接的狀態,是一種無狀態調度。但也不會考慮每臺服務器的處理能力。
-
wrr(weight round robin,加權輪詢):由於每臺服務器的配置、安裝的業務應用等不同,其處理能力會不一樣。所以,根據服務器的不同處理能力,給每個服務器分配不同的權值,使其能夠接受相應權值數的服務請求。
-
sh(source hashing,源地址 HASH):實現會話綁定(session affinity),將同一客戶端的請求發給同一個真實服務器,源地址散列調度算法正好與目標地址散列調度算法相反,它根據請求的源 IP 地址,作爲散列鍵(Hash Key)從靜態分配的散列表找出對應的服務器,若該服務器是可用的並且沒有超負荷,將請求發送到該服務器,否則返回空。它採用的散列函數與目標地址散列調度算法的相同。它的算法流程與目標地址散列調度算法的基本相似,除了將請求的目標 IP 地址換成請求的源 IP 地址。
-
dh(destination hashing,目標地址 HASH):將同樣的請求發送給同一個後端服務器,一般用於緩存服務器。簡單的說,LB 集羣后面又加了一層,在 LB 與真實服務器之間加了一層緩存服務器,通過這種方式來提高緩存的命中率。目標地址散列調度算法也是針對目標 IP 地址的負載均衡,它是一種靜態映射算法,通過一個散列函數將一個目標 IP 地址映射到一臺服務器。目標地址散列調度算法先根據請求的目標 IP 地址,作爲散列鍵(Hash Key)從靜態分配的散列表找出對應的服務器,若該服務器是可用的且未超載,將請求發送到該服務器,否則返回空。
動態負載均衡
-
lc(leash-connection,最少連接 ):最少連接調度算法是把新的連接請求分配到當前連接數最小的服務器。最小連接調度是一種動態調度短算法,它通過服務器當前所活躍的連接數來估計服務器的負載均衡,調度器需要記錄各個服務器已建立連接的數目,當一個請求被調度到某臺服務器,其連接數加 1,當連接中止或超時,其連接數減 1。當服務器的權值爲 0 時,表示該服務器不可用而不被調度。
-
簡單算法:active * 256 + inactive (誰的小選誰)
-
wlc(加權最少連接):lc 算法忽略了服務器的性能問題,有的服務器性能好,有的服務器性能差。通過加權重可以區分性能,各個服務器用相應的權值表示其處理性能。服務器的缺省權值爲 1,可以動態地設置服務器的權限,加權最小連接調度在調度新連接時儘可能使服務器的已建立連接數和其權值成比例。由於服務器的性能不同,給性能相對好的服務器,加大權重,即會接收到更多的請求。
-
簡單算法:(active * 256 + inactive) / weight(誰的小選誰)
-
sed(最少期望延遲):不考慮非活動連接,誰的權重大,我們優先選擇權重大的服務器來接收請求,但會出現問題,就是權重比較大的服務器會很忙,但權重相對較小的服務器很閒,甚至會接收不到請求,所以便有了下面的算法 nq。
-
簡單算法:(active + 1) * 256 / weight (誰的小選誰)
-
nq(never queue,永不排隊):是 sed 的改進,不管權重多大都會被分配到請求。如果真實服務器的連接數爲 0 就直接分配過去,不需要再進行 sed 運算。
-
LBLC(基於局部性的最少連接 ):針對請求報文目標 IP 地址的負載均衡調度,主要用於 Cache 集羣系統,因爲 Cache 集羣中客戶請求報文的目標 IP 地址是變化的,這裏假設任何後端服務器都可以處理任何請求,算法的設計目標在服務器的負載基本平衡的情況下,將相同的目標 IP 地址的請求調度到同一個臺服務器,來提高服務器的訪問局部性和主存 Cache 命中率,從而調整整個集羣系統的處理能力。
-
LBLCR(基於局部性的帶複製功能的最少連接):針對目標 IP 地址的負載均衡,該算法根據請求的目標 IP 地址找出該目標 IP 地址對應的服務器組,按 “最小連接” 原則從服務器組中選出一臺服務器,若服務器沒有超載,將請求發送到該服務器;若服務器超載,則按 “最小連接” 原則從這個集羣中選出一臺服務器,將該服務器加入到服務器組中,將請求發送到該服務器。同時,當該服務器組有一段時間沒有被修改,將最忙的服務器從服務器組中刪除,以降低複製的程度。
ipvsadm CLI
查看
查看幫助手冊:
$ ipvsadm --help
查看 LVS 規則:
$ ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
UDP 10.0.0.9:5678 rr
-> 192.168.1.8:5678 Masq 1 0 0
添加
- 添加集羣服務:
$ ipvsadm -A -t 192.168.1.100:80 -s rr
- 添加真實服務器到集羣服務:
$ ipvsadm -a -t 192.168.1.100:80 -r 172.16.16.2:80 -m -w 1
修改
- 修改集羣服務:
$ ipvsadm -E -t 192.168.1.100:80 -s wlc
- 修改集羣服務中的真實服務器:
$ ipvsadm -e -t 192.168.1.100:80 -r 172.16.16.2:80 -m -w 2
刪除
- 刪除集羣服務:
$ ipvsadm -D -t 192.168.1.100:80
- 刪除集羣服務中的一個真實服務器:
$ ipvsadm -d -t 192.168.1.100:80 -r 172.16.16.2:80
- 刪除所有集羣服務
$ ipvsadm -C
LVS-NAT & Keepalived 部署示例
雖然 LVS-NAT 模式存在着缺點,但由於其優秀的多場景適用性,所以大多數 LB 商業產品依舊會選擇使用此模式,例如:Cisco LocalDirector、F5 Big/IP、Alteon ACEDirector 等。
- 官方文檔:LVS NAT + Keepalived HOWTO
在 2 臺 DS 節點上安裝 Keepalived & LVS:
$ yum install -y keepalived ipvsadm
$ keepalived --version
Keepalived v1.3.5 (03/19,2017), git commit v1.3.5-6-g6fa32f2
$ ipvsadm --version
ipvsadm v1.27 2008/5/15 (compiled with popt and IPVS v1.2.1)
TCP 負載均衡應用場景
IP 規劃
-
Client(CIP):192.168.1.100/24
-
DS1:
-
外部網卡:192.168.1.110/24
-
內部網卡:10.0.0.103/24
-
DS2:
-
外部網卡:192.168.1.111/24
-
內部網卡:10.0.0.104/24
-
VS 外部 VIP:192.168.1.112
-
DS 內部 DIP:10.0.0.105
-
RS1:
-
RIP:10.0.0.101/24
-
Default Gateway:10.0.0.105/24
-
RS2:
-
RIP:0.0.0.102/24
-
Default Gateway:10.0.0.105/24
網絡拓撲
DS1 配置
啓動 ipvsadm:
$ touch /etc/sysconfig/ipvsadm
$ systemctl start ipvsadm.service
啓動 keepalived:
$ cat /etc/sysconfig/keepalived
# Options for keepalived. See `keepalived --help' output and keepalived(8) and
# keepalived.conf(5) man pages for a list of all options. Here are the most
# common ones :
#
# --vrrp -P Only run with VRRP subsystem.
# --check -C Only run with Health-checker subsystem.
# --dont-release-vrrp -V Dont remove VRRP VIPs & VROUTEs on daemon stop.
# --dont-release-ipvs -I Dont remove IPVS topology on daemon stop.
# --dump-conf -d Dump the configuration data.
# --log-detail -D Detailed log messages.
# --log-facility -S 0-7 Set local syslog facility (default=LOG_DAEMON)
#
KEEPALIVED_OPTIONS="-D -d"
$ cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
lvs_id LVS_01
}
vrrp_sync_group VG1 {
group {
VI_1
VI_GATEWAY
}
}
vrrp_instance VI_1 {
state MASTER
interface eno16777736
lvs_sync_daemon_inteface eno16777736
virtual_router_id 51
priority 150
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.1.112
}
}
vrrp_instance VI_GATEWAY {
state MASTER
interface eno33554960
lvs_sync_daemon_inteface eno33554960
virtual_router_id 52
priority 150
advert_int 1
authentication {
auth_type PASS
auth_pass example
}
virtual_ipaddress {
10.0.0.105
}
}
virtual_server 192.168.1.112 80 {
delay_loop 6
lb_algo rr
lb_kind NAT
nat_mask 255.255.255.0
protocol TCP
real_server 10.0.0.101 80 {
weight 1
}
real_server 10.0.0.102 80 {
weight 1
}
}
$ systemctl start keepalived
查看 VIP 和 DIP:
$ ip a s
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eno16777736: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:27:d5:3b brd ff:ff:ff:ff:ff:ff
inet 192.168.1.110/24 brd 192.168.1.255 scope global dynamic eno16777736
valid_lft 6646sec preferred_lft 6646sec
inet 192.168.1.112/32 scope global eno16777736
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe27:d53b/64 scope link tentative dadfailed
valid_lft forever preferred_lft forever
3: eno33554960: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:27:d5:45 brd ff:ff:ff:ff:ff:ff
inet 10.0.0.103/24 brd 10.0.0.255 scope global eno33554960
valid_lft forever preferred_lft forever
inet 10.0.0.105/32 scope global eno33554960
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe27:d545/64 scope link
valid_lft forever preferred_lft forever
查看 ipvs 規則: ipvs 的規則應該是 VIP 轉發到 RS,而不是 DIP 轉發到 RS。
$ ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.1.112:80 rr
-> 10.0.0.101:80 Masq 1 0 0
-> 10.0.0.102:80 Masq 1 0 0
NOTE:LVS1 上並不會真的開啓 80 端口,只是一個 VPORT。
$ netstat -lpntu | grep 80
開啓路由轉發功能(DS 要開啓路由轉發功能):
$ cat /etc/sysctl.conf
# System default settings live in /usr/lib/sysctl.d/00-system.conf.
# To override those settings, enter new settings here, or in an /etc/sysctl.d/<name>.conf file
#
# For more information, see sysctl.conf(5) and sysctl.d(5).
net.ipv4.ip_forward = 1
[root@localhost ~]# sysctl -p
net.ipv4.ip_forward = 1
清空防火牆規則:
$ iptables -F -t filter
$ iptables -F -t raw
$ iptables -F -t mangle
$ iptables -F -t nat
DS2 配置
配置 LVS2 和配置 LVS1 的步驟基本一致,但 Keepalived 的配置文件有些許變動。
$ cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
lvs_id LVS_01
}
vrrp_sync_group VG1 {
group {
VI_1
VI_GATEWAY
}
}
vrrp_instance VI_1 {
state BACKUP
interface eno16777736
lvs_sync_daemon_inteface eno16777736
virtual_router_id 51
priority 140
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.1.112
}
}
vrrp_instance VI_GATEWAY {
state BACKUP
interface eno33554960
lvs_sync_daemon_inteface eno33554960
virtual_router_id 52
priority 150
advert_int 1
authentication {
auth_type PASS
auth_pass example
}
virtual_ipaddress {
10.0.0.105
}
}
virtual_server 192.168.1.112 80 {
delay_loop 6
lb_algo rr
lb_kind NAT
nat_mask 255.255.255.0
protocol TCP
real_server 10.0.0.101 80 {
weight 1
}
real_server 10.0.0.102 80 {
weight 1
}
}
RS1 配置
網卡的 Gateway 指向 DIP:RS 的默認網關應該指向 DIP。
$ cat /etc/sysconfig/network-scripts/ifcfg-eno33554960
HWADDR=00:0C:29:15:40:15
TYPE=Ethernet
BOOTPROTO=static
DEFROUTE=yes
PEERDNS=yes
PEERROUTES=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_PEERDNS=yes
IPV6_PEERROUTES=yes
IPV6_FAILURE_FATAL=no
NAME=eno33554960
UUID=be63d7a3-f7eb-4204-9c1d-cecb2e857d0b
ONBOOT=yes
IPADDR=10.0.0.101
GATEWAY=10.0.0.105
NETMASK=255.255.255.0
DNS1=114.114.114.114
清空防火牆規則:
$ iptables -F -t filter
$ iptables -F -t raw
$ iptables -F -t mangle
$ iptables -F -t nat
安裝 TCP 80 的 httpd 服務:
$ yum install -y httpd
$ cat /var/www/html/index.html
<html>
<body>
<h1>RS1</h1>
</body>
</html>
$ systemctl start httpd
$ netstat -lpntu | grep 80
tcp6 0 0 :::80 :::* LISTEN 18227/httpd
RS2 配置
配置 RS2 與 RS1 的步驟基本一致,只是 httpd 的 index.html 有些許改變:
$ cat /var/www/html/index.html
<html>
<body>
<h1>RS2</h1>
</body>
</html>
驗證
在客戶端 curl http://VIP:VPort 會輪詢的訪問 RS1 和 RS2。
$ curl 192.168.1.112
<html>
<body>
<h1>RS2</h1>
</body>
</html>
$ curl 192.168.1.112
<html>
<body>
<h1>RS1</h1>
</body>
</html>
在 MR(Master Router) 查看連接表:
$ ipvsadm -Lnc
IPVS connection entries
pro expire state source virtual destination
TCP 01:27 TIME_WAIT 192.168.1.100:52034 192.168.1.112:80 10.0.0.101:80
在 BR(Backup Router) 查看連接表:
$ ipvsadm -Lnc
IPVS connection entries
pro expire state source virtual destination
可以看見因爲 Keepalived 只支持主從 HA 模式,所以 LVS 的連接表狀態並沒有同步,但是可以 Failover(故障轉移)。當關閉 MR 電源之後還可以繼續通過客戶端訪問 curl http://VIP:VPort,查看發現 VIP 漂移到了 BR,同時再次查看 BR 的連接表:
$ ipvsadm -Lnc
IPVS connection entries
pro expire state source virtual destination
TCP 01:57 TIME_WAIT 192.168.1.100:52115 192.168.1.112:80 10.0.0.101:80
UDP 負載均衡應用場景
DS1/2 配置
配置 Keepalived,添加 UDP 協議負載均衡 virtual_server:
$ cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
lvs_id LVS_01
}
vrrp_sync_group VG1 {
group {
VI_1
VI_GATEWAY
}
}
vrrp_instance VI_1 {
state MASTER
interface eno16777736
lvs_sync_daemon_inteface eno16777736
virtual_router_id 51
priority 150
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.1.112
}
}
vrrp_instance VI_GATEWAY {
state MASTER
interface eno33554960
lvs_sync_daemon_inteface eno33554960
virtual_router_id 52
priority 150
advert_int 1
authentication {
auth_type PASS
auth_pass example
}
virtual_ipaddress {
10.0.0.105
}
}
virtual_server 192.168.1.112 80 {
delay_loop 6
lb_algo rr
lb_kind NAT
nat_mask 255.255.255.0
protocol TCP
real_server 10.0.0.101 80 {
weight 1
}
real_server 10.0.0.102 80 {
weight 1
}
}
virtual_server 192.168.1.112 9999 {
delay_loop 6
lb_algo rr
lb_kind NAT
nat_mask 255.255.255.0
protocol UDP
real_server 10.0.0.101 9999 {
weight 1
}
real_server 10.0.0.102 9999 {
weight 1
}
}
$ systemctl restart keepalived
$ ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.1.112:80 rr
-> 10.0.0.101:80 Masq 1 0 0
-> 10.0.0.102:80 Masq 1 0 0
UDP 192.168.1.112:9999 rr
-> 10.0.0.101:9999 Masq 1 0 0
-> 10.0.0.102:9999 Masq 1 0 0
NOTE:DS1/2 的配置大同小異,只是 vrrp_instance 的角色和權重有所區別而已。
RS1/2 配置
啓用 nc udp 服務器,接收外部傳輸過來的文件:
$ yum install -y nc
$ nc -ul 9999 > file.txt
$ netstat -lpntu | grep 9999
udp 0 0 0.0.0.0:9999 0.0.0.0:* 2618/nc
udp6 0 0 :::9999 :::* 2618/nc
驗證
在客戶端上準備兩個文件並執行文件傳輸:
$ nc -u -w 1 192.168.1.112 9999 < 1.txt
$ nc -u -w 1 192.168.1.112 9999 < 2.txt
可以看見這兩個文件分別被 RS1 和 RS2 的 nc udp 服務端接收。
- RS1
$ nc -ul 9999 > file.txt
Ncat: Connection refused.
$ cat file.txt
22222222222
- RS2
$ nc -ul 9999 > file.txt
Ncat: Connection refused.
$ cat file.txt
11111111111
查看 ipvs 轉發表:
$ ipvsadm -Lnc
IPVS connection entries
pro expire state source virtual destination
UDP 04:20 UDP 192.168.1.100:65136 192.168.1.112:9999 10.0.0.101:9999
UDP 04:19 UDP 192.168.1.100:51930 192.168.1.112:9999 10.0.0.102:9999
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/N2X1tMdQtriP7gjO2l5dhw