创意电子

标题: Sentinel-Go 源码系列(一)|开篇 [打印本页]

作者: 捉虫大师    时间: 2021-10-19 10:59
标题: Sentinel-Go 源码系列(一)|开篇
大家好呀,打算写一个 Go 语言组件源码分析系列,一是为了能学习下 Go 语言,看下别人是怎么写 Go 的,二是也掌握一个组件。

本次选择了 Sentinel-Go,一是对 Java 版本的 Sentinel 算是有一些了解,也在生产上落地过,二是感觉他的代码应该不会太复杂(仅仅是感觉),三是在云原生越来越热的趋势下,用 Go 实现的限流降级容错应该是比较通用的。

源码阅读本身是枯燥的,我只管用轻易理解的语言来描述,希望大家也多支持我的文章,点个在看关注就是对我最大的支持。

<hr>配景

Sentinel 简介

随着微服务的盛行,服务和服务之间的稳定性变得越来越紧张。Sentinel 是面向分布式服务架构的流量控制组件,主要以流量为切入点,从流量控制、熔断降级、系统自适应保护等多个维度来帮助您保障微服务的稳定性。

Sentinel 是阿里2018年开源的项目,最初是 Java 版本,截止现在有 17.6k 的star,项目地址为

https://github.com/alibaba/Sentinel/

2020年又开源了 Go 的版本,目的是朝云原生方向演进,截止现在 1.7k star,项目地址为

https://github.com/alibaba/sentinel-golang

Sentinel 的作用

在上面简介中也说了,Sentinel 是微服务期间保障稳定的神兵利器

举个例子:电商系统中用户浏览商品详情页,通常会通过 RPC 调用多个微服务,查询商品信息的同时还会查询用户的信息,也会展示优惠信息,通常下拉列表还会展示推荐,广告等信息,如下图


                               
登录/注册后可看大图

如果流量较大时,CouponService 容量不足,或者某种原因导致 RecomService 不可用,此时 AggrService 会被拖死,导致商品详情服务不可用,但细致想想这些服务不是那么紧张,可以举行限流或者直接降级(不再调用),总比直接服务不消要好吧

又或者流量着实太高,ProductService 也顶不住了,那是否可以采取限流措施,保住部分用户的哀求是正常的,也比全部不可用要好

这些标题,Sentinel 都能办理

Sentinel 提供的能力

Sentinel 将要保护的对象(可以是某个服务或一段代码)抽象为资源,通过动态下发的规则,对资源举行

针对这两个主要功能又有许多的玩法,比如限流是针对QPS还是并发数,控制的效果是直接拒绝还是排队等等。

当然 Sentinel 也提供一个开箱即用的 Dashboard,可扩展配中心举行下发规则,展示监控指标,调用关系链等等

快速开始

源码阅读环境预备

git clone [email protected]:lkxiaolou/sentinel-golang.git


go mod download

目次结构先容

样例跑通

在 /example 目次下新建 mytests 目次,并创建一个 quick_start.go 文件,按照官网给出的例子,先用最简单的默认方式初始化

if err := sentinel.InitDefault(); err != nil { // 初始化失败 panic(err.Error())}
再用写死的方式加载规则

// 资源名resource := "test-resource"// 加载流控规则,写死_, err := flow.LoadRules([]*flow.Rule{ {  Resource: resource,  // Threshold + StatIntervalInMs 可组合出多长时间限制通过多少哀求,这里相当于限制为 10 qps  Threshold: 10,  StatIntervalInMs: 1000,  // 暂时不消关注这些参数  TokenCalculateStrategy: flow.Direct,  ControlBehavior: flow.Reject, },})
最后写测试代码

// 修改这个看看效果吧currency := 100for i := 0; i < currency; i++ { go func() {  e, b := sentinel.Entry(resource, sentinel.WithTrafficType(base.Inbound))  if b != nil {   // 被流控   fmt.Printf("blocked %s \n", b.BlockMsg())  } else {   // 通过   fmt.Println("pass...")   // 通过后必须调用Exit   e.Exit()  } }()}
这里限制了 10 qps,我们用 100 个协程并发测试跑一下,刚好通过10个哀求


                               
登录/注册后可看大图

测试代码已上传到我的仓库

https://github.com/lkxiaolou/sentinel-golang/tree/master/example/mytests

总结

本文先容了 Sentinel 的和它能办理的标题,以及源码阅读的一些预备工作,并跑通了一个最简单的例子,见识到了 Sentinel 限流的效果,本文先到这里,我们下一节见。

<hr>
搜刮关注"捉虫大师",后端技术分享,架构设计、性能优化、源码阅读、标题排查、踩坑实践。








欢迎光临 创意电子 (https://www.wxcydz.cc/) Powered by Discuz! X3.4