https://gitee.com/dai-xiangyin/sih/tree/master/%E7%9F%A5%E8%AF%86%E7%82%B9
服务注册
https://martinfowler.com/
Eureka
- @EnableEurekaClient
- @EnableEurekaServer 注册中心
zookeeper
- @EnableDiscoveryClient
consul - @EnableDiscoveryClient
服务调用
ribbon
loadBalancer
- @LoadBalanced
openfeign
- @EnableFeignClients
- @FeignClient(value = "服务名称")
服务降级
hystrix
1. 服务降级
主启动类
@EnableCircuitBreaker 回路
@EnableHystrix
全局
1. controller
类:
@DefaultProperties(defaultFallback = "**方法名**")
方法:
@HystrixCommand 不指明fallbackMethod,用DefaultProperties
2. service @FeignClient添加fallback
@FeignClient(value = "服务名称", fallback= class)
局部
@HystrixCommand(fallbackMethod = "**方法名**", commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value="3000")
})
@HystrixProperty描述
1. execution.isolation.thread.timeoutInMilliseconds 线程
2. 3000 1的线程超时时间3s 单位s
client -- yml:
feign:
hystrix:
enabled: true
2. 服务熔断
应对雪崩效应得一种微服务链路保护机制, 当检查到该节点微服务调用响应正常后,恢复调用链路
注解: @HystrixCommand
// 在10秒钟的窗口期 请求10次访问有60%失败率 跳闸
@HystrixCommand(fallbackMethod = "方法名", commandProperties = {
// 是否开启断路器
@HystrixProperty(name = "circuitBreaker.enabled", value = "true"),
// 请求次数
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),
// 时间窗口期
@HystrixProperty(name = "circuitBreaker.sellpwindowInMilliSeconds", value = "10000"),
// 失败率达到多少后跳闸
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60"),
})
服务监控
启动类: @EnableHystrixDashboard
出现这个异常: Unable to connect to Command Metric Stream
被监控服务启动类:
@Bean
public ServletRegistrationBean getServlet() {
HystrixMetricsStreamServlet hy = new HystrixMetricsStreamServlet();
ServletRegistrationBean rt = new ServletRegistrationBean(hy);
rt.setLoadOnStartup(1);
rt.addUrlMappings("/hystrix.stream");
rt.setName("<name>")
return rt
}
网关
Gateway
官网地址: https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-starter
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gatewar</artifactId>
</dependency>
Route 路由
由ID, 目标URL, 一系列断言和过滤器组成; 如果断言为true则匹配该路由
- 通过YML配置
spring:
# ····· 其他配置
cloud:
gateway:
discovery:
locator:
enabled: true #开启服务注册中心动态创建路由的功能,使用服务名
routes:
- id:
- id: unique_id #唯一ID
## url: http://localhost:8080 #微服务《原始》路由地址
url: lb://<服务名称>
predicates:
- Path=/do.something/** #断言,匹配地址
filters:
- ...
# 多个
- id: ····
####lb打头指的是去你的注册中心上找服务,http打头就要指定域名不能写服务名
#### https://blog.csdn.net/qq_41988504/article/details/107227870 动态路由java版
- 通过java手写
Predicate 断言
参考java8得java.util.function.Predicate
eg: - Path=/do.something/** #断言,匹配地址
- Path: 路径匹配
- After: 给与一个时间,表示这个时间以后的lb请求才有效 《ZonedDateTime.now()》
- Between: 同上,时间区间
- Cookie: key,value (正则)
- Header: key,value (正则)
- Host: 主机域名
- Method: GET/PUT?POST...
- Query: 参数名,value(正则)
Filter 过滤
指Spring框架中GatewayFilter的实例
eg: - AddRequestParamenter=X-Request-Id,1024
- AddRequestParamenter: key:value
自定义全局过滤器
// implements GolbalFilter, Ordered
/**
* @auther ButiF 2022/2/18
**/
public class GateWayFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String key = exchange.getRequest().getQueryParams().getFirst("key");
if (Objects.isNull(key)) {
// 反馈信息
exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
/**
* 数值月销优先级越高
*/
@Override
public int getOrder() {
return 0;
}
}
配置中心
Spring Cloud Config
服务端: 分布式配置中心,一个独立的微服务应用
客户端: 通过指定的配置中心来管理应用资源
服务端
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
spring:
cloud:
config:
server:
git:
url: <仓库地址>
search-paths:
- <仓库名称>
label: master
// 主启动注解
@EnableConfigServer
客户端
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config</artifactId>
</dependency>
bootstreap.yml 是系统级的,优先于application.yml
server:
port: 0000
spring:
application:
name: name
cloud:
config:
label: master # 分支名称
name: config # 配置文件名称
profile: dev # 后缀 config-dev.yml
动态刷新
- pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
- 修改bootstreap.yml
management:
endpoints:
web:
exposure:
include: "*"
- 修改controller
// 类上添加注解
@RefreshScope // 动态刷新
- curl -X POST "请求地址" 主动请求客户端刷新激活
消息总线
Spring Cloud Bus
配合SpringCloudConfig实现动态刷新
支持 RabbitMQ & KafKa
全局通知
设计思想
1. 利用消息总线触发一个***客户端***,从而刷新所有客户端
2. 利用消息总线触发一个***服务端***,从而刷新所有客户端 ***更优***
第二种:
- 修改bootstreap.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
# rabbitmq 配置
spring:
application:
name: name
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
# 暴露bus刷新配置的断电
management:
endpoints:
exposure:
include: 'bus-refresh'
## 被通知服务端配置: bus-refresh , 其他: *
- curl -X POST "服务端配置中心请求地址" 主动请求客户端刷新激活
定点通知
curl -X POST "服务端配置中心请求地址/spring.application.name:定点通知的端口号"
消息驱动
Spring Cloud Stream
目前仅支持RabbitMQ、Kafka
Binder 邦定器,链接中间件
Channel 通道,是队列Queue的一种抽象,在消息通知系统中就是实现存储和转发的媒介
Source和Sink: 输入/输出;生产者/消费者
1. 服务生产者配置示例
- 配置文件
<!-- stream-rabbit rabbit为例 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rabbit</artifactId>
</dependency>
# 配置示例
server:
port: 8801
spring:
application:
name: stream-rabbit-8801
cloud:
stream:
binders: # 在此配置要绑定的 <消息中间件> 的服务信息
defaultRabbit: # 表示定义的名称,用于binding整合
type: rabbit #消息中间件类型
environment: #rabbit相关配置
spring:
rabbitma:
host: localhost
port: 15672
username: guest
password: guest
bindings: #服务整合处理
output: #通道的名称 input、output
destination: studyExchange #表示使用的是Exchange<自定义名称>
content-type: application/json #设置消息类型 文本:text/plain
binder: defaultRabbit #设置要绑定的消息服务的具体设置
group: groupA # 重复消费问题,将消费者分配到同一个组;加了group 自动支持持久化
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka
instance:
# 心跳间隔时间
lease-renewal-interval-in-seconds: 2
# 超时时间
lease-expiration-duration-in-seconds: 5
# 自定义主机名称
instance-id: send-8801.com
# 访问路径变为IP false: 服务名称
prefer-ip-address: true
- 发送消息的功能示例
/**
* @auther ButiF 2022/2/19
**/
@EnableBinding(Source.class) //// 指信道channel和exchange绑定在一起; 定义消息的推送管道
public class IMessageProviderImpl implements IMessageProvider {
@Autowired
private MessageChannel output; // 消息发送管道
@Override
public String send() {
// 定义需要发送的消息
String msg = UUID.randomUUID().toString();
// 创建消息对象
Message<String> build = MessageBuilder.withPayload(msg).build();
boolean send = output.send(build);
return null;
}
}
1. 服务消费者配置示例
- 配置文件
<!-- stream-rabbit rabbit为例 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rabbit</artifactId>
</dependency>
server:
port: 80 #【 同上区别 】
spring:
application:
name: stream-rabbit-80 #【 同上区别 】
cloud:
stream:
binders: # 在此配置要绑定的 <消息中间件> 的服务信息
defaultRabbit: # 表示定义的名称,用于binding整合
type: rabbit #消息中间件类型
environment: #rabbit相关配置
spring:
rabbitma:
host: localhost
port: 15672
username: guest
password: guest
bindings: #服务整合处理
input: #通道的名称 input、output 【 同上区别 】
destination: studyExchange #表示使用的是Exchange<自定义名称>
content-type: application/json #设置消息类型 文本:text/plain
binder: defaultRabbit #设置要绑定的消息服务的具体设置
group: groupA # 重复消费问题,将消费者分配到同一个组;加了group 自动支持持久化
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka
instance:
# 心跳间隔时间
lease-renewal-interval-in-seconds: 2
# 超时时间
lease-expiration-duration-in-seconds: 5
# 自定义主机名称 【 同上区别 】
instance-id: receive-80.com
# 访问路径变为IP false: 服务名称
prefer-ip-address: true
- 业务类
@Component
@EnableBinding(Sink.class)
public class ReceiveMsgController {
@StreamListener(Sink.INPUT)
public void input(Message<String> message) {
// ······ 操作
System.out.println(message.getPayload());
}
}
重点
分组:重复消费问题(上面已添加)
group: groupA #避免重复消费的分组配置
实现轮询消费持久化: 加了group 自动支持持久化
Spring Cloud Sleuth 分布式请求链路跟踪
Sleuth: 收集
zipkin: 展现
zipkin下载地址:https://search.maven.org/remote_content?g=io.zipkin&a=zipkin-server&v=LATEST&c=exec
- 配置
服务者 & 消费者
<!--zipkin&sleuth-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
spring:
#······
zipkin:
base-url: http://127.0.0.1:9411/zipkin/
sleuth:
sampler:
# 采样率值间于 0/1 1表示全部采样
probability: 1