前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >熔断限流原理与实践

熔断限流原理与实践

原创
作者头像
alieliu
发布2020-12-08 20:04:57
8700
发布2020-12-08 20:04:57
举报
文章被收录于专栏:一诺千金一诺千金

前言:

高稳定性和高可用一直是系统服务追求的终极目标,一个系统如果连最基本的稳定性都无法保障,就不太可能获得用户的认可。随着微服务的流行,服务和服务之间的稳定性变得越来越重要。本文结合自己在实践过程中,基于sentinel来实现grpc服务之间的限流和熔断功能。

理论知识:

Sentinel 是阿里开源的一款面向分布式服务架构的流量控制组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护等多个维度来帮助您保障微服务的稳定性。它目前java,golang,c++, nodejs等多种语言。

资源:是 Sentinel 的关键概念。它可以是程序中的任何内容,只要通过 Sentinel API 定义的代码块,就是资源,能够被 Sentinel 保护起来。

规则:围绕资源的实时状态设定的规则,可以包括流量控制规则、熔断降级规则、系统保护规则以及用户自己扩展的规则。所有规则都可以动态实时调整。

实践:

为了防止突发流量导致后端服务雪崩,需要对超出服务承受的流量进行主动丢弃,通过限制多余的流量,来保证后端服务的稳定性。当我们自身服务依赖的第三方服务出现问题时,我们需要及时发现并且进行熔断。

设计思路:

  1. 支持配置化,新增限流或者熔断时通过该配置和尽量少的修改代码来实现
  2. 发生限流或熔断时能够及时发现与告警

我目前使用 Sentinel 的版本为:v1.0.0-M1

配置设计:

这样设计的好处能够最大的保留原生配置,根据自己需要进行任意配置,同时相同策略的接口或者资源可以共享一套配置,这样也能够减少配置项。

代码语言:txt
复制
import (
	"github.com/alibaba/sentinel-golang/core/circuitbreaker"
	"github.com/alibaba/sentinel-golang/core/flow"
)

// FlowRule
type FlowRule struct {
	FlowResources []string  `json:"flowResources"`
	FlowRule      flow.Rule `json:"flowRule"`
}

// CbRule
type CbRule struct {
	CbResources []string            `json:"cbResources"`
	CbRule      circuitbreaker.Rule `json:"cbRule"`
}

// Conf
type Conf struct {
	FlowRules []FlowRule `json:"flowRules"`
	CbRules   []CbRule   `json:"cbRules"`
}

核心功能封装:

代码语言:txt
复制
import (
	"encoding/json"
	"fmt"

	sentinelapi "github.com/alibaba/sentinel-golang/api"
	"github.com/alibaba/sentinel-golang/core/base"
	"github.com/alibaba/sentinel-golang/core/circuitbreaker"
	"github.com/alibaba/sentinel-golang/core/config"
	"github.com/alibaba/sentinel-golang/core/flow"
)

// cbStateChangeListener
type cbStateChangeListener struct {
}

// 熔断关闭
func (s *cbStateChangeListener) OnTransformToClosed(prev circuitbreaker.State, rule circuitbreaker.Rule) {
	dd, _ := json.Marshal(rule)
	msg := fmt.Sprintf("资源名:%s,\n熔断状态:由 %s 变成 Closed,\n规则:%s\n",
		rule.Resource, prev.String(), string(dd))
	// 这里增加相应的监控告警
	println(msg)
}

// 熔断打开
func (s *cbStateChangeListener) OnTransformToOpen(prev circuitbreaker.State,
	rule circuitbreaker.Rule, snapshot interface{}) {
	dd, _ := json.Marshal(rule)
	msg := fmt.Sprintf("资源名:%s,\n熔断状态:由 %s 变成 Open,\n规则:%s,\nsnapshot: %.2f\n",
		rule.Resource, prev.String(), string(dd), snapshot)
	// 这里增加相应的监控告警
	println(msg)
}

// 熔断半开
func (s *cbStateChangeListener) OnTransformToHalfOpen(prev circuitbreaker.State, rule circuitbreaker.Rule) {
	dd, _ := json.Marshal(rule)
	msg := fmt.Sprintf("资源名:%s,\n熔断状态:由 %s 变成 Half-Open,\n规则:%s\n",
		rule.Resource, prev.String(), string(dd))
	// 这里增加相应的监控告警
	println(msg)
}

// InitSentinel
func InitSentinel(confMap Conf) error {

	defaultConf := config.NewDefaultConfig()
	defaultConf.Sentinel.Log.Dir = "./log/sentinel"
	err := sentinelapi.InitWithConfig(defaultConf)
	if err != nil {
		return err
	}

	// 配置限流
	if len(confMap.FlowRules) > 0 {
		var rs = make([]*flow.Rule, 0)
		for _, rule := range confMap.FlowRules {
			for _, res := range rule.FlowResources {
				var r = rule.FlowRule
				r.Resource = res
				rs = append(rs, &r)
			}
		}
		_, err = flow.LoadRules(rs)
		if err != nil {
			println(err.Error())
		}
	}

	// 配置熔断
	circuitbreaker.RegisterStateChangeListeners(&cbStateChangeListener{})
	if len(confMap.CbRules) > 0 {
		var rs = make([]*circuitbreaker.Rule, 0)
		for _, rule := range confMap.CbRules {
			for _, res := range rule.CbResources {
				var r = rule.CbRule
				r.Resource = res
				rs = append(rs, &r)
			}
		}
		_, err = circuitbreaker.LoadRules(rs)
		if err != nil {
			println(err.Error())
		}
	}
	return nil
}

效果:

以下是我们项目中触发熔断时的告警信息

Closed 变成 Open
Closed 变成 Open
 Open 变成 Half-Open
Open 变成 Half-Open
HalfOpen 变成 Closed
HalfOpen 变成 Closed

后记:

目前熔断限流功能已经在我们项目中取得了良好的效果,他们是保证系统稳定性不可或缺的利器。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言:
  • 理论知识:
  • 实践:
    • 设计思路:
      • 配置设计:
        • 核心功能封装:
          • 效果:
            • 后记:
            相关产品与服务
            正版曲库直通车
            正版曲库直通车(Authorized Music Express,AME)聚合多家版权方优质曲目资源,结合腾讯云存储、编解码、内容分发、智能音乐等能力,有效解决多场景正版音乐素材应用问题。您可通过API、SDK等多种接入方式,便捷应用,高效完成版权音乐在多端的播放和使用。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档