文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Sentinel限流熔断降级怎么使用

2023-07-04 14:37

关注

这篇文章主要讲解了“Sentinel限流熔断降级怎么使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Sentinel限流熔断降级怎么使用”吧!

Sentinel限流熔断降级

什么是限流 \ 熔断 \ 降级

限流:在我们的后天系统中,如果那一天突然进入大量流量,我们服务原本最高只能处理同时 2k 的请求,突然一

下就来来了 5k 的请求,这对服务器的压力是不是很要命,这很可能直接导致服务器宕机,崩溃,导致原本 2K 的处

理量都不能处理了,这时候我们需要限流,限流的作用就是保持访问量到达服务器最高的情况下,对多余的请求

不做处理,相比之下,比服务器直接挂掉是好很多的。例如在双十一的时候,我们要下单就会看到类似” 请求繁

忙,请稍后重试!”。

熔断: 相信大家对断路器并不陌生,它就相当于一个开关,打开后可以阻止流量通过。比如保险丝,当电流过大

时,就会熔断,从而避免元器件损坏。

服务熔断是指调用方访问服务时通过断路器做代理进行访问,断路器会持续观察服务返回的成功、失败的状态,

当失败超过设置的阈值时断路器打开,请求就不能真正地访问到服务了。

使用场景

* 降级 *: 服务降级是从整个系统的负荷情况出发和考虑的,对某些负荷会比较高的情况,为了预防某些功能(业务

场景)出现负荷过载或者响应慢的情况,在其内部暂时舍弃对一些非核心的接口和数据的请求,而直接返回一个

提前准备好的 fallback(退路)错误处理信息。这样,虽然提供的是一个有损的服务,但却保证了整个系统的稳

定性和可用性。

什么是 Sentinel

Sentinel 是阿里开源的项目,提供了流量控制、熔断降级、系统负载保护等多个维度来保障服务之间的稳定性。

官网:github.com/alibaba/Sentinel/wiki

2012 年,Sentinel 诞生于阿里巴巴,其主要目标是流量控制。2013-2017 年,Sentinel 迅速发展,并成为阿里巴巴所有微服务的基本组成部分。 它已在 6000 多个应用程序中使用,涵盖了几乎所有核心电子商务场景。2018 年,Sentinel 演变为一个开源项目。2020 年,Sentinel Golang 发布。

特点 :

丰富的应用场景 :Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即

突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。

完备的实时监控 :Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机

器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。

* 生态广广泛 *

Sentinel 的历史

Sentinel-go 的安装

官网文档

安装:go get github.com/alibaba/sentinel-golang/api

Go 限流实战

qps 限流

package mainimport (    "fmt"    "log"    sentinel "github.com/alibaba/sentinel-golang/api"    "github.com/alibaba/sentinel-golang/core/base"    "github.com/alibaba/sentinel-golang/core/flow")func main() {    //基于sentinel的qps限流    //必须初始化    err := sentinel.InitDefault()    if err != nil {        log.Fatalf("Unexpected error: %+v", err)    }    //配置限流规则:1秒内通过10次    _, err = flow.LoadRules([]*flow.Rule{        {            Resource:               "some_test",            TokenCalculateStrategy: flow.Direct,            ControlBehavior:        flow.Reject, //超过直接拒绝            Threshold:              10,          //请求次数            StatIntervalInMs:       1000,        //允许时间内        },    })    if err != nil {        log.Fatalf("Unexpected error: %+v", err)        return    }    for i := 0; i < 12; i++ {        e, b := sentinel.Entry("some_test", sentinel.WithTrafficType(base.Inbound))        if b != nil {            fmt.Println("限流了")        } else {            fmt.Println("检查通过")            e.Exit()        }    }}

打印结果:

检查通过检查通过检查通过检查通过检查通过检查通过检查通过检查通过检查通过检查通过限流了限流了

Thrnotting

package mainimport (    "fmt"    "log"    "time"    sentinel "github.com/alibaba/sentinel-golang/api"    "github.com/alibaba/sentinel-golang/core/base"    "github.com/alibaba/sentinel-golang/core/flow")func main() {    //基于sentinel的qps限流    //必须初始化    err := sentinel.InitDefault()    if err != nil {        log.Fatalf("Unexpected error: %+v", err)    }    //配置限流规则    _, err = flow.LoadRules([]*flow.Rule{        {            Resource:               "some_test",            TokenCalculateStrategy: flow.Direct,            ControlBehavior:        flow.Throttling, //匀速通过            Threshold:              10,              //请求次数            StatIntervalInMs:       1000,            //允许时间内        },    })    if err != nil {        log.Fatalf("Unexpected error: %+v", err)        return    }    for i := 0; i < 12; i++ {        e, b := sentinel.Entry("some_test", sentinel.WithTrafficType(base.Inbound))        if b != nil {            fmt.Println("限流了")        } else {            fmt.Println("检查通过")            e.Exit()        }        time.Sleep(time.Millisecond * 100)    }}
检查通过检查通过检查通过检查通过检查通过检查通过检查通过检查通过检查通过检查通过检查通过检查通过

Warrm_up

package mainimport (    "fmt"    "log"    "math/rand"    "time"    sentinel "github.com/alibaba/sentinel-golang/api"    "github.com/alibaba/sentinel-golang/core/base"    "github.com/alibaba/sentinel-golang/core/flow")func main() {    //先初始化sentinel    err := sentinel.InitDefault()    if err != nil {        log.Fatalf("初始化sentinel 异常: %v", err)    }    var globalTotal int    var passTotal int    var blockTotal int    ch := make(chan struct{})    //配置限流规则    _, err = flow.LoadRules([]*flow.Rule{        {            Resource:               "some-test",            TokenCalculateStrategy: flow.WarmUp, //冷启动策略            ControlBehavior:        flow.Reject, //直接拒绝            Threshold:              1000,            WarmUpPeriodSec:        30,        },    })    if err != nil {        log.Fatalf("加载规则失败: %v", err)    }    //我会在每一秒统计一次,这一秒只能 你通过了多少,总共有多少, block了多少, 每一秒会产生很多的block    for i := 0; i < 100; i++ {        go func() {            for {                globalTotal++                e, b := sentinel.Entry("some-test", sentinel.WithTrafficType(base.Inbound))                if b != nil {                    //fmt.Println("限流了")                    blockTotal++                    time.Sleep(time.Duration(rand.Uint64()%10) * time.Millisecond)                } else {                    passTotal++                    time.Sleep(time.Duration(rand.Uint64()%10) * time.Millisecond)                    e.Exit()                }            }        }()    }    go func() {        var oldTotal int //过去1s总共有多少个        var oldPass int  //过去1s总共pass多少个        var oldBlock int //过去1s总共block多少个        for {            oneSecondTotal := globalTotal - oldTotal            oldTotal = globalTotal            oneSecondPass := passTotal - oldPass            oldPass = passTotal            oneSecondBlock := blockTotal - oldBlock            oldBlock = blockTotal            time.Sleep(time.Second)            fmt.Printf("total:%d, pass:%d, block:%d\n", oneSecondTotal, oneSecondPass, oneSecondBlock)        }    }()    <-ch}

打印结果:逐渐到达 1k, 在 1k 位置上下波动

total:11, pass:9, block:0total:21966, pass:488, block:21420total:21793, pass:339, block:21414total:21699, pass:390, block:21255total:21104, pass:393, block:20654total:21363, pass:453, block:20831total:21619, pass:491, block:21052total:21986, pass:533, block:21415total:21789, pass:594, block:21123total:21561, pass:685, block:20820total:21663, pass:873, block:20717total:20904, pass:988, block:19831total:21500, pass:996, block:20423total:21769, pass:1014, block:20682total:20893, pass:1019, block:19837total:21561, pass:973, block:20524total:21601, pass:1014, block:20517total:21475, pass:993, block:20420total:21457, pass:983, block:20418total:21397, pass:1024, block:20320total:21690, pass:996, block:20641total:21526, pass:991, block:20457total:21779, pass:1036, block:20677

Go 熔断实战

这里我们介绍一个错误数量的,查看详细熔断机制

error_countpackage mainimport (    "errors"    "fmt"    "log"    "math/rand"    "time"    sentinel "github.com/alibaba/sentinel-golang/api"    "github.com/alibaba/sentinel-golang/core/circuitbreaker"    "github.com/alibaba/sentinel-golang/core/config"    "github.com/alibaba/sentinel-golang/logging"    "github.com/alibaba/sentinel-golang/util")type stateChangeTestListener struct {}func (s *stateChangeTestListener) OnTransformToClosed(prev circuitbreaker.State, rule circuitbreaker.Rule) {    fmt.Printf("rule.steategy: %+v, From %s to Closed, time: %d\n", rule.Strategy, prev.String(), util.CurrentTimeMillis())}func (s *stateChangeTestListener) OnTransformToOpen(prev circuitbreaker.State, rule circuitbreaker.Rule, snapshot interface{}) {    fmt.Printf("rule.steategy: %+v, From %s to Open, snapshot: %d, time: %d\n", rule.Strategy, prev.String(), snapshot, util.CurrentTimeMillis())}func (s *stateChangeTestListener) OnTransformToHalfOpen(prev circuitbreaker.State, rule circuitbreaker.Rule) {    fmt.Printf("rule.steategy: %+v, From %s to Half-Open, time: %d\n", rule.Strategy, prev.String(), util.CurrentTimeMillis())}func main() {    //基于连接数的降级模式    total := 0    totalPass := 0    totalBlock := 0    totalErr := 0    conf := config.NewDefaultConfig()    // for testing, logging output to console    conf.Sentinel.Log.Logger = logging.NewConsoleLogger()    err := sentinel.InitWithConfig(conf)    if err != nil {        log.Fatal(err)    }    ch := make(chan struct{})    // Register a state change listener so that we could observer the state change of the internal circuit breaker.    circuitbreaker.RegisterStateChangeListeners(&stateChangeTestListener{})    _, err = circuitbreaker.LoadRules([]*circuitbreaker.Rule{        // Statistic time span=10s, recoveryTimeout=3s, maxErrorCount=50        {            Resource:         "abc",            Strategy:         circuitbreaker.ErrorCount,            RetryTimeoutMs:   3000, //3s只有尝试回复            MinRequestAmount: 10,   //静默数            StatIntervalMs:   5000,            Threshold:        50,        },    })    if err != nil {        log.Fatal(err)    }    logging.Info("[CircuitBreaker ErrorCount] Sentinel Go circuit breaking demo is running. You may see the pass/block metric in the metric log.")    go func() {        for {            total++            e, b := sentinel.Entry("abc")            if b != nil {                // g1 blocked                totalBlock++                fmt.Println("协程熔断了")                time.Sleep(time.Duration(rand.Uint64()%20) * time.Millisecond)            } else {                totalPass++                if rand.Uint64()%20 > 9 {                    totalErr++                    // Record current invocation as error.                    sentinel.TraceError(e, errors.New("biz error"))                }                // g1 passed                time.Sleep(time.Duration(rand.Uint64()%20+10) * time.Millisecond)                e.Exit()            }        }    }()    go func() {        for {            total++            e, b := sentinel.Entry("abc")            if b != nil {                // g2 blocked                totalBlock++                time.Sleep(time.Duration(rand.Uint64()%20) * time.Millisecond)            } else {                // g2 passed                totalPass++                time.Sleep(time.Duration(rand.Uint64()%80) * time.Millisecond)                e.Exit()            }        }    }()    go func() {        for {            time.Sleep(time.Second)            fmt.Println(totalErr)        }    }()    <-ch}

感谢各位的阅读,以上就是“Sentinel限流熔断降级怎么使用”的内容了,经过本文的学习后,相信大家对Sentinel限流熔断降级怎么使用这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯