• 微服务是什么?它的优缺点有哪些?
  • Spring Boot简介
  • Spring Boot项目搭建步骤(超详细)
  • 使用Eureka编写服务提供者
  • 使用Eureka编写服务消费者
  • Eureka注册中心开启密码认证
  • Spring Cloud使用Eureka集群搭建实现高可用服务注册中心
  • Eureka自我保护模式和InstanceID的配置
  • Eureka开发时快速移除失效服务
  • Eureka开发时快速移除失效服务
  • Spring Cloud Ribbon(负载均衡器)介绍及使用
  • Spring Cloud Ribbon结合RestTemplate实现负载均衡
  • Spring Cloud Ribbon配置详解
  • Spring Cloud使用Feign调用服务接口
  • Spring Cloud Feign的自定义配置及使用
  • Spring Cloud Hystrix缓存与合并请求
  • Spring Cloud Zuul网关的介绍及使用
  • Spring Cloud Zuul过滤器介绍及使用(传递数据、拦截请求和异常处理)
  • Spring Cloud使用Zuul实现容错回退功能
  • Spring Cloud Zuul请求响应信息输出
  • Spring Cloud实现Zuul自带的Debug功能
  • Spring Cloud Gateway整合Eureka路由转发
  • Spring Cloud Gateway的常用路由断言工厂
  • Spring Cloud Gateway过滤器工厂的使用
  • Spring Cloud Gateway全局过滤器(GlobalFilter)
  • Smconf(分布式配置管理框架)概述
  • Apollo(分布式配置中心)核心概念及核心功能介绍
  • Apollo本地部署详细步骤
  • Apollo Portal管理后台的使用
  • Apollo高可用设计分析
  • Spring Cloud使用Sleuth在应用中进行日志跟踪
  • Spring Cloud Sleuth与ELK(日志分析系统)配合使用
  • Spring Cloud整合Zipkin进行服务跟踪
  • JWT(Json Web Token)是什么?
  • Spring Cloud基于JWT创建统一的认证服务
  • Zuul中传递Token到路由的服务中
  • Spring Boot Admin的介绍及使用
  • Swagger是什么?Swagger怎么用?
  • 使用Zuul聚合多个微服务的Swagger文档
  • 微服务架构下如何获取用户信息并认证?
  • 服务降级是什么?Spring Cloud如何实现?
  • Guava Cache本地缓存介绍及使用
  • 防止缓存雪崩的方案
  • 服务降级是什么?Spring Cloud如何实现?

    当访问量剧增,服务出现问题时,需要做一些处理,比如服务降级。服务降级就是将某些服务停掉或者不进行业务处理,释放资源来维持主要服务的功能。

    某电商网站在搞活动时,活动期间压力太大,如果再进行下去,整个系统有可能挂掉,这个时候可以释放掉一些资源,将一些不那么重要的服务采取降级措施,比如登录、注册。登录服务停掉之后就不会有更多的用户抢购,同时释放了一些资源,登录、注册服务就算停掉了也不影响商品抢购。

    服务降级有很多种方式,最好的方式就是利用 Docker 来实现。当需要对某个服务进行降级时,直接将这个服务所有的容器停掉,需要恢复的时候重新启动就可以了。

    还有就是在 API 网关层进行处理,当某个服务被降级了,前端过来的请求就直接拒绝掉,不往内部服务转发,将流量挡回去。

    在 Zuul 中对服务进行动态降级,结合我们的配置中心来做。

    定义 Apollo 配置类,存储需要降级的服务信息见如下代码。

    1. @Data
    2. @Configuration
    3. public class BasicConf {
    4. // 降级的服务 ID,多个用逗号分隔
    5. @Value("${downGradeServiceStr:default}")
    6. private String downGradeServiceStr;
    7. }

    编写过滤器来执行降级逻辑,见如下代码。

    1. public class DownGradeFilter extends ZuulFilter {
    2. @Autowired
    3. private BasicConf basicConf;
    4. public DownGradeFilter() {
    5. super();
    6. }
    7. @Override
    8. public boolean shouldFilter() {
    9. RequestContext ctx = RequestContext.getCurrentContext();
    10. Object success = ctx.get("isSuccess");
    11. return success == null ? true : Boolean.parseBoolean(success.toString());
    12. }
    13. @Override
    14. public String filterType() {
    15. return "route";
    16. }
    17. @Override
    18. public int filterOrder() {
    19. return 4;
    20. }
    21. @Override
    22. public Object run() {
    23. RequestContext ctx = RequestContext.getCurrentContext();
    24. Object serviceId = ctx.get("serviceId");
    25. if (serviceId != null && basicConf != null) {
    26. List<String> serviceIds = Arrays.asList(basicConf.getDownGradeServiceStr().split(","));
    27. if (serviceIds.contains(serviceId.toString())) {
    28. ctx.setSendZuulResponse(false);
    29. ctx.set("isSuccess", false);
    30. ResponseData data = ResponseData.fail("服务降级中", ResponseCode.DOWNGRADE.getCode());
    31. ctx.setResponseBody(JsonUtils.toJson(data));
    32. ctx.getResponse().setContentType("application/json; charset=utf-8");
    33. return null;
    34. }
    35. }
    36. return null;
    37. }
    38. }

    主要逻辑在 run 方法中,通过 RequestContext 获取即将路由的服务 ID,通过配置信息获取降级的服务信息,如果当前路由的服务在其中,就直接拒绝,返回对应的信息让客户端做对应的处理。

    当需要降级的时候,直接在 Apollo 的后台改一下配置就可以马上生效,当然也可以做成自动的,比如监控某些指标,流量、负载等,当达到某些指标后就自动触发降级。