作者:十眠

布景

微服务的稳定性一直是开发者十分重视的论题。随着事务从单体架构向分布式架构演进以及布置办法的变化,服务之间的依靠联系变得越来越杂乱,事务体系也面临着巨大的高可用挑战。疫情期间,咱们或许都经历过以下的场景:

  • 线上预约购买口罩时瞬间洪峰流量导致体系超出最大负载,load 飙高,用户无法下单;
  • 在线选课时同一时刻提交选课的恳求过多,体系无法响应;
  • 在线办公/教学时一起在线会议的用户过多,会议比较卡;

这些可用性下降的场景会严重影响用户体会,所以咱们需求预先经过一些手段来提前对不稳定的要素进行防护,一起在突发流量的状况下咱们也要具有快速止损的才能。

流控降级 – 保证微服务稳定性重要的一环

影响微服务可用性的要素有十分多,而这些不稳定的场景或许会导致严重后果。咱们从微服务流量的视角来看,能够粗略分为两类常见的场景:

  1. 服务本身流量超越承载才能导致不行用。比方激增流量、批量任务投递导致服务负载飙高,无法正常处理恳求。

流量是十分随机性的、不行预测的。前一秒或许还风平浪静,后一秒或许就呈现流量洪峰了(例如双十一零点的场景)。但是咱们体系的容量总是有限的,假如突但是来的流量超越了体系的承受才能,就或许会导致恳求处理不过来,堆积的恳求处理缓慢,CPU/Load 飙高,最后导致体系溃散。因而,咱们需求针对这种突发的流量来进行约束,在尽或许处理恳求的一起来保证服务不被打垮。

无需编写一行代码,实现任何方法的流量防护能力

  1. 服务因依靠其他不行用服务,导致本身连环不行用。比方咱们的服务或许依靠好几个第三方服务,假设某个付出服务呈现反常,调用十分慢,而调用端又没有有效地进行预防与处理,则调用端的线程池会被占满,影响服务本身正常工作。在分布式体系中,调用联系是网状的、错综杂乱的,某个服务呈现毛病或许会导致级联反响,导致整个链路不行用。

一个服务常常会调用其他模块,或许是另外的一个长途服务、数据库,或许第三方 API 等。例如,付出的时分,或许需求长途调用银联供给的 API;查询某个产品的价格,或许需求进行数据库查询。但是,这个被依靠服务的稳定性是不能保证的。假如依靠的服务呈现了不稳定的状况,恳求的响应时刻变长,那么调用服务的办法的响应时刻也会变长,线程会产生堆积,终究或许耗尽事务本身的线程池,服务本身也变得不行用。现代微服务架构都是分布式的,由十分多的服务组成。不同服务之间彼此调用,组成杂乱的调用链路。以上的问题在链路调用中会产生扩大的作用。杂乱链路上的某一环不稳定,就或许会层层级联,终究导致整个链路都不行用。因而咱们需求对不稳定的服务进行熔断降级,暂时堵截不稳定调用,防止部分不稳定要素导致全体的雪崩

无需编写一行代码,实现任何方法的流量防护能力

MSE 服务管理根据阿里限流降级组件 Sentinel 的稳定性防护才能,以流量为切入点,从流量操控、并发操控、熔断降级、热点防护、体系自适应保护等多个维度来协助保证服务的稳定性,掩盖微服务、云原生网关、Service Mesh 等几大场景。

介绍完流控降级的场景与才能之后,下面讲请出咱们今日要重点介绍的主人公:运行时动态 Enhance 才能。咱们将介绍怎么经过 MSE 服务管理一键完成恣意点位的流控降级,恣意点位包含但不限于 Web、Rpc、SQL、Redis 等访问接口、恣意编写的事务办法、框架的接口等等。

运行时 Enhance 才能 – 一键完成恣意点位的流控降级

怎么在运行时,给恣意指定的办法增加一个流控降级才能呢?下面我将以一个 Demo 为例简略介绍。咱们编写了如下一个事务代码,咱们编写了一个简略的 Spring Boot 使用,其中 a 办法是一个随意编写的内部办法。

@SpringBootApplication
public class AApplication {
    public static void main(String[] args) {
        SpringApplication.run(AApplication.class, args);
    }
    @Api(value = "/", tags = {"进口使用"})
    @RestController
    class AController {
        ...
    @ApiOperation(value = "HTTP 全链路灰度进口", tags = {"进口使用"})
        @GetMapping("/a")
        public String restA(HttpServletRequest request) {
            return a(request);
        }
        private String a(HttpServletRequest request) {
            StringBuilder headerSb = new StringBuilder();
            Enumeration<String> enumeration = request.getHeaderNames();
            while (enumeration.hasMoreElements()) {
                String headerName = enumeration.nextElement();
                Enumeration<String> val = request.getHeaders(headerName);
                while (val.hasMoreElements()) {
                    String headerVal = val.nextElement();
                    headerSb.append(headerName + ":" + headerVal + ",");
                }
            }
            return "A"+SERVICE_TAG+"[" + inetUtils.findFirstNonLoopbackAddress().getHostAddress() + "]" + " -> " +
                    restTemplate.getForObject("http://sc-B/b", String.class);
        }
        ...
    }
}

到目前为止监控是看不到 a 办法的,咱们只能看到 restA 的接口或许说是 GET:/a 的监控数据,而且能够对其装备限流降级规矩。

无需编写一行代码,实现任何方法的流量防护能力

开源的办法咱们需求在代码中增加Sentinel的依靠,而且对com.alibabacloud.mse.demo.AApplication.AController#a 办法装备注解或许编码办法增加 Sentinel 才能

// 注解办法进行埋点,注解办法受 AOP 代理的许多约束
@SentinelResource("com.alibabacloud.mse.demo.AApplication.AController:a")
private String a(HttpServletRequest request) {
    StringBuilder headerSb = new StringBuilder();
    Enumeration<String> enumeration = request.getHeaderNames();
    while (enumeration.hasMoreElements()) {
        String headerName = enumeration.nextElement();
        Enumeration<String> val = request.getHeaders(headerName);
        while (val.hasMoreElements()) {
            String headerVal = val.nextElement();
            headerSb.append(headerName + ":" + headerVal + ",");
        }
    }
    return "A"+SERVICE_TAG+"[" + inetUtils.findFirstNonLoopbackAddress().getHostAddress() + "]" + " -> " +
            restTemplate.getForObject("http://sc-B/b", String.class);
}
// SDK 办法增加流控降级才能,需求侵入事务代码
private String a(HttpServletRequest request) {
    Entry entry = null;
    try {
        entry = SphU.entry("HelloWorld");
        StringBuilder headerSb = new StringBuilder();
        Enumeration<String> enumeration = request.getHeaderNames();
        while (enumeration.hasMoreElements()) {
            String headerName = enumeration.nextElement();
            Enumeration<String> val = request.getHeaders(headerName);
            while (val.hasMoreElements()) {
                String headerVal = val.nextElement();
                headerSb.append(headerName + ":" + headerVal + ",");
            }
        }
        return "A"+SERVICE_TAG+"[" + inetUtils.findFirstNonLoopbackAddress().getHostAddress() + "]" + " -> " +
                restTemplate.getForObject("http://sc-B/b", String.class);
    } catch (BlockException ex) {
      System.err.println("blocked!");
    } finally {
        if (entry != null) {
            entry.exit();
        }
    }
}

需求编码那就天然会有许多的坏处,要增加依靠要改代码,要重新发布,难以做到即上即下…到处都是成本。

那么咱们怎么能够不编写一行代码,就能够做到对 com.alibabacloud.mse.demo.AApplication.AController#a 的限流降级才能呢?

装备运行时白屏化规矩

装备运行时白屏化规矩,并挑选当时使用的自定义埋点类型的接口,并填入类与办法。

无需编写一行代码,实现任何方法的流量防护能力

当然能够看到,咱们白屏化规矩才能不仅仅支撑动态限流降级,还支撑恣意点位的访问日志以及恳求上下文的搜集

无需编写一行代码,实现任何方法的流量防护能力

观察到指定办法的监控数据

咱们在使用管理找到方针使用,在接口监控 > 自定义埋点中看到指定办法com.alibabacloud.mse.demo.AApplication.AController#a 的监控数据

无需编写一行代码,实现任何方法的流量防护能力

装备流控规矩

咱们能够点击接口概览右上角的“新增防护规矩”按钮,增加一条流控规矩:

无需编写一行代码,实现任何方法的流量防护能力

咱们能够装备最简略的 QPS 模式的流控规矩,比方上面的例子即约束该接口每秒单机调用量不超越 1 次。

装备规矩后,稍等片刻即可在监控页面看到限流作用:

无需编写一行代码,实现任何方法的流量防护能力

被拒绝的流量也会回来错误信息。MSE 自带的框架埋点都有默许的流控处理逻辑,如 Web 接口被限流后回来 429 Too Many Requests,DAO 层、java 办法被限流后抛出反常等。

总结

咱们将运行时白屏化才能抽象为如下规矩:WhiteScreenRule = Taget + Action****

无需编写一行代码,实现任何方法的流量防护能力

Target:

  • ResourceTarget: 方针接口,支撑Web、Rpc、SQL 以及恣意的自定义办法
  • WorkloadTarget: 方针实例,能够挑选一切机器或指定机器 IP
  • TrafficCondition: 是否仅针对反常、慢调用、全链路灰度标签

Action:

  • 相关上下文确诊信息的搜集,参数、回来值、线程上下文、Target目标、类加载器信息等
  • 后续链路是否日志打印
  • 进行限流降级
  • 指定流量进行打标染色(规划中)

近期 MSE 将推出根据上述规矩的模型结合动态 Enhance 才能的日志管理,咱们不仅仅有根据动态 Enhance 才能的恣意点位的限流降级,还能够协助咱们洞察全链路流量运行的行为,并做出实时的管理与保护。

无需编写一行代码,实现任何方法的流量防护能力

MSE Sentinel 不仅在阿里内部淘宝、天猫等电商范畴有着广泛的使用,在互联网金融、在线教育、游戏、直播行业和其他大型政央企行业也有着大量的实践。有了针对任何办法都能够做到限流降级的才能后,咱们能够快速赋予恣意一个微服务体系具有流量防护的才能,让咱们有更多的时刻专注于事务的快速发展,关于体系的稳定性就放心地交给 MSE ,让专业的团队做专业的事情。

MSE 云原生网关预付费、MSE 注册装备预付费首购 8折,首购 1年及以上 7 折。点击此处,检查更多详情~