Skip to content

Commit bc2a867

Browse files
committed
quic 使用调研
1 parent ae7cb85 commit bc2a867

File tree

6 files changed

+495
-7
lines changed

6 files changed

+495
-7
lines changed

client.go

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,17 @@
55
package vex
66

77
import (
8+
"crypto/tls"
89
"io"
910
"net"
1011

1112
"github.com/FishGoddess/vex/log"
1213
)
1314

15+
var (
16+
cert, certPool = generateCert()
17+
)
18+
1419
type Client interface {
1520
io.ReadWriteCloser
1621
}
@@ -46,7 +51,18 @@ func (c *client) connect() (err error) {
4651
}
4752
}()
4853

49-
conn, err := net.DialTimeout(network, c.address, c.connectTimeout)
54+
// conn, err := net.DialTimeout(network, c.address, c.connectTimeout)
55+
// if err != nil {
56+
// return err
57+
// }
58+
59+
tlsConf := &tls.Config{
60+
Certificates: []tls.Certificate{cert},
61+
RootCAs: certPool,
62+
MinVersion: tls.VersionTLS13, // 必须为 TLS 1.3
63+
}
64+
65+
conn, err := tls.Dial(network, c.address, tlsConf)
5066
if err != nil {
5167
return err
5268
}

go.mod

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,26 @@
11
module github.com/FishGoddess/vex
22

3-
go 1.23
3+
go 1.23.0
44

55
toolchain go1.23.7
66

7-
require github.com/FishGoddess/rego v0.3.0
7+
require (
8+
github.com/FishGoddess/rego v0.3.0
9+
github.com/quic-go/quic-go v0.52.0
10+
golang.org/x/net v0.40.0
11+
)
12+
13+
require (
14+
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
15+
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect
16+
github.com/onsi/ginkgo/v2 v2.9.5 // indirect
17+
go.uber.org/mock v0.5.0 // indirect
18+
golang.org/x/mod v0.18.0 // indirect
19+
golang.org/x/sync v0.8.0 // indirect
20+
golang.org/x/tools v0.22.0 // indirect
21+
)
22+
23+
require (
24+
golang.org/x/crypto v0.38.0 // indirect
25+
golang.org/x/sys v0.33.0 // indirect
26+
)

go.sum

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,54 @@
1-
github.com/FishGoddess/rego v0.2.2 h1:bQy+XJ5SKDfyMPN/+OWE0wQmlEtEcnOet8fr1BZZdxo=
2-
github.com/FishGoddess/rego v0.2.2/go.mod h1:wwemmf3ghUHddWzK7BgAjyy6qHoIgGeuKrKM4Rbf91k=
3-
github.com/FishGoddess/rego v0.2.4 h1:+WZOd9oBc5Bu0ArHcFepEFMmBkGNIpzZfe7V4jIuuNc=
4-
github.com/FishGoddess/rego v0.2.4/go.mod h1:wwemmf3ghUHddWzK7BgAjyy6qHoIgGeuKrKM4Rbf91k=
51
github.com/FishGoddess/rego v0.3.0 h1:JPsgB9s3ySXZwzqoeyMB5ZQJtGBedBRB0Jbb0VGeu/U=
62
github.com/FishGoddess/rego v0.3.0/go.mod h1:wwemmf3ghUHddWzK7BgAjyy6qHoIgGeuKrKM4Rbf91k=
3+
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
4+
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
5+
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
6+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
7+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
8+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
9+
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
10+
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
11+
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
12+
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
13+
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
14+
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
15+
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
16+
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
17+
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE=
18+
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
19+
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
20+
github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q=
21+
github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k=
22+
github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE=
23+
github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg=
24+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
25+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
26+
github.com/quic-go/quic-go v0.52.0 h1:/SlHrCRElyaU6MaEPKqKr9z83sBg2v4FLLvWM+Z47pA=
27+
github.com/quic-go/quic-go v0.52.0/go.mod h1:MFlGGpcpJqRAfmYi6NC2cptDPSxRWTOGNuP4wqrWmzQ=
28+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
29+
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
30+
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
31+
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
32+
go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
33+
go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
34+
golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8=
35+
golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw=
36+
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
37+
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
38+
golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=
39+
golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
40+
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
41+
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
42+
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
43+
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
44+
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
45+
golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
46+
golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
47+
golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
48+
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
49+
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
50+
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
51+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
52+
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
53+
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
54+
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

quic_test.go

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
package vex
2+
3+
import (
4+
"context"
5+
"crypto/tls"
6+
"errors"
7+
"io"
8+
"math"
9+
"sync"
10+
"testing"
11+
"time"
12+
13+
"github.com/FishGoddess/rego"
14+
"github.com/quic-go/quic-go"
15+
)
16+
17+
func calculateRPS(loop int, cost time.Duration) float64 {
18+
return math.Round(float64(loop) * float64(time.Second) / float64(cost))
19+
}
20+
21+
// go test -v -run=^TestQUIC$
22+
func TestQUIC(t *testing.T) {
23+
benchmarkData := make([]byte, 1024)
24+
ctx := context.Background()
25+
26+
addr := "127.0.0.1:9707"
27+
cert, certPool := generateCert()
28+
29+
tlsConf := &tls.Config{
30+
Certificates: []tls.Certificate{cert},
31+
RootCAs: certPool,
32+
MinVersion: tls.VersionTLS13, // 必须为 TLS 1.3
33+
}
34+
35+
quicConf := &quic.Config{
36+
MaxIncomingStreams: 10000,
37+
//InitialStreamReceiveWindow: (1 << 20) * 4,
38+
//MaxStreamReceiveWindow: (1 << 20) * 64,
39+
InitialConnectionReceiveWindow: (1 << 20) * 4,
40+
MaxConnectionReceiveWindow: (1 << 20) * 64,
41+
}
42+
43+
go func() {
44+
listener, err := quic.ListenAddr(addr, tlsConf, quicConf)
45+
if err != nil {
46+
panic(err)
47+
}
48+
49+
defer listener.Close()
50+
for {
51+
conn, err := listener.Accept(ctx)
52+
if err != nil {
53+
panic(err)
54+
}
55+
56+
go func(conn quic.Connection) {
57+
for {
58+
select {
59+
case <-conn.Context().Done():
60+
break
61+
default:
62+
}
63+
64+
stream, err := conn.AcceptStream(ctx)
65+
if err != nil {
66+
panic(err)
67+
}
68+
69+
go func(stream quic.Stream) {
70+
defer stream.Close()
71+
72+
buffer := make([]byte, 1024)
73+
for {
74+
_, err = stream.Read(buffer)
75+
if errors.Is(err, io.EOF) {
76+
return
77+
}
78+
79+
if err != nil {
80+
panic(err)
81+
}
82+
83+
_, err = stream.Write(benchmarkData)
84+
if err != nil {
85+
panic(err)
86+
}
87+
}
88+
}(stream)
89+
}
90+
}(conn)
91+
}
92+
}()
93+
94+
time.Sleep(time.Second)
95+
96+
acquireConn := func(ctx context.Context) (quic.Connection, error) {
97+
return quic.DialAddr(ctx, addr, tlsConf, quicConf)
98+
}
99+
100+
releaseConn := func(ctx context.Context, conn quic.Connection) error {
101+
return nil
102+
}
103+
104+
connPool := rego.New(1, acquireConn, releaseConn)
105+
defer connPool.Close(ctx)
106+
107+
acquireStream := func(ctx context.Context) (quic.Stream, error) {
108+
conn, err := connPool.Take(ctx)
109+
if err != nil {
110+
return nil, err
111+
}
112+
113+
defer connPool.Put(ctx, conn)
114+
return conn.OpenStreamSync(ctx)
115+
}
116+
117+
releaseStream := func(ctx context.Context, stream quic.Stream) error {
118+
return stream.Close()
119+
}
120+
121+
streamPool := rego.New(64, acquireStream, releaseStream)
122+
defer streamPool.Close(ctx)
123+
124+
fn := func() {
125+
stream, err := streamPool.Take(ctx)
126+
if err != nil {
127+
panic(err)
128+
}
129+
130+
defer streamPool.Put(ctx, stream)
131+
132+
_, err = stream.Write(benchmarkData)
133+
if err != nil {
134+
panic(err)
135+
}
136+
137+
buffer := make([]byte, 1024)
138+
139+
_, err = stream.Read(buffer)
140+
if errors.Is(err, io.EOF) {
141+
return
142+
}
143+
144+
if err != nil {
145+
panic(err)
146+
}
147+
}
148+
149+
loop := 100000
150+
beginTime := time.Now()
151+
152+
var wg sync.WaitGroup
153+
for i := 0; i < loop; i++ {
154+
wg.Add(1)
155+
go func() {
156+
defer wg.Done()
157+
158+
fn()
159+
}()
160+
}
161+
162+
wg.Wait()
163+
cost := time.Since(beginTime)
164+
t.Logf("Took %s, rps is %.0f!\n", cost, calculateRPS(loop, cost))
165+
}

0 commit comments

Comments
 (0)