如何解决 “主节点故障恢复的自动化” 问题?
今日主题: 1、恢复主节点的故障,通过 redis 自动化哨兵的方式 2、预计阅读 6 分钟,正文 2700 字。一、开场介绍 hello,八点半的铁友们,其实在讲文章内容之前,我们先简单来知晓一下,哨兵是什么?用在哪里?等等一系列。这样我们先做一层铺垫,在后续的理解起来会更加容易,快似飞起般的感觉~~~我们来以 Q&A 的回答方式先来了解一些基础内容Q:哨兵是什么?A:网上说:哨兵是一种运行模式;其实可以理解哨兵就是一个进程,因此会独立运行。Q:哨兵原理 &用在何处?A:网上说:主节点出现故障,redis 进行通知、转移,来实现高可用;其实可以白话文理解为:哨兵就是通过发送命令,等待 redis 服务响应,从而监控运行 redis 多个实例。Q:哨兵的应用场景是?A:主服务器宕机了,那么需要人工处理切换服务器,这多麻烦,还影响业务服务。因此哨兵它来了,带着高可用慢慢的走来了,实现了自动化。Q:哨兵是怎么使用的?A:你猜猜难道是....对,就是通过配置的,操作核心的 redis.conf 文件等若干文件二、实战操作通过上述开场的基础介绍,想必我们脑子里已经有对 哨兵 有个相对闭环的了解了吧。话不多说,兄弟们上操作,有不足地方欢迎评论区探讨 &指出你认为应该改变的地方~~~毕竟刚开始操作,我们就不要想太复杂,我们就简单来一波哨兵系统。1、准备一台服务器即可(有 money 的准备 3~4 台,换着玩😂),准备一台的玩家需要注意,我们使用端口来区分滴哈。2、按照网上教程的来,那我们也部署 1 个主 2 个从 2 个哨兵,跟着大佬走,幸福到长久~~~3、开始部署主 &从节点,配置一样哈,没有特殊化,不需要额外关注其他配置,可以看我插入的代码配置,代码中会标注细节点。#redis.conf - 这里是主节点,port端口给了一个6379port 6379#守护线程,默认是NOdaemonize yeslogfile "6379.log"dbfilename "dump-6379.rdb" #redis-6300.conf - 这里是从节点,port端口给了一个6300port 6300#守护线程,默认是NOdaemonize yeslogfile "6300.log"dbfilename "dump-6300.rdb"slaveof 192.168.1.1 6379 - 192.168.1.1(模拟服务器ip) #redis-6301.conf - 这里是从节点,port端口给了一个6301port 6301#守护线程,默认是NOdaemonize yeslogfile "6301.log"dbfilename "dump-6301.rdb"slaveof 192.168.1.1 6379 - 192.168.1.1(模拟服务器ip)复制代码4、配置就这么愉快的完了,上述代码很详细,还是不懂评论区见,那么接下来需要做什么?当然是:依次启动 redis 服务的主节点 、从节点 ~~~redis-server redis-6379.confredis-server redis-6300.confredis-server redis-6301.conf复制代码5、启动后,那么我们来个命令看下状态即可,下图标注的命令会有解释:192.168.1.1:6379> info replication# Replication# 角色role:master# 从节点的连接数connected_slaves:2# 从节点详细信息 IP PORT 状态 命令(单位:字节长度)偏移量 延迟秒数# 主节点每次处理完写操作,会把命令的字节长度累加到master_repl_offset中。# 从节点在接收到主节点发送的命令后,会累加记录偏移量信息slave_repl_offset,同时,也会每秒钟上报自身的复制偏移量到主节点,以供主节点记录存储。# 在实际应用中,可以通过对比主从复制偏移量信息来监控主从复制健康状况。slave0:ip=192.168.1.1,port=6300,state=online,offset=236,lag=1slave1:ip=192.168.1.1,port=6301,state=online,offset=236,lag=0# master启动时生成的40位16进制的随机字符串,用来标识master节点master_replid:acc2aaa1f0bb0fd79d7d3302f16bddcbe4add423master_replid2:0000000000000000000000000000000000000000# master 命令(单位:字节长度)已写入的偏移量master_repl_offset:23866second_repl_offset:-1# 0/1:关闭/开启复制积压缓冲区标志(2.8+),主要用于增量复制及丢失命令补救repl_backlog_active:1# 缓冲区最大长度,默认 1Mrepl_backlog_size:1048576# 缓冲区起始偏移量repl_backlog_first_byte_offset:1# 缓冲区已存储的数据长度repl_backlog_histlen:23866复制代码6、接下来我们配置哨兵的配置,也是大家关注点之一,哨兵的配置简化版,端口区分:#sentinel-26000.confport 26000#守护线程,默认是NOdaemonize yeslogfile "26000.log"#sentinel monitor mymaster 配置的含义是:#该哨兵节点监控192.168.1.1:6379这个主节点,该主节点的名称是mymaster;#最后2含义与主节点的故障判定有关:至少需要2个哨兵节点同意,才能判定主节点故障并进行故障转移。sentinel monitor mymaster 192.168.1.1 6379 2复制代码7、启动哨兵节点#redis sentinel 是哨兵的英文名redis-server sentinel-26000.conf --sentinel复制代码8、全部结束,这个时候整个系统就开始运行了,这个时候想要验证,我们可以通过一个命令来看:通过redis-cli连接哨兵节点:info sentinel
#sentinelsentinel_master:1sentinel_tilt:0sentinel_running_scripts:0sentinel_scripts_queue_length:0#看到这里主节点名称,以及状态,以及地址,以及从节点数量,哨兵数量master0:name=myaster,status=ok,address=192.168.1.1:6379,salves:2,sentinel:3复制代码9、这个时候,我们也可以看下哨兵的配置文件,例如:打开 sentinel-26000.conf 文件目录,从这里可以看到哨兵已经发现从节点与其他哨兵的一个存在。复制代码10、整个配置过程就结束了,我个人建议可以玩玩,挺不错的。三、总结 兄弟姐妹们能看到现在,必须给个赞👍。基础内容看了,配置也教了;但是整体感觉还差点,那么就对了,还差一波总结,总结就是精华 &核心。看一篇文章,总结一定要看呐,过来人~~~总结列举:1、哨兵,又名(redis sentinel),独立运行,进程方式。2、哨兵,自动化监控服务、切换主从节点,恢复故障。3、哨兵,也有单点问题,也可以搞集群。4、哨兵,每秒钟/次的频率向它的 master,salve 以及其他 哨兵 实例发送一个 ping 命令。5、哨兵,监控记录,可以查看哨兵所对应的 conf 文件。6、哨兵,配置种出现 epoch 的参数,是一个从 0 开始的计数器,选举机制。7、哨兵,故障发现和转移是由哨兵来控制和完成的。8、哨兵,节点本质上是 redis 节点。9、哨兵,可以监控多个主节点,通过配置多 sentinel monitor 即可实现。四、下期预告下期预告:故障如何转移?它是如何运行 &切换的呢?感谢各位的阅览 &关注,如果感觉对您或者周围的人不管在面试中还是实际学习中,如有所帮助,欢迎点赞、转发,谢谢。有任何疑问🤔️或后续想要了解的内容点,欢迎评论区留言,我来帮助你梳理 &总结,你来读。
阿里云微服务引擎 MSE 2022年 7月份产品动态
【云原生】4.1 DevOps基础与实战
哈喽~大家好呀,在前面的一篇扩展篇里面简单的介绍了下 DevOps ,从这篇开始就进入到了自动化部署项目了。在前面我们写到的一些项目,它们都是手动一步一步添加上去的,未免显得太笨重了,如何我们有 1000 个项目,那这可不能手动部署(这会累 si 人的),所以官方为了效率,推出了 DevOps。一、DevOps简介DevOps 是一系列做法和工具,可以使 IT 和软件开发团队之间的流程实现自动化。其中,随着敏捷软件开发日趋流行,持续集成 (CI) 和持续交付 (CD) 已经成为该领域一个理想的解决方案。在 CI/CD 工作流中,每次集成都通过自动化构建来验证,包括编码、发布和测试,从而帮助开发者提前发现集成错误,团队也可以快速、安全、可靠地将内部软件交付到生产环境。二、尚医通项目上云这里有服务端、客户端、以及网关;服务端与客户端部署完之后,发送请求给网关,网关把各个请求给微服务项目架构yygh-parent
|---common //通用模块
|---hospital-manage //医院后台 [9999]
|---model //数据模型
|---server-gateway //网关 [80]
|---service //微服务层
|-------service-cmn //公共服务 [8202]
|-------service-hosp //医院数据服务 [8201]
|-------service-order //预约下单服务 [8206]
|-------service-oss //对象存储服务 [8205]
|-------service-sms //短信服务 [8204]
|-------service-statistics //统计服务 [8208]
|-------service-task //定时服务 [8207]
|-------service-user //会员服务 [8203]
====================================================================
yygh-admin //医院管理后台 [9528]
yygh-site //挂号平台 [3000]三、sentinel 部署上云之前呢首先要部署好中间件,像 Nacos、MySQL、Redis是之前已经部署好了的,所以接下来部署剩下的部分。1、Sentinel它是用来做流量保护功能的在应用负载——>服务里面创建一个服务(设置好基本信息、容器镜像、挂载存储、高级设置等设置)四、mongo部署 同样的,在应用负载——>应用里面选择好创建模板,点击部署(设置好基本信息、应用配置等设置),为了侯浩方便的访问,可以将端口号暴露出去。 然后指定工作负载创建服务(设置基本信息、服务设置、高级设置),部署好了之后我们可以用个工具来测试一下是否部署完成(MongoDB Compass 的软件),连接一下,发现没问题mysq|数据初始化使用工具(SQLyog)连接上 mysql ,将我们要使用的 sql 语句导入进去并运行。五、生产环境配置抽取项目默认规则每个微服务项目,在生产环境时,会自动获取 微服务名-prod.yml 作为自己的核心配置文件每个微服务项目,在生产环境时,默认都是使用 8080 端口创建一个 service-cmntprod.yml 将所有的中间件的地址改为我们的生产的地址,同样的每一个微服务(Sentinel、MongoDB、RabbitMQ、Redis等)都要进行这样的操作,后面配置好 deploy.yaml 文件apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: service-cart
name: service-cart
namespace: his #一定要写名称空间
spec:
progressDeadlineSeconds: 600
replicas: 1
selector:
matchLabels:
app: service-cart
strategy:
rollingUpdate:
maxSurge: 50%
maxUnavailable: 50%
type: RollingUpdate
template:
metadata:
labels:
app: service-cart
spec:
imagePullSecrets:
- name: aliyun-docker-hub #提前在项目下配置访问阿里云的账号密码
containers:
- image: $REGISTRY/$ALIYUNHUB_NAMESPACE/service-cart
readinessProbe:
httpGet:
path: /actuator/health
port: 8080
timeoutSeconds: 10
failureThreshold: 30
periodSeconds: 5
imagePullPolicy: Always
name: app
ports:
- containerPort: 8080
protocol: TCP
resources:
limits:
cpu: 300m
memory: 600Mi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
terminationGracePeriodSeconds: 30
---
apiVersion: v1
kind: Service
metadata:
labels:
app: service-cart
name: service-cart
namespace: his
spec:
ports:
- name: http
port: 8080
protocol: TCP
targetPort: 8080
selector:
app: service-cart
sessionAffinity: None
type: ClusterIP不积跬步无以至千里,趁年轻,使劲拼,给未来的自己一个交代!向着明天更好的自己前进吧!
分享是奉献的果实,推荐5款高效率的黑科技软件
1.硬盘工具——Hard DiskHard Disk Sentinel是一款用于HDD/SSD硬盘监控与分析的工具,使用可以查看硬盘的状态、健康程度以及性能,通过它可以查找,测试,诊断和修复磁盘驱动器问题,报告和显示SSD和HDD运行状况,检测性能下降和故障等,Hard Disk Sentinel同时还可以测试硬盘的实时传输率以便用来做为性能测试或者硬盘是否有隐含问题的功能,可用作基准测试或检测可能的硬盘故障,性能下降等。2.数据恢复工具——EaseUS DataEaseUS Data Recovery Wizard是一款简单易用的数据恢复工具,给用户提供了三种恢复模式:1、已删除文件恢复,该模式适用于用户误删、清空回收站的情形;2、完整恢复,该模式适用于磁盘格式化、文件系统崩溃或磁盘盘符丢失的情形;3、分区恢复,该模式适用于分区丢失情形时的恢复,总之,EaseUS Data Recovery Wizard简单易用,功能强大,是电脑用户不可多得的一款数据恢复软件。3.数据清洗——燃精灵好评率非常高的一个数据清洗工具,检测速度快,精准度高,检测后数据中将不存在没有微信的号码。4、图表制作——Chartistic一个备受好评的图表制作软件,可以让我们在手机上完成简单的图表统计。它完全免费,打开首页就能看到为大家提供的5种图表模板,包括:条形图、面积图、线状图、饼状图等,创建非常简单。支持创建单个图表和多个图表,而且还能导入图片。操作方法很简单,打开软件右击第一个按钮,就会进入到编辑页面。可以自由地编辑部分内容和图表中的数据,这些操作都可以通过手机输入完成。5.图片批注软件-iPhotoDraw这是一款最容易给图片加标注的工具,目前这类软件还不是很多,常用的图像处理软件要么太复杂,要么太庞大。比如,虽然PS及其它的软件也可以完成这些功能,但是他们远远比不了这款软件更方便。这个软件比较小众,我第一次接触时还是在上一家公司,当时有位同事在做产品图片时,我发现他用的就是这款软件,给图片添加文字、指示箭头、局部细节放大、线条、尺寸等等非常简单。
MSE 新金融行业标杆案例|费芮互动的云原生网关改造实践
MSE 注册配置首购8折,首购1年及以上7折。MSE 云原生网关预付费全规格享 9 折优惠。
不改一行源码,实现 sentinel-dashboard 所有配置支持 apollo 持久化
sentinel-dashboard-apollosentinel-dashboard-apollo 是从官方 Sentinel fork 的 dashboard 定制版,支持所有配置持久化到 apollo。github:https://github.com/fengjx/Sentinel使用文档:http://blog.fengjx.com/sentinel-dashboard-apollo-wikisentinel-dashboard 为什么需要定制Sentinel 是阿里巴巴开源的流量治理组件。功能非常齐全,包括了:请求过滤、降级、限流、流量监控等功能。如果对 sentinel 还不是很了解可以查看官方文档:https://sentinelguard.io/zh-cn/docs/basic-api-resource-rule.html虽然 sentinel 的设计非常优秀,基本上满足了流量治理的所有需求,但是 sentinel-dashboard(管理后台)的配置都是存储在内存,在服务重启后就会丢失。所以 sentinel 目前是不具备在生产环境上使用的。即使 sentinel 客户端是支持了从 apollo、consul、etcd、eureka、nacos、redis、spring-cloud-config、zookeeper 读取配置,但是如果不使用 dashboard,直接手动修改配置的话,官网也没有提供详细的参数配置文档,想知道哪些参数可配置,需要自己查看源码,使用上非常不友好。而这个问题早在 2020 年就有人提出来了(github issue) dashboard 配置持久化功能,但是官方至今(2022-07)依然没有实现这个功能。https://github.com/alibaba/Sentinel/issues/1759https://github.com/alibaba/Sentinel/issues/2179值得一提的是,阿里云的商业版 sentinel-dashboard 是有这个功能的。并且在 test 代码中可以看到有对应持久化实现的。所以这很明显官方并不想在开源版实现这个功能,需要我们自己去实现。这其中的原由已经非常明显了。方案选型目前已经实现的组件中,sentinel 客户端已经支持:apolloconsuletcdeurekanacosredisspring-cloud-configzookeeper以最小化改动原则,我们可以从上面其中一个作为持久化存储方案,否则就需要自己再开发一套客户端同步数据组件。这里我选择 apollo,理由是:apollo 作为配置中心,有丰富的配置功能,与其他方案如 nacos 都要完善和稳定许多。而其他如 redis、zookeeper 在数据排查方面都不是太方便。源码分析sentinel-dashboard 的源码结构非常简单。后端使用 spring-boot,前端使用 angular1。我们打开浏览器抓包工具,在界面上操作增删改查对应配置,就可以知道对应的接口是多少,然后通过接口路径找到对应的 Controller,继续往下跟踪就可以知道完整的处理流程了。例如:新增网关流控规则的接口是 /gateway/flow/new.json通过分析不难发现,不管是什么配置,对应增删改查的接口路径都是类似的。sentinel 规则总共有 7 中类型,都实现了 RuleEntity 接口我们需要实现的也是将这7种数据类型持久化到 apollo。从 sentinel 的架构设计上可以知道分为 sentinel 客户端(也就是我们的应用)和 sentinel-dashboard(管理后台)。通过分析 FlowControllerV1 源码,可以知道配置读写都是通过 SentinelApiClient 来完成的。读数据:通过 SentinelApiClient 请求客户端,拉取配置,然后更新到内存写数据:先保存到内存,然后调用 SentinelApiClient 将请求同步到客户端改造实现对于在生产环境中使用 Sentinel,官网文档中给我们介绍了几种模式。通过上面源码分析的流程实现的就是原始模式,我们的改造方案是要实现推模式。对于改造方案,如果做过这方面调研的同学,找到的资料基本上都是只实现了流量控制规则持久化,而剩下其他 6 中规则并没有实现持久化,包括姚秋辰(姚半仙)老师在极客时间上的专栏《Spring Cloud 微服务项目实战》第 20 章节Sentinel 实战:如何接入 Nacos 实现规则持久化? 中的方案也只是把流控规则配置做了持久化。大家可以自己搜索一下,这里不再赘述。以上方案都存在几个不足。只实现了流控规则持久化需要修改源码(包括前端代码),不放面后续滚动升级如果 7 中类型数据都做持久化的,那需要修改的地方会比较多通过上面源码分析可以知道,其实数据拉取和推送都是通过SentinelApiClient 的 fetchXXX(拉取数据)和 setXXX, modifyXXX(推送数据)方法来实现的,所以我们只要把对应的方法改成从 apollo 拉取数据和将数据推送到 apollo 上就可以了,因为 SentinelApiClient 没有定义接口,所以要在不改变源码的情况下改变它的默认行为,就要通过aop来实现了。下面是实现网关流控规则读写 apollo 的示例代码。@Aspect
@Component
public class SentinelApiClientAspect {
private static final Logger LOG = LoggerFactory.getLogger(SentinelApiClientAspect.class);
@SuppressWarnings("PMD.ThreadPoolCreationRule")
private static final ExecutorService EXECUTOR = Executors.newSingleThreadExecutor(
new NamedThreadFactory("sentinel-dashboard-api-aspect"));
@Resource
private DynamicRuleStoreFactory factory;
@Pointcut("execution(public * com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient.fetchGatewayFlowRules(..))")
public void fetchGatewayFlowRulesPointcut() {
}
@Pointcut("execution(public * com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient.modifyGatewayFlowRules(..))")
public void modifyGatewayFlowRulesPointcut() {
}
/**
* 拉取网关流控规则配置
*/
@Around("fetchGatewayFlowRulesPointcut()")
public Object fetchGatewayFlowRules(final ProceedingJoinPoint pjp) throws Throwable {
return fetchRulesWithCompletableFuture(pjp, RuleType.GW_FLOW);
}
/**
* 推送网关流控规则配置
*/
@Around("modifyGatewayFlowRulesPointcut()")
public Object modifyGatewayFlowRules(final ProceedingJoinPoint pjp) throws Throwable {
return publishRules(pjp, RuleType.GW_FLOW);
}
// 中间省略了部分代码,完整代码可以从 github 查看
private Object fetchRules(ProceedingJoinPoint pjp, RuleType ruleType) throws Throwable {
DynamicRuleStore<?> dynamicRuleStore = factory.getDynamicRuleStoreByType(ruleType);
if (dynamicRuleStore == null) {
return pjp.proceed();
}
Object[] args = pjp.getArgs();
String app = (String) args[0];
return dynamicRuleStore.getRules(app);
}
private CompletableFuture<Object> fetchRulesWithCompletableFuture(ProceedingJoinPoint pjp, RuleType ruleType) {
return CompletableFuture.supplyAsync(() -> {
try {
return fetchRules(pjp, ruleType);
} catch (Throwable e) {
throw new RuntimeException("fetch rules error: " + ruleType.getName(), e);
}
}, EXECUTOR);
}
@SuppressWarnings("unchecked")
private boolean publishRules(ProceedingJoinPoint pjp, RuleType ruleType) {
DynamicRuleStore<RuleEntity> dynamicRuleStore = factory.getDynamicRuleStoreByType(ruleType);
Object[] args = pjp.getArgs();
String app = (String) args[0];
List<RuleEntity> rules = (List<RuleEntity>) args[3];
try {
dynamicRuleStore.publish(app, rules);
return true;
} catch (Exception e) {
LOG.error("publish rules error", e);
return true;
}
}
private CompletableFuture<Void> publishRulesWithCompletableFuture(ProceedingJoinPoint pjp, RuleType ruleType) {
return CompletableFuture.runAsync(() -> publishRules(pjp, ruleType), EXECUTOR);
}
}对应 apollo 读写数据的代码在 test 包下已经有了,拿过来稍加改动就可以了完整的代码实现可以在 github 上查看:https://github.com/fengjx/Sentinel,整个改动没有修改一行源码,只是新增了一些类,方便后续升级不会引起代码冲突。改造后的效果dashboard 配置apollo 配置升级&版本维护本项目从 sentinel 官方 github 仓库 fork,只针对 dashboard 模块进行修改,保持与官方发布版本同步修改,版本对应关系Sentinelsentinel-dashboard-apollo说明branch - masterbranch: dashboard/apollo/master保持最新版本与官方 master 同步tag - 1.8.4branch: dashboard/apollo/1.8.4从官方发布的 tag checkout 出来进行修改tag - 1.8.4tag: dashboard/apollo/v1.8.4修改完成后发布tag相关文档Sentinel 控制台在生产环境中使用 Sentinel
(已结束)杭州站 | 阿里云中间件开发者 Meetup 开启报名
活动回顾:现场图片:https://live.photoplus.cn/live/pc/84924142/#/live视频回放:https://yqh.aliyun.com/live/detail/29133演讲PDF下载:https://github.com/mse-group/Slides活动报名须知:报名地址:https://survey.aliyun.com/apps/zhiliao/j8TOc41eR参会免费,点击下方报名地址,完成问卷,即为报名成功 我们将在活动前两天发送阿里巴巴西溪园区B区的访客凭证,凭借短信参会签到 现场准备了程序员礼品三大件,机械键盘、水杯和T恤,还有一些好看的书 活动详情:中间件开发者 Meetup 汇集了 Appactive、ChaosBlade、Nacos、OpenSergo、Seata、Sentinel、Serverless Devs、Spring Cloud Alibaba 等阿里云应用中间件领域开源项目的最新进展和开源实践。阿里巴巴西溪园区B区,访客中心415A,7月30日(周六)13:30开始
阿里云 MSE 支持 Go 语言流量防护
作者:卜比概述随着 Go 语言、云原生的广泛采用,Go 语言在微服务场景中使用的越来越广泛,对 Go 语言微服务的治理、限流降级需求也越来越强。在 Go 语言中,虽然社区提供了 go.uber.org/ratelimit 等限流库,但其一,对多语言支持不足,只支持 Go,其二,功能上,限流降级会细分为流控、隔离、熔断、热点等功能,也不支持动态配置,在功能支持度上不够完善。阿里云微服务引擎(MSE)结合 Sentinel,给 Go 语言、Java 语言应用带来微服务治理能力。本文将给大家介绍如何在 Go 语言微服务应用中使用限流降级能力。什么是限流降级在微服务应用中,限流降级主要分为三步:Target: 针对什么样的流量Strategy: 限流降级的策略FallbackAction: 触发后的行为 比如,针对订单创建接口(Target),我们限制请求为 1000QPS(Strategy),触发限流后,请求返回异常(FallbackAction)。在阿里云 MSE 支持通过开源 Sentinel 的方式来定义资源,并从 MSE 获取、应用限流降级规则,整体接入如下:如何使用 MSE 限流降级应用接入下载 MSE Go SDK[1],解压到项目的./pkg-custom/github.com/aliyun/aliyun-mse-go-sdk-v1.0.7 目录。可以参考 SDK 的 example 目录下的例子,来进行接入。在 go.mod 文件中,添加如下依赖声明:require (
github.com/aliyun/aliyun-mse-go-sdk v1.0.7
)
replace github.com/aliyun/aliyun-mse-go-sdk => ./pkg-custom/github.com/aliyun/aliyun-mse-go-sdk在应用的启动过程中,添加 MSE SDK 初始化命令:import (
mse_sdk "github.com/aliyun/aliyun-mse-go-sdk"
)
// 在应用的初始化逻辑中加入以下代码。
// Sentinel core的初始化包含在了这里面。如果之前有调用过Sentinel的初始化函数,需要去掉。
err := mse_sdk.InitMseDefault
if err != nil {
log.Fatalf("Failed to init MSE: %+v", err)
}应用部署在云原生部署方式中,通常的部署规范是 12 因子[2],其中关于配置,推荐将应用的配置存储于环境变量中。这样应用在部署时,只需要切换不同的环境变量,就可以接入不同的环境。同样的,MSE-Go-SDK 也推荐大家通过环境变量的方式接入 MSE,使用的环境变量如下:按照上述步骤接入后,可以在应用列表页面看到我们接入的应用:资源定义在文章开始的时候,我们提到了限流降级=Target+Strategy+FallbackAction。所以第一步就是要定义 Target。Sentinel 定义资源MSE 支持用户通过 Sentinel 定义的资源,只需要用如下代码块包裹业务逻辑即可:import (
sentinel "github.com/alibaba/sentinel-golang/api"
)
// Entry 方法用于埋点
e, b := sentinel.Entry("your-resource-name", sentinel.WithTrafficType(base.Inbound))
if b != nil {
// 请求被流控,可以从 BlockError 中获取限流详情
} else {
// 请求可以通过,在此处编写您的业务逻辑
// 务必保证业务逻辑结束后 Exit
e.Exit()
}当然,在日常的业务开发中,开发者常常通过微服务框架提供服务,比如 dubbo-go、Gin、gRPC 等,自然而然的,我们希望能够将这些服务注册为资源:dubbo-go 方式定义资源只需要引入 dubbo-go adaptor 即可自动注册资源到 MSE:import (
_ "github.com/alibaba/sentinel-golang/adapter/dubbo"
)Dubbo 应用是在代码中通过 import 包的形式引入 Dubbo adapter,其中的 init()函数会自动注入相关 filter。Dubbo-Go 版本需要≥1.3.0。Sentinel Dubbo adapter 会自动统计所有 provider 和 consumer 的调用。 gRPC应用接入import (
sentinelPlugin "github.com/alibaba/sentinel-golang/adapter/grpc"
"google.golang.org/grpc"
)
s := grpc.NewServer(grpc.UnaryInterceptor(sentinelPlugin.NewUnaryServerInterceptor()))
gRPC 应用在 gRPC 的初始化代码中引入 Sentinel 提供的 interceptor,Sentinel 针对 Server 和 Client 都提供了 unary 和 streaming 两种 interceptor,以上代码以 Server 端为例。默认的限流处理逻辑是返回 Sentinel 的 BlockError。您也可以在创建 interceptor 时提供自定义的 fallback 处理逻辑。Gin Web 应用接入import (
sentinelPlugin "github.com/alibaba/sentinel-golang/adapter/gin"
"github.com/gin-gonic/gin"
)
r := gin.New()
r.Use(sentinelPlugin.SentinelMiddleware())Gin Web 应用在 Gin 的初始化代码中引入 SentinelMiddleware。Sentinel 会对每个 API route 进行统计,资源名称类似于 GET:/foo/:id。默认的限流处理逻辑是返回 429 (Too Many Requests)错误码。 Micro应用接入import (
sentinelPlugin "github.com/alibaba/sentinel-golang/adapter/micro"
"github.com/micro/go-micro/v2"
)
svc := micro.NewService(micro.WrapHandler(sentinelPlugin.NewHandlerWrapper()))在 Go-Micro 的初始化代码中引入 Sentinel 提供的 wrapper。Sentinel 针对 Go-Micro Server 和 Client 都提供了 wrapper。以上代码以 Server端为例。埋点默认会提取服务 method 作为资源名,默认的流控处理逻辑是返回 Sentinel 的 BlockError。您也可以在创建 wrapper 时提供自定义的 fallback 处理逻辑。如何配置限流降级规则通过上述方式接入后,就可以配置流控规则、隔离规则、熔断规则、热点规则等规则了:查看应用 接入后,可以在应用列表页面看到我们接入的应用:在应用详情页面,也可以看到应用的概览数据:可以查看代码中注册的资源:配置流控规则 可以针对每种资源设置流控规则:设置流控规则后,可以看到拒绝 QPS 增加、通过 QPS 减少:选择流控防护,可以预设服务可承受的 QPS 流量,当流量达到设定阈值时立即拦截超出部分的请求,避免应用被瞬时的流量高峰冲垮。 配置隔离规则选择隔离防护,可以通过控制接口或依赖的并发线程数,来保证系统的稳定性。通常适用于应用内部或下游依赖出现不稳定的场景,例如慢 SQL、下游应用响应时间变长等。 配置熔断规则选择熔断防护,可以监控应用内部或者下游依赖的响应时间或异常比例,当达到指定的阈值时立即降低下游依赖的优先级。在指定的时间内,系统不会调用该不稳定的资源,避免应用受到影响,从而保障应用高可用性。当指定时间过后,再重新恢复对该资源的调用。 配置热点规则选择热点参数防护,AHAS 将分析统计参数,即资源调用过程中的调用次数较高的参数,并根据配置的热点规则对包含热点参数的资源调用进行限流,保护系统稳定性。热点即经常被访问的数据。例如在以下场景中需要统计某个热点数据中访问频次最高的 Top 数据,并对其访问进行限制。针对一段时间内最频繁购买的商品 ID 进行限制,防止击穿缓存而导致大量请求到数据库的情形。针对一段时间内频繁访问的用户 ID 进行限制,防止恶意刷单。MSE 微服务治理规划OpenSergo 开源项目联合 Sentinel 项目,正在制定、完善限流降级标准,方便不同语言应用通过统一控制面来实现统一的微服务治理。阿里云微服务引擎(MSE)也会逐步支持 OpenSergo 标准,让微服务开发者能够使用 OpenSergo 来统一治理不同语言的微服务应用。同时,阿里云 MSE 也会基于微服务治理进行探索,探索实现流量治理、限流降级、数据库治理、消息治理等功能,给微服务开发者带来全生命周期的微服务治理。MSE 注册配置中心专业版首购享 9 折优惠,MSE 云原生网关预付费全规格享 9 折优惠。点击此处,即享优惠!参考链接:[1] MSE Go SDK:https://mse-cn-hangzhou.oss-cn-hangzhou.aliyuncs.com/sdk/go/latest/aliyun-mse-go-sdk.zip[2] 12因子:https://12factor.net/zh_cn/
springcloud集成sentinel 《微服务》
1.安装1.1 docker安装docker run --name sentinel -d -p 8858:8858 -p 8719:8719 -d bladex/sentinel-dashboard
1.2 jar 安装java -jar sentinel-dashboard-1.8.4.jar
1.3 登录账号和密码都是sentinel2.集成Sentinel控制台修改规则:仅存在于服务的内存中,不会修改Nacos中配置值,重启后恢复原来的值 Nacos控制台修改规则:Nacos持久化规则,服务的内存也同步更新2.1 pom 配置<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>cloud2020</artifactId>
<groupId>com.lys.springcloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-sentinel-service</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<!--<version>2.2.1.RELEASE</version>-->
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- web组件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- SpringCloud alibaba sentinel-datasource-nacos,后续做持久化用到 -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
</dependencies>
</project>2.2 bootstrap.yml规则没有持久化,需要自行配置server:
port: 8002
nacos:
config:
bootstrap:
log:
enable: true
spring:
application:
name: nacos-sentinel-service
cloud:
nacos:
discovery:
server-addr: 10.6.8.238:8848 #Nacos作为服务注册中心地址
config:
server-addr: 10.6.8.238:8848 #Nacos作为配置中心地址
file-extension: yaml #指定yaml格式的配置
group: DEFAULT_GROUP #指定在哪个group里
namespace:
# {spring.application.name}-{spring.profiles.active}.{spring.cloud.nacos.config.file-extension}
# 实际访问的配置nacos-payment-provider.yaml
sentinel:
filter:
url-patterns: /**
transport:
#配置sentinel,dashboard地址
dashboard: 10.6.8.238:8858
#默认8719端口,假如被占用会自动从8719开始依次+1扫描,直至找到未被占用的端口
port: 8719
#clientIp: 10.7.0.25
规则持久化配置server:
port: 8002
nacos:
config:
bootstrap:
log:
enable: true
spring:
application:
name: nacos-sentinel-service
cloud:
nacos:
discovery:
server-addr: 10.6.8.238:8848 #Nacos作为服务注册中心地址
config:
server-addr: 10.6.8.238:8848 #Nacos作为配置中心地址
file-extension: yaml #指定yaml格式的配置
group: DEFAULT_GROUP #指定在哪个group里
namespace:
# {spring.application.name}-{spring.profiles.active}.{spring.cloud.nacos.config.file-extension}
# 实际访问的配置nacos-payment-provider.yaml
sentinel:
filter:
url-patterns: /**
transport:
#配置sentinel,dashboard地址
dashboard: 10.6.8.238:8858
#默认8719端口,假如被占用会自动从8719开始依次+1扫描,直至找到未被占用的端口
port: 8719
#clientIp: 10.7.0.25
# 下面为持久化到nacos
datasource:
# 这里的flow名字随便取 流控规则
flow:
nacos:
server-addr: ${spring.cloud.nacos.discovery.server-addr}
groupId: DEFAULT_GROUP
dataId: ${spring.application.name}-flow-rules
rule-type: flow
data-type: json
# 授权规则
authority:
nacos:
server-addr: ${spring.cloud.nacos.config.server-addr}
dataId: ${spring.application.name}-authority-rules
groupId: DEFAULT_GROUP
data-type: json
rule-type: authority
# 降级规则
degrade:
nacos:
server-addr: ${spring.cloud.nacos.config.server-addr}
dataId: ${spring.application.name}-degrade-rules
groupId: DEFAULT_GROUP
data-type: json
rule-type: degrade
# 热点规则
param-flow:
nacos:
server-addr: ${spring.cloud.nacos.config.server-addr}
dataId: ${spring.application.name}-param-flow-rules
groupId: DEFAULT_GROUP
data-type: json
rule-type: param-flow
# 系统规则
system:
nacos:
server-addr: ${spring.cloud.nacos.config.server-addr}
dataId: ${spring.application.name}-system-rules
groupId: DEFAULT_GROUP
data-type: json
rule-type: system
nacos 增加对应的规则如:nacos-sentinel-service-flow-rules.json[
{
"resource": "/testA",
"limitApp": "default",
"grade": 1,
"count": 1,
"strategy": 0,
"controlBehavior": 0,
"clusterMode": false
},
{
"resource": "/testB",
"limitApp": "default",
"grade": 1,
"count": 1,
"strategy": 0,
"controlBehavior": 0,
"clusterMode": false
}
]
resource:资源名称;IimitApp:来源应用;grade:國值类型,0表示线程数,1表示QPS;count:单机阈值strategy:流控模式,0表示直接,1表示关联,2表示链路controlbehavior:流控效果,0表示快速失败,1表示 Warm Up,2表示排队等待;cluster Mode:是否集群。2.3 FlowLimitControllerpackage com.lys.controller;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.TimeUnit;
/**
* @Auther: liuysh
* @Date: 2022/7/20 21:55
* @Description:
*/
@RestController
@Slf4j
public class FlowLimitController {
@GetMapping("/testA")
public String testA() {
return "testA";
}
@GetMapping("/testB")
public String testB() {
return "testB";
}
@GetMapping("/testC")
public String testC() {
try {
TimeUnit.SECONDS.sleep(1);
}catch(InterruptedException e) {
e.printStackTrace();
}
log.info("testC,测试RT");
return "testC";
}
@GetMapping("/testD")
public String testD() {
log.info("testD测试,异常比例");
int age = 10/0;
return "testD";
}
@GetMapping("/testE")
public String testE() {
log.info("testE测试,异常数");
int age = 10/0;
return "testE";
}
@GetMapping("/testHotKey")
@SentinelResource(value = "testHotKey",blockHandler = "deal_testHotKey")
public String testHotKey(@RequestParam(value = "p1",required = false) String p1,
@RequestParam(value = "p2",required = false) String p2
) {
return "testHotKey";
}
public String deal_testHotKey(String p1, String p2, BlockException exception) {
return "testHotKey的兜底方法deal_testHotKey执行";
}
}
3.sentinel与hystrix对比功能SentinelHystrix总结 隔离策略信号量隔离(并发线程数限流)(模拟信号量)线程池隔离/信号量隔离Sentinel不创建线程依赖tomcat或jetty容器的线程池,存在的问题就是运行容器的线程数量限制了sentinel设置值的上限可能设置不准。比如tomcat线程池为10,sentinel设置100是没有意义的,同时隔离性不好hystrix使用自己创建的线程池,隔离性会更好熔断降级策略基于响应时间、异常比率、异常数基于异常比率快速失败的本质功能实时统计实现滑动窗口(LeapArray)滑动窗口(基于 RxJava) 动态规则配置支持多种数据源支持多种数据源 扩展性多个扩展点插件的形式 基于注解的支持支持支持 限流基于 QPS,支持基于调用关系的限流有限的支持(并发线程数或信号量大小)快速失败的本质功能流量整形支持预热模式、匀速器模式、预热排队模式不支持(排队)支持排队好吧系统自适应保护支持(仅对linux生效)不支持所谓的自适应就是设置一个服务器最大允许处理量的阈值。(有比没有强,但是要知道最大负载量是多少。)控制台提供开箱即用的控制台,可配置规则、查看秒级监控、机器发现等简单的监控查看接近实时数据控制台是非常有竞争力的功能,因为能集中配置限制数据更方便,但是展示数据和实时性没有hystrix直观。配置持久化ZooKeeper, Apollo, NacosGit/svn/本地文件Sentinel客户端采用直接链接持久化存储,应用客户端引用了更多的依赖,同样的存储链接可能有多个配置动态配置支持支持hystrix可能需要手动触发,sentinel增加了额外的端口进行配置文件控制,应该也支持spring boot动态配置黑白名单支持不支持个人觉得这个功能用的不是很多springcloud集成高非常高Spring boot使用hystrix会更方便整体优势集中配置设置及监控+更细的控制规则漂亮的界面+接近实时的统计结果集中配置可能更有吸引力,但是配置值是多少以及让谁控制依然是很头疼的事情。运维控制可能不知道哪个应该优先哪个不优先,应该调整到多大。什么时候更适合使用sentinel?个人认为docker容器化部署之后sentinel可能更会发挥作用,但是会有另外的竞品出现做选型。sentinel本身支持qps(qps:每秒可以进来的请求数,只是进来,不管是否进来之后服务走完。只管进来不管出去。),不会创建线程池,比较轻;而远程调用服务的时候,hystrix调用一个方法就会创建一个线程池,所以hystrix特别重;sentinel本身支持有qps,远程调用不会创建线程池,如果qps大,后面的服务处理不过来,所以就要进行限流降级处理;信号量隔离hystrix远程调用会创建线程池,并且该线程池是依赖tomcat的,不会比tomcat线程多,即使多了也没意义。线程池隔离限流方案:qps 、线程数
Java & Go 专场 | 阿里云中间件开发者线下 Meetup 开启报名
活动报名须知参会免费,点击文末阅读原文,完成问卷,即为报名成功 🔖我们将在活动前两天发送阿里巴巴西溪园区 B 区的访客凭证,凭借短信参会签到 📨收到访客凭证,可在园区内免费停车 🚗现场准备了程序员礼品三大件,机械键盘、水杯和T恤,还有一些好看的书 😉活动详情中间件开发者 Meetup 汇集了 Appactive、ChaosBlade、Nacos、OpenSergo、Seata、Sentinel、Serverless Devs、Spring Cloud Alibaba 等阿里云应用中间件领域开源项目的最新进展和开源实践。阿里巴巴西溪园区 B 区,访客中心 415A,7 月 30 日(周六)13:30 开始报名地址:点击此处。