Sentinel 是阿里巴巴开源的,面向分布式服务架构的流量控制组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统自适应保护等多个维度来帮助开发者保障微服务的稳定性。Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀、冷启动、消息削峰填谷、集群流量控制、实时熔断下游不可用服务等,是保障微服务高可用的利器。
利用的go-micro的wraphandler(服务端中间件)和wrapclient(客户端中间件)特性,可以对入口流量、出口流量进行限流。
以下以wraphandler中间件为例
- 初始化sentinal
- 构建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)
}
}
}
- 初始化micro service时配置使用handlerwrapper