流量治理神器-Sentinel 究竟是怎么做到让业务方接入简单?
大家好,我是架构摆渡人,这是流量治理系列的第10篇原创文章,如果有收获,还请分享给更多的朋友。
做业务开发,需要考虑业务的扩展性。做基础框架开发,需要考虑如何让业务方接入,使用简单,尽量不要耦合在业务代码中。
Sentinel里面是如何做到让业务方接入简单,使用方便的呢?这篇文章就来剖析下Sentinel的那些适配是如何实现的。
基本使用
基本使用可以直接用SphU类对资源进行保护,使用方式如下:
public static void main(String[] args) {
// 配置规则.
initFlowRules();
while (true) {
// 1.5.0 版本开始可以直接利用 try-with-resources 特性
try (Entry entry = SphU.entry("HelloWorld")) {
// 被保护的逻辑
System.out.println("hello world");
} catch (BlockException ex) {
// 处理被流控的逻辑
System.out.println("blocked!");
}
}
}
这种方式其实就违背了前面我们说的耦合问题,跟业务代码耦合在了一起,扩展性不好。
注解使用
可以在基本使用的基础上优化下,不在业务代码中出现SphU相关的代码,比如说定义一个注解在来实现这个功能。
使用方式如下:
@SentinelResource("HelloWorld")
public void helloWorld() {
// 资源中的逻辑
System.out.println("hello world");
}
通过注解和切面我们就可以将逻辑收拢,不会在散落在各个业务代码中,就算有一天你的限流方式改成了其他框架,注解都不用变,直接将切面里面的逻辑更新即可。
适配Dubbo
当我们需要对Dubbo的接口进行限流时,使用原生的代码方式和注解方式都可以,但是这样就需要我们在每个调用的地方进行改造,那么能不能做成自动适配的方式,连注解都不用加呢?
在Sentinel中有一个sentinel-apache-dubbo-adapter的模块就是专门用于适配dubbo的。原理就是通过Dubbo的Filter机制来实现通用的适配逻辑。
有consumer Filter和provider Filter, 业务方只需要依赖这个包,就自动适配dubbo了,然后通过Sentinel的控制台进行配置,就可以达到限流和熔断的效果了。
适配Feign
Dubbo都适配了,怎么能少的了Feign呢,其实原理都是一样,也是通过Feign的Filter机制来适配。不过Feign的适配整合放在了Spring Cloud Alibaba中。
通过定义SentinelInvocationHandler,在invoke方法中适配Sentinel的逻辑。详细代码在com.alibaba.cloud.sentinel.feign.SentinelInvocationHandler中。
适配Zuul
对于Zuul的适配同样有一个单独的模块sentinel-zuul-adapter。原理呢还是一样,Zuul也有Filter, 既然是限流在Zuul中肯定是用pre filter。
实现类是com.alibaba.csp.sentinel.adapter.gateway.zuul.filters.SentinelZuulPreFilter,贴一小段代码给大家看下:
public Object run() throws ZuulException {
RequestContext ctx = RequestContext.getCurrentContext();
String origin = this.parseOrigin(ctx.getRequest());
String routeId = (String)ctx.get("proxy");
Deque<AsyncEntry> asyncEntries = new ArrayDeque();
String fallBackRoute = routeId;
try {
if (StringUtil.isNotBlank(routeId)) {
ContextUtil.enter("sentinel_gateway_context$$route$$" + routeId, origin);
this.doSentinelEntry(routeId, 0, ctx, asyncEntries);
}
Set<String> matchingApis = this.pickMatchingApiDefinitions(ctx);
if (!matchingApis.isEmpty() && ContextUtil.getContext() == null) {
ContextUtil.enter("zuul_default_context", origin);
}
Iterator var14 = matchingApis.iterator();
while(var14.hasNext()) {
String apiName = (String)var14.next();
this.doSentinelEntry(apiName, 1, ctx, asyncEntries);
}
} catch (BlockException var12) {
ZuulBlockFallbackProvider zuulBlockFallbackProvider = ZuulBlockFallbackManager.getFallbackProvider(fallBackRoute);
BlockResponse blockResponse = zuulBlockFallbackProvider.fallbackResponse(fallBackRoute, var12);
ctx.setRouteHost((URL)null);
ctx.set("serviceId", (Object)null);
ctx.setResponseBody(blockResponse.toString());
ctx.setResponseStatusCode(blockResponse.getCode());
ctx.getResponse().setContentType("application/json; charset=utf-8");
} finally {
if (!asyncEntries.isEmpty()) {
ctx.put("_sentinel_entries", asyncEntries);
}
}
return null;
}
总结
本文只是为了让大家了解,在开发一个底层框架的时候,需要考虑的问题。这个问题就是使用起来越简单越好,这才是好的框架该有的样子。
当然,Sentinel还适配了其他很多的框架,比如httpclient, Spring Cloud Gateway啊等,底层思想都是相同的,都是利用扩展机制进行统一处理。
流量治理神器-Sentinel 究竟是怎么做到让业务方接入简单?的更多相关文章
- 流量治理神器-Sentinel的限流模式,选单机还是集群?
大家好,架构摆渡人.这是我的第5篇原创文章,还请多多支持. 上篇文章给大家推荐了一些限流的框架,如果说硬要我推荐一款,我会推荐Sentinel,Sentinel的限流模式分为两种,分别是单机模式和集群 ...
- 阿里限流神器Sentinel夺命连环 17 问?
1.前言 这是<spring Cloud 进阶>专栏的第五篇文章,这篇文章介绍一下阿里开源的流量防卫兵Sentinel,一款非常优秀的开源项目,经过近10年的双十一的考验,非常成熟的一款产 ...
- Istio 流量治理功能原理与实战
一.负载均衡算法原理与实战 负载均衡算法(load balancing algorithm),定义了几种基本的流量分发方式,在Istio中共有4种标准负载均衡算法. •Round_Robin: 轮询算 ...
- 最小轻量级的Istio来了,仅使用流量治理能力
Istio 1.0.1作为8月份的版本已经发布,主要修复了1.0版本发布以来发现的一些关键Issue.官网的release note(https://istio.io/about/notes/1.0. ...
- idou老师教你学Istio 19 : Istio 流量治理功能原理与实战
一.负载均衡算法原理与实战 负载均衡算法(load balancing algorithm),定义了几种基本的流量分发方式,在Istio中一共有4种标准负载均衡算法. •Round_Robin: 轮询 ...
- Istio流量治理原理之负载均衡
流量治理是一个非常宽泛的话题,例如: ● 动态修改服务间访问的负载均衡策略,比如根据某个请求特征做会话保持: ● 同一个服务有两个版本在线,将一部分流量切到某个版本上: ● 对服务进行保护,例如限制并 ...
- istio流量管理:非侵入式流量治理
在服务治理中,流量管理是一个广泛的话题,一般情况下,常用的包括: 动态修改服务访问的负载均衡策略,比如根据某个请求特征做会话保持: 同一个服务有多版本管理,将一部分流量切到某个版本上: 对服务进行保护 ...
- 限流神器Sentinel,不了解一下吗?
概述 书接上回:你来说说什么是限流? ,限流的整体概述中,描述了 限流是什么,限流方式和限流的实现.在文章尾部的 分布式限流,没有做过多的介绍,选择了放到这篇文章中.给大伙细细讲解一下 Sentine ...
- 快速体验 Sentinel 集群限流功能,只需简单几步
️ Pic by Alibaba Tech on Facebook 集群限流 可以限制某个资源调用在集群内的总 QPS,并且可以解决单机流量不均导致总的流控效果不佳的问题,是保障服务稳定性的利器. S ...
随机推荐
- C++ - C语言中数组的另一种常用写法(数组大小可变!!!)
在 C 和 C++ 中,数组在声明过程中,数组名称为 const 指针,不许修改.且数组的大小在声明时被写死,非常不方便. C语言中常用下面代码替代指针. #include <stdio.h&g ...
- C语言泛型编程——泛型冒泡排序
在实际编程中,常常会需要一些方法(函数),比如排序,它们具体实现基本一致,仅仅只有参数类型不同, 那么可不可以有一种通用的函数,不管是什么类型的参数都可以通用呢? 泛型编程:泛型即是指具有在多种数据类 ...
- 【译】感谢 Flash 所做的一切
翻译:疯狂的技术宅来源:Chromium Blog原文标题:So long, and thanks for all the Flash英文原文:https://blog.chromium.org/20 ...
- 前端面试题整理——手写flatern摊平数组
// flatern 是摊平数组 function flat(arr) { const isDeep = arr.some(item => item instanceof Array) if(! ...
- Hadoop本地编写的jar包放到集群执行时报错处理
错误描述: 020-03-24 22:45:23,204 WARN org.apache.hadoop.yarn.server.nodemanager.DefaultContainerExecutor ...
- Blazor组件自做二 : 使用JS隔离制作手写签名组件
Blazor组件自做二 : 使用JS隔离制作手写签名组件 本文相关参考链接 JavaScript 模块中的 JavaScript 隔离 Viewer.js工程 Blazor组件自做一 : 使用JS隔离 ...
- SpringCloud Alibaba入门之Nacos(SCA)
SpringCloud Alibaba Spring Cloud Alibaba 致力于提供微服务开发 的一站式解决方案.此项目包含开发分布式应用微服务的必需组件,方便开发者通过 Spring Clo ...
- Go 1.18泛型的局限性初探
前言 Go 1.18 版本之后正式引入泛型,它被称作类型参数(type parameters),本文初步介绍 Go 中泛型的使用.长期以来 go 都没有泛型的概念,只有接口 interface 偶尔类 ...
- zookeeper面试1-9
1.选举机制 SID:服务器ID.用来唯一标识一台ZooKeeper集群中的机器,每台机器不能重复,和myid一致. ZXID:事务ID.ZXID是一个事务ID,用来标识一次服务器状态的变更.在某一时 ...
- 基础设施即代码(IAC),Zalando Postgres Operator UI 入门
Postgres Operator UI 提供了一个图形界面,方便用户体验数据库即服务.一旦 database 和/或 Kubernetes (K8s) 管理员设置了 operator,其他团队就很容 ...