Sentinel 的golang版本简单使用以及介绍

开始

  • 对 Sentinel 进行相关配置并进行初始化
  • 埋点(定义资源)
  • 配置规则

对 Sentinel 进行相关配置并进行初始化

使用 Sentinel 时需要在应用启动时对 Sentinel 进行相关配置并触发初始化。 api包下提供如下函数:

  • InitDefault():从环境变量中读取相应配置来初始化 Sentinel,若环境变量不存在则使用默认值
  • Init(configPath string):从给定的 YAML 文件中读取相应配置来初始化 Sentinel。日志目录配置会从环境变量读取或采用默认路径(~/logs/csp)。
  • InitWithLogDir(configPath, logDir string)):将日志目录初始化为 logDir,并从给定的 YAML 文件中读取相应配置来初始化 Sentinel。
import (
    sentinel "github.com/sentinel-group/sentinel-golang/api"
)
 
func initSentinel() {
    
    
    err := sentinel.InitWithLogDir(confPath, logDir)
    if err != nil {
    
    
        // 初始化 Sentinel 失败
    }
}

注意:必须成功调用 Sentinel 的初始化函数以后再调用埋点 API。

埋点(定义资源)

使用 Sentinel 的 Entry API 将业务逻辑封装起来,这一步称为“埋点”。每个埋点都有一个资源名称(resource),代表触发了这个资源的调用或访问。

埋点 API 位于 api 包中:

  • Entry(resource string, opts …Option) (base.SentinelEntry, base.BlockError)

其中 resource 代表埋点资源名, opts 代表埋点配置。目前支持以下埋点配置:

  • WithTrafficType(entryType base.TrafficType):标记该埋点资源的流量类型,其中 Inbound 代表入口流量,Outbound 代表出口流量。若不指定,默认为 Outbound。
  • WithResourceType(resourceType base.ResourceType):标记该埋点资源的分类
  • WithAcquireCount(acquireCount uint32):标记每次触发该埋点计为几次调用(可以理解为 batch count)。若不指定,默认为 1
  • WithArgs(args …interface{}):埋点携带的参数列表,为热点参数统计预留。
import (
    sentinel "github.com/sentinel-group/sentinel-golang/api"
)
 
// Entry 方法用于埋点
e, b := sentinel.Entry("your-resource-name", sentinel.WithTrafficType(base.Inbound))
if b != nil {
    
    
    // 请求被流控,可以从 BlockError 中获取限流详情
} else {
    
    
    // 请求可以通过,在此处编写您的业务逻辑
    // 务必保证业务逻辑结束后 Exit
    e.Exit()
}

若该次调用被拒绝,则 Entry API 会返回 BlockError 代表被 Sentinel 限流。BlockError 提供了限流原因以及触发的规则等信息,可以方便开发者获取相关信息进行记录和处理。

配置规则

先简单的解释硬编码配置

_, err := flow.LoadRules([]*flow.FlowRule{
    
    
    {
    
    
        ID:                666,
        Resource:          "some-resource",
        MetricType:        flow.QPS,
        Count:             10,
        ControlBehavior:   flow.Reject,
    },
})
if err != nil {
    
    
    // 加载规则失败,进行相关处理
}

流量规则

一条流控规则主要由下面几个因素组成,我们可以组合这些元素来实现不同的限流效果

  • Resource:资源名,即规则的作用目标
  • MetricType: 指标类型
  • Count: 流控阈值
  • RelationStrategy: 调用关系限流策略
  • ControlBehavior: 流量控制效果(直接拒绝、Warm Up、匀速排队等)
流控指标

目前支持的流控指标:

  • QPS
  • 并发数(用于信号量隔离
流量控制效果

流控效果对应流控规则中的 ControlBehavior 字段。目前支持直接拒绝和匀速排队这几种控制效果。

直接拒绝

Sentinel 默认的流控效果是直接拒绝(Reject)。当前的请求量超过对应规则的阈值后,新的请求就会被立即拒绝。这种方式适用于对系统处理能力确切已知的情况下,比如通过压测确定了系统的准确水位时。

匀速排队

匀速排队(Throttling)方式会严格控制请求通过的间隔时间,也即是让请求以均匀的速度通过,对应的是漏桶算法。多余的请求可以排队等待而不是立即拒绝

//以下规则代表每 100ms 最多通过一个请求,多余的请求将会排队等待通过,若排队时队列长度大于 500ms 则直接拒绝:
{
    
    
    Resource:          "some-test",
    MetricType:        flow.QPS,
    Count:             10, // 请求的间隔控制在 1000/10=100 ms
    ControlBehavior:   flow.Throttling, // 流控效果为匀速排队
    MaxQueueingTimeMs: 500, // 最长排队等待时间
}

一个完整的示例

针对埋点资源配置相应的规则,来达到流量控制的效果。目前 Sentinel Golang 支持流控规则 (FlowRule) 和系统保护规则 (SystemRule)。

//此示例为FlowRule
import (
    sentinel "github.com/sentinel-group/sentinel-golang/api"
)
 
func main() {
    
    
    // 务必先进行初始化
    err := sentinel.InitDefault()
    if err != nil {
    
    
        log.Fatal(err)
    }
 
    // 配置一条限流规则
    _, err = flow.LoadRules([]*flow.FlowRule{
    
    
        {
    
    
            Resource:          "some-test",
            MetricType:        flow.QPS,
            Count:             10,
            ControlBehavior:   flow.Reject,
        },
    })
    if err != nil {
    
    
        fmt.Println(err)
        return
    }
 
    ch := make(chan struct{
    
    })
    for i := 0; i < 10; i++ {
    
    
        go func() {
    
    
            for {
    
    
                // 埋点逻辑,埋点资源名为 some-test
                e, b := sentinel.Entry("some-test")
                if b != nil {
    
    
                    // 请求被拒绝,在此处进行处理
                    time.Sleep(time.Duration(rand.Uint64() % 10) * time.Millisecond)
                } else {
    
    
                    // 请求允许通过,此处编写业务逻辑
                    fmt.Println(util.CurrentTimeMillis(), "Passed")
                    time.Sleep(time.Duration(rand.Uint64() % 10) * time.Millisecond)
 
                    // 务必保证业务结束后调用 Exit
                    e.Exit()
                }
 
            }
        }()
    }
    <-ch
}

系统自适应

这种系统自适应算法的效果是一个“兜底”的效果。对于不是应用本身造成的负载高的情况(如其它进程导致的不稳定的情况),效果不明显。

import "github.com/sentinel-group/sentinel-golang/core/system"
 
// 自适应流控,启发因子为 load1 >= 8
_, err := system.LoadRules([]*system.SystemRule{
    
    
    {
    
    
        MetricType:system.Load,
        TriggerCount:8.0,
        Strategy:system.BBR,
    },
})

猜你喜欢

转载自blog.csdn.net/weixin_39998006/article/details/106499198