Skip to main content
Version: 2.8.x(Latest)

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

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

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

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)
}
}

Start two servers separately and run the client.

server1 terminal output:

$ 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 terminal output:

$ 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

Client terminal output:

$ 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)
}
}

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:

$ 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 terminal output:

$ 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"

Client terminal output:

$ 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