gRPC負載平衡庫grpc-lb的使用

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

grpc-lb採用用戶端進程內負載平衡方式,支援隨機、輪詢、一致性雜湊三種負載平衡策略,並支援服務端權重。可採用etcd或consul作為註冊中心。

項目地址:
https://github.com/liyue201/grpc-lb

基本架構,服務提供者起來後向註冊中心註冊自己的資訊,ip、連接埠、權重等,並保持心跳。用戶端監聽註冊中心,擷取伺服器列表,一旦伺服器發生變化,用戶端馬上更新本地的伺服器列表。用戶端每個請求都通過負載平衡策略選擇一個合適的伺服器去訪問。


隨機負載平衡用戶端例子:

package mainimport (    etcd "github.com/coreos/etcd/client"    grpclb "github.com/liyue201/grpc-lb"    "github.com/liyue201/grpc-lb/examples/proto"    registry "github.com/liyue201/grpc-lb/registry/etcd"    "golang.org/x/net/context"    "google.golang.org/grpc"    "log")func main() {    etcdConfg := etcd.Config{        Endpoints: []string{"http://120.24.44.201:4001"},    }    r := registry.NewResolver("/grpc-lb", "test", etcdConfg)    b := grpclb.NewBalancer(r, grpclb.NewRandomSelector())    c, err := grpc.Dial("", grpc.WithInsecure(), grpc.WithBalancer(b))    if err != nil {        log.Printf("grpc dial: %s", err)        return    }    defer c.Close()    client := proto.NewTestClient(c)    resp, err := client.Say(context.Background(), &proto.SayReq{Content: "random"})    if err != nil {        log.Println(err)        return    }    log.Printf(resp.Content)}

輪詢負載平衡,只需把NewRandomSelector改成NewRoundRobinSelector即可。

package mainimport (    etcd "github.com/coreos/etcd/client"    grpclb "github.com/liyue201/grpc-lb"    "github.com/liyue201/grpc-lb/examples/proto"    registry "github.com/liyue201/grpc-lb/registry/etcd"    "golang.org/x/net/context"    "google.golang.org/grpc"    "log")func main() {    etcdConfg := etcd.Config{        Endpoints: []string{"http://120.24.44.201:4001"},    }    r := registry.NewResolver("/grpc-lb", "test", etcdConfg)    b := grpclb.NewBalancer(r, grpclb.NewRoundRobinSelector())    c, err := grpc.Dial("", grpc.WithInsecure(), grpc.WithBalancer(b))    if err != nil {        log.Printf("grpc dial: %s", err)        return    }    defer c.Close()    client := proto.NewTestClient(c)    resp, err := client.Say(context.Background(), &proto.SayReq{Content: "round robin"})    if err != nil {        log.Println(err)        return    }    log.Printf(resp.Content)}

 

一致性雜湊負載平衡,需要給每個請求傳一個雜湊的參數,這個根據應用情境而定,就是下面這個例子中的hashData。

package mainimport (    "fmt"    etcd "github.com/coreos/etcd/client"    grpclb "github.com/liyue201/grpc-lb"    "github.com/liyue201/grpc-lb/examples/proto"    registry "github.com/liyue201/grpc-lb/registry/etcd"    "golang.org/x/net/context"    "google.golang.org/grpc"    "log"    "time")func main() {    etcdConfg := etcd.Config{        Endpoints: []string{"http://120.24.44.201:4001"},    }    r := registry.NewResolver("/grpc-lb", "test", etcdConfg)    b := grpclb.NewBalancer(r, grpclb.NewKetamaSelector(grpclb.DefaultKetamaKey))    c, err := grpc.Dial("", grpc.WithInsecure(), grpc.WithBalancer(b), grpc.WithTimeout(time.Second))    if err != nil {        log.Printf("grpc dial: %s", err)        return    }    client := proto.NewTestClient(c)    for i := 0; i < 10; i++ {        ctx := context.Background()        hashData := fmt.Sprintf("aaaa %d", i)        resp, err := client.Say(context.WithValue(ctx, grpclb.DefaultKetamaKey, hashData),            &proto.SayReq{Content: "ketama"})        if err != nil {            log.Println(err)            time.Sleep(time.Second)            continue        }        log.Printf(resp.Content)        time.Sleep(time.Second)    }}

 

服務端的代碼如下, 使用以下命令運行3個服務進程,再啟動用戶端。
go run main.go -node node1 -port 28544
go run main.go -node node2 -port 18562
go run main.go -node node3 -port 27772

package mainimport (    "flag"    "fmt"    etcd "github.com/coreos/etcd/client"    "github.com/liyue201/grpc-lb/examples/proto"    registry "github.com/liyue201/grpc-lb/registry/etcd"    "golang.org/x/net/context"    "google.golang.org/grpc"    "log"    "net"    "sync"    "time")var nodeID = flag.String("node", "node1", "node ID")var port = flag.Int("port", 8080, "listening port")type RpcServer struct {    addr string    s    *grpc.Server}func NewRpcServer(addr string) *RpcServer {    s := grpc.NewServer()    rs := &RpcServer{        addr: addr,        s:    s,    }    return rs}func (s *RpcServer) Run() {    listener, err := net.Listen("tcp", s.addr)    if err != nil {        log.Printf("failed to listen: %v", err)        return    }    log.Printf("rpc listening on:%s", s.addr)    proto.RegisterTestServer(s.s, s)    s.s.Serve(listener)}func (s *RpcServer) Stop() {    s.s.GracefulStop()}func (s *RpcServer) Say(ctx context.Context, req *proto.SayReq) (*proto.SayResp, error) {    text := "Hello " + req.Content + ", I am " + *nodeID    log.Println(text)    return &proto.SayResp{Content: text}, nil}func StartService() {    etcdConfg := etcd.Config{        Endpoints: []string{"http://120.24.44.201:4001"},    }    registry, err := registry.NewRegistry(        registry.Option{            EtcdConfig:  etcdConfg,            RegistryDir: "/grpc-lb",            ServiceName: "test",            NodeID:      *nodeID,            NData: registry.NodeData{                Addr: fmt.Sprintf("127.0.0.1:%d", *port),                //Metadata: map[string]string{"weight": "1"}, //這裡配置權重,不配置預設是1            },            Ttl: 10 * time.Second,        })    if err != nil {        log.Panic(err)        return    }    server := NewRpcServer(fmt.Sprintf("0.0.0.0:%d", *port))    wg := sync.WaitGroup{}    wg.Add(1)    go func() {        server.Run()        wg.Done()    }()    wg.Add(1)    go func() {        registry.Register()        wg.Done()    }()    //stop the server after one minute    //go func() {    //    time.Sleep(time.Minute)    //    server.Stop()    //    registry.Deregister()    //}()    wg.Wait()}//go run main.go -node node1 -port 28544//go run main.go -node node2 -port 18562//go run main.go -node node3 -port 27772func main() {    flag.Parse()    StartService()}

 

390 次點擊  
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.