学习springCloud 相关的知识
软件架构说明
微服务架构是一站式解决方案,是多种微服务架构落地技术的的集合体,俗称微服务全家桶。
Eureka 实现服务治理(服务注册与发现)
Ribbon 提供客户测得软件负载均衡算法
Hystrix 断路器 ,保护系统,控制故障范围
Zuul api 网关、路由、负载均衡等多种作用
Config 配置管理 支持标签版本的配置环境
Java 微服务实践 - Spring Cloud 系列(一)云原生应用
Java 微服务实践 - Spring Cloud 系列(二)配置客户端
Java 微服务实践 - Spring Cloud 系列(三)配置服务器
Java 微服务实践 - Spring Cloud 系列(四)服务发现/注册
Java 微服务实践 - Spring Cloud 系列(五)高可用服务治理
Java 微服务实践 - Spring Cloud 系列(六)负载均衡
Java 微服务实践 - Spring Cloud 系列(七)Ribbon 源码
Java 微服务实践 - Spring Cloud 系列(八)服务短路
Java 微服务实践 - Spring Cloud 系列(九)Hystrix源码
Java 微服务实践 - Spring Cloud 系列(十)服务调用
Java 微服务实践 - Spring Cloud 系列(十一)服务网关
Java 微服务实践 - Spring Cloud 系列(十二)消息驱动整合
Java 微服务实践 - Spring Cloud 系列(十三)Binder实现
Java 微服务实践 - Spring Cloud 系列(十四)消息总线
Java 微服务实践 - Spring Cloud 系列(十五)分布式应用跟踪
Java 微服务实践 - Spring Cloud 系列(十六)系列回顾
面向服务的架构 (SOA)
微服务架构(MSA)
本次版本相应的版本
组件 | 版本 |
---|---|
SpringCloud | HoxTon.SR1 |
BOOT | 2.2.2.RELEASE |
cloud_alibaba | 2.1.0.RELEASE |
java | 1.8 |
maven | 3.5及以上 |
Mysql | 5.7及以上 |
微服务 对应boot版本要求 https://spring.io/projects/spring-cloud
Release Train | Boot Version |
---|---|
2021.0.x aka Jubilee | 2.6.x |
2020.0.x aka Ilford | 2.4.x, 2.5.x (Starting with 2020.0.3) |
Hoxton | 2.2.x, 2.3.x (Starting with SR5) |
Greenwich | 2.1.x |
Finchley | 2.0.x |
Edgware | 1.5.x |
Dalston | 1.5.x |
cloud升级 相关组件
微服务大件 | |
---|---|
服务注册中心 | Eureka 、Zookeeper、Consul、Nacos |
服务调用 | Ribbon、LoadBalancer |
服务调用2 | Feign、OpenFeign |
服务降级 | Hystrix、resilience4j、Sentinel |
服务网关 | Zuul、Zuul2、gateway |
服务配置 | Config、Nacos |
服务总线 | Bus、Nacos |
项目构建
预定> 配置 > 编码
IDEA 新建project 工作空间
###父搭建步骤
Rest微服务工程构建
其中maven中dependencyManagement和dependencies区别
dependencyManagement里只是声明依赖,并不实现引入,因此子项目需要显式的声明需要用的依赖。如果不在子项目中声明依赖,是不会从父项目中继承下来的;只有在子项目中写了该依赖项,并且没有指定具体版本,才会从父项目中继承该项,并且version和scope都读取自父pom;另外如果子项目中指定了版本号,那么会使用子项目中指定的jar版本。
简言之 父类写一个dependencyManagement 对应的管理在子类中可以复用,默认则是复用父类的版本。
支付模块构建 8001
提供者Module模块 8001 服务端
微服务消费者订单Module模块 80 客户端
模块基本流程
1.建module
2.改pom 文件
3.写yml 文件
4.主启动
5 .业务类
消费订单模块 80
RestTemplate 提供了多种便捷访问远程Http服务的方法
是一种简单便捷的访问restful服务模板类,是Spring 提供的用于访问Rest服务的客户端模板工具集
构建过程中发现 8001 和 80 模块都有重复的实体类
在使用过程中发现此处多余因此进行重构
创建cloud-api-commons 模块 粘贴 CommonResult 和Payment 实体类 删除 其他两个模块下的实体类 并在其他两个模块下的pom文件下 加入
<!-- 引入自己定义的api依赖包-->
<dependency>
<groupId>com.grapecc.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</dependency>
基础知识
Eureka 包含两大组件 Eureka Server 和 Eureka Client
各个服务节点通过配置启动后,会在Eureka Server 进行注册,这样Eureka Server 中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直接看到。
是一个java客户端,用于简化Eureka Server 的交互,客户端同时具备一个内置的、使用轮询负载均衡算法的负载均衡器。在应用启动后,将会向Eureka Server 发送心跳(默认是30秒),如果Eureka Server在多个心跳周期内没有收到某个节点的心跳,Eureka Server 将会从服务注册表中把这个服务节点移除(默认是90秒)
将 消费方和服务方注册进 服务注册中心
在对应的模块pom文件引入 依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
在模块下的yml文件追加配置后对启动类进行追加@EnableEurekaClient 注解
# eureka 配置
eureka:
client:
# false 用于 不注册自己
register-with-eureka: true
#fasle 表示自己端就是注册中心
fetch-registry: true
service-url:
defaultZone: http://localhost:7001/eureka
出现集群的背景 单机版eureka 出现故障的时候会导致整个服务环境不可用,
因此使用集群来达到负载均衡和故障容错
微服务RPC 远程调用最核心的是什么
高可用
集群eureka 主要特点:互相注册 、互相守望
更改本地配置
C:\Windows\System32\drivers\etc
修改hosts文件
############StrpingCloud2021#################
127.0.0.1 eureka7001.com
127.0.0.1 eureka7002.com
127.0.0.1 eureka7003.com
注意一点集群版的yml文件 域名映射 相互注册 相互守望
#7001 的配置
eureka:
instance:
hostname: eureka7001.com
client:
# false 用于 不注册自己
register-with-eureka: false
#fasle 表示自己端就是注册中心
fetch-registry: false
service-url:
#设置 与 Eureka server 交互的地址查询服务和注册服务都需要以来这个地址
defaultZone: http://eureka7002.com:7002/eureka/
将消费方和服务方 注册进注册中心
# eureka 配置
eureka:
client:
# false 用于 不注册自己
register-with-eureka: true
#fasle 表示自己端就是注册中心
fetch-registry: true
service-url:
# defaultZone: http://localhost:7001/eureka 单机版
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka # 集群版
支付服务提供者8001 集群环境构建
# defaultZone: http://localhost:7001/eureka 单机版
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka # 集群版
主机名称:微服务名称修改
instance: # 和eureka下的client 平齐
instance-id: payment8001
访问信息有IP信息提示
prefer-ip-address: true # 路径显示ip
模块下的启动类 追加@EnableDiscoveryClient
控制类 即可调用出相关信息
@Resource
private DiscoveryClient discoveryClient;
@GetMapping(value = "/payment/discovery")
public Object discovery(){
List<String> list = discoveryClient.getServices();
for (String s : list) {
System.out.println(s);
}
List<ServiceInstance> instances = discoveryClient.getInstances("cloud-payment-service");
for (ServiceInstance instance : instances) {
log.info(instance.getInstanceId()+"\t"+ instance.getHost()+"\t"
+instance.getPort());
}
return this.discoveryClient;
}
Eureka自我保护机制
为什么会产生 Eureka自我保护 机制
为了防止EurekaClient 可以正常运行,但是与EurekaServer 网络不通情况下,EurekaServer不会立刻将EurekaClient 服务剔除
什么是自我保护模式?
默认情况下,如果Eureka Server 在一定时间内没有收到某个微服务实例的心跳,Eureka Server 将会注销该实例(默认90秒)。但是网络分区故障发生时(延时、卡顿、拥挤)时,微服务和Eureka Server之间无法正常通信,以上行为可能变得非常危险了----------因为微服务本身其实是健康的。此时本不应该注销这个微服务。Eureka 通过"自我保护模式" 来解决这个问题-------当Eureka Server 节点在短时间内丢失过多客户端时(网络分区故障),那么节点进入故障模式。
综上所述宁可保护所有微服务,也不盲目注销任何健康的微服务
在eureka 注册中心模块 添加 一下配置 进行关闭自我保护机制
server:
enable-self-preservation: false
eviction-interval-timer-in-ms: 2000 # 默认时间为2000毫秒
在提供方 模块中进行 追加配置
instance:
instance-id: payment8001
prefer-ip-address: true # 路径显示ip
# Eureka 客户端 向服务端 发送心跳的时间间隔 ,单位为秒(默认30秒)
lease-renewal-interval-in-seconds: 1
# Eureka服务端在收到最后一次心跳后等待时间上限,单位微妙(90秒),超时将剔除服务
lease-expiration-duration-in-seconds: 2
Zookeeper (略过)
Consul
下载地址 https://www.consul.io/downloads
中文操作手册: https://www.springcloud.cc/spring-cloud-consul.html
安装后 相应目录中 调出dos命令
consul --version
consul agent -dev //启动命令
Ribbon 负载均衡 服务调用
是基于 Netflix Ribbon 实现的一套客户端 负载均衡的工具
负载均衡 +RestTemplate 调用
RestTemplate
restTemplate.postForObject 返回的是json
restTemplate.getForEntity 返回的是
关于替换Ribbon规则
在建立 和启动类 父级包同级的包
如 启动类在 com.grapecc.springcloud 下
MySelfRule 则在com.grapecc下 和springcloud 同级
@Configuration
public class MySelfRule {
@Bean
public IRule getMyRule(){
return new RandomRule(); //随机
}
}
并在 其模块下主启动类 加入注解 @RibbonClient
@RibbonClient(name = "cloud-payment-service",configuration = MySelfRule.class)
服务调用 OpenFeign 服务接口调用
OpenFeign 定义
feign是一个生命是的web服务客户端,让编写web服务客户端变动非常容易,只需创建一个接口并在接口上添加注解
openFeign使用步骤 使用在消费端
接口 +注解
建模块
pom文件
yml
主启动类 模块下的主启动类 追加 @EnableFeignClients
业务类
@FeignClient(value = "CLOUD-PAYMENT-SERVICE") //服务名称
public interface PaymentFeignService {
@GetMapping("/payment/get/{id}")
CommonResult<Payment> getPayment(@PathVariable("id") Long id);
}
控制层
@RestController
@Slf4j
public class OrderFeignController {
@Resource
private PaymentFeignService paymentFeignService;
@GetMapping("/consumer/payment/get/{id}")
public CommonResult<Payment> getPayment(@PathVariable("id") Long id){
CommonResult<Payment> payment = paymentFeignService.getPayment(id);
return payment;
}
}
openFeign 超时控制
由于feign 默认等待时间为1秒 超过等待就报错
因此修改yml文件 开启超时等待 openFeign
## 设置feign 客户端超时时间
ribbon:
##是指 建立链接所用的时间 5000 ->五秒
ReadTimeout: 5000
## 建立连接后从服务器上读取可用资源所用的时间
Connectimeout: 5000
断路器Hystrix 服务降级
断路器定义
Hystrix 是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统里,许多依赖
主要用于服务降级 、 服务熔断、 接近实时监控
保证能够在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。
Hystrix 案例
提供方
在主启动类上加 @EnableCircuitBreaker
service 类上加
@HystrixCommand(fallbackMethod = "payment_timeoutHandler",commandProperties = {
@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="5000")
})
/// 并追加 payment_timeoutHandler方法 进行兜底
出现 计算异常,超时异常。当前服务不可用,做服务降级,兜底方案 是使用上述方法
消费方:
application.yml
#消费端开启 hystrix
feign:
hystrix:
enabled: true
主启动类追加注解 @EnableHystrix
模块下的控制层
@GetMapping("/consumer/payment/hystrix/timeout/{id}")
@HystrixCommand(fallbackMethod = "payment_timeoutHandler",commandProperties = {
@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="1500")
})
public String paymentFeignTimeout(@PathVariable("id") Integer id){
int num = 10/0;
String s = baseService.payment_timeout(id);
return s;
}
public String payment_timeoutHandler(Integer id){
return "线程池:"+Thread.currentThread().getName()+"payment_timeoutHandler_id:"+id+"耗时时间为超过5min";
}
每个方法都配置兜底 会导致整个代码块膨胀
@DefaultProperties(defaultFallback = "payment_global_fallbackMethod") ///标注通用的 已经指明的就使用指明得
// @HystrixCommand(fallbackMethod = "payment_timeoutHandler",commandProperties = {
// @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="1500")
// })
@HystrixCommand
熔断机制
熔断机制是应对雪崩效应的一种微服务链路保护机制,当扇出链路的某个微服务出现不可用胡后者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回错误的响应信息。
在微服务中 ,熔断机制通过Hystrix 实现,Hystrix会监控微服务间调用的状况。
当失败的调用到一定的阈值,缺省时5秒内20次调用失败,就会启动熔断机制。熔断机制的注解是@HystrixCommand
HystrixDashboard 仪表盘 9001模块 搭建
其中主启动类需要加注解
@SpringBootApplication
@EnableHystrixDashboard
监控下的某些模块 必须含有该依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
测试本地是否依然能够上传
Gateway 网关 主要又三大部分组成 路由、 断言 和过滤
gateway 9527模块
熟悉的配方 增模块 改pom 加 application.yml 启动类
测试 8001 模块 原来是 http://192.168.31.62:8001/payment/get/1
可以通过 http://192.168.31.62:9527/payment/get/1进行调用 即反向代理
可以调用成功则表示搭建模块成功
网关配置有两种方式
第一种 即在网关模块下的yml文件中配置
cloud:
gateway:
routes:
- id: payment_routh #payment_route 路由id 没有固定的规则,要求唯一建议配合服务名
uri: http://localhost:8001 #匹配后提供路由地址
predicates:
- Path=/payment/get/**
第二种就是代码中注入
RouteLocator的Bean
调试基本工具
postman
curl
dos 命令控制板 不带cookie
curl http://localhost:9527/payment/lb
带cookie
curl http://localhost:9527/payment/lb --cookie "username=grape"
带请求头
curl http://localhost:9527/payment/lb -H "X-Request-Id:123"
filter 过滤器
分生命周期,only Two :pre 和post
种类,only Two:GatewayFilter和GlobalFilter
自定义过滤器
分布式配置中心
微服务意味着要将单体应用中的业务拆分成一个个子服务,每个服务的粒度相对较小,因此系统中会出现大量的服务,由于每个服务都需要必要的配置信息才能运行,所以一套集中式的、动态的配置管理设施式必不可少
功能:
集中管理配置文件
不同环境不同配置 动态化配置文件
运行期间动态调整配置
当配置发生变化时,服务不需要重启即可感知配置的变化并应用的配置
将配置信息以rest接口形式弹出
Config配置总控中心搭建
使用自己账号在github上新建一个名为springcloud-config的新Repository
在当前的项目下D:\projectWork\javaWork\learn-spring-cloud\cloud2020 clone git项目地址
新建模块Module cloud-config-center-3344
它即为cloud的配置中心模块cloudConfig Center
配置文件配置
server:
port: 3344
spring:
application:
name: cloud-config-center
cloud:
config:
server:
git:
uri: https://gitee.com/grapecc/springcloud-config.git
###搜索目录
search-paths:
- springcloud-config
##读取分支
label: master
##服务注册到eureka地址
eureka:
client:
service-url:
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka # 集群版
测试 http://localhost:3344/master/config-dev.yml
label分支 name 服务名 profile 环境(dev/test/prod)
http://localhost:3344/{label}/{application}-{profile}.yml
或者
http://localhost:3344/{application}-{profile}.yml
或者
http://localhost:3344/{application}/{profile}/master
客户端 访问中心端 服务
application.yml 是用户级别的资源配置项
bootstrap.yml 是系统级的 ,优先级更高
bus之 RabbitMQ环境配置
erlang下载地址 https://erlang.org/download/otp_win64_21.3.exe
RabbitMQ 下载地址 https://www.rabbitmq.com/install-windows.html
进入到RabbitMQ 安装目录下的sbin 目录
rabbitmq-plugins enable rabbitmq_management
Scloud stream
解决操作 ActiveMQ 、RabbitMQ 、RockerMQ 、kafka底层中间件的差异,降低切换成本,统一消息的编程模型。
Scloud stream 标准套路
binder 方便的连接中间件,屏蔽差异、channel 、source和sink 简单的理解未参照对象事springC loud Stream自身,从stream发布消息就是输出,接受消息就是输入。
SpringCloud Sleuth 分布式请求链路跟踪
Sleuth 配合 zipkin
zipkin jar包下载地址
https://repo1.maven.org/maven2/io/zipkin/java/zipkin-server/2.12.9/
下载完jar包后 调用 控制台运行
出现则代表下载成功 本地访问 9411端口 http://localhost:9411/zipkin/
<img alt="image-20220320102713917">
Alibaba Seate 处理分布式事务
Nacos
中文网址
下载版本
解压后运行 windos环境的话运行 startup.cmd
命令成功后直接访问 http://localhost:8848/nacos 账号默认 nacos /nacos
均衡负载 nacos 支持ap/cp的切换
模块
cloudalibaba-config-nacos-client3377
为啥有两个配置文件
Nacos 彤 springcloud-config 一样 ,在项目初始化时,要保证 从配置中心进行配置拉取
拉去配置之后,才能保证项目的正常启动。
Data Id
# ${spring.application.name}-${spring.profile.active}.${spring.cloud.nacos.config.file-extension}
# nacos-config-client-dev.yaml
group
namespace
nacos 集群集群和持久化配置 ***
https://nacos.io/zh-cn/docs/cluster-mode-quick-start.html 参考文档
nacos自带嵌入式数据库derby 集群部署需要切换到 mysql
nacos\conf\nacos-mysql.sql 执行脚本
然后nacos\conf\pplication.properties 更改配置
# spring.datasource.platform=mysql
### Count of DB:
# db.num=1
# db.url.0=jdbc:mysql://127.0.0.1:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
# db.user.0=nacos
# db.password.0=nacos
配置 cluster.conf 梳理三台nacos 集群的不同服务端口号
cp nacos\conf\cluster.conf.example cluster.conf
然后编辑 cluster.conf
添加 此处未ip 不能是127.0.0.1的ip
192.168.111.144:3333
192.168.111.144:4444
192.168.111.144:5555
修改start.sh 使它能够接受不同的启动端口号
while getopts ":m:f:s:" opt
do
case $opt in
m)
MODE=$OPTARG;;
f)
FUNCTION_MODE=$OPTARG;;
s)
SERVER=$OPTARG;;
?)
echo "Unknown parameter"
exit 1;;
esac
done
变更为
while getopts ":m:f:s:p:" opt
do
case $opt in
m)
MODE=$OPTARG;;
f)
FUNCTION_MODE=$OPTARG;;
s)
SERVER=$OPTARG;;
s)
port=$OPTARG;;
?)
echo "Unknown parameter"
exit 1;;
esac
done
nohup $JAVA ${JAVA_OPT} nacos.nacos >> ${BASE_DIR}/logs/start.out 2>&1 &
变更为
nohup $JAVA-Dserver.port=${PORT}${JAVA_OPT} nacos.nacos >> ${BASE_DIR}/logs/start.out 2>&1 &
配置完nacos 后进行配置nginx配置
<img alt="微信截图_20220321215523">
Sentinel 分布式系统的流量防卫兵 同 hystrix 熔断降级
优势:
单独的一个组件,可以独立出来
直接界面化的细粒度统一配置
下载地址 https://github.com/alibaba/Sentinel/releases
Sentinel 有两个部分
核心库(java客户端)
控制台 基于springboot 开发 打包后可以直接运行不需要额外的tomcat
下完jar包后 直接用java 命令启动 访问 http://localhost:8080
sentinel/sentinel
流控规则:
基本介绍:
流控模式: 直接 / 关联/链路
流控效果:
当与A关联的资源B达到阈值后,就限流A, 简言之B惹事,A挂了。
<img alt="微信截图_20220325153504">
测试postman
测试案例如下图
<img alt="微信截图_20220325153907">
流控预热:
预热单机阈值默认是3 预热时长为 5 s 即 在五秒内 将单机阈值 达到10
案例 系统初始化 阈值为10/3 约等于 3 ,刚开始分阈值开始为3 ,然后过了5秒后阈值才慢慢升高恢复到 10
<img alt="微信截图_20220325155756">
RT平均响应时间(秒级)
异常比例: 当比如异常请求数达到一定的比例是就会返回友好的提示
fallback 只负责业务异常 兜底 异常 熔断
blockhander 只负责 serntinel控制台配置违规 限流异常 降级
若fallback 和blockhander 都进行配置了,则被限流而降级抛出 BlockException 时 只会进入blockHander 处理逻辑。
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。