go-micro中使用sentinel-go进行限流

3,113 阅读1分钟

Sentinel 是阿里巴巴开源的,面向分布式服务架构的流量控制组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统自适应保护等多个维度来帮助开发者保障微服务的稳定性。Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀、冷启动、消息削峰填谷、集群流量控制、实时熔断下游不可用服务等,是保障微服务高可用的利器。

利用的go-micro的wraphandler(服务端中间件)和wrapclient(客户端中间件)特性,可以对入口流量、出口流量进行限流。

以下以wraphandler中间件为例

  1. 初始化sentinal
  2. 构建HandlerWrapper中间件
package sentinel

import (
	"context"
	sentinel_api "github.com/alibaba/sentinel-golang/api"
	"github.com/alibaba/sentinel-golang/core/base"
	"github.com/alibaba/sentinel-golang/core/flow"
	"github.com/micro/go-micro/server"
	"log"
)

/*
time: 2020/6/10-10:38
author: waiwen
*/
//化sentinal
func InitSentinel() {
	err := sentinel_api.InitDefault()
	if err != nil {
		log.Fatalf("Unexpected error: %+v", err)
	}

	_, err = flow.LoadRules([]*flow.FlowRule{
		{
			Resource:        "list-limit",
			MetricType:      flow.QPS,
			Count:           10,
			ControlBehavior: flow.Reject,
		},
	})
	if err != nil {
		log.Fatalf("Unexpected error: %+v", err)
		return
	}
}

//构建HandlerWrapper中间件
func NewSentinelHandlerWrapper() server.HandlerWrapper {
	return func(handlerFunc server.HandlerFunc) server.HandlerFunc {
		return func(ctx context.Context, req server.Request, rsp interface{}) error {
			//name := fmt.Sprintf("%s.%s", req.Service(), req.Endpoint())
			resourceName := "list-limit"
			entry, err := sentinel_api.Entry(
				resourceName,
				sentinel_api.WithResourceType(base.ResTypeRPC),
				sentinel_api.WithTrafficType(base.Inbound),
			)
			if err != nil {
				return errors.BadRequest("gk.micro.srv.circle","too many requests")
			}
			defer entry.Exit()
			return handlerFunc(ctx, req, rsp)
		}
	}
}

  1. 初始化micro service时配置使用handlerwrapper

image.png