grpc的负载均衡

一.grpc的负载均衡介绍

1.官网地址

https://github.com/grpc/grpc/blob/master/doc/load-balancing.md

2.架构

 

3. Name Resolver(grpc从consul中同步服务信息进行负载均衡)

作用:从指定的DNS服务器或者一个注册中心拉取数据到本地来

目前已经有人已经做好此方面的功能,直接使用即可

官方文档介绍:https://github.com/mbobakov/grpc-consul-resolver

使用示例:

package main

import (
	"time"
	"log"

	_ "github.com/mbobakov/grpc-consul-resolver" // It's important

	"google.golang.org/grpc"
)

func main() {
    conn, err := grpc.Dial(
        "consul://127.0.0.1:8500/whoami?wait=14s&tag=manual",
        grpc.WithInsecure(),
        grpc.WithDefaultServiceConfig(`{"loadBalancingPolicy": "round_robin"}`),
    )
    if err != nil {
        log.Fatal(err)
    }
    defer conn.Close()
    ...
}

  

4.gin中集成

在initialize下的srv_conn.go初始化配置中配置如下即可 InitSrvConn

package initialize

import (
	"fmt"
	"github.com/hashicorp/consul/api"
	"go.uber.org/zap"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials/insecure"
	"mxshop-api/user-web/global"
	"mxshop-api/user-web/proto"

	_ "github.com/mbobakov/grpc-consul-resolver" // It's important
)

func InitSrvConn() {
	userConn, err := grpc.Dial(
		fmt.Sprintf("consul://%s:%d/%s?wait=14s", global.ServerConfig.ConsulInfo.Host, global.ServerConfig.ConsulInfo.Port, global.ServerConfig.UserSrvInfo.Name),
		//grpc.WithInsecure(),
		grpc.WithTransportCredentials(insecure.NewCredentials()),
		grpc.WithDefaultServiceConfig(`{"loadBalancingPolicy": "round_robin"}`),
	)
	if err != nil {
		zap.S().Fatal("【InitSrvConn】链接【用户失败】")
	}
	userSrvClient := proto.NewUserClient(userConn)

	global.UserSrvClient = userSrvClient
}

func InitSrvConn2() {
	//从注册中心获取到用户服务的信息
	cfg := api.DefaultConfig()
	cfg.Address = "127.0.0.1:8500"

	//zap.S().Infof(fmt.Sprintf("配置:%s", global.ServerConfig.ConsulInfo.Host))
	cfg.Address = fmt.Sprintf("%s:%d", global.ServerConfig.ConsulInfo.Host, global.ServerConfig.ConsulInfo.Port)

	userSrvHost := ""
	userSrvPost := 0

	client, err := api.NewClient(cfg)
	if err != nil {
		panic(err)
	}

	data, err := client.Agent().ServicesWithFilter(fmt.Sprintf(`Service == "%s"`, global.ServerConfig.UserSrvInfo.Name))
	//data, err := client.Agent().ServicesWithFilter(fmt.Sprintf("Service == \"%s\"", global.ServerConfig.UserSrvInfo.Name))

	if err != nil {
		panic(err)
	}
	for _, value := range data {
		userSrvHost = value.Address
		userSrvPost = value.Port
		break
	}

	if userSrvHost == "" {
		zap.S().Fatal("【InitSrvConn】链接【用户失败】")
	}
	//拨号连接用户RPC服务
	userConn, err := grpc.Dial(fmt.Sprintf("%s:%d", userSrvHost, userSrvPost), grpc.WithTransportCredentials(insecure.NewCredentials()))
	if err != nil {
		zap.S().Errorw("[GetUserList]连接失败【用户服务失败】", "msg", err.Error())
	}

	//1. 后续的用户服务下线了 2. 改端口了 3. 改ip了 负载均衡来做

	//2. 已经事先创立好了连接,这样后续就不用进行再次tcp的三次握手
	//3. 一个连接多个groutine共用,性能 - 连接池

	userSrvClient := proto.NewUserClient(userConn)

	global.UserSrvClient = userSrvClient
}

  

 

 

posted @ 2022-11-10 13:15  wanghhhh  阅读(251)  评论(0)    收藏  举报