- Created by 郭强, last modified on Mar 15, 2023
基本介绍
负载均衡组件使用在客户端中。GoFrame
框架提供了解耦化设计的、灵活性高、扩展性强的负载均衡组件,由gsel
组件管理,该组件定义了负载均衡的接口,并提供了多种内置的负载均衡策略实现。开发者也可以根据接口实现自定义的负载均衡策略。
策略列表
gsel
组件提供了多种常用的负载均衡策略,供开发者选择使用:
策略名称 | 策略描述 |
---|---|
LeastConnection | 最小连接数。 |
Random | 随机访问。 |
RoundRobin | 轮训访问。 |
Weight | 权重访问。服务注册时需要设置Weight 参数。 |
使用示例
HTTP
server.go
package main import ( "github.com/gogf/gf/contrib/registry/etcd/v2" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/net/ghttp" "github.com/gogf/gf/v2/net/gsvc" ) func main() { gsvc.SetRegistry(etcd.New(`127.0.0.1:2379`)) s := g.Server(`hello.svc`) s.BindHandler("/", func(r *ghttp.Request) { g.Log().Info(r.Context(), `request received`) r.Response.Write(`Hello world`) }) s.Run() }
client.go
这里使用 gsel.SetBuilder(gsel.NewBuilderRoundRobin())
设置全局的负载均衡策略为轮训访问策略。
package main import ( "github.com/gogf/gf/contrib/registry/etcd/v2" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/net/gsel" "github.com/gogf/gf/v2/net/gsvc" "github.com/gogf/gf/v2/os/gctx" ) func main() { gsvc.SetRegistry(etcd.New(`127.0.0.1:2379`)) gsel.SetBuilder(gsel.NewBuilderRoundRobin()) for i := 0; i < 10; i++ { ctx := gctx.New() res := g.Client().GetContent(ctx, `http://hello.svc/`) g.Log().Info(ctx, res) } }
分别启动两个服务端,并执行客户端。
server1
终端输出:
$ go run server.go 2023-03-15 21:24:08.413 [INFO] pid[10219]: http server started listening on [:63956] 2023-03-15 21:24:08.413 [INFO] openapi specification is disabled 2023-03-15 21:24:08.413 [DEBU] service register: &{Head: Deployment: Namespace: Name:hello.svc Version: Endpoints:10.35.12.81:63956 Metadata:map[insecure:true protocol:http]} 2023-03-15 21:24:08.455 [DEBU] etcd put success with key "/service/default/default/hello.svc/latest/10.35.12.81:63956", value "{"insecure":true,"protocol":"http"}", lease "7587869265945813020" SERVER | DOMAIN | ADDRESS | METHOD | ROUTE | HANDLER | MIDDLEWARE ------------|---------|---------|--------|-------|-----------------------------------------------------------------|-------------------- hello.svc | default | :63956 | ALL | / | main.main.func1 | ------------|---------|---------|--------|-------|-----------------------------------------------------------------|-------------------- hello.svc | default | :63956 | ALL | /* | github.com/gogf/gf/v2/net/ghttp.internalMiddlewareServerTracing | GLOBAL MIDDLEWARE ------------|---------|---------|--------|-------|-----------------------------------------------------------------|-------------------- 2023-03-15 21:24:18.357 [INFO] {e05b6049859a4c17d1de5d62eafa5a5f} request received 2023-03-15 21:24:18.358 [INFO] {785e9349859a4c17d3de5d62049e5b51} request received 2023-03-15 21:24:18.360 [INFO] {7076ab49859a4c17d5de5d62aaa64c85} request received 2023-03-15 21:24:18.360 [INFO] {205fb849859a4c17d7de5d62cb2590f4} request received 2023-03-15 21:24:18.361 [INFO] {885fc349859a4c17d9de5d6235937e31} request received
server2
终端输出:
$ go run server.go 2023-03-15 21:24:10.769 [INFO] pid[10242]: http server started listening on [:63964] 2023-03-15 21:24:10.770 [INFO] openapi specification is disabled 2023-03-15 21:24:10.770 [DEBU] service register: &{Head: Deployment: Namespace: Name:hello.svc Version: Endpoints:10.35.12.81:63964 Metadata:map[insecure:true protocol:http]} 2023-03-15 21:24:10.812 [DEBU] etcd put success with key "/service/default/default/hello.svc/latest/10.35.12.81:63964", value "{"insecure":true,"protocol":"http"}", lease "7587869265945813023" SERVER | DOMAIN | ADDRESS | METHOD | ROUTE | HANDLER | MIDDLEWARE ------------|---------|---------|--------|-------|-----------------------------------------------------------------|-------------------- hello.svc | default | :63964 | ALL | / | main.main.func1 | ------------|---------|---------|--------|-------|-----------------------------------------------------------------|-------------------- hello.svc | default | :63964 | ALL | /* | github.com/gogf/gf/v2/net/ghttp.internalMiddlewareServerTracing | GLOBAL MIDDLEWARE ------------|---------|---------|--------|-------|-----------------------------------------------------------------|-------------------- 2023-03-15 21:24:18.357 [INFO] {602d8749859a4c17d2de5d62d515e464} request received 2023-03-15 21:24:18.359 [INFO] {e0ed9b49859a4c17d4de5d628284ae62} request received 2023-03-15 21:24:18.360 [INFO] {e0e0b249859a4c17d6de5d62beda3001} request received 2023-03-15 21:24:18.361 [INFO] {7087bd49859a4c17d8de5d62f892e8aa} request received 2023-03-15 21:24:18.361 [INFO] {e8aec849859a4c17dade5d6247101836} request received
客户端终端输出:
$ go run client.go 2023-03-15 21:24:18.357 [INFO] {e05b6049859a4c17d1de5d62eafa5a5f} Hello world 2023-03-15 21:24:18.358 [INFO] {602d8749859a4c17d2de5d62d515e464} Hello world 2023-03-15 21:24:18.358 [INFO] {785e9349859a4c17d3de5d62049e5b51} Hello world 2023-03-15 21:24:18.359 [INFO] {e0ed9b49859a4c17d4de5d628284ae62} Hello world 2023-03-15 21:24:18.360 [INFO] {7076ab49859a4c17d5de5d62aaa64c85} Hello world 2023-03-15 21:24:18.360 [INFO] {e0e0b249859a4c17d6de5d62beda3001} Hello world 2023-03-15 21:24:18.360 [INFO] {205fb849859a4c17d7de5d62cb2590f4} Hello world 2023-03-15 21:24:18.361 [INFO] {7087bd49859a4c17d8de5d62f892e8aa} Hello world 2023-03-15 21:24:18.361 [INFO] {885fc349859a4c17d9de5d6235937e31} Hello world 2023-03-15 21:24:18.361 [INFO] {e8aec849859a4c17dade5d6247101836} Hello world
GRPC
server.go
package main import ( "github.com/gogf/gf/contrib/rpc/grpcx/v2" "github.com/gogf/gf/example/rpc/grpcx/balancer/controller" ) func main() { s := grpcx.Server.New() controller.Register(s) s.Run() }
client.go
package main import ( "context" "github.com/gogf/gf/contrib/rpc/grpcx/v2" "github.com/gogf/gf/example/rpc/grpcx/balancer/protobuf" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/os/gctx" ) func main() { var ( ctx context.Context conn = grpcx.Client.MustNewGrpcClientConn("demo", grpcx.Balancer.WithRandom()) client = protobuf.NewGreeterClient(conn) ) for i := 0; i < 10; i++ { ctx = gctx.New() res, err := client.SayHello(ctx, &protobuf.HelloRequest{Name: "World"}) if err != nil { g.Log().Error(ctx, err) return } g.Log().Debug(ctx, "Response:", res.Message) } }
其中的grpcx.Balancer.WithRandom()
表示使用随机的请求策略。启动两个server.go
服务端,随后运行client.go
客户端,查看服务端的请求日志:
server1
终端输出:
$ go run server.go 2023-03-15 19:50:44.801 [DEBU] set default registry using file registry as no custom registry set 2023-03-15 19:50:44.802 [DEBU] service register: &{Head: Deployment: Namespace: Name:demo Version: Endpoints:10.35.12.81:53962 Metadata:map[protocol:grpc]} 2023-03-15 19:50:44.802 [INFO] pid[89290]: grpc server started listening on [:53962] 2023-03-15 19:50:57.282 {7025612f6d954c17c5f335051bf10899} /protobuf.Greeter/SayHello, 0.003ms, name:"World", message:"Hello World" 2023-03-15 19:50:57.283 {60567c2f6d954c17c7f335052ce05185} /protobuf.Greeter/SayHello, 0.002ms, name:"World", message:"Hello World" 2023-03-15 19:50:57.285 {f8d09b2f6d954c17ccf33505dff1a4ea} /protobuf.Greeter/SayHello, 0.002ms, name:"World", message:"Hello World" 2023-03-15 19:50:57.287 {f0fab02f6d954c17cdf33505438b2c80} /protobuf.Greeter/SayHello, 0.001ms, name:"World", message:"Hello World"
server2
终端输出:
$ go run server.go 2023-03-15 19:50:51.720 [DEBU] set default registry using file registry as no custom registry set 2023-03-15 19:50:51.721 [DEBU] service register: &{Head: Deployment: Namespace: Name:demo Version: Endpoints:10.35.12.81:53973 Metadata:map[protocol:grpc]} 2023-03-15 19:50:51.722 [INFO] pid[89351]: grpc server started listening on [:53973] 2023-03-15 19:50:57.280 {b89a0d2f6d954c17c4f33505a046817c} /protobuf.Greeter/SayHello, 0.002ms, name:"World", message:"Hello World" 2023-03-15 19:50:57.282 {28bf732f6d954c17c6f33505adedff5f} /protobuf.Greeter/SayHello, 0.002ms, name:"World", message:"Hello World" 2023-03-15 19:50:57.283 {9876832f6d954c17c8f3350580ed535b} /protobuf.Greeter/SayHello, 0.002ms, name:"World", message:"Hello World" 2023-03-15 19:50:57.284 {684e8b2f6d954c17c9f33505d56e4b05} /protobuf.Greeter/SayHello, 0.001ms, name:"World", message:"Hello World" 2023-03-15 19:50:57.284 {c045912f6d954c17caf3350599006197} /protobuf.Greeter/SayHello, 0.001ms, name:"World", message:"Hello World" 2023-03-15 19:50:57.284 {500a972f6d954c17cbf33505252b0e01} /protobuf.Greeter/SayHello, 0.001ms, name:"World", message:"Hello World"
客户端终端输出:
$ go run client.go 2023-03-15 19:50:57.278 [DEBU] client conn updated with addresses [{"Addr":"10.35.12.81:53962","ServerName":"demo","Attributes":{},"BalancerAttributes":null,"Type":0,"Metadata":null},{"Addr":"10.35.12.81:53973","ServerName":"demo","Attributes":{},"BalancerAttributes":null,"Type":0,"Metadata":null}] 2023-03-15 19:50:57.281 [DEBU] {b89a0d2f6d954c17c4f33505a046817c} Response: Hello World 2023-03-15 19:50:57.282 [DEBU] {7025612f6d954c17c5f335051bf10899} Response: Hello World 2023-03-15 19:50:57.282 [DEBU] {28bf732f6d954c17c6f33505adedff5f} Response: Hello World 2023-03-15 19:50:57.283 [DEBU] {60567c2f6d954c17c7f335052ce05185} Response: Hello World 2023-03-15 19:50:57.283 [DEBU] {9876832f6d954c17c8f3350580ed535b} Response: Hello World 2023-03-15 19:50:57.284 [DEBU] {684e8b2f6d954c17c9f33505d56e4b05} Response: Hello World 2023-03-15 19:50:57.284 [DEBU] {c045912f6d954c17caf3350599006197} Response: Hello World 2023-03-15 19:50:57.285 [DEBU] {500a972f6d954c17cbf33505252b0e01} Response: Hello World 2023-03-15 19:50:57.286 [DEBU] {f8d09b2f6d954c17ccf33505dff1a4ea} Response: Hello World 2023-03-15 19:50:57.287 [DEBU] {f0fab02f6d954c17cdf33505438b2c80} Response: Hello World
Content Menu
- No labels
2 Comments
lin
这里的负载均衡有点问题,场景如下, A机器上部署了两个RPC,B机器上部署了一个RPC
RPC : A , A, B
RPC-CLIENT: A
我设置了 负载均衡,但是rpc流量都往同一台机器A上走,B根本就收不到流量,除非把A的RPC下线了
然后不知道哪里来的404,一直在写日志
郭强 可以帮忙解释一下么
lzx
grpc权重访问如何设置weight参数?