Introduction

The load balancing component is used on the client side. The GoFrame framework provides a decoupled design with high flexibility and strong extensibility for the load balancing component, which is managed by the gsel component. This component defines the interface for load balancing and provides multiple built-in load balancing strategy implementations. Developers can also implement custom load balancing strategies based on the interface.

Strategy List

The gsel component provides several commonly used load balancing strategies for developers to choose from:

Strategy NameStrategy Description
LeastConnectionLeast number of connections.
RandomRandom access.
RoundRobinRound-robin access.
WeightWeighted access. The Weight parameter needs to be set during service registration.

Usage Example

HTTP

server.go

  1. package main
  2. import (
  3. "github.com/gogf/gf/contrib/registry/etcd/v2"
  4. "github.com/gogf/gf/v2/frame/g"
  5. "github.com/gogf/gf/v2/net/ghttp"
  6. "github.com/gogf/gf/v2/net/gsvc"
  7. )
  8. func main() {
  9. gsvc.SetRegistry(etcd.New(`127.0.0.1:2379`))
  10. s := g.Server(`hello.svc`)
  11. s.BindHandler("/", func(r *ghttp.Request) {
  12. g.Log().Info(r.Context(), `request received`)
  13. r.Response.Write(`Hello world`)
  14. })
  15. s.Run()
  16. }

client.go

Here, gsel.SetBuilder(gsel.NewBuilderRoundRobin()) is used to set the global load balancing strategy to round-robin access.

  1. package main
  2. import (
  3. "github.com/gogf/gf/contrib/registry/etcd/v2"
  4. "github.com/gogf/gf/v2/frame/g"
  5. "github.com/gogf/gf/v2/net/gsel"
  6. "github.com/gogf/gf/v2/net/gsvc"
  7. "github.com/gogf/gf/v2/os/gctx"
  8. )
  9. func main() {
  10. gsvc.SetRegistry(etcd.New(`127.0.0.1:2379`))
  11. gsel.SetBuilder(gsel.NewBuilderRoundRobin())
  12. for i := 0; i < 10; i++ {
  13. ctx := gctx.New()
  14. res := g.Client().GetContent(ctx, `http://hello.svc/`)
  15. g.Log().Info(ctx, res)
  16. }
  17. }

Start two servers separately and run the client.

server1 terminal output:

  1. $ go run server.go
  2. 2023-03-15 21:24:08.413 [INFO] pid[10219]: http server started listening on [:63956]
  3. 2023-03-15 21:24:08.413 [INFO] openapi specification is disabled
  4. 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]}
  5. 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"
  6. SERVER | DOMAIN | ADDRESS | METHOD | ROUTE | HANDLER | MIDDLEWARE
  7. ------------|---------|---------|--------|-------|-----------------------------------------------------------------|--------------------
  8. hello.svc | default | :63956 | ALL | / | main.main.func1 |
  9. ------------|---------|---------|--------|-------|-----------------------------------------------------------------|--------------------
  10. hello.svc | default | :63956 | ALL | /* | github.com/gogf/gf/v2/net/ghttp.internalMiddlewareServerTracing | GLOBAL MIDDLEWARE
  11. ------------|---------|---------|--------|-------|-----------------------------------------------------------------|--------------------
  12. 2023-03-15 21:24:18.357 [INFO] {e05b6049859a4c17d1de5d62eafa5a5f} request received
  13. 2023-03-15 21:24:18.358 [INFO] {785e9349859a4c17d3de5d62049e5b51} request received
  14. 2023-03-15 21:24:18.360 [INFO] {7076ab49859a4c17d5de5d62aaa64c85} request received
  15. 2023-03-15 21:24:18.360 [INFO] {205fb849859a4c17d7de5d62cb2590f4} request received
  16. 2023-03-15 21:24:18.361 [INFO] {885fc349859a4c17d9de5d6235937e31} request received

server2 terminal output:

  1. $ go run server.go
  2. 2023-03-15 21:24:10.769 [INFO] pid[10242]: http server started listening on [:63964]
  3. 2023-03-15 21:24:10.770 [INFO] openapi specification is disabled
  4. 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]}
  5. 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"
  6. SERVER | DOMAIN | ADDRESS | METHOD | ROUTE | HANDLER | MIDDLEWARE
  7. ------------|---------|---------|--------|-------|-----------------------------------------------------------------|--------------------
  8. hello.svc | default | :63964 | ALL | / | main.main.func1 |
  9. ------------|---------|---------|--------|-------|-----------------------------------------------------------------|--------------------
  10. hello.svc | default | :63964 | ALL | /* | github.com/gogf/gf/v2/net/ghttp.internalMiddlewareServerTracing | GLOBAL MIDDLEWARE
  11. ------------|---------|---------|--------|-------|-----------------------------------------------------------------|--------------------
  12. 2023-03-15 21:24:18.357 [INFO] {602d8749859a4c17d2de5d62d515e464} request received
  13. 2023-03-15 21:24:18.359 [INFO] {e0ed9b49859a4c17d4de5d628284ae62} request received
  14. 2023-03-15 21:24:18.360 [INFO] {e0e0b249859a4c17d6de5d62beda3001} request received
  15. 2023-03-15 21:24:18.361 [INFO] {7087bd49859a4c17d8de5d62f892e8aa} request received
  16. 2023-03-15 21:24:18.361 [INFO] {e8aec849859a4c17dade5d6247101836} request received

Client terminal output:

  1. $ go run client.go
  2. 2023-03-15 21:24:18.357 [INFO] {e05b6049859a4c17d1de5d62eafa5a5f} Hello world
  3. 2023-03-15 21:24:18.358 [INFO] {602d8749859a4c17d2de5d62d515e464} Hello world
  4. 2023-03-15 21:24:18.358 [INFO] {785e9349859a4c17d3de5d62049e5b51} Hello world
  5. 2023-03-15 21:24:18.359 [INFO] {e0ed9b49859a4c17d4de5d628284ae62} Hello world
  6. 2023-03-15 21:24:18.360 [INFO] {7076ab49859a4c17d5de5d62aaa64c85} Hello world
  7. 2023-03-15 21:24:18.360 [INFO] {e0e0b249859a4c17d6de5d62beda3001} Hello world
  8. 2023-03-15 21:24:18.360 [INFO] {205fb849859a4c17d7de5d62cb2590f4} Hello world
  9. 2023-03-15 21:24:18.361 [INFO] {7087bd49859a4c17d8de5d62f892e8aa} Hello world
  10. 2023-03-15 21:24:18.361 [INFO] {885fc349859a4c17d9de5d6235937e31} Hello world
  11. 2023-03-15 21:24:18.361 [INFO] {e8aec849859a4c17dade5d6247101836} Hello world

GRPC

server.go

  1. package main
  2. import (
  3. "github.com/gogf/gf/contrib/rpc/grpcx/v2"
  4. "github.com/gogf/gf/example/rpc/grpcx/balancer/controller"
  5. )
  6. func main() {
  7. s := grpcx.Server.New()
  8. controller.Register(s)
  9. s.Run()
  10. }

client.go

  1. package main
  2. import (
  3. "context"
  4. "github.com/gogf/gf/contrib/rpc/grpcx/v2"
  5. "github.com/gogf/gf/example/rpc/grpcx/balancer/protobuf"
  6. "github.com/gogf/gf/v2/frame/g"
  7. "github.com/gogf/gf/v2/os/gctx"
  8. )
  9. func main() {
  10. var (
  11. ctx context.Context
  12. conn = grpcx.Client.MustNewGrpcClientConn("demo", grpcx.Balancer.WithRandom())
  13. client = protobuf.NewGreeterClient(conn)
  14. )
  15. for i := 0; i < 10; i++ {
  16. ctx = gctx.New()
  17. res, err := client.SayHello(ctx, &protobuf.HelloRequest{Name: "World"})
  18. if err != nil {
  19. g.Log().Error(ctx, err)
  20. return
  21. }
  22. g.Log().Debug(ctx, "Response:", res.Message)
  23. }
  24. }

The grpcx.Balancer.WithRandom() indicates using a random request strategy. Start two server.go servers and then run the client.go client to check the server request logs:

server1 terminal output:

  1. $ go run server.go
  2. 2023-03-15 19:50:44.801 [DEBU] set default registry using file registry as no custom registry set
  3. 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]}
  4. 2023-03-15 19:50:44.802 [INFO] pid[89290]: grpc server started listening on [:53962]
  5. 2023-03-15 19:50:57.282 {7025612f6d954c17c5f335051bf10899} /protobuf.Greeter/SayHello, 0.003ms, name:"World", message:"Hello World"
  6. 2023-03-15 19:50:57.283 {60567c2f6d954c17c7f335052ce05185} /protobuf.Greeter/SayHello, 0.002ms, name:"World", message:"Hello World"
  7. 2023-03-15 19:50:57.285 {f8d09b2f6d954c17ccf33505dff1a4ea} /protobuf.Greeter/SayHello, 0.002ms, name:"World", message:"Hello World"
  8. 2023-03-15 19:50:57.287 {f0fab02f6d954c17cdf33505438b2c80} /protobuf.Greeter/SayHello, 0.001ms, name:"World", message:"Hello World"

server2 terminal output:

  1. $ go run server.go
  2. 2023-03-15 19:50:51.720 [DEBU] set default registry using file registry as no custom registry set
  3. 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]}
  4. 2023-03-15 19:50:51.722 [INFO] pid[89351]: grpc server started listening on [:53973]
  5. 2023-03-15 19:50:57.280 {b89a0d2f6d954c17c4f33505a046817c} /protobuf.Greeter/SayHello, 0.002ms, name:"World", message:"Hello World"
  6. 2023-03-15 19:50:57.282 {28bf732f6d954c17c6f33505adedff5f} /protobuf.Greeter/SayHello, 0.002ms, name:"World", message:"Hello World"
  7. 2023-03-15 19:50:57.283 {9876832f6d954c17c8f3350580ed535b} /protobuf.Greeter/SayHello, 0.002ms, name:"World", message:"Hello World"
  8. 2023-03-15 19:50:57.284 {684e8b2f6d954c17c9f33505d56e4b05} /protobuf.Greeter/SayHello, 0.001ms, name:"World", message:"Hello World"
  9. 2023-03-15 19:50:57.284 {c045912f6d954c17caf3350599006197} /protobuf.Greeter/SayHello, 0.001ms, name:"World", message:"Hello World"
  10. 2023-03-15 19:50:57.284 {500a972f6d954c17cbf33505252b0e01} /protobuf.Greeter/SayHello, 0.001ms, name:"World", message:"Hello World"

Client terminal output:

  1. $ go run client.go
  2. 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}]
  3. 2023-03-15 19:50:57.281 [DEBU] {b89a0d2f6d954c17c4f33505a046817c} Response: Hello World
  4. 2023-03-15 19:50:57.282 [DEBU] {7025612f6d954c17c5f335051bf10899} Response: Hello World
  5. 2023-03-15 19:50:57.282 [DEBU] {28bf732f6d954c17c6f33505adedff5f} Response: Hello World
  6. 2023-03-15 19:50:57.283 [DEBU] {60567c2f6d954c17c7f335052ce05185} Response: Hello World
  7. 2023-03-15 19:50:57.283 [DEBU] {9876832f6d954c17c8f3350580ed535b} Response: Hello World
  8. 2023-03-15 19:50:57.284 [DEBU] {684e8b2f6d954c17c9f33505d56e4b05} Response: Hello World
  9. 2023-03-15 19:50:57.284 [DEBU] {c045912f6d954c17caf3350599006197} Response: Hello World
  10. 2023-03-15 19:50:57.285 [DEBU] {500a972f6d954c17cbf33505252b0e01} Response: Hello World
  11. 2023-03-15 19:50:57.286 [DEBU] {f8d09b2f6d954c17ccf33505dff1a4ea} Response: Hello World
  12. 2023-03-15 19:50:57.287 [DEBU] {f0fab02f6d954c17cdf33505438b2c80} Response: Hello World