所有配套资料已上传到QQ群:167356412 需要的话群文件自取
十、Gateway新一代网关
1、概述简介
(1)、是什么
(2)、能干嘛
(3)、微服务架构中网关所处的位置
(4)、我们为什么选择Gateway
(5)、Zuul1模型
2、三大核心概念
(1)、Route(路由)
(2)、Predicate(断言)
(3)、Filter(过滤)
(4)、总体
3、Gateway工作流程
核心逻辑:路由转发+执行过滤器链
4、入门配置
(1)、引pom
<!--gateway-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
(2)、写yml
server:
port: 9527
spring:
application:
name: cloud-gateway
cloud:
gateway:
discovery:
locator:
enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
routes:
- id: payment_routh #payment_route #路由的ID,没有固定规则但要求唯一,建议配合服务名
#uri: http://localhost:8001 #匹配后提供服务的路由地址
uri: lb://cloud-payment-service #匹配后提供服务的路由地址
predicates:
- Path=/payment/get/** # 断言,路径相匹配的进行路由
- id: payment_routh2 #payment_route #路由的ID,没有固定规则但要求唯一,建议配合服务名
#uri: http://localhost:8001 #匹配后提供服务的路由地址
uri: lb://cloud-payment-service #匹配后提供服务的路由地址
predicates:
- Path=/payment/lb/** # 断言,路径相匹配的进行路由
#- After=2020-02-21T15:51:37.485+08:00[Asia/Shanghai]
#- Cookie=username,zzyy
#- Header=X-Request-Id, \d+ # 请求头要有X-Request-Id属性并且值为整数的正则表达式
eureka:
instance:
hostname: cloud-gateway-service
client: #服务提供者provider注册进eureka服务列表内
service-url:
register-with-eureka: true
fetch-registry: true
defaultZone: http://eureka7001.com:7001/eureka
(3)、如何做路由映射
spring:
application:
name: cloud-gateway
cloud:
gateway:
discovery:
locator:
enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
routes:
- id: payment_routh #payment_route #路由的ID,没有固定规则但要求唯一,建议配合服务名
uri: http://localhost:8001 #匹配后提供服务的路由地址
# uri: lb://cloud-payment-service #匹配后提供服务的路由地址
predicates:
- Path=/payment/get/** # 断言,路径相匹配的进行路由
- id: payment_routh2 #payment_route #路由的ID,没有固定规则但要求唯一,建议配合服务名
uri: http://localhost:8001 #匹配后提供服务的路由地址
# uri: lb://cloud-payment-service #匹配后提供服务的路由地址
predicates:
- Path=/payment/lb/** # 断言,路径相匹配的进行路由
#- After=2020-02-21T15:51:37.485+08:00[Asia/Shanghai]
#- Cookie=username,zzyy
#- Header=X-Request-Id, \d+ # 请求头要有X-Request-Id属性并且值为整数的正则表达式
(4)、yml新增网关配置
4)、Gateway的网关配置方法
①yml中配置(见前面步骤)
②代码中注入RouteLocator的Bean
配置
@Configuration
public class GateWayConfig
{
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder)
{
RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
routes.route("path_route_liuscoding",
r -> r.path("/guonei")
.uri("http://news.baidu.com/guonei")).build();
return routes.build();
}
}
(5)、yml配置说明
5、通过微服务名实现动态路由
(1)、开启动态路由功能
spring:
application:
name: cloud-gateway
cloud:
gateway:
discovery:
locator:
enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
(2)、将路由中写死的路由地址改为注册中心的服务名
routes:
- id: payment_routh #payment_route #路由的ID,没有固定规则但要求唯一,建议配合服务名
# uri: http://localhost:8001 #匹配后提供服务的路由地址
uri: lb://CLOUD-PAYMENT-SERVICE #匹配后提供服务的路由地址
predicates:
- Path=/payment/get/** # 断言,路径相匹配的进行路由
6、Predicate的使用
(1)、Route Predicate Factories是什么?
(2)、常用的Route Predicate
1)、After Route (时间级别路由)
获取当前时间方法:
public class T2 {
public static void main(String[] args) {
ZonedDateTime zbj = ZonedDateTime.now();//默认时区
System.out.println(zbj);
}
}
解释:当前路由必须在配置的时间后访问才能使用,配置世间之前不生效。
2)、Before Between 路由 (时间级别路由)
解释:Before 在配置世间前访问有效,之后无效。
Between 在配置世间区间内访问有效,之外无效。
3)、Cookie Route (Cookie限制路由)
操作 (curl相当于Postman等测试软件的底层实现)
不带cookie
带cookie
4)、Header Route (限制请求头信息)
5)、Host Route
6)、Method Route (请求方式 POST/GET 限制)
7)、Query Route (限制查询条件)
7、Filter的使用
(1)、Filter
(2)、常用的GatewayFilter
(3)、自定义过滤器
@Component
@Slf4j
public class MyLogGateWayFilter implements GlobalFilter, Ordered
{
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain)
{
log.info("***********come in MyLogGateWayFilter: "+new Date());
String uname = exchange.getRequest().getQueryParams().getFirst("uname");
if(uname == null)
{
log.info("*******用户名为null,非法用户,o(╥﹏╥)o");
exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
@Override
public int getOrder()
{
return 0;
}
}
十一、SpringCloud Config分布式配置中心
1、概述
(1)、分布式系统面临的配置问题
微服务意味着要将单体应用中的业务拆分成一个个子服务,每个服务的粒度相对较小,因此系统中会出现大量的服务。由于每个服务都需要必要的配置信息才能运行,所以一套集中式的、动态的配置管理设施是必不可少的。
SpringCloud提供了ConfigServer来解决这个问题,我们每一个微服务自己带着一个application.yml,上百个配置文件的管理......
(2)、是什么
SpringCloud Config为微服务架构中的微服务提供集中化的外部配置支持,配置服务器为各个不同微服务应用的所有环境提供了一个中心化的外部配置。
(3)、能干嘛
SpringCloud Config分为服务端和客户端两部分。
服务端也称为分布式配置中心,它是一个独立的微服务应用,用来连接配置服务器并为客户端提供获取配置信息,加密/解密信息等访问接口
客户端则是通过指定的配置中心来管理应用资源,以及与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息配置服务器默认采用git来存储配置信息,这样就有助于对环境配置进行版本管理,并且可以通过git客户端工具来方便的管理和访问配置内容
(4)、与Github整合配置
由于SpringCloud Config默认使用Git来存储配置文件(也有其它方式,比如支持SVN和本地文件),但最推荐的还是Git,而且使用的是http/https访问的形式。
2、Config服务端配置与测试
(1)、引入pom
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
(2)、yml
server:
port: 3344
spring:
application:
name: cloud-config-center #注册进Eureka服务器的微服务名
cloud:
config:
server:
git:
uri: https://github.com/liusCoding/springcloud-config.git #GitHub上面的git仓库名字
####搜索目录
search-paths:
- springcloud-config
####读取分支
label: master
#服务注册到eureka地址
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka
(3)、主启动类
(4)、仓库
(5)、效果
(6)、配置规则
默认master
3、Config客户端配置与测试
(1)、pom
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
(2)、bootstrap.yml
bootstrap详解:
applicaiton.yml是用户级的资源配置项
bootstrap.yml是系统级的,优先级更加高
Spring Cloud会创建一个“BootstrapContext”,作为Spring应用的`Application Context的父上下文。初始化的时候,`BootstrapContext`负责从外部源加载配置属性并解析配置。这两个上下文共享一个从外部获取的'Environment'。
'Bootstrap`属性有高优先级,默认情况下,它们不会被本地配置覆盖。Bootstrap context和 Application ~onteXTt月有个同的到正,所以新增了一个'bootstrap.yml'文件,保证`Bootstrap Context`和`Application Context'`配置的分离。
要将Client模块下的application.yml文件改为bootstrap.yml,这是很关键的,
因为bootstrap.yml是比application.yml先加载的。bootstrap.yml优先级高于application.yml
配置
server:
port: 3355
spring:
application:
name: config-client
cloud:
#Config客户端配置
config:
label: master #分支名称
name: config #配置文件名称
profile: dev #读取后缀名称 上述3个综合:master分支上config-dev.yml的配置文件被读取http://config-3344.com:3344/master/config-dev.yml
uri: http://localhost:3344 #配置中心地址k
#rabbitmq相关配置 15672是Web管理界面的端口;5672是MQ访问的端口
# rabbitmq:
# host: localhost
# port: 5672
# username: guest
# password: guest
#服务注册到eureka地址
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka
# 暴露监控端点
#management:
# endpoints:
# web:
# exposure:
# include: "*"
(3)、业务类
@RestController
//@RefreshScope
public class ConfigClientController {
@Value("${config.info}")
private String configInfo;
@GetMapping("/configInfo")
public String getConfigInfo() {
return configInfo;
}
}
4、Config客户端之动态刷新
(1)、引pom 方便被别的服务监控到
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
(2)、改yml
# 暴露监控端点
management:
endpoints:
web:
exposure:
include: "*"
(3)、加注解
(4)、发送POST请求
http://localhost:3355/actuator/refresh POST请求!!!
(5)、效果
(6)、问题
解决:引入消息总线
十二、SpringCloud Bus消息总线
1、概述
(1)、是什么
(2)、能干嘛
(3)、为什么被称为总线?
2、RabbitMQ环境配置
(1)、引pom
<!--添加消息总线RabbitMQ支持-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
(2)、改yml
server:
port: 3366
spring:
application:
name: config-client
cloud:
#Config客户端配置
config:
label: master #分支名称
name: config #配置文件名称
profile: dev #读取后缀名称 上述3个综合:master分支上config-dev.yml的配置文件被读取http://config-3344.com:3344/master/config-dev.yml
uri: http://localhost:3344 #配置中心地址
#rabbitmq相关配置 15672是Web管理界面的端口;5672是MQ访问的端口
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
#服务注册到eureka地址
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka
# 暴露监控端点
management:
endpoints:
web:
exposure:
include: "*"
(3)、业务类
@RestController
@RefreshScope
public class ConfigClientController
{
@Value("${server.port}")
private String serverPort;
@Value("${config.info}")
private String configInfo;
@GetMapping("/configInfo")
public String configInfo()
{
return "serverPort: "+serverPort+"\t\n\n configInfo: "+configInfo;
}
}
(4)、设计思想
思想1
思想2
思路1不合适的原因
3、SpringCloud Bus动态刷新全局广播
(1)、服务器、客户端引入pom
<!--添加消息总线RabbitMQ支持-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
(2)、config服务器改yml增加rabbitmq配置
##rabbitmq相关配置
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
#rabbitmq相关配置,暴露bus刷新配置的端点
management:
endpoints: #暴露bus刷新配置的端点
web:
exposure:
include: 'bus-refresh'
(3)、客户端配置yml
spring:
#rabbitmq相关配置 15672是Web管理界面的端口;5672是MQ访问的端口
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
# 暴露监控端点
management:
endpoints:
web:
exposure:
include: "*"
4、SpringCloud Bus动态刷新定点通知
(1)、不想全部通知,需要定点通知。
(2)、指定具体某一实例生效而不是全部生效
(3)、案例
destination:微服务名称 + : + 3355
只通知3355
(4)、通知总结
十三、SpringCloud Stream消息驱动
1、为什么引入Cloud Stream?
2、概述
(1)、什么是SpringCloudStream?
官方定义Spring Cloud Stream是一个构建消息驱动微服务的框架。
应用程序通过inputs 或者outputs来与Spring Cloud Stream中binder对象交互。
通过我们配置来birlding(绑定),而Spring Cloud Stream的 binder对象负责
与消息中间件交互。所以,我们只需要搞清楚如何与Spring Cloud Stream交互就可以方便使用消息驱动的方式。
通过使用Spring Integration来连接消息代理中间件以实现消息事件驱动。
Spring Cloud Stream为一些供应商的消息中间件产品提供了个性化的自动化配置实现
引用了发布-订阅、消费组、分区的三个核心概念。
目前仅支持RabbitMQ、Kafka。
(2)、设计思想
1)、标准mq
2)、为什么用Cloud Stream?
这些中间件的差异性导致我们实际项目开发给我们造成了一定的困扰,我们如果用了两个消息队列的其中一种,后面的业务需求,我想往另外一种消息队列进行迁移,这时候无疑就是一个灾难性的,一大堆东西都要重新推倒重新做,因为它跟我们的系统耦合了,这时候springcloud Stream给我们提供了—种解耦合的方式。
3)、为什么能实现?
(3)、Spring Cloud Stream标准流程套路
Channel:
(4)、编码API和常用注解
4、消息驱动之生产者
(1)、引pom rabbitmq
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rabbit</artifactId>
</dependency>
(2)、yml
server:
port: 8801
spring:
application:
name: cloud-stream-provider
cloud:
stream:
binders: # 在此处配置要绑定的rabbitmq的服务信息;
defaultRabbit: # 表示定义的名称,用于于binding整合
type: rabbit # 消息组件类型
environment: # 设置rabbitmq的相关的环境配置
spring:
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
bindings: # 服务的整合处理
output: # 这个名字是一个通道的名称
destination: studyExchange # 表示要使用的Exchange名称定义
content-type: application/json # 设置消息类型,本次为json,文本则设置“text/plain”
binder: defaultRabbit # 设置要绑定的消息服务的具体设置
eureka:
client: # 客户端进行Eureka注册的配置
service-url:
defaultZone: http://localhost:7001/eureka
instance:
lease-renewal-interval-in-seconds: 2 # 设置心跳的时间间隔(默认是30秒)
lease-expiration-duration-in-seconds: 5 # 如果现在超过了5秒的间隔(默认是90秒)
instance-id: send-8801.com # 在信息列表时显示主机名称
prefer-ip-address: true # 访问的路径变为IP地址
(3)、主启动
@SpringBootApplication
@EnableEurekaClient
public class StreamMain8801 {
public static void main(String[] args) {
SpringApplication.run(StreamMain8801.class, args);
}
}
(4)、业务类
发送消息接口
public interface IMessageProvider {
public String send();
}
接口实现类
@EnableBinding(Source.class) //定义消息的推送管道
public class MessageProviderImpl implements IMessageProvider {
@Resource
private MessageChannel output; //消息发送管道
@Override
public String send() {
String serial = UUID.randomUUID().toString();
output.send(MessageBuilder.withPayload(serial).build());
System.out.println("******serial: " + serial);
return null;
}
}
controller
@RestController
public class SendMessageController {
@Resource
private IMessageProvider messageProvider;
@GetMapping(value = "/sendMessage")
public String sendMessage(){
return messageProvider.send();
}
}
5、消息驱动之消费者
(1)、引pom rabbitmq
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rabbit</artifactId>
</dependency>
(2)、yml
server:
port: 8802
spring:
application:
name: cloud-stream-consumer
cloud:
stream:
binders: # 在此处配置要绑定的rabbitmq的服务信息;
defaultRabbit: # 表示定义的名称,用于于binding整合
type: rabbit # 消息组件类型
environment: # 设置rabbitmq的相关的环境配置
spring:
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
bindings: # 服务的整合处理
input: # 这个名字是一个通道的名称
destination: studyExchange # 表示要使用的Exchange名称定义
content-type: application/json # 设置消息类型,本次为对象json,如果是文本则设置“text/plain”
binder: defaultRabbit # 设置要绑定的消息服务的具体设置
#group: liuscoding
eureka:
client: # 客户端进行Eureka注册的配置
service-url:
defaultZone: http://localhost:7001/eureka
instance:
lease-renewal-interval-in-seconds: 2 # 设置心跳的时间间隔(默认是30秒)
lease-expiration-duration-in-seconds: 5 # 如果现在超过了5秒的间隔(默认是90秒)
instance-id: receive-8802.com # 在信息列表时显示主机名称
prefer-ip-address: true # 访问的路径变为IP地址
(3)、主启动类
@SpringBootApplication
@EnableEurekaClient
public class StreamMQMain8802 {
public static void main(String[] args) {
SpringApplication.run(StreamMQMain8802.class,args);
}
}
(4)、业务类
@Controller
@EnableBinding(Sink.class)
public class ReceiveMessageListenerController {
@Value("${server.Port}")
private String serverPort;
@StreamListener(Sink.INPUT)
public void input(Message<String> message) {
System.out.println("消费者1号,---->接收到的消息:" + message.getPayload() + "\t port" + serverPort);
}
}
6、分组消费与持久化
(1)、启动
(2)、运行问题
(3)、消费
生产实际案例
(4)、分组
解释
不同组重复消费演示
配置
(5)、持久化
总结:一直监听队列中的消息,不能脱离绑定,否则消息丢失。
十四、SpringCloud Sleuth分布式请求链路追踪
1、概述
(1)、为什么出现这个技术?需要解决那些问题?
在微服务框架中,一个由客户端发起的请求在后端系统中会经过多个不同的的服务节点调用来协同产生最后的请求结果,每一个前段请求都会形成一条复杂的分布式服务调用链路,链路中的任何一环出现高延时或错误都会引起整个请求最后的失败。
(2)、是什么
(3)、解决
2、搭建链路步骤
(1)、启动 运行jar
(2)、运行控制台
(3)、完整的调用链路
表示一请求链路,一条链路通过Trace ld唯一标识,Span标识发起的请求信息,各span通过parent id关联起来
(4)、引入依赖 生产消费都要配置
<dependency>
<groupId>repository.org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
(5)、配置yml 生产消费都要配置
生产者
spring:
application:
name: cloud-payment-service
zipkin:
base-url: http://localhost:9411
sleuth:
sampler:
#采样率值介于 0 到 1 之间,1 则表示全部采集
probability: 1
消费者
spring:
application:
name: cloud-order-service
zipkin:
base-url: http://localhost:9411
sleuth:
sampler:
#采样率值介于 0 到 1 之间,1 则表示全部采集
probability: 1
(6)、业务类
生产者
@GetMapping("/payment/zipkin")
public String paymentZipkin(){
return "hi ,i'am paymentzipkin server fall back, welcome to aiguigu.";
}
消费者
@GetMapping("/consumer/payment/zipkin")
public String paymentZipkin() {
String result = restTemplate.getForObject("http://localhost:8001" + "/payment/zipkin/", String.class);
return result;
}