通用连接多路复用协议
- 复用已有连接,省去握手时间。可用于解决websocket+CDN代理场景下建立连接握手时间太长
- 聚合多个IP/服务器,同时聚合带宽,多个低带宽服务器聚合成高带宽
- 某些情况下聚合多条TCP连接可以提高峰值带宽
mpx-tunnel使用多个TCP连接承载
假设我们有两台服务器server-1
, server-2
公网IP | 内网IP | |
---|---|---|
server-1 | public-ip-1 | private-ip-1 |
server-2 | public-ip-2 | private-ip-2 |
docker run -d --restart=always --name=ssgo -p 2551:2551 -t niiv0832/go-shadowsocks2:latest -u -s 'ss://AEAD_CHACHA20_POLY1305:password@:2551'
docker run -d --restart=always --name mpx -p 5512:5512 -e LISTEN_ADDR="0.0.0.0:5512" -e TARGET_ADDR="private-ip-1:2551" fregie/mpx:latest
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p
iptables -t nat -I POSTROUTING -j MASQUERADE
iptables -t nat -I PREROUTING -p tcp --dport 6666 -j DNAT --to-destination private-ip-1:5512
iptables -t nat -I POSTROUTING -d private-ip-1 -p tcp --dport 5512 -j SNAT --to-source private-ip-2
docker run -d --restart=always --name mpx -p 5513:5513 -e LISTEN_ADDR="0.0.0.0:5513" -e SERVER_ADDR="public-ip-1:5512|1,public-ip-2:6666|1" fregie/mpx:latest
使用以下配置启动任意shadowsocks客户端
server: 127.0.0.1
port: 5513
method: AEAD_CHACHA20_POLY1305
password: password
go install github.com/fregie/mpx/mpx-tunnel@latest
以go-shadowsocks2举例,首先在服务器启动ss服务端:
go-shadowsocks2 -s 'ss://AEAD_CHACHA20_POLY1305:your-password@:8488' -verbose
在服务器启动mpx server,转发连接到ss服务端端口
# 指定target则为服务端
mpx-tunnel -listen 0.0.0.0:5512 -target 127.0.0.1:8848
或使用docker部署
docker run -d --restart=always --name mpx -p 5512:5512 -e LISTEN_ADDR="0.0.0.0:5512" -e TARGET_ADDR="127.0.0.1:8848" fregie/mpx:latest
启动mpx client
# 指定server则为客户端
mpx-tunnel -listen 0.0.0.0:5513 --server server-ip:5512 -p 4
或使用docker部署
docker run -d --restart=always --name mpx -p 5512:5512 -e LISTEN_ADDR="0.0.0.0:5512" -e SERVER_ADDR="server-ip:5512" fregie/mpx:latest
-p
:配置保持的长连接数量
启动ss客户端
go-shadowsocks2 -c 'ss://AEAD_CHACHA20_POLY1305:your-password@127.0.0.1:5513' -socks :1080 -verbose
假如你有两台XX云30mbps轻量级服务器server-1
,server-2
,在同一个内网中,公网ip分别为public-ip-1
,public-ip-2
,内网ip分别为private-ip-1
,private-ip-2
。
- 在
server-1
按以上方法部署mpx-ser
以及ss server
- 在
server-2
配置通过iptables端口转发,转发6666
端口到server-1
的5512
端口
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p
iptables -t nat -I POSTROUTING -j MASQUERADE
iptables -t nat -I PREROUTING -p tcp --dport 6666 -j DNAT --to-destination private-ip-1:5512
iptables -t nat -I POSTROUTING -d private-ip-1 -p tcp --dport 5512 -j SNAT --to-source private-ip-2
- 在客户端使用以下命令启动
mpx-cli
:
mpx-tunnel -listen 0.0.0.0:5513 -server "public-ip-1:5512|2,public-ip-2:6666|2" -p 4
# 使用docker部署
docker run -d --restart=always --name mpx -p 5512:5512 -e LISTEN_ADDR="0.0.0.0:5512" -e SERVER_ADDR="public-ip-1:5512|2,public-ip-2:6666|2" fregie/mpx:latest
-s
: 使用,
分割不同服务端,|
前为服务端地址ip:port
,|
之后为权重,会根据其权重来分配对应地址承载的带宽。例如你有一台30m和一台60m的服务器,那你应该将其权重配为1:2
- 按上面的方法启动
ss client
mpx是一个基于标准库 net
中interface同时也实现了 net
库中部分interface的连接多路复用库。
mpx接受任何实现了 net.Conn
接口的连接作为输入。
可以直接调用 AddConn
方法将Conn输入,也可以调用 ServeWithListener
输入一个 net.Listener
,调用 StartWithDialer
输入一个 dailer
(mpx库中的一个interface)来使用mpx
mpx提供给调用者一个名为 ConnPool
的struct。
该struct实现了 net.Listener
供服务端调用,同时提供一个 dial
方法供客户端建立连接(返回一个 net.Conn
)。
- 支持丢包重传
- 输入连接可用性检测
- 支持配置输入连接权重
go get github.com/fregie/mpx
import (
"github.com/fregie/mpx"
"net"
)
func main(){
lis, _ := net.Listen("tcp", "0.0.0.0:5512")
// Skip exception handling here
cp := mpx.NewConnPool()
go cp.ServeWithListener(lis)
for {
conn, _ := cp.Accept()
// Skip exception handling here
go func(){
defer conn.Close()
// Do something with conn(net.Conn)
}
}
}
import (
"github.com/fregie/mpx"
"net"
)
type TCPDialer struct {
ServerAddr string
}
func (t *TCPDialer) Dial() (net.Conn, error) {
return net.Dial("tcp", t.ServerAddr)
}
func main(){
cp := mpx.NewConnPool()
cp.StartWithDialer(&TCPDialer{ServerAddr: "ip:port"}, 5)
conn, _ := cp.Dial(nil)
// Skip exception handling here
defer conn.Close()
// Do something with conn(net.Conn)
conn.Write([]byte("something"))
}