nacos集群
修改端口号(8849)
端口号不一样即可
配置cluster.conf
在nacos的解压目录nacos/的conf目录下,有配置文件cluster.conf,请每行配置成ip:port。(请配置3个或3个以上节点)
导入数据源
使用数据源
连接数据库
Application.properties:
8850和8851
复制修改好的nacos并复制修改conf/application.properties文件中的server.port=8850/8851
其他的保持不变即可
然后依次点击startup.cmd打开
都打开成功后,浏览器打开http://localhost:8849/nacos,用户和密码都是nacos
点击节点管理
服务雪崩
由于服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成灾难性的严重后果,这就是 服务故障的 “雪崩效应” 。
那么,服务熔断和服务降级就可以视为解决服务雪崩的手段之一。
熔断
目的: 防止服务雪崩
如何实现的熔断:
熔断存在的基础服务之间的调用使用的组件是openfeign
调用的时候下游的服务如果响应慢或者服务宕机熔断:
@FeignClient(fallback=””)
直接走的是fallback中的代码 不再去访问下游 牺牲局部保整体
Application.properties 中 Openfeign支持熔断
feign.sentinel.enabled=true
在互联网系统中,当下游服务因访问压力过大而响应变慢或失败,上游服务为了保护系统整 体的可用性,可以暂时切断对下游服务的调用。这种牺牲局部,保全整体的措施就叫做熔断。
服务熔断一般有三种状态:
熔断关闭状态(Closed)
a->b ->c
服务没有故障时,熔断器所处的状态,对调用方的调用不做任何限制
熔断开启状态(Open)
a->b->c(x)
a->b
后续对该服务接口的调用不再经过网络,直接执行本地的fallback方法
半熔断状态(Half-Open)
c
尝试恢复服务调用,允许有限的流量调用该服务,并监控调用成功率。如果成功率达到预 期,则说明服务已恢复,进入熔断关闭状态;如果成功率仍旧很低,则重新进入熔断关闭状态
降级
降级其实就是为服务提供一个备用方案,一旦服务无法正常调用,就使用备用方案
一 Sentinel入门
介绍 · alibaba/Sentinel Wiki · GitHub
Sentinel (分布式系统的流量防卫兵) 是阿里开源的一套用于服务容错的综合性解决方案。它以流量为切入点, 从流量控制、熔断降级、系统负载保护等多个维度来保护服务的稳定性。
Sentinel 具有以下特征:
丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景, 例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
完备的实时监控:Sentinel 提供了实时的监控功能。通过控制台可以看到接入应用的单台机器秒级数据, 甚至 500 台以下规模的集群的汇总运行情况。
广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块, 例如与 Spring Cloud、Dubbo、gRPC 的整合。只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口快
速地定制逻辑。例如定制规则管理、适配动态数据源等
Sentinel 分为两个部分:
核心库(Java 客户端)不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo /Spring Cloud 等框架也有较好的支持。
控制台(Dashboard)基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。
二 微服务集成Sentinel
为微服务集成Sentinel非常简单, 只需要加入Sentinel的依赖即可
在pom.xml中加入下面依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
编写消费者的controller并调用
代码:
@RestController
@RequestMapping("/tab-product")
public class TabProductController {
@Resource
private ITabProductService productService;
// 查询所有的商品的信息
@GetMapping
public List<TabProduct> findAll(){
return productService.list();
}
}
三 安装Sentinel控制台
Sentinel 提供一个轻量级的控制台, 它提供机器发现、单机资源实时监控以及规则管理等功能
sentinel的版本一定要和组件的版本对应一致,否则出现会在一定程序出现不可预知的错误,当前的环境需要1.8.1版本的sentinel
1 下载jar包,解压到文件夹
Release v1.8.1 · alibaba/Sentinel · GitHub
2 启动控制台
# 直接使用jar命令启动项目(控制台本身是一个SpringBoot项目)
复制命令后在jar包文件夹cmd使用(避免中文或符号路径)
使用localhost:8888端口即可成功
密码用户名都是sentinel
java -Dserver.port=8888 -Dcsp.sentinel.dashboard.server=localhost:8888 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.1.jar
3 修改 product ,在里面加入有关控制台的配置
spring.cloud.sentinel.transport.port=9999
# 该端口号为sentinal于服务之间的交互 随便写只要不被占用
spring.cloud.sentinel.transport.dashboard=localhost:8888
#sentinal服务所在的地址和端口号
限流
流量控制,其原理是监控应用流量的QPS(每秒查询率) 或并发线程数等指标,当达到指定的阈值时对流量进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性。
新增流控规则
资源名:唯一名称,默认是请求路径,可自定义
针对来源:指定对哪个微服务进行限流,默认指default,意思是不区分来源,全部限制
阈值类型/单机阈值:
l QPS(每秒请求数量): 当调用该接口的QPS达到阈值的时候,进行限流
l 线程数:当调用该接口的线程数达到阈值的时候,进行限流
没有特殊处理情况下资源名为路径以/开头,阈值自设
超过阈值,限流成功
自定义限流的异常处理
BlockException异常统一处理
springwebmvc接口资源限流入口在HandlerInterceptor的实现类AbstractSentinelInterceptor的preHandle方法中,对异常的处理是BlockExceptionHandler的实现类
自定义BlockExceptionHandler 的实现类统一处理BlockException
Resout为一个自建的返回类
ObjectMapper App中写入一个bean
@Bean
public ObjectMapper getObjectMapper(){
return new ObjectMapper();
}
新建一个exception包,下建一个类
package com.example.exception;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.example.util.Resout;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component//代表将一个类作为一个bean注册到容器中
public class MyexceptionHandler implements BlockExceptionHandler {
@Resource
private ObjectMapper objectMapper;
@Override
public void handle(HttpServletRequest httpServletRequest, HttpServletResponse response, BlockException e) throws Exception {
Resout r = null;
if (e instanceof FlowException) {
r = new Resout(100, "限流了", "");
}
//返回json数据
response.setStatus(500);
response.setCharacterEncoding("utf-8");
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
objectMapper.writeValue(response.getWriter(), r);
}
}
返回一个信息
sentinel共有三种流控模式
分别是:
l 直接(默认):接口达到限流条件时,开启限流
l 关联:当关联的资源达到限流条件时,开启限流 [适合做应用让步]
l 链路:当从某个接口过来的资源达到限流条件时,开启限流
直接流控模式
直接流控模式是最简单的模式,当指定的接口达到限流条件时开启限流。上面案例使用的就是直接流控模式。
关联流控模式 (隔山打牛)
关联流控模式指的是,当指定接口关联的接口达到限流条件时,开启对指定接口开启限流。
第1步:写一个Controler,两个路径信息。
配置限流规则, 将流控模式设置为关联,关联资源设置为的 /meg1。
同时访问 获得测试结果
链路流控模式
链路流控模式指的是,当从某个接口过来的资源达到限流条件时,开启限流。
注解:@SentinelResource
我们可以对某一个方法进行限流控制,无论是谁在何处调用了它,这里需要使用到@SentinelResource
,一旦方法被标注,那么就会进行监控@SentinelResource
,一旦方法被标注,那么就会进行监控。
第1步: 编写一个service,在里面添加一个方法message
@Service
public class SentinelService {
@SentinelResource("msg")
public void msgResourse(){
System.out.println("-------------");
}
第2步: 在Controller中声明方法
package com.example.controler;
import com.example.service.SentinelService;
import com.example.util.Resout;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
public class LianLuControler {
@Resource
private SentinelService service;
@GetMapping("lianlu1")
public Resout aaa1(){
service.msgResourse();
return Resout.success("");
}
@GetMapping("lianlu2")
public Resout aaa2(){
service.msgResourse();
return Resout.success("");
}
}
第3步: 禁止收敛URL的入口 context
在application.properties中添加:
spring.cloud.sentinel.web-context-unify=false
#用于控制是否收敛context。将其配置为 false 即可根据不同的URL 进行链路限流。
第4步: 控制台配置限流规则
第5步: 分别通过 message1 和 message2 访问, 发现message2 没问题, message1的被限流了