1.高并发带来的问题
在微服务架构中,我们将业务拆成一个个的服务,服务与服务之间可以相互调用,但是由于网络原因或者自身原因,并不能保证服务的100%可用,如果单个服务出现问题,调用这个服务就会出现网络延迟,此时若有大量的网路涌入,会形成任务堆积,最终导致服务瘫痪.
1.1利用jmeter.apache压测工具,対请求进行压力测试
结论: 此时会发现如果当其中一个url囤积了大量请求,会导致调用另一个url访问的方法出现克顿延迟问题,这就是服务雪崩的雏形
2.服务雪崩效应
在分布式系统中,由于网络原因或自身的原因,服务一般无法保证100%可用.如果一个服务出现了问题,调用这个服务就会出现线程阻塞的情况,此时若有大量的请求涌入,就会出现多条线程阻塞等待,进而导致服务瘫痪. 由于服务与服务之间的依赖性,故障就会传播,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的**雪崩效应**
雪崩发生的原因多种多样,有不合理的容量设计,或者是高并发下某一个方法相应变慢,亦或是某台机器的资源耗尽.我们 无法完全杜绝雪崩源头的发生,只有做好足够的容错,保证在一个服务发生问题,不会影响到其他服务的正常运行. 也就是**“雪落而不雪崩”**
3.常见容错方案
要防止雪崩的扩散,我们就要做好服务的容错,容错说白了就是保护自己不被猪队友拖垮的一些措施,下面介绍常见的容错服务思路和组件
3.1常见的容错思路
常见的容错思路有: 隔离. 超时. 熔断. 限流,降级 这几种
3.2隔离
它是指将系统按照一定的原则划分为若干个方法模块,各个模块之间的相对独立,无强依赖, 当有故障发生时,能将问题和影响隔离在某个模块内部,而不扩散风险,不波及其他模块,不影响整体的系统服务,常见的隔离方案有: 线程池隔离和信号量隔离
3.3超时,限流,熔断,降级
3.4针对微服务来源 全部限流
3.5针对资源,访问来源
3.6热点数据 写道下面的规则中了
5.微服务集成Sentinel
**为微服务集成Sentinel非常简单, 只需要加入Sentinel的依赖即可 **
1 在pom.xml中加入下面依赖
<!--引入sentinal的依赖jar文件-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
2 启动控制台 cmd
java -jar sentinel-dashboard-1.7.0.jar
# 直接使用jar命令启动项目(控制台本身是一个SpringBoot项目)
java -Dserver.port=8888 -Dcsp.sentinel.dashboard.server=localhost:8888 -
Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.7.0.jar
3 修改 shop-order ,在里面加入有关控制台的配置
spring:
cloud:
sentinel:
transport:
port: 9999 # 该端口号为sentinal于服务之间的交互 随便写只要不被占用
dashboard: localhost:8888 #sentinal服务所在的地址和端口号
第4步: 通过浏览器访问localhost:8080 进入控制台 ( 默认用户名密码是 sentinel/sentinel )
1. Sentinel的概念和功能
资源:资源就是sentinel要保护的内容.
规则:规则*以什么样的方式来保护你的资源.
Sentinel的主要功能就是容错,主要体现为下面这三个:
**流量控制 **
流量控制在网络传输中是一个常用的概念,它用于调整网络包的数据.任意时间到来的请求往往是随机不可控制的,而系统的处理能力是有限的,我们需要根据系统的处理能力对流量进行控制 Sentinel作为一个调配器,**可以根据需要把随机的请求调整成时候的形状**
**熔断降级 **
当检测到调用链路中某个资源出现不稳定的表现,列如:请求相应时间长,或者异常比例升高的时候,则对这个资源的调用进行限制,让请求快速失败,避免影响到其他的资源而导致级联故障,Sentinel对这个问题采用了两种手段
-
通过并发线程数进行限制
-
Sentinel 通过限制资源并发线程的数量,来减少不稳定资源对其它资源的影响。当某个资源出现不稳定的情况下,例如响应时间变长,对资源的直接影响就是会造成线程数的逐步堆积。当线程数在特定资源上堆积到一定的数量之后,对该资源的新请求就会被拒绝。堆积的线程完成任务后才开始继续接收请求。
-
通过响应时间对资源进行降级
-
除了对并发线程数进行控制以外,Sentinel 还可以通过响应时间来快速降级不稳定的资源。当依赖的资源出现响应时间过长后,所有对该资源的访问都会被直接拒绝,直到过了指定的时间窗口之后才重新恢复。
-
系统负载保护 《了解》
-
Sentinel 同时提供系统维度的自适应保护能力。当系统负载较高的时候,如果还持续让请求进入可能会导致系统崩溃,无法响应。在集群环境下,会把本应这台机器承载的流量转发到其它的机器上去。如果这个时候其它的机器也处在一个边缘状态的时候,Sentinel 提供了对应的保护机制,让系统的入口流量和系统的负载达到一个平衡,保证系统在能力范围之内处理最多的请求。
总之一句话: 我们需要做的事情,就是在Sentinel的资源上配置各种各样的规则,来实现各种容错的功能
3. Sentinel规则
3.1流控规则
-
流量控制,其原理是监控应用流量的QPS(每秒查询率)
或并发线程数等指标,当达到指定的阈值时对流量进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性。 第1步:
点击簇点链路,我们就可以看到访问过的接口地址,然后点击对应的流控按钮,进入流控规则配置页面。新增流控规则界面如下:
**资源名:**唯一名称,默认是请求路径,可自定义
**针对来源:**指定对哪个微服务进行限流,默认指default,意思是不区分来源,全部限制
阈值类型/单机阈值: -
QPS(每秒请求数量): 当调用该接口的QPS达到阈值的时候,进行限流
-
线程数:当调用该接口的线程数达到阈值的时候,进行限流
**是否集群:**暂不需要集群
接下来我们以QPS为例来研究限流规则的配置
3.2简单配置
我们先做一个简单配置,设置阈值类型为QPS,单机阈值为3。即每秒请求量大于3的时候开始限流
接下来,在流控规则页面就可以看到这个配置
然后快速访问 /order/message1 接口,观察效果。此时发现,当QPS > 3的时候,服务就不能正常响应,而是返回Blocked by Sentinel (flflow limiting)结果。
3.3配置流控模式
点击上面设置流控规则的编辑按钮,然后在编辑页面点击高级选项,会看到有流控模式一栏。
sentinel共有三种流控模式,分别是:
- 直接(默认):接口达到限流条件时,开启限流
- 关联:当关联的资源达到限流条件时,开启限流 [适合做应用让步]
- 链路:当从某个接口过来的资源达到限流条件时,开启限流
下面呢分别演示三种模式: - 直接流控模式
直接流控模式是最简单的模式,当指定的接口达到限流条件时开启限流。上面案例使用的就是直接流控模式。 - 关联流控模式
关联流控模式指的是,当指定接口关联的接口达到限流条件时,开启对指定接口开启限流。
第1步:配置限流规则, 将流控模式设置为关联,关联资源设置为的 /order/message2。
第4步:访问/order/message1,会发现已经被限流
链路流控模式(了解)
链路流控模式指的是,当从某个接口过来的资源达到限流条件时,开启限流。它的功能有点类似于针对来源配置项,区别在于:针对来源是针对上级微服务,而链路流控是针对上级接口,也就是说它的粒度更细。
1.第1步: 编写一个service,在里面添加一个方法message
@Service
public class OrderServiceImpl3 {
@SentinelResource("message")
public void message() {
System.out.println("message");
}
}
2.第2步: 在Controller中声明两个方法,分别调用service中的方法m
@RestController
@Slf4j
public class OrderController3 {
@Autowired
private OrderServiceImpl3 orderServiceImpl3;
@RequestMapping("/order/message1")
public String message1() {
orderServiceImpl3.message();
return "message1";
}
@RequestMapping("/order/message2")
public String message2() {
orderServiceImpl3.message();
return "message2";
}
}
3.第3步: 禁止收敛URL的入口 context
从1.6.3 版本开始,Sentinel Web fifilter默认收敛所有URL的入口context,因此链路限流不生效。
1.7.0 版本开始(对应SCA的2.1.1.RELEASE),官方在CommonFilter 引入了
WEB_CONTEXT_UNIFY 参数,用于控制是否收敛context。将其配置为 false 即可根据不同的
URL 进行链路限流。
SCA 2.1.1.RELEASE之后的版本,可以通过配置spring.cloud.sentinel.web-context-unify=false即
可关闭收敛
我们当前使用的版本是SpringCloud Alibaba 2.1.0.RELEASE,无法实现链路限流。
目前官方还未发布SCA 2.1.2.RELEASE,所以我们只能使用2.1.1.RELEASE,需要写代码的形式实
现
(1) 暂时将SpringCloud Alibaba的版本(父类)调整为2.1.1.RELEASE
<spring-cloud-alibaba.version>2.1.1.RELEASE</spring-cloud-alibaba.version>
(2) 配置文件中关闭sentinel的CommonFilter实例化
spring:
cloud:
sentinel:
filter:
enabled: false
(3) 添加一个配置类,自己构建CommonFilter实例
package com.ykq.config;
import com.alibaba.csp.sentinel.adapter.servlet.CommonFilter;
import org.springframework.boot.web.servlet.<