sentinel熔断简单实现

sentinel详细介绍网址
在这里插入图片描述
基于qps限流

package main

import (
	"fmt"
	sentinel "github.com/alibaba/sentinel-golang/api"
	"github.com/alibaba/sentinel-golang/core/base"
	"github.com/alibaba/sentinel-golang/core/flow"
	"log"
)

//基于qps配置

func main() {
	//初始化sentinel
	err := sentinel.InitDefault()
	if err != nil {
		log.Fatalf("初始化sentinel 异常:%v", err)
	}

	//配置限流的规则
	_, err = flow.LoadRules([]*flow.Rule{
		{
			Resource:               "some-test", //资源名称
			TokenCalculateStrategy: flow.Direct, //前流量控制器的Token计算策略 目前限流
			ControlBehavior:        flow.Reject, //直接拒绝
			Threshold:              10,          //表示流控阈值
			StatIntervalInMs:       1000,        //1s能传10个
		},

		{
			Resource:               "some-test1", //资源名称
			TokenCalculateStrategy: flow.Direct,  //前流量控制器的Token计算策略 目前限流
			ControlBehavior:        flow.Reject,  //直接拒绝
			Threshold:              10,           //表示流控阈值
			StatIntervalInMs:       1000,         //1s能传10个
		},
	})

	if err != nil {
		log.Fatalf("配置限流的规则 异常:%v", err)
	}

	//目前1s有10个进来
	for i := 0; i < 12; i++ {
		//会调用12次
		e, b := sentinel.Entry("some-test", sentinel.WithTrafficType(base.Inbound)) //(base.Inbound 入口流量配置

		//是否满足规则
		if b != nil {
			fmt.Println("限流了")
		} else {
			fmt.Println("检查通过")
			e.Exit() //退出
		}
	}

}

sentinel的预热和冷启动–>在60s内逐步达到1000

package main

import (
	"fmt"
	sentinel "github.com/alibaba/sentinel-golang/api"
	"github.com/alibaba/sentinel-golang/core/base"
	"github.com/alibaba/sentinel-golang/core/flow"
	"log"
	"math/rand"
	"time"
)

//基于qps配置

func main() {
	//初始化sentinel
	err := sentinel.InitDefault()
	if err != nil {
		log.Fatalf("初始化sentinel 异常:%v", err)
	}

	//配置限流的规则
	_, err = flow.LoadRules([]*flow.Rule{
		{
			Resource:               "some-test", //资源名称
			TokenCalculateStrategy: flow.WarmUp, //预热/冷启动策略
			ControlBehavior:        flow.Reject, //直接拒绝
			Threshold:              1000,        //表示流控阈值
			//StatIntervalInMs:       1000,        //1s能传10个
			WarmUpPeriodSec: 60, //预热时长 1分钟左右达到
		},

		{
			Resource:               "some-test1", //资源名称
			TokenCalculateStrategy: flow.Direct,  //前流量控制器的Token计算策略 目前限流
			ControlBehavior:        flow.Reject,  //直接拒绝
			Threshold:              10,           //表示流控阈值
			StatIntervalInMs:       1000,         //1s能传10个
		},
	})

	if err != nil {
		log.Fatalf("配置限流的规则 异常:%v", err)
	}

	ch := make(chan struct{})
	var globalTotal int
	var passTotal int
	var blockTotal int

	//我会在每一秒统计一次,这一秒之内 你通过了多少,总共有多少, block了多少, 每一秒会产生很多的block
	for i := 0; i < 100; i++ {
		go func() {
			for {
				globalTotal++
				//会调用12次
				e, b := sentinel.Entry("some-test", sentinel.WithTrafficType(base.Inbound)) //(base.Inbound 入口流量配置
				//是否满足规则
				if b != nil {
					//fmt.Println("限流了")
					blockTotal++
					time.Sleep(time.Duration(rand.Uint64()%10) * time.Millisecond)
				} else {
					//fmt.Println("检查通过")
					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

}

匀速通过,更换掉就行,比如一秒你有100个通过,那么就是每10ms通过一个,那么就需要延迟10ms就会全部通过
sentinel的熔断接口
基于错误数

// Copyright 1999-2020 Alibaba Group Holding Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"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() //加入loging
	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=5s, recoveryTimeout=3s, maxErrorCount=50
		{
			Resource:                     "abc",
			Strategy:                     circuitbreaker.ErrorCount,
			RetryTimeoutMs:               3000, //3s之后进入half-open
			MinRequestAmount:             10,   //静默数
			StatIntervalMs:               5000, //5s统计一次
			StatSlidingWindowBucketCount: 10,   //活动窗口的个数
			Threshold:                    50,   //数量不超过50个
		},
	})
	fmt.Println(circuitbreaker.ErrorCount)
	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 {
				totalBlock++
				fmt.Println("协程熔断了")
				// g1 blocked
				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()%80+10) * time.Millisecond)
				e.Exit()
			}
		}
	}()
	go func() {
		for {
			total++
			e, b := sentinel.Entry("abc")
			if b != nil {
				totalBlock++
				// g2 blocked
				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
}

具体需要修改源码的测试

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/306386.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CentOS常用命令

CentOS常用命令 1 背景知识1.1 Centos 简介1.2 centos 和ubuntu的区别1.3 安装centos的时候需要注意什么 2 常用命令集锦2.1 文件目录类&#xff1a;2.2 驱动挂载类&#xff1a;2.3 关机命令&#xff1a;2.4 查看系统信息命令&#xff1a;2.5 文本命令2.6 系统管理命令&#xf…

Redis异步写失败后补数逻辑设计

背景 最近各种机房事故频发&#xff0c;所以很多公司都对Redis存储等进行异步多活&#xff0c;我们公司采用的方式是通过客户端双写的方式来实现异地Redis机房的备份&#xff0c;但是当异地机房出现临时网络故障时&#xff0c;就涉及到了如何进行补数的操作&#xff0c;本文就…

6 - 数据备份与恢复|innobackupex

数据备份与恢复&#xff5c;innobackupex 数据备份与恢复数据备份相关概念物理备份与恢复逻辑备份&#xff08;推荐&#xff09;使用binlog日志文件实现对数据的时时备份‘使用日志 恢复数据 innobackupex 对数据做备份和恢复增量备份与恢复 数据备份与恢复 数据备份相关概念 …

【算法Hot100系列】搜索插入位置

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老导航 檀越剑指大厂系列:全面总结 jav…

资源调度(2)-----pod的亲和性和反亲和性

集群调度: schedule的调度算法。 预算策略&#xff1a;过滤出合适的节点 优先策略&#xff1a; 选择部署的节点 nodeName:硬匹配&#xff0c;不走调度策略。node01. nodeSelector&#xff1a;根据节点的标签选择&#xff0c;会走调度算法。 只要是走调度算法&#xff0c;在不满…

软件测试|Python对JSON的解析和创建详解

简介 JSON&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的数据交换格式&#xff0c;已经成为当今互联网应用中广泛使用的数据格式之一。Python提供了内置的模块来解析和创建JSON数据&#xff0c;使得在Python中处理JSON变得非常简单。本文将详细介绍Python…

ProtoBuf一些踩坑记录

一、Protobuf学习基础 学习的资料很多也很全&#xff0c;这里添加几个链接进行Protobuf的基础学习的链接&#xff0c;链接中的案例使用C编辑&#xff1a; 链接&#xff1a;Protobuf介绍及简单使用(上&#xff09;_google_protobuf_version-CSDN博客 Protobuf介绍及简单使用(下&…

从网页连接socket服务器和I/O

1.i/o InputStream和InputStreamReader是Java I/O类库中的两个关键类&#xff0c;用于处理字节流。它们的主要区别在于它们处理数据的方式。 InputStream: InputStream是用于读取字节流的抽象类。它是所有字节输入流类的父类。InputStream的子类可以从不同的数据源读取字节&…

了解 Node.js 的运行机制:从事件循环到模块系统(上)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

typora导出html添加目录

typora导出html添加目录 使用方法 首先要从typora导出html文件&#xff0c;之后用记事本编辑器html文件 找到文档最后面&#xff0c;如图&#xff1a; 用文字编辑类工具打开sideBar.txt&#xff0c;复制其中所有内容【内容在下面】 在如上图的位置插入所复制的内容 打开修改…

面试宝典进阶之Java线程面试题

T1、【初级】线程和进程有什么区别&#xff1f; &#xff08;1&#xff09;线程是CPU调度的最小单位&#xff0c;进程是计算分配资源的最小单位。 &#xff08;2&#xff09;一个进程至少要有一个线程。 &#xff08;3&#xff09;进程之间的内存是隔离的&#xff0c;而同一个…

信息系统安全——基于 AFL 的模糊测试

实验 3 基于 AFL 的模糊测试 3.1 实验名称 《基于 AFL 的模糊测试》 3.2 实验目 1 、熟悉模糊测试方法 2 、熟悉模糊测试工具 AFL 的使用 3.3 实验步骤及内容 1 、 安装 AFL 2 、 任意选择一个有源代码的样本 这里采用教材上一个包含栈溢出漏洞的样本。 3 、 结合源代码分析用 …

8.云原生存储之Ceph集群

1. 私有云实战之基础环境搭建 2. 云原生实战之kubesphere搭建 3.云原生之kubesphere运维 4. 云原生之kubesphere基础服务搭建 5.云原生安全之kubesphere应用网关配置域名TLS证书 6.云原生之DevOps和CICD 7.云原生之jenkins集成SonarQube 8.云原生存储之Ceph集群 文章目录 为什么…

python 队列

队列常用方法 Python中的队列是一种数据结构&#xff0c;遵循先进先出&#xff08;FIFO&#xff09;的原则。在Python中&#xff0c;你可以使用内置模块queue提供的Queue类来实现队列数据结构。队列是一种常见的数据结构&#xff0c;用于按照特定顺序处理数据项&#xff0c;例…

x-cmd pkg | termsvg - 用于记录终端会话并导出为 SVG 图像的终端录制工具

目录 简介首次用户简单易用支持暂停录制兼容asciinema类似工具进一步阅读 简介 termsvg 是一款用 Go 编写命令行工具&#xff0c;可以用来录制终端操作和重新播放&#xff0c;而且可以导出录制文件为 svg 动画。其录制文件使用与 asciinema 相同的格式&#xff0c;因此您可以使…

【2024最新-python3小白零基础入门】No2.python基础语法

文章目录 1 编码2 标识符规则3 python保留字4 注释5 行与缩进6 多行语句7 数字(Number)类型8 字符串(String)9 空行10 等待用户输入11 同一行显示多条语句12 import 与 from...import 环境准备&#xff0c;打开pycharm,新建一个python文件 文件名称随便&#xff0c;可中文可英文…

ECMAScript6历史-前端开发+ECMAScript+基础语法+入门教程

ECMAScript6详解 ECMAScript 历史 我们首先来看 ECMA 是什么。ECMA&#xff0c;读音类似“埃科妈”&#xff0c;是欧洲计算机制造商协会&#xff08;European Computer Manufacturers Association&#xff09;的简称&#xff0c;是一家国际性会员制度的信息和电信标准组织。19…

ML:2-2neural network layer

文章目录 1. 神经网络层2. 更复杂的神经网络3. 神经网络的前向传播 【吴恩达机器学习笔记p47-49】 1. 神经网络层 input&#xff1a;4个数字的向量。3个神经元分别做logistic regression。下角标&#xff1a;标识第 i 个神经元的值。上角标&#xff1a;表示第 j 层layer的值。…

JAVA面向对象基础-容器

一、泛型 我们可以在类的声明处增加泛型列表&#xff0c;如&#xff1a;<T,E,V>。 此处&#xff0c;字符可以是任何标识符&#xff0c;一般采用这3个字母。 【示例9-1】泛型类的声明 1 2 3 4 5 6 7 8 9 10 class MyCollection<E> {// E:表示泛型; Object[] o…

使用 Apache PDFBox 操作PDF文件

简介 Apache PDFBox库是一个开源的Java工具&#xff0c;专门用于处理PDF文档。它允许用户创建全新的PDF文件&#xff0c;编辑现有的PDF文档&#xff0c;以及从PDF文件中提取内容。此外&#xff0c;Apache PDFBox还提供了一些命令行实用工具。 Apache PDFBox提供了创建、渲染、…