首页 > 其他分享 >Go微服务框架go-kratos实战学习08:负载均衡基本使用

Go微服务框架go-kratos实战学习08:负载均衡基本使用

时间:2023-04-12 20:35:02浏览次数:53  
标签:github kratos err grpc 08 go com

微服务框架 go-kratos 中负载均衡使用

一、介绍

在前面这篇文章 负载均衡和它的算法介绍,讲了什么是负载均衡以及作用、算法介绍。

go-kratos 的负载均衡主要接口是 Selector,它是一个可插拔的设计。因为它设计的都是接口,只要实现了接口就实现了负载均衡。

go-kratos 在目录下提供了一个默认的 Selector 实现,default_node.godefault_selector.go

你可以自定义程序来替换这个默认实现。可以通过替换 NodeBuilder 实现节点权重计算算法,Filter 实现服务路由过滤策,Balancer 来实现负载均衡算法。

go-kratos 负载均衡结构主要组成:

image-20230403183123409

在 go-kratos 中已支持 3 种负载均衡算法,分别是:

  • wrr : Weighted round robin (Kratos Client内置默认算法),权重轮询算法
  • p2c : Power of two choices
  • random : Random,随机算法

二、基本使用

go-kratos 负载均衡有2个使用,一个是 http ,一个是 gRPC。

go-kratos 文档中展示了主要代码。

> go-kratos v2.6.1
>
> go v1.20.2

示例代码在 go-kratosexamples 中的 Selector。

从上面例子中摘出 grpc 负载均衡例子,代码如下:

client/grpc.go

package main

import (
	"context"
	"log"
	"time"

	"github.com/go-kratos/kratos/contrib/registry/consul/v2"
	"github.com/go-kratos/v2/selector/filter"
	"github.com/go-kratos/v2/selector/wrr"
	"github.com/go-kratos/v2/transport/grpc"
	"github.com/hashicorp/consul/api"
	"gitub.com/go-kratos/examples/helloworld/helloworld"
)

func main() {
	consulCli, err := api.NewClient(api.DefaultConfig())
	if err != nil {
		panic(err)
	}

	r := consul.New(consulCli)

	// grpc client
	conn, err := grpc.DialInsecure(
		context.Background(),
		grpc.WithEndpoint("discovery:///helloworld"),
		grpc.WithDiscovery(r), // consul作为服务发现中心
		// 负载均衡 和 filter,weighted round robin算法
		grpc.WithBalancerName(wrr.Name),
		grpc.WithFilter(
			filter.Version("1.0.0"), //静态version=1.0.0的Filter
		),
	)
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()
	gClient := helloworld.NewGreeterClient(conn)

	for {
		time.Sleep(time.Second)

		CallGRPC(gClient)
	}
}

func CallGRPC(client helloworld.NewGreeterClient) {
	reply, err := client.SayHello(context.Background(), &helloworld.HelloRequest{Name: "go-kratos"})
	if err != nil {
		log.Fatal(err)
	}
	log.Printf("[grpc] SayHello %+v \n", reply)
}

服务端,server/grpc.go

package main

import (
	"context"
	"fmt"
	"os"

	"github.com/go-kratos/examples/helloworld/helloworld"
	"github.com/go-kratos/kratos/contrib/registry/consul/v2"
	"github.com/go-kratos/kratos/v2"
	"github.com/go-kratos/kratos/v2/log"
	"github.com/go-kratos/kratos/v2/middleware/logging"
	"github.com/go-kratos/kratos/v2/middleware/recovery"
	"github.com/go-kratos/kratos/v2/transport/grpc"
	"github.com/hashicorp/consul/api"
)

type server struct {
	helloworld.UnimplementedGreeterServer
}

func (s *server) SayHello(ctx context.Context, in *helloworld.HelloRequest) (*helloworld.HelloReply, error) {
	return &helloworld.HelloReply{Message: fmt.Sprintf("welcome %+v!", in.Name)}, nil
}

func main() {
	logger := log.NewStdLogger(os.Stdout)

	consulClient, err := api.NewClient(api.DefaultConfig())
	if err != nil {
		log.NewHelper(logger).Fatal(err)
	}
	go runServer("1.0.0", logger, consulClient, 8000)
	go runServer("1.0.0", logger, consulClient, 8010)

	runServer("2.0.0", logger, consulClient, 8020)
}

func runServer(version string, logger log.Logger, client *api.Client, port int) {
	logger = log.With(logger, "version", version, "port:", port)
	log := log.NewHelper(logger)

	grpcSrv := grpc.NewServer(
		grpc.Address(fmt.Sprintf(":%d", port+1000)),
		grpc.Middleware(
			recovery.Recovery(),
			logging.Server(logger),
		),
	)

	s := &server{}
	helloworld.RegisterGreeterServer(grpcSrv, s)

	r := consul.New(client)
	app := kratos.New(
		kratos.Name("helloworld"),
		kratos.Server(
			grpcSrv,
		),
		kratos.Version(version),
		kratos.Registrar(r),
	)

	if err := app.Run(); err != nil {
		log.Fatal(err)
	}
}

三、参考

标签:github,kratos,err,grpc,08,go,com
From: https://www.cnblogs.com/jiujuan/p/17311134.html

相关文章

  • Go语言入门6(struct 结构体)
    结构体​ 结构体是一种聚合的数据类型,是由零个或多个任意类型的值聚合成的实体。每个值称为结构体的成员结构体声明type+结构体名+struct+{成员列表}​ ⭐如果结构体成员名字是以大写字母开头的,那么该成员就是导出的。这是Go语言导出规则决定的。一个结构体可能同时包......
  • Django自带的Admin后台中如何获取当前登录用户
    需求背景在使用Django快速开发一个IT电脑、显示器资产管理小系统的时候,遇到一个问题是,当变更资产设备(新增、修改、删除)的时候,能记录是谁在什么时间进行的变更。确认的是肯定是登录状态,但是在使用Django的signal中获取不到当前登录的用户问题演示1、定义资产设备模型和 自定义日志......
  • PAT Basic 1089. 狼人杀-简单版
    PATBasic1089.狼人杀-简单版1.题目描述:以下文字摘自《灵机一动·好玩的数学》:“狼人杀”游戏分为狼人、好人两大阵营。在一局“狼人杀”游戏中,1号玩家说:“2号是狼人”,2号玩家说:“3号是好人”,3号玩家说:“4号是狼人”,4号玩家说:“5号是好人”,5号玩家说:“4号是好人”......
  • 快速搭建一个go语言web后端服务脚手架
    快速搭建一个go语言web后端服务脚手架源码:https://github.com/weloe/go-web-demoweb框架使用gin,数据操作使用gorm,访问控制使用casbin首先添加一下自定义的middlewarerecover_control.go,统一处理panicerror返回的信息packagemiddlewareimport( "fmt" "github.com/gin-......
  • UVa 11498 Division of Nlogonia (water ver.)
    11498-DivisionofNlogoniaTimelimit:1.000secondshttp://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=2493TheProblemAftercenturiesofhostilitiesandskirmishesbetweenthefour......
  • UVa 757 / POJ 1042 / East Central North America 1999 Gone Fishing (枚举&贪心&想
    757-GoneFishingTimelimit:3.000secondshttp://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=698http://poj.org/problem?id=1042Johnisgoingonafishingtrip.Hehas h hoursavailable( ),andther......
  • UVa 408 Uniform Generator (最大公约数&证明)
    408-UniformGeneratorTimelimit:3.000secondshttp://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=100&page=show_problem&problem=349Computersimulationsoftenrequirerandomnumbers.Onewaytogeneratepseudo-r......
  • go语言学习-gin框架中间件
    全局中间件所有的请求都经过此中间件//所有请求经过此中间件packagemainimport( "fmt" "time" "github.com/gin-gonic/gin")//定义中间件funcMiddleWare()gin.HandlerFunc{ returnfunc(ctx*gin.Context){ t:=time.Now() fmt.Println("中间件开始执行了......
  • 在django中自动删除超过10天的数据
    需求:比如过期10天的产品自动删除记录posting_date=models.DateTimeField(auto_now_add=True)#purge_old_data.pyfromdjango.core.management.baseimportBaseCommand,CommandErrorfromcus_leads.modelsimportCustomerLeadsfromdatetimeimportdatetime,timedel......
  • PAT Basic 1088. 三人行
    PATBasic1088.三人行1.题目描述:子曰:“三人行,必有我师焉。择其善者而从之,其不善者而改之。”本题给定甲、乙、丙三个人的能力值关系为:甲的能力值确定是2位正整数;把甲的能力值的2个数字调换位置就是乙的能力值;甲乙两人能力差是丙的能力值的X倍;乙的能力值是丙的Y倍。......