大家好,我是架构摆渡人,这是流量治理系列的第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 究竟是怎么做到让业务方接入简单?的更多相关文章

  1. 流量治理神器-Sentinel的限流模式,选单机还是集群?

    大家好,架构摆渡人.这是我的第5篇原创文章,还请多多支持. 上篇文章给大家推荐了一些限流的框架,如果说硬要我推荐一款,我会推荐Sentinel,Sentinel的限流模式分为两种,分别是单机模式和集群 ...

  2. 阿里限流神器Sentinel夺命连环 17 问?

    1.前言 这是<spring Cloud 进阶>专栏的第五篇文章,这篇文章介绍一下阿里开源的流量防卫兵Sentinel,一款非常优秀的开源项目,经过近10年的双十一的考验,非常成熟的一款产 ...

  3. Istio 流量治理功能原理与实战

    一.负载均衡算法原理与实战 负载均衡算法(load balancing algorithm),定义了几种基本的流量分发方式,在Istio中共有4种标准负载均衡算法. •Round_Robin: 轮询算 ...

  4. 最小轻量级的Istio来了,仅使用流量治理能力

    Istio 1.0.1作为8月份的版本已经发布,主要修复了1.0版本发布以来发现的一些关键Issue.官网的release note(https://istio.io/about/notes/1.0. ...

  5. idou老师教你学Istio 19 : Istio 流量治理功能原理与实战

    一.负载均衡算法原理与实战 负载均衡算法(load balancing algorithm),定义了几种基本的流量分发方式,在Istio中一共有4种标准负载均衡算法. •Round_Robin: 轮询 ...

  6. Istio流量治理原理之负载均衡

    流量治理是一个非常宽泛的话题,例如: ● 动态修改服务间访问的负载均衡策略,比如根据某个请求特征做会话保持: ● 同一个服务有两个版本在线,将一部分流量切到某个版本上: ● 对服务进行保护,例如限制并 ...

  7. istio流量管理:非侵入式流量治理

    在服务治理中,流量管理是一个广泛的话题,一般情况下,常用的包括: 动态修改服务访问的负载均衡策略,比如根据某个请求特征做会话保持: 同一个服务有多版本管理,将一部分流量切到某个版本上: 对服务进行保护 ...

  8. 限流神器Sentinel,不了解一下吗?

    概述 书接上回:你来说说什么是限流? ,限流的整体概述中,描述了 限流是什么,限流方式和限流的实现.在文章尾部的 分布式限流,没有做过多的介绍,选择了放到这篇文章中.给大伙细细讲解一下 Sentine ...

  9. 快速体验 Sentinel 集群限流功能,只需简单几步

    ️ Pic by Alibaba Tech on Facebook 集群限流 可以限制某个资源调用在集群内的总 QPS,并且可以解决单机流量不均导致总的流控效果不佳的问题,是保障服务稳定性的利器. S ...

随机推荐

  1. C++ - C语言中数组的另一种常用写法(数组大小可变!!!)

    在 C 和 C++ 中,数组在声明过程中,数组名称为 const 指针,不许修改.且数组的大小在声明时被写死,非常不方便. C语言中常用下面代码替代指针. #include <stdio.h&g ...

  2. C语言泛型编程——泛型冒泡排序

    在实际编程中,常常会需要一些方法(函数),比如排序,它们具体实现基本一致,仅仅只有参数类型不同, 那么可不可以有一种通用的函数,不管是什么类型的参数都可以通用呢? 泛型编程:泛型即是指具有在多种数据类 ...

  3. 【译】感谢 Flash 所做的一切

    翻译:疯狂的技术宅来源:Chromium Blog原文标题:So long, and thanks for all the Flash英文原文:https://blog.chromium.org/20 ...

  4. 前端面试题整理——手写flatern摊平数组

    // flatern 是摊平数组 function flat(arr) { const isDeep = arr.some(item => item instanceof Array) if(! ...

  5. Hadoop本地编写的jar包放到集群执行时报错处理

    错误描述: 020-03-24 22:45:23,204 WARN org.apache.hadoop.yarn.server.nodemanager.DefaultContainerExecutor ...

  6. Blazor组件自做二 : 使用JS隔离制作手写签名组件

    Blazor组件自做二 : 使用JS隔离制作手写签名组件 本文相关参考链接 JavaScript 模块中的 JavaScript 隔离 Viewer.js工程 Blazor组件自做一 : 使用JS隔离 ...

  7. SpringCloud Alibaba入门之Nacos(SCA)

    SpringCloud Alibaba Spring Cloud Alibaba 致力于提供微服务开发 的一站式解决方案.此项目包含开发分布式应用微服务的必需组件,方便开发者通过 Spring Clo ...

  8. Go 1.18泛型的局限性初探

    前言 Go 1.18 版本之后正式引入泛型,它被称作类型参数(type parameters),本文初步介绍 Go 中泛型的使用.长期以来 go 都没有泛型的概念,只有接口 interface 偶尔类 ...

  9. zookeeper面试1-9

    1.选举机制 SID:服务器ID.用来唯一标识一台ZooKeeper集群中的机器,每台机器不能重复,和myid一致. ZXID:事务ID.ZXID是一个事务ID,用来标识一次服务器状态的变更.在某一时 ...

  10. 基础设施即代码(IAC),Zalando Postgres Operator UI 入门

    Postgres Operator UI 提供了一个图形界面,方便用户体验数据库即服务.一旦 database 和/或 Kubernetes (K8s) 管理员设置了 operator,其他团队就很容 ...