SpringCloud-Alibaba
SpringCloud-Alibaba
概述
Spring Cloud Alibaba致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用微服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。
依托 Spring Cloud Alibaba,您只需要添加一些注解和少量配置
,就可以将 Spring Cloud 应用接入阿里微服务解决方案,通过阿里中间件来迅速搭建分布式应用系统。
简单来说:就是在以前的微服务搭建中,如果使用SpringCloudAlibaba,来替代以前的某些产品,那么开发SpringCloud应用会变得更加简单。
主要功能
- 服务限流降级:默认支持 WebServlet、WebFlux, OpenFeign、RestTemplate、Spring Cloud Gateway, Zuul, Dubbo 和 RocketMQ 限流降级功能的接入,可以在运行时通过控制台实时修改限流降级规则,还支持查看限流降级 Metrics 监控。
- 服务注册与发现:适配 Spring Cloud 服务注册与发现标准,默认集成了 Ribbon 的支持。
- 分布式配置管理:支持分布式系统中的外部化配置,配置更改时自动刷新。
- 消息驱动能力:基于 Spring Cloud Stream 为微服务应用构建消息驱动能力。
- 分布式事务:使用 @GlobalTransactional 注解, 高效并且对业务零侵入地解决分布式事务问题。
- 阿里云对象存储:阿里云提供的海量、安全、低成本、高可靠的云存储服务。支持在任何应用、任何时间、任何地点存储和访问任意类型的数据。
- 分布式任务调度:提供秒级、精准、高可靠、高可用的定时(基于 Cron 表达式)任务调度服务。同时提供分布式的任务执行模型,如网格任务。网格任务支持海量子任务均匀分配到所有 Worker(schedulerx-client)上执行。
- 阿里云短信服务:覆盖全球的短信服务,友好、高效、智能的互联化通讯能力,帮助企业迅速搭建客户触达通道。
主要组件
Sentinel:把流量作为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
Nacos:一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。
RocketMQ:一款开源的分布式消息系统,基于高可用分布式集群技术,提供低延时的、高可靠的消息发布与订阅服务。
Dubbo:Apache Dubbo™ 是一款高性能 Java RPC 框架。
Seata:阿里巴巴开源产品,一个易于使用的高性能微服务分布式事务解决方案。
Alibaba Cloud OSS: 阿里云对象存储服务(Object Storage Service,简称 OSS),是阿里云提供的海量、安全、低成本、高可靠的云存储服务。您可以在任何应用、任何时间、任何地点存储和访问任意类型的数据。
Alibaba Cloud SchedulerX: 阿里中间件团队开发的一款分布式任务调度产品,提供秒级、精准、高可靠、高可用的定时(基于 Cron 表达式)任务调度服务。
Alibaba Cloud SMS: 覆盖全球的短信服务,友好、高效、智能的互联化通讯能力,帮助企业迅速搭建客户触达通道。
如何使用
只需要在SpringCloud的父项目中引入以下依赖即可
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.5.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
在接下来的子项目中根据需求添加依赖即可
Nacos
概述
Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。
Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。 Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。
简单来说:Nacos就是注册中心+配置中心的组合
,就是利用Nacos来代替之前学习的Eureka来做注册中心,代替SpringCloudConfig来做配置中心。
Nacos中文文档:
https://nacos.io/zh-cn/docs/what-is-nacos.html
各大注册中心的比较
CAP原则:指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)。CAP 原则指的是,这三个要素最多只能同时实现两点,不可能三者兼顾。P原则是必须满足的,即自能又两种原则 CP或者 AP
CP原则:放弃了系统的高可用性,但保证了数据准确唯一
AP原则:维护了系统的高可用,但是得到的数据可能有缺陷,不唯一。
由上图可知Nacos同时支持了CP或者AP原则,对于两个原则,它是可变的,我们只需要启动发送一个命令即可切换(默认是AP)
curl -X PUT 'nacos服务ip或者主机域名:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=CP'
CP和AP切换原则:
一般来说:
如果不需要存储服务级别的信息且服务实例是通过nacos-client注册,并能够保持心跳上报,那么就可以选择AP模式。当前主流的服务如Spring cloud和Dubbo服务 ,都适用于AP模式,AP模式为了服务的可用性而减弱了一致性,因此AP模式下只支持注册临时实例。
如果需要在服务级别编辑或者存储配置信息,那么CP是必须的,K8S服务和DNS服务则适用于CP模式
CP模式下则支持注册持久化实例,此时则是以Raft协议为集群运行模式,该模式下注册实例之前必须先注册服务,如果服务不存在,则会返回错误。
Nacos下载
所有版本下载地址:https://github.com/alibaba/nacos/releases
Nacos-server2.0.1-windows版本下载地址:https://github.com/alibaba/nacos/releases/download/2.0.1/nacos-server-2.0.1.zip
Nacos-server2.0.1-linux版本下载地址:https://github.com/alibaba/nacos/releases/download/2.0.1/nacos-server-2.0.1.tar.gz
Nacos-server1.4.2-windows版本下载地址:https://github.com/alibaba/nacos/releases/download/1.4.2/nacos-server-1.4.2.zip
Nacos-server1.4.2-linux版本下载地址:https://github.com/alibaba/nacos/releases/download/1.4.2/nacos-server-1.4.2.tar.gz
安装与启动
安装:将下载的压缩包解压即可
启动:
-
修改解压目录的nacos下的config目录下的 application.yaml,将数据库的注释打开,如下
-
根据配置文件中的数据库名称建立数据库,默认叫nacos,linux有所不同,字符编码utf8 ,排序规则utf8_general_ci
-
将解压目录的nacos下的config目录下的nacos-mysql.sql的数据库脚本放到建立的数据中执行。
-
在nacos启动目录下的bin目录下,修改配置文件windows修改startup.cmd,linux修改startup.sh
# windows 将文件中的 set MODE="cluster" 改为 set MODE="standalone" # linux 将文件中的 export MODE="cluster" 改为 export MODE="standalone"
-
执行启动文件windows 启动startup.cmd linux启动 startup.sh
注意
默认登录用户名和密码都是 nacos
服务注册与发现
微服务父项目搭建参考:https://www.cnblogs.com/Rampant/p/14770855.html
微服务提供者的注册
-
创建新模块 nacos-provider-9001
-
导入pom.xml依赖
<dependencies> <!--Nacos 服务注册的依赖--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!--spring-boot-web 模块 常用的3个--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!--热部署插件--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <!--测试插件--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-test</artifactId> <scope>test</scope> </dependency> <!--lombok 依赖--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies>
-
配置application.yaml
server: port: 9001 # 端口号 spring: application: name: cloud-alibaba-provider # 微服务名称 cloud: nacos: discovery: server-addr: 127.0.0.1:8848 # 连接的注册中心 management: endpoints: web: exposure: include: '*' #暴露端口
-
主启动类
package com.wyx.cloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @SpringBootApplication @EnableDiscoveryClient public class NacosProviderMain9001 { public static void main(String[] args) { SpringApplication.run(NacosProviderMain9001.class,args); } }
-
业务类
package com.wyx.cloud.controller; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; @RestController public class ProviderController { @Value("${server.port}") private String serverPort; @GetMapping("/provider/{id}") public String provider(@PathVariable String id){ return "使用Nacos服务注册中心,当前服务端口: "+serverPort+"\t"+"查询参数:"+id; } }
启动测试,访问:http://localhost:9001/provider/1
-
为了实现后面的负载均衡,我们在用相同的步骤搭建一个9002端口的服务
微服务消费者的注册
-
创建模块nacos-consumer-80
-
添加依赖
<dependencies> <!--Nacos 服务注册的依赖--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!--spring-boot-web 模块 常用的3个--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!--热部署插件--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <!--测试插件--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-test</artifactId> <scope>test</scope> </dependency> <!--lombok 依赖--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies>
-
修改yaml
server: port: 80 # 端口号 spring: application: name: cloud-alibaba-consumer # 微服务名称 cloud: nacos: discovery: server-addr: 127.0.0.1:8848 # 连接的注册中心 service-url: nacos-service: http://cloud-alibaba-provider #将微服务提供者的名字放入配置文件,后面读取即可
-
主启动类
package com.wyx.cloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class NacosConsumerMain80 { public static void main(String[] args) { SpringApplication.run(NacosConsumerMain80.class,args); } }
-
业务类
RestTemplate注入
package com.wyx.cloud.config; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate; @Configuration public class RestTemplateConfig { @Bean @LoadBalanced public RestTemplate restTemplate(){ return new RestTemplate(); } }
服务调用
package com.wyx.cloud.controller; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; import javax.annotation.Resource; @RestController public class ConsumerController { @Value("${service-url.nacos-service}") private String serviceUrl; @Resource RestTemplate restTemplate; @GetMapping("/consumer/{id}") public String getConsumer(@PathVariable String id){ return restTemplate.getForObject(serviceUrl+"/provider/"+id,String.class); } }
负载均衡
概述
对于Nacos服务注册中心,天生集成了 ribbon
做负载均衡,
使用Ribbon做负载均衡,就是它默认给我们写了很多负载均衡类
1、随机策略——RandomRule
2、轮询策略——RoundRobinRule
注:Ribbon默认策略
3、重试策略——RetryRule
4、最低并发策略——BestAvailableRule
5、可用过滤策略——AvailabilityFilteringRule
过滤掉那些因为一直连接失败的被标记为circuit tripped的后端server,并过滤掉那些高并发的的后端server(active connections 超过配置的阈值)
性能仅次于最低并发策略。
6、响应时间加权策略——WeightedResponseTimeRule
每隔30秒计算一次服务器响应时间,以响应时间作为权重,响应时间越短的服务器被选中的概率越大。
7、区域权衡策略——ZoneAvoidanceRule
Ribbon的负载均衡策略使用建议
一般情况下,推荐使用最低并发策略,这个性能比默认的轮询策略高很多。
负载均衡替换
-
编写配置类
// 编写一个类注入负载均衡算法类,该类必须不能让springboot扫描到,不能放在同级,或者子包下面,必须放在其它地方 @Configuration public class RibbonConfiguration { @Bean public IRule ribbonRule() { // 负载均衡规则,改为随机,可以new的类,参考上面提供的类名,官方写好的的类,也可以自定义负载均衡类 return new RandomRule(); } }
-
在RestTemplate注入配置类添加注解
package com.wyx.cloud.config; import com.wyx.loadbalance.RibbonConfiguration; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.cloud.netflix.ribbon.RibbonClient; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate; // name 是微服务的应用名 @Configuration @RibbonClient(name = "cloud-alibaba-provider", configuration = RibbonConfiguration.class) public class RestTemplateConfig { @Bean @LoadBalanced public RestTemplate restTemplate(){ return new RestTemplate(); } }
-
其他配置不修改,启动即可。
-
当然如果对提供的负载均衡算法,不满意,也可以自定义负载均衡算法,只需要编写一个类,实现
IRule
接口即可。
配置中心的使用
项目创建
-
创建新模块nacos-config-3344
-
导入 pom.xml
<dependencies> <!--Nacos 配置中心依赖--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> <!--这个依赖,看版本来修改版本是20版之后的最好导入,因为在版后默认剔除了,不导入启动项目会出错--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bootstrap</artifactId> </dependency> <!--Nacos 服务注册的依赖--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!--spring-boot-web 模块 常用的3个--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!--热部署插件--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <!--测试插件--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-test</artifactId> <scope>test</scope> </dependency> <!--lombok 依赖--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies>
-
添加application.yaml、bootstrap.yml
# application.yml server: port: 3344 spring: profiles: active: dev
# bootstrap.yml spring: application: name: nacos-config-client cloud: nacos: discovery: server-addr: localhost:8848 #服务注册中心地址 config: server-addr: localhost:8848 #配置中心地址 file-extension: yaml #指定文件后缀名,切记配置中心的后缀,必须一样,不能一个是yml 一个是yaml
-
主启动类
package com.wyx.cloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @SpringBootApplication @EnableDiscoveryClient public class NacosConfigMain3344 { public static void main(String[] args) { SpringApplication.run(NacosConfigMain3344.class,args); } }
-
业务类
package com.wyx.cloud.controller; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RefreshScope //动态刷新功能,nacos修改后,不需要在发送什么命令,直接会自动刷新 public class ConfigClientController { @Value("${config.info}") private String configInfo; @GetMapping("/config/info") public String getConfigInfo() { return configInfo; } }
在配置中心准备配置的文件
文件名要求规则如下(dataId)即为文件名
在 Nacos Spring Cloud 中,dataId
的完整格式如下:
${prefix}-${spring.profiles.active}.${file-extension}
prefix
默认为spring.application.name
的值,也可以通过配置项spring.cloud.nacos.config.prefix
来配置。spring.profiles.active
即为当前环境对应的 profile,详情可以参考 Spring Boot文档。 注意:当spring.profiles.active
为空时,对应的连接符-
也将不存在,dataId 的拼接格式变成${prefix}.${file-extension}
file-exetension
为配置内容的数据格式,可以通过配置项spring.cloud.nacos.config.file-extension
来配置。目前只支持properties
和yaml
类型。
由文件命名规则可知,我们该项目的配置文件命令为:nacos-config-client-dev.yml
添加配置文件如下图
启动项目测试即可:访问,http://localhost:3344/config/info
在修改配置文件后继续访问,发现是动态刷新的,不在像 springcloud-config 一样需要实时的刷新配置。
多环境多项目管理
对于SpringCloud-config一般情况下都是通过修改文件名字来实现生产环境,测试环境的使用,但是在Nacos中,利用了Java的包名类名管理思想。
它存在三级管理配置文件的功能,具体来说就是命名空间 + GROUP + Data ID
,三者之间的关系命名空间 > GROUP > Data ID,
命名空间的使用
下面我们来看一下如何创建命令空间
我们可以通过修改application.yaml来获取我们的命名空间,如下
spring:
cloud:
nacos:
discovery:
server-addr: localhost:8848 #服务注册中心地址
config:
server-addr: localhost:8848 #配置中心地址
file-extension: yaml #指定文件后缀名,切记配置中心的后缀,必须一样,不能一个是yml 一个是yaml
namespace: f50332a2-9b31-479c-9111-102c125d97d7 # 这个数字是刚刚创建时自动生成的命名空间ID
组的使用
在新建配置的时候可以自定义组名
我们在配置中如何配置组
spring:
cloud:
nacos:
discovery:
server-addr: localhost:8848 #服务注册中心地址
config:
server-addr: localhost:8848 #配置中心地址
file-extension: yaml #指定文件后缀名,切记配置中心的后缀,必须一样,不能一个是yml 一个是yaml
namespace: f50332a2-9b31-479c-9111-102c125d97d7 # 这个数字是刚刚创建时自动生成的命名空间ID
group: DEV_GROUP # 指定组名
Data ID的使用
Data ID就是一个对应文件名的配置,上面已经解释过了。
Nacos集群配置
架构部署
官方集群架构部署图
可能开起来不是很理解,下面是根据官网修改后的集群部署图:
简单来说:
- 就是我们访问一个域名,给我们解析成为一个虚拟IP。
- 虚拟IP映射到对应的Nginx服务器。
- 在由Nginx服务器反向代理到我们的需要正规访问的Nacos。
- Nacos的一些操作(比如保持配置文件)在将其持久化到我们的高可用的MySQL数据库。
持久化配置
默认Nacos使用的是内嵌式数据库实现数据存储(derby)。如果采用集群配置,每个Nacos节点都有自己的配置,就会存在数据一致性的问题。为了解决这个问题,Nacos采用了集中式存储方式来支持集群化部署(目前只支持MySQL)。
切换默认的数据源
-
创建数据库nacos_devtest,字符编码utf8 ,排序规则utf8_general_ci
-
将在安装nacos的目录下的conf下的
nacos-mysql.sql
文件复制到自己刚刚创建的数据库中执行SQL命令 -
修改在安装nacos的目录下的conf下的
application.properties
文件,添加如下配置#使用的数据源 spring.datasource.platform=mysql # 数据库的数量 db.num=1 #连接的URL注意数据库名称 db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_devtest?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC #用户名 db.user.0=root #密码 db.password.0=970699
重新启动即可。
特别注意,数据库的名字不能改变,必须使用 nacos_devtest
否则不能用
MySQL 8.0
,需要加上时区配置。
开始配置
环境准备
-
环境准备(3台虚拟机+阿里云服务器一台)
环境说明,由于服务器不够所以这里数据库就不集群了。其他的都集群配置
master 192.168.137.129 slave1 192.168.137.130 slave2 192.168.137.131 阿里云服务器 47.97.218.81
-
三台虚拟机上都先安装JDK,教程很多不在说明
准备
Nginx
安装包,Nacos
安装包下载地址:
Nginx(1.20.0版本):http://nginx.org/download/nginx-1.20.0.tar.gz
Nacos(nacos-server2.0.1版本):https://github.com/alibaba/nacos/releases/download/2.0.1/nacos-server-2.0.1.tar.gz
并将
Nginx和Nacos
放到三台虚拟机上
Nacos集群安装
说明以下,这里三台服务器的Nacos安装教程都一样,只对一台讲解
-
解压配置上传的压缩包
# 我是安装在 /opt目录下 [root@localhost opt]# pwd /opt [root@localhost opt]# tar -xzvf nacos-server-2.0.1.tar.gz
-
配置MySQL数据源(我选用的是阿里云的服务器来配置数据源,如果条件不允许,可以自己用虚拟机来装MySQL也可以)
首先:
查看数据库配置文件在解压目录下的nacos 下的 conf目录下的数据库名称[root@localhost opt]# vim /opt/nacos/conf/nacos-mysql.sql
使用navicat连接我的阿里云服务器的数据库建立数据库名为nacos_config,字符集为
utf8
,排序规则为utf8_general_ci
将刚刚我们查看的
nacos-mysql.sql
脚本,拿到navicat中运行数据库脚本。具体简单,不在操作。 -
配置nacos目录下的conf目录下的
application.properties
文件# 首先将文件备份,防止修改错 [root@localhost conf]# cp application.properties application.properties.bk # 修改文件 [root@localhost conf]# vim application.properties
在文件最后配置数据源的位置,就是在文件最后添加如下内容
#使用的数据源 spring.datasource.platform=mysql # 数据库的数量 db.num=1 #连接的URL注意数据库名称,及其数据源的位置IP db.url.0=jdbc:mysql://xxx.xxx.xxx.xxx:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC #用户名 db.user.0=root #密码 db.password.0=970699
-
配置集群文件
# j将集群文件先复制一份,并改名为 cluster.conf [root@localhost conf]# cp cluster.conf.example cluster.conf # 编辑 cluster.conf [root@localhost conf]# vim cluster.conf
上面修改的这个文件 3个服务器上都需要配置
在三台服务器上都启动nacos
# 启动命令,三台都要启动 [root@localhost conf]# sh /opt/nacos/bin/startup.sh # 关闭防火墙,如果是阿里云服务器建议开启端口,并配置安全组规则不要关闭防火墙 systemctl stop firewalld.service # 查看防火墙状态 firewall-cmd --state
访问:http://192.168.100.129:8848/nacos/
注意:
启动实在太慢了,需要多等一会。我3G
的运行内存启动差不多花了3分钟,这里可能是网络原因。所以记得等,如果等不了,使用如下命令查看启动日志1G内存启动花了6分钟左右
# 默认就是安装目录下的logs下的start.out [root@localhost bin]# vim /opt/nacos/logs/start.out
看到出现如下信息才算启动成功,看服务器配置启动时间。
全部启动成功后可以查看节点状态
Nginx集群接入
-
两台服务器安装Nginx
安装教程参考:Nginx安装教程
-
这里使用
192.168.100.129和192.168.100.130
来搭建Nginx安装完成后测试访问没有问题后开始搭建
搭建过程如果看不到可以参考这里:https://www.cnblogs.com/Rampant/p/14785179.html 的
反向代理模式中的负载均衡,和Nginx高可用
两个部分 -
修改Nginx启动配置文件
# 编辑配置文件 [root@localhost conf]# vim /usr/local/nginx/conf/nginx.conf
编辑后如下
upstream nacoscluster{ server 192.168.100.129:8848; server 192.168.100.130:8848; server 192.168.100.131:8848; } server { listen 5000; server_name 192.168.137.129; #charset koi8-r; #access_log logs/host.access.log main; location / { # root html; # index index.html index.htm; proxy_pass http://nacoscluster }
另外一台也做配置
upstream nacoscluster{ server 192.168.100.129:8848; server 192.168.100.130:8848; server 192.168.100.131:8848; } server { listen 5000; # 只需要这里的IP是本机IP,其他不变 server_name 192.168.137.130; #charset koi8-r; #access_log logs/host.access.log main; location / { # root html; # index index.html index.htm; proxy_pass http://nacoscluster }
Nginx高可用接入
参考:Nginx高可用搭建
安装 keeplived
# 安装命令
yum install keepalived
编辑配置文件
# 进入配置文件目录
cd /etc/keepalived/
# 编辑配置文件
vim keepalived.conf
! Configuration File for keepalived
## 两台服务器都要配置
global_defs {
notification_email { # keepalived服务宕机异常出现的时候,发送通知邮件 可以是多个
acassen@firewall.loc # 收件人邮箱1
failover@firewall.loc # 收件人邮箱2
sysadmin@firewall.loc # 收件人邮箱3
}
notification_email_from Alexandre.Cassen@firewall.loc #邮件发件人
smtp_server 192.168.200.1 # 邮件服务器地址
smtp_connect_timeout 30 # 超时时间
router_id LVS_DEVEL # 机器标识 局域网内唯一即可
vrrp_skip_check_adv_addr # 默认是不跳过检查。检查收到的VRRP通告中的所有地址可能会比较耗时,设置此命令的意思是,如果通告与接收的上一个通告来自相同的master路由器,则不执行检查(跳过检查)。
#vrrp_strict # 严格遵守VRRP协议。下列情况将会阻止启动Keepalived:1. 没有VIP地址。2. 单播邻居。3. 在VRRP版本2中有IPv6地址。
vrrp_garp_interval 0 # 小数类型,单位秒,在一个网卡上每组gratuitous arp消息之间的延迟时间,默认为0,一个发送的消息=n组 arp报文
vrrp_gna_interval 0 # 小数类型,单位秒, 在一个网卡上每组na消息之间的延迟时间,默认为0
}
# 检测 nginx 的活动状态
vrrp_script chk_http_port{
# 检测脚本路径
script "/etc/keepalived/nginx_chech.sh"
interval 2
weight 2
}
# vrrp实例 我们集群设置 多机配置,除了state和priority不一样,其他都一样
vrrp_instance VI_1 {
state MASTER # 服务器状态 MASTER是主服务器 BACKUP是备份服务器 主服务器的priority要比备份服务器大
interface ens33 # 通信端口 通过ip addr可以看到 根据自己的机器配置
virtual_router_id 51 # vrrp实例id keepalived集群,实例id必须一致
priority 100 # 权重比 主服务器的priority要比备份服务器大
advert_int 1 # 心跳间隔 单位秒 keepalived多机器集群 通过心跳检测,如果发送心跳没反应 就立刻接管;
authentication { # 服务器之间通信密码
auth_type PASS
auth_pass 1111
}
virtual_ipaddress { # 自定义虚拟IP
# 虚拟IP池,要求必须在一个网段内,必须192.168.100开头
192.168.100.80
}
}
配置检测脚本
#!/bin/bash
A=`ps -C nginx -no-header | wc -l`
if [$A -eq 0 ];then
/usr/local/neginx/sbin/nginx
sleep 2
if [`PS -C nginx --no-header |wc -1` -eq 0 ]; then
killall keepalived
fi
fi
访问:192.168.100.80:5000/nacos/测试,当主服务器192.168.100.129宕机后,测试访问依然成功,搭建完成。
Sentinel
概述
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
简单来说:它是一个轻量级的流量控制、熔断降级的Java库,就是以前学习的Hystrix的加强版
。
中文官方文档
:SpringCloudalibaba Sentinel中文官方文档
Sentinel 分为两个部分:
- 核心库(Java 客户端)不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。
- 控制台(Dashboard)基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。
特点
- 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
- 完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
- 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
- 完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。
主要功能
安装启动
-
下载Setinel
下载地址(全部版本):https://github.com/alibaba/Sentinel/releases
1.8.2版本:https://github.com/alibaba/Sentinel/releases/download/1.8.2/sentinel-dashboard-1.8.2.jar
-
启动,运行下载出来的jar包就可以了
# 运行jar包 java -jar Sentinel-dashboard-1.8.2.jar
-
访问:http://localhost:8080/ 如下启动成功
登录用户和密码都是
sentinel
服务搭建
-
创建新模块nacos-sentinel-service-9003
-
pom.xml
<dependencies> <!--Sentinel 服务监控的依赖--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> <!--Nacos 服务注册的依赖--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!--spring-boot-web 模块 常用的3个--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!--热部署插件--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <!--测试插件--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-test</artifactId> <scope>test</scope> </dependency> <!--lombok 依赖--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies>
-
application.yaml
server: port: 9003 spring: application: name: nacos-sentinel-service cloud: nacos: discovery: server-addr: localhost:8848 #注册到nacos注册中心 sentinel: transport: dashboard: localhost:8080 #在8080d port: 8719 #默认8719,假如被占用了会自动从8719开始依次+1扫描。直至找到未被占用的端口 management: #凡是涉及监控的都需要暴露端口 endpoints: web: exposure: include: '*'
-
主启动类
package com.wyx.cloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @SpringBootApplication @EnableDiscoveryClient public class SentinelServiceMain9003 { public static void main(String[] args) { SpringApplication.run(SentinelServiceMain9003.class,args); } }
-
业务类
package com.wyx.cloud.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; @RestController public class SentinelController { private Integer contA=0; private Integer contB=0; @GetMapping("/getInfoA") public String getInfoA(){ contA++; return "提供A服务次数"+contA; } @GetMapping("/getInfoB") public String getInfoB(){ contB++; return "提供B服务次数"+contB; } }
访问 http://localhost:8080/ 查看监控信息,发现没有上面,是因为Sentinel使用懒加载模式
只有访问服务后才会进入监控列表。
我们访问 http://localhost:9003/getInfoA
再次查看监控信息
仪表盘介绍
实时监控
显示在一段时间内对服务的每个请求的访问量,并以秒吉显示出来
簇点链路
触电链路主要有两种显示方式 树状视图
和列表视图,主要功能就是显示某个服务的请求路径,并可用为其添加 流控、熔断、热点、授权
等规则
流控规则
通过一定的规则来配置限流规则,来对服务提供一种保护作用,具体如何实现请看后面
热点规则
也是一种限流规则,具体参考后面。
系统规则
授权规则
集群流控
机器列表
查看当前服务名下有多少台实例的服务。
流控规则设置
在学习流控规则前,我们先来了解几个基本概念
阈值类型
QPS:单位时间类的请求如果超过设定的规则就返回失败
默认返回错误的页面,后期可用自定义
并发线程数:给定固定线程数,如果请求大于线程数的处理范围就快速失败
流控模式
直接:针对自己的流控规则,满足规则就对自己限流。这个很简单不在解释
关联:将两个资源名进行关联,当关联资源达到限流规则时,来限流与之关联的资源。
简单理解:如下图,当/getInfoB
在单位时间内的访问次数超过2次以上,那么/getInfoA
将会被限流
,如果是并发线程数也是一样。当两个线程数处理不过来时,那么/getInfoA
限流。(适用于当支付模块处理不过来时,可以对下单模块限流)
链路:在微服务调用过程中,如果入口资源调用资源名的服务,满足限流规则,则开始限流。
简单来说:假设微服务之间互相调用,那么当/getIfoB
服务调用/getInfoA
满足单位时间内超过2次以上触发限流
流控效果
流控效果只能针对QPS
模式,并发线程模式,只能时快速失败
快速失败:就是快速放回默认的错误信息如下图(可以自定义)。
Warm UP(缓慢唤醒):即预热/冷启动方式。当系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮。
简单理解如下:起始单机阈值是3(在源码WarmUpController类中)当请求量突然增大时,系统会自动的在5秒钟内将我们的单机阈值调到我们设定的最大值10。(使用场景:抢购东西时,避免一开始就出现系统死机的情况)
等待排队:等待排队利用的原理是漏桶算法,就是对所有请求都不返回错误(在不超时的情况下,超时也会返回错误),而是将请求拿过来后,经行排队,以此处理。什么是漏桶算法
熔断规则设置
熔断规则又称服务熔断
:但是这里的服务熔断和Hystrix
有区别,它并没有半开状态
,就只有两种状态可用,不可用。
慢比例调用模式
慢比例调用:在设置的统计时间内,如果满足最小请求数,且响应时间(最大RT
)大于设定值的比例高于阈值就熔断设定的时长,当过了熔断时长,若接下来的一个请求响应时间小于设置的慢调用 RT 则结束熔断,若大于设置的慢调用 RT 则会再次被熔断。
下图的例子:/getInfoA
请求,如果在统计时长(1秒内)内,请求次数大于4次(最小请求数),并且响应时间大于50毫秒(最大RT)的比例大于0.4(比例阈值),就会进入熔断 10秒(熔断时长)。过了熔断时长就恢复访问。熔断界面为默认的出错界面,可用修改。
异常比例模式
异常比例模式:当单位统计时长(statIntervalMs
)内请求数目大于设置的最小请求数目,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。异常比率的阈值范围是 [0.0, 1.0]
,代表 0% - 100%。
例如,表示在一秒钟内,请求次数大于5次,并且出现异常的的次数大于请求次数的百分之四十,就会开启熔断,熔断时间过了后,如果请求还是异常继续熔断,等待下一次可用。
异常数模式
异常数模式:当单位统计时长内的异常数目超过阈值之后会自动进行熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。
热点规则设置
何为热点?热点即经常访问的数据。很多时候我们希望统计某个热点数据中访问频次最高的 Top K 数据,并对其访问进行限制。比如:
- 商品 ID 为参数,统计一段时间内最常购买的商品 ID 并进行限制
- 用户 ID 为参数,针对一段时间内频繁访问的用户 ID 进行限制
热点参数限流会统计传入参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。热点参数限流可以看做是一种特殊的流量控制,仅对包含热点参数的资源调用生效。
Sentinel 利用 LRU 策略统计最近最常访问的热点参数,结合令牌桶算法来进行参数级别的流控。热点参数限流支持集群模式。
热点设置
-
环境准备,在业务类新加一个请求
// 新增一个请求参数为非必须,这里只能用 SentinelResource,单独使用/hotKey是没效果的 @GetMapping("/hotKey") @SentinelResource(value = "hotKey", blockHandler = "del_hotKet") //定义访问的资源名,和失败后走的处理方法 public String hotKet(@RequestParam(value = "p1", required = false) String p1, @RequestParam(value = "p2", required = false) String p2){ return "热点访问成功"; } // 失败后的处理方法 public String del_hotKet(String p1, String p2 , BlockException exception){ return "热点新闻访问失败!😢😢😢😢"; }
-
重启,添加热点规则
上面的规则代表当访问
/hotKey
时,如果添加第一个参数(参数索引0开始),对应代码中的第一个参数为 p1,即当带有p1参数的访问在统计时间内,访问超过2次,就进行熔断。效果如下
参数例外项配置
简单来说:对于上述的请求,当p1等于任何值是,只要单机访问超过2个QPS,那么他就会熔断,对于参数例外项配置,就是可用当p1等于特殊的某个值,进行重新的定义限流规则。
如下,即当我们请求的参数为第一个(对于代码中的p1)本来限流是每秒钟超过2次进行限流,但是现在如果请求参数 p1 = 5并且请求类型为String类型,那么他的限流就为200。
系统规则设置
系统保护规则是从应用级别的入口流量进行控制,从单台机器的 load、CPU 使用率、平均 RT、入口 QPS 和并发线程数等几个维度监控应用指标,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。
简单来说:就是对我们之前定义的限流规则在外面包裹一层,来做新的限流规则,必须满足系统的限流规则,才能走到里面的限流规则
参考:系统自适应限流
系统规则支持以下的模式:(一般不是很常用,因为会如果配置不好,可能会导致下一层的一些规则失效不可用。导致系统瘫痪)
- Load 自适应(仅对 Linux/Unix-like 机器生效):系统的 load1 作为启发指标,进行自适应系统保护。当系统 load1 超过设定的启发值,且系统当前的并发线程数超过估算的系统容量时才会触发系统保护(BBR 阶段)。系统容量由系统的
maxQps * minRt
估算得出。设定参考值一般是CPU cores * 2.5
。 - CPU usage(1.5.0+ 版本):当系统 CPU 使用率超过阈值即触发系统保护(取值范围 0.0-1.0),比较灵敏。
- 平均 RT:当单台机器上所有入口流量的平均 RT 达到阈值即触发系统保护,单位是毫秒。
- 并发线程数:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护。
- 入口 QPS:当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护。
@SentinelResource
控制台资源限流配置
用来配置访问资源名和达到限流规则后应该怎么处理
@GetMapping("/hotKey")
@SentinelResource(value = "hotKey", blockHandler = "del_hotKet") //定义访问的资源名,和失败后走的处理方法
public String hotKet(@RequestParam(value = "p1", required = false) String p1,
@RequestParam(value = "p2", required = false) String p2){
return "热点访问成功";
}
// 失败后的处理方法
public String del_hotKet(String p1, String p2 , BlockException exception){
return "热点新闻访问失败!😢😢😢😢";
}
当然也可用只用定义的访问资源名称,就算定义了资源名称,配置流控规则时依然可以使用URL来做资源名,就是请求地址,但是热点规则除外,不能使用URL
// 达到限流规则时默认走,系统默认的
@SentinelResource(value = "hotKey")
问题存在:
- 当我们不想使用系统默认时,自定义替换。
- 但是每个方法一个替换,会显得代码膨胀,不直观
- 没有体现全局统一管理等问题
问题解决:
-
自定义一个类,用来写异常的方法
package com.wyx.cloud.myHandler; import com.alibaba.csp.sentinel.slots.block.BlockException; public class ConsumerHandler { // 因为JVM 的加载机制只能使用 static 返回值和要处理的方法的返回值相同 public static String handlerEx(BlockException exception){ return "自定义异常处理方法"; } }
-
在方法中调用自定义的异常处理
@GetMapping("/handlerEx") // blockHandlerClass 指定处理异常的类, blockHandler 指定处理异常类中的那个方法,如果没有异常类就是在自己的类中找方法 @SentinelResource(value = "hotKey", blockHandlerClass = ConsumerHandler.class ,blockHandler = "handlerEx") public String handlerEx(){ return "访问成功"; }
运行时Java异常处理
fallback:
// 参数中还有defaultFallback,代表默认的处理,当与fallback同时标注时,fallback优先级高于defaultFallback
@GetMapping("/fallBack")
@SentinelResource(value = "fallBack",fallback = "fallbackMethod")
public String fallBack(){
return "访问成功";
}
// 失败后的处理方法
public String fallbackMethod(Throwable exception){
return "运行时异常处理方法";
}
上面的配置方式还是存在代码膨胀的问题
我们这里也可以用控制台资源处理的方法来处理。即创建一个fallbackMethod的类,然后通过fallbackClass来处理
-
创建类ConsumerFallbackMethod
package com.wyx.cloud.myHandler; public class ConsumerFallbackMethod { // 因为JVM 的加载机制只能使用 static 返回值和要处理的方法的返回值相同 public static String fallback(Throwable exception){ return "自定义运行时异常处理方法"; } }
-
在方法中调用
@GetMapping("/fallBack") @SentinelResource(value = "fallBack", fallbackClass = ConsumerFallbackMethod.class, fallback = "fallback") public String fallBack(){ int a=10/0; return "访问成功"; }
特别说明:
当Java运行时异常和控制台限流规则同时配置,且同时生效时,优先使用控制台的限流或熔断处理方法
Sentinel中使用openfeign做服务降级
使用方法和在Hystrix中使用类似,有一点点微小差异(开启的yaml支持不一样),可以参考
OpenFeign的使用:OpenFeign使用流程
Hystrix中使用OpenFeign做服务降级:Hystrix配合OpenFeign使用服务降级
具体步骤如下:
微服务提供者搭建:(2个微服务提供者)
-
新建模块Nacos-Sentinel-OpenFeign-Provider-8001,Nacos-Sentinel-OpenFeign-Provider-8002,两个搭建的东西都一样改端口即可
-
pom.xml
<dependencies> <!--Nacos 服务注册的依赖--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!--spring-boot-web 模块 常用的3个--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!--热部署插件--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <!--测试插件--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-test</artifactId> <scope>test</scope> </dependency> <!--lombok 依赖--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies>
-
yaml
server: port: 8001 # 端口号 spring: application: name: nacos-sentinel-openfeign # 微服务名称 cloud: nacos: discovery: server-addr: 127.0.0.1:8848 # 连接的注册中心 management: endpoints: web: exposure: include: '*' #暴露端口
-
主启动类
package com.wyx.cloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class NacosSentinelOpenFeignProviderMain8001 { public static void main(String[] args) { SpringApplication.run(NacosSentinelOpenFeignProviderMain8001.class,args); } }
-
业务类
OpenFeign调用服务
package com.wyx.cloud.service; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @Service public class Provider { @Value("${server.port}") private String serverPort; public String getService(){ return "提供服务成功,当前服务端口:"+serverPort; } }
控制层
package com.wyx.cloud.controller; import com.wyx.cloud.service.Provider; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; @RestController public class ProviderController { @Resource Provider provider; @GetMapping("/getServer") public String getService(){ return provider.getService(); } }
微服务消费者搭建:
-
创建新模块Nacos-Sentinel-OpenFeign-Consumer-80
-
pom.xml
<dependencies> <!--添加 openfeign 的启动依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-loadbalancer</artifactId> </dependency> <!--Sentinel 服务监控的依赖--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> <!--Nacos 服务注册的依赖--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <exclusions> <exclusion> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </exclusion> </exclusions> </dependency> <!--spring-boot-web 模块 常用的3个--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!--热部署插件--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <!--测试插件--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-test</artifactId> <scope>test</scope> </dependency> <!--lombok 依赖--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies>
-
yaml
server: port: 80 spring: application: name: nacos-order-consumer cloud: nacos: discovery: server-addr: localhost:8848 sentinel: transport: dashboard: localhost:8080 port: 8719 service-url: nacos-user-service: http://nacos-sentinel-openfeign #对Feign的支持 feign: sentinel: enabled: true
-
主启动类
package com.wyx.cloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.openfeign.EnableFeignClients; @SpringBootApplication @EnableDiscoveryClient @EnableFeignClients public class NacosSentinelOpenFeignConsumerMain80 { public static void main(String[] args) { SpringApplication.run(NacosSentinelOpenFeignConsumerMain80.class,args); } }
-
业务类
OpenFeign调用接口
package com.wyx.cloud.service; import com.wyx.cloud.fallback.ProviderFallBackImpl; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; @FeignClient(value = "nacos-sentinel-openfeign",fallback = ProviderFallBackImpl.class) public interface ProviderService { @GetMapping("/getServer") public String getService(); }
出错处理类
package com.wyx.cloud.fallback; import com.wyx.cloud.service.ProviderService; import org.springframework.stereotype.Component; @Component public class ProviderFallBackImpl implements ProviderService { @Override public String getService() { return "Nacos下Sentinel的程序运行出错方法调用"; } }
控制层
package com.wyx.cloud.controller; import com.wyx.cloud.service.ProviderService; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; @RestController public class ConsumerController { @Resource private ProviderService provider; @GetMapping("/getServer") public String getServer(){ int a = 10/0; return provider.getService(); } }
启动测试即可
配置规则持久化
一旦我们重启应用,Sentinel规则将消失,生产环境需要将配置规则进行持久化。那么如何持久化呢?
-
导入依赖
<dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-datasource-nacos</artifactId> </dependency>
-
添加yaml配置
spring: cloud: sentinel: datasource: ds1: nacos: server-addr: localhost:8848 dataid: ${spring.application.name} groupid: DEFAULT_GROUP data-type: json rule-type: flow
-
在Nacos中添加配置Data Id配置文件名:是
spring.application.name,服务名称
,类型为json[ { "resource": "/getInfoB", "limitApp": "default", "grade": 1, "count": 1, "strategy": 0, "controlBehavior": 0, "clusterMode": false } ]
重启即可