什么是服务雪崩

在微服务架构中,根据业务来拆分成一个个的服务,服务与服务之间可以通过HTTP/RPC相互调用,在SpringCloud 中可以用RestTemplate + LoadBalanceclientFeign来调用。为了保证其高可用,单个服务通常会集群部署。由于网络原因或者自身的原因,服务并不能保证100%可用,如果单个服务出现问题,调用这个服务就会出现线程阻塞,此时若有大量的请求涌入,Servlet容器的线程资源会被消耗完毕,导致服务瘫痪。服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的“雪崩”效应。为了解决这个问题,业界提出了 熔断器模型

阿里巴巴开源了Sentinel组件,实现了熔断器模式,Spring Cloud对这一组件进行了整合。在微服务架构中,一个请求需要调用多个服务是非常常见的
image.png
较底层的服务如果出现故障,会导致连锁故障。当对特定的服务的调用的不可用达到一个阀值熔断器将会被打开
image.png
熔断器打开后,为了避免连锁故障,通过 fallback 方法可以直接返回一个固定值。

什么是 Sentinel

Sentinel 具有以下特征:

  • 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
  • 完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
  • 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Apache Dubbo、gRPC、Quarkus 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。同时 Sentinel 提供 Java/Go/C++ 等多语言的原生实现。
  • 完善的 SPI 扩展机制:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。

    Sentinel 的主要特性

    image.png

    Sentinel 的开源生态

    image.png

    Sentinel 分为两个部分

  • 核心库(Java 客户端)不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。

  • 控制台(Dashboard)基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。

    Sentinel 控制台

    概述

    Sentinel 提供一个轻量级的开源控制台,它提供机器发现以及健康情况管理、监控(单机和集群),规则管理和推送的功能。这里,我们将会详细讲述如何通过简单的步骤就可以使用这些功能。

接下来,我们将会逐一介绍如何整合 Sentinel 核心库和 Dashboard,让它发挥最大的作用。同时我们也在阿里云上提供企业级的 Sentinel 服务:AHAS Sentinel 控制台,您只需要几个简单的步骤,就能最直观地看到控制台如何实现这些功能,并体验多样化的监控及全自动托管的集群流控能力。

Sentinel 控制台包含如下功能:

  • 查看机器列表以及健康情况:收集 Sentinel 客户端发送的心跳包,用于判断机器是否在线。
  • 监控 (单机和集群聚合):通过 Sentinel 客户端暴露的监控 API,定期拉取并且聚合应用监控信息,最终可以实现秒级的实时监控。
  • 规则管理和推送:统一管理推送规则。
  • 鉴权:生产环境中鉴权非常重要。这里每个开发者需要根据自己的实际情况进行定制。

    获取

    您可以从 release 页面 下载最新版本的控制台 jar 包。
    您也可以从最新版本的源码自行构建 Sentinel 控制台:

  • 下载 控制台 工程

  • 使用以下命令将代码打包成一个 fat jar: mvn clean package

    启动

    注意:启动 Sentinel 控制台需要 JDK 版本为 1.8 及以上版本。
    1. java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar
    其中 -Dserver.port=8080 用于指定 Sentinel 控制台端口为 8080。
    从 Sentinel 1.6.0 起,Sentinel 控制台引入基本的登录功能,默认用户名和密码都是 sentinel。可以参考 鉴权模块文档 配置用户名和密码。
    注:若您的应用为 Spring Boot 或 Spring Cloud 应用,您可以通过 Spring 配置文件来指定配置,详情请参考 Spring Cloud Alibaba Sentinel 文档

将下载的 jar 包上传服务器执行
image.png

[root@deployment-vervices sentinel]# pwd
/usr/local/sentinel
[root@deployment-vervices sentinel]# java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.4.jar

image.png
启动完成后访问
账号/密码: sentinel/sentinel
image.png
进入控制台
image.png

Sentinel 客户端接入控制台

pom

客户端需要引入 Transport 模块来与 Sentinel 控制台进行通信。您可以通过 pom.xml 引入 JAR 包:
hello-spring-cloud-alibaba-nacos-consumer项目加入依赖包,早期版本 groupId 是 org.springframework.cloud

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

application

修改 Nacos 服务里的nacos-consumer-config.yaml配置文件
image.png
配置内容如下:

spring:
  application:
    # 服务名
    name: nacos-consumer
  cloud:
    nacos:
      discovery:
        # 服务注册中心
        server-addr: 192.168.3.192:8848
    # 熔断限流
    sentinel:
      transport:
        dashboard: 192.168.3.192:8080
    loadbalancer:
      ribbon:
        enabled: false

# 开启 Feign 对 Sentinel 的支持
feign:
  sentinel:
    enabled: true

server:
  # 服务端口
  port: 9091

management:
  # 端点检查(健康检查)
  endpoints:
    web:
      exposure:
        include: "*"
  endpoint:
    health:
      show-details: always

user:
  name: "1111造门炭治郎2222"

创建服务熔断类

package com.funtl.hello.spring.cloud.alibaba.nacos.consumer.service.fallback;

import com.funtl.hello.spring.cloud.alibaba.nacos.consumer.service.EchoService;
import org.springframework.stereotype.Component;

@Component
public class EchoServiceFallback implements EchoService {
    @Override
    public String echo(String message) {
        return "你的网络有问题";
    }

    @Override
    public String lb() {
        return "请联系管理员";
    }
}

修改服务接口,加上fallback = EchoServiceFallback.class

package com.funtl.hello.spring.cloud.alibaba.nacos.consumer.service;

import com.funtl.hello.spring.cloud.alibaba.nacos.consumer.service.fallback.EchoServiceFallback;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

@FeignClient(value = "nacos-provider", fallback = EchoServiceFallback.class)
public interface EchoService {

    @GetMapping(value = "/echo/{message}")
    String echo(@PathVariable("message") String message);

    @GetMapping(value = "/lb")
    public String lb();
}

访问:[http://192.168.3.191:9091/feign/echo](http://192.168.3.191:9091/feign/echo)能正常访问
image.png
现在我们停掉所有的服务提供者再访问:
image.png
发现已成功熔断
image.png