Spring Cloud(2020版) 学习笔记(三)
54.Bus消息总线是什么
- 上—讲解的加深和扩充
一言以蔽之,分布式自动刷新配置功能。
Spring Cloud Bus配合Spring Cloud Config使用可以实现配置的动态刷新。
- 是什么
Spring Cloud Bus 配合Spring Cloud Config 使用可以实现配置的动态刷新。
Spring Cloud Bus是用来将分布式系统的节点与轻量级消息系统链接起来的框架,它整合了Java的事件处理机制和消息中间件的功能。Spring Clud Bus目前支持RabbitMQ和Kafka。
- 能干嘛
Spring Cloud Bus能管理和传播分布式系统间的消息,就像一个分布式执行器,可用于广播状态更改、事件推送等,也可以当作微服务间的通信通道。
- 什么是总线
在微服务架构的系统中,通常会使用轻量级的消息代理来构建一个共用的消息主题,并让系统中所有微服务实例都连接上来。由于该主题中产生的消息会被所有实例监听和消费,所以称它为消息总线。在总线上的各个实例,都可以方便地广播一些需要让其他连接在该主题上的实例都知道的消息。
- 基本原理
ConfigClient实例都监听MQ中同一个topic(默认是Spring Cloud Bus)。当一个服务刷新数据的时候,它会把这个信息放入到Topic中,这样其它监听同一Topic的服务就能得到通知,然后去更新自身的配置。
55.Bus之RabbitMQ环境配置
-
安装Erlang,下载地址:http://erlang.org/download/otp_win64_21.3.exe
-
安装RabbitMQ,下载地址:https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.8.3/rabbitmq-server-3.8.3.exe
-
打开cmd进入RabbitMQ安装目录下的sbin目录,如:D:\devSoft\RabbitMQ Scrverk\rabbitmq_server-3.7.14\sbin
-
输入以下命令启动管理功能
rabbitmq-plugins enable rabbitmq _management
这样就可以添加可视化插件。
-
访问地址查看是否安装成功:http://localhost:15672/
-
输入账号密码并登录:guest guest
56.Bus动态刷新全局广播的设计思想和选型
- 修改cloud-config-center的pom文件
<!--添加消息总线RabbitNQ支持-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amap</artifactId>
</dependency>
<dependency>
<groupId>org-springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
或者
<!--添加消息总线kafka支持-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-kafka</artifactId>
</dependency>
<dependency>
<groupId>org-springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
- yaml文件
- RabbitNQ
server:
port: 3344
spring:
application:
name: cloud-config-center #注册进Eureka服务器的微服务名
cloud:
config:
server:
git:
uri: https://github.com/20086996/springcloud-config.git #GitHub上面的git仓库名字
username: 20086996
password: hd20086996
####搜索目录
search-paths:
- springcloud-config
####读取分支
label: master
#rabbitmq相关配置<--------------------------
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
#服务注册到eureka地址
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka
##rabbitmq相关配置,暴露bus刷新配置的端点<--------------------------
management:
endpoints: #暴露bus刷新配置的端点
web:
exposure:
include: 'bus-refresh'
- kafka
server:
port: 3344
spring:
application:
name: cloud-config-center #注册进Eureka服务器的微服务名
cloud:
config:
server:
git:
uri: https://github.com/20086996/springcloud-config.git #GitHub上面的git仓库名字
username: 20086996
password: hd20086996
####搜索目录
search-paths:
- springcloud-config
####读取分支
label: master
kafka:
bootstrap-servers: 172.18.8.97:9092
#服务注册到eureka地址
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka
##rabbitmq相关配置,暴露bus刷新配置的端点<--------------------------
management:
endpoints: #暴露bus刷新配置的端点
web:
exposure:
include: 'bus-refresh'
- 修改客户端
- 修改cloud-provider-payment的pom文件
RabbitNQ
<!--添加消息总线RabbitNQ支持-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amap</artifactId>
</dependency>
<dependency>
<groupId>org-springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
或者kafka
<!--添加消息总线kafka支持-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-kafka</artifactId>
</dependency>
<dependency>
<groupId>org-springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
- 修改yaml
kafka
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource # 当前数据源操作类型
driver-class-name: org.gjt.mm.mysql.Driver # mysql驱动包
url: jdbc:mysql://172.18.8.117:3306/new_assets_db?useAffectedRows=true&allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=CTT&zeroDateTimeBehavior=convertToNull
username: root
password: 7cz.jXR3mycw
kafka:
bootstrap-servers: 172.18.8.97:9092
eureka:
client:
#表示是否将自己注册进Eurekaserver默认为true。
register-with-eureka: true
#是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetchRegistry: true
# Eureka Server每8秒拉取服务地址清单后缓存到本地
registry-fetch-interval-seconds: 8
service-url:
defaultZone: http://localhost:7001/eureka
# defaultZone: http://eureka7001.com:7001/eureka, http://eureka7002.com:7002/eureka
instance:
instance-id: payment8001 #添加此处
prefer-ip-address: true #添加此处
#心跳检测与续约时间
#开发时没置小些,保证服务关闭后注册中心能即使剔除服务
#Eureka客户端向服务端发送心跳的时间间隔,单位为秒(默认是30秒)
lease-renewal-interval-in-seconds: 1
#Eureka服务端在收到最后一次心跳后等待时间上限,单位为秒(默认是90秒),超时将剔除服务
lease-expiration-duration-in-seconds: 2
mybatis:
mapperLocations: classpath:mapper/*.xml
type-aliases-package: com.chenyc.springcloud.entities # 所有Entity别名类所在包
#开启
feign:
hystrix:
enabled: true
config:
info: "master branch,springcloud-config/application-dev.yml version=2"
# 暴露监控端点
management:
endpoints:
web:
exposure:
include: "*"
RabbitNQ
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource # 当前数据源操作类型
driver-class-name: org.gjt.mm.mysql.Driver # mysql驱动包
url: jdbc:mysql://172.18.8.117:3306/new_assets_db?useAffectedRows=true&allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=CTT&zeroDateTimeBehavior=convertToNull
username: root
password: 7cz.jXR3mycw
#rabbitmq相关配置 15672是Web管理界面的端口;5672是MQ访问的端口<----------------------
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
eureka:
client:
#表示是否将自己注册进Eurekaserver默认为true。
register-with-eureka: true
#是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetchRegistry: true
# Eureka Server每8秒拉取服务地址清单后缓存到本地
registry-fetch-interval-seconds: 8
service-url:
defaultZone: http://localhost:7001/eureka
# defaultZone: http://eureka7001.com:7001/eureka, http://eureka7002.com:7002/eureka
instance:
instance-id: payment8001 #添加此处
prefer-ip-address: true #添加此处
#心跳检测与续约时间
#开发时没置小些,保证服务关闭后注册中心能即使剔除服务
#Eureka客户端向服务端发送心跳的时间间隔,单位为秒(默认是30秒)
lease-renewal-interval-in-seconds: 1
#Eureka服务端在收到最后一次心跳后等待时间上限,单位为秒(默认是90秒),超时将剔除服务
lease-expiration-duration-in-seconds: 2
mybatis:
mapperLocations: classpath:mapper/*.xml
type-aliases-package: com.chenyc.springcloud.entities # 所有Entity别名类所在包
#开启
feign:
hystrix:
enabled: true
config:
info: "master branch,springcloud-config/application-dev.yml version=2"
# 暴露监控端点
management:
endpoints:
web:
exposure:
include: "*"
- 测试
启动一下服务
- EurekaMain7001
- ConfigcenterMain3344
- cloud-provider-payment8001
- cloud-provider-payment8002
运维工程师
- 修改Github上配置文件内容,增加版本号
- 发送POST请求
curl -X POST “http://localhost:3344/actuator/bus-refresh” - —次发送,处处生效
客户端
- http://localhost:8001/configInfo
- http://localhost:8002/configInfo
- 获取配置信息,发现都已经刷新了
—次修改,广播通知,处处生效
57.Bus动态刷新定点通知
不想全部通知,只想定点通知
只通知8001
不通知8002
简单一句话 - 指定具体某一个实例生效而不是全部
公式:http://localhost:3344/actuator/bus-refresh/{destination}
/bus/refresh请求不再发送到具体的服务实例上,而是发给config server通过destination参数类指定需要更新配置的服务或实例
案例
我们这里以刷新运行在8001端口上的cloud-provider-payment(配置文件中设定的应用名称)为例,只通知8001,不通知8002
curl -X POST "http://localhost:3344/actuator/bus-refresh/cloud-provider-payment:8001
58.Sleuth是什么
- 为什么会出现这个技术?要解决哪些问题?
在微服务框架中,一个由客户端发起的请求在后端系统中会经过多个不同的的服务节点调用来协同产生最后的请求结果,每一个前段请求都会形成一条复杂的分布式服务调用链路,链路中的任何一环出现高延时或错误都会引起整个请求最后的失败。
是什么
- https://github.com/spring-cloud/spring-cloud-sleuth
- Spring Cloud Sleuth提供了一套完整的服务跟踪的解决方案
- 在分布式系统中提供追踪解决方案并且兼容支持了zipkin
解决
59. Sleuth之zipkin搭建安装
下载
- SpringCloud从F版起已不需要自己构建Zipkin Server了,只需调用jar包即可
- https://dl.bintray.com/openzipkin/maven/io/zipkin/java/zipkin-server/
- zipkin-server-2.12.9-exec.jar
运行jar
java -jar zipkin-server-2.12.9-exec.jar
运行控制台
- http://localhost:9411/zipkin/
术语
-
完整的调用链路
-
表示一请求链路,一条链路通过Trace ld唯一标识,Span标识发起的请求信息,各span通过parent id关联起来
60.Sleuth链路监控展现
- cloud-provider-payment的pom文件新增依赖
<!--包含了sleuth+zipkin-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
- 修改yaml
spring:
profiles:
active: payment8001
---
# 8001和8002测试用eureka作为注册中心
server:
port: 8001
spring:
application:
name: cloud-provider-payment
profiles: payment8001
cloud:
config:
label: master #分支名称
name: application #配置文件名称
profile: dev #读取后缀名称 上述3个综合:master分支上config-dev.yml的配置文件被读取http://config-3344.com:3344/master/config-dev.yml
uri: http://localhost:3344 #配置中心地址k
zipkin: #<-------------------------------------关键
base-url: http://localhost:9411
sleuth: #<-------------------------------------关键
sampler:
#采样率值介于 0 到 1 之间,1 则表示全部采集
probability: 1
---
server:
port: 8002
spring:
application:
name: cloud-provider-payment
profiles: payment8002
cloud:
config:
label: master #分支名称
name: application #配置文件名称
profile: dev #读取后缀名称 上述3个综合:master分支上config-dev.yml的配置文件被读取http://config-3344.com:3344/master/config-dev.yml
uri: http://localhost:3344 #配置中心地址k
zipkin: #<-------------------------------------关键
base-url: http://localhost:9411
sleuth: #<-------------------------------------关键
sampler:
#采样率值介于 0 到 1 之间,1 则表示全部采集
probability: 1
- PaymentController
@RestController
@Slf4j
public class PaymentController {
...
@GetMapping("/payment/zipkin")
public String paymentZipkin() {
return "hi ,i'am paymentzipkin server fall back,welcome to here, O(∩_∩)O哈哈~";
}
}
- cloue-consumer-order的pm文件新增依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
- 修改yaml
spring:
profiles:
active: orderEureka
---
#将order服务注册到eureka的配置
server:
port: 80
spring:
application:
name: cloud-consumer-order
profiles: orderEureka
zipkin: #<-------------------------------------关键
base-url: http://localhost:9411
sleuth: #<-------------------------------------关键
sampler:
#采样率值介于 0 到 1 之间,1 则表示全部采集
probability: 1
eureka:
client:
#表示是否将自己注册进Eurekaserver默认为true。
register-with-eureka: true
#是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetchRegistry: true
service-url:
defaultZone: http://localhost:7001/eureka
# defaultZone: http://eureka7001.com:7001/eureka, http://eureka7002.com:7002/eureka
#设置feign客户端超时时间(OpenFeign默认支持ribbon)(单位:毫秒)
ribbon:
#指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间
ReadTimeout: 5000
#指的是建立连接后从服务器读取到可用资源所用的时间
ConnectTimeout: 5000
logging:
level:
# feign日志以什么级别监控哪个接口
com.chenyc.springcloud.openFeign.PaymentFeignService: debug
#开启
feign:
hystrix:
enabled: true
---
#将order服务注册到zookeeper的配置
server:
port: 80
spring:
application:
name: cloud-consumer-order
profiles: orderZookeeper
cloud:
zookeeper:
connect-string: 172.18.8.112:2181
---
#将order服务注册到consul的配置
server:
port: 80
spring:
application:
name: cloud-consumer-order
profiles: orderConsul
cloud:
consul:
host: localhost
port: 8500
discovery:
#hostname: 127.0.0.1
service-name: ${spring.application.name}
- 修改controller,新增方法
// ====================> zipkin+sleuth
@GetMapping("/payment/zipkin")
public String paymentZipkin()
{
String result = restTemplate.getForObject("http://localhost:8001"+"/payment/zipkin/", String.class);
return result;
}
- 测试
80调用8001几次测试下
http://localhost/consumer/payment/zipkin
打开浏览器访问: http://localhost:9411
61Stream为什么被引入
常见MQ(消息中间件):
- ActiveMQ
- RabbitMQ
- RocketMQ
- Kafka
有没有一种新的技术诞生,让我们不再关注具体MQ的细节,我们只需要用一种适配绑定的方式,自动的给我们在各种MQ内切换。(类似于Hibernate)
Cloud Stream是什么?屏蔽底层消息中间件的差异,降低切换成本,统一消息的编程模型。
62.Stream是什么及Binder介绍
- 什么是Spring Cloud Stream?
官方定义Spring Cloud Stream是一个构建消息驱动微服务的框架。
应用程序通过inputs或者 outputs 来与Spring Cloud Stream中binder对象交互。
通过我们配置来binding(绑定),而Spring Cloud Stream 的binder对象负责与消息中间件交互。所以,我们只需要搞清楚如何与Spring Cloud Stream交互就可以方便使用消息驱动的方式。
通过使用Spring Integration来连接消息代理中间件以实现消息事件驱动。
Spring Cloud Stream为一些供应商的消息中间件产品提供了个性化的自动化配置实现,引用了发布-订阅、消费组、分区的三个核心概念。
目前仅支持RabbitMQ、 Kafka。
63.Stream的设计思想
标准MQ
- 生产者/消费者之间靠消息媒介传递信息内容
- 消息必须走特定的通道 - 消息通道 Message Channel
- 消息通道里的消息如何被消费呢,谁负责收发处理 - 消息通道MessageChannel的子接口SubscribableChannel,由MessageHandler消息处理器所订阅。
为什么用Cloud Stream?
比方说我们用到了RabbitMQ和Kafka,由于这两个消息中间件的架构上的不同,像RabbitMQ有exchange,kafka有Topic和Partitions分区。
这些中间件的差异性导致我们实际项目开发给我们造成了一定的困扰,我们如果用了两个消息队列的其中一种,后面的业务需求,我想往另外一种消息队列进行迁移,这时候无疑就是一个灾难性的,一大堆东西都要重新推倒重新做,因为它跟我们的系统耦合了,这时候Spring Cloud Stream给我们提供了—种解耦合的方式。
Stream凭什么可以统一底层差异?
在没有绑定器这个概念的情况下,我们的SpringBoot应用要直接与消息中间件进行信息交互的时候,由于各消息中间件构建的初衷不同,它们的实现细节上会有较大的差异性通过定义绑定器作为中间层,完美地实现了应用程序与消息中间件细节之间的隔离。通过向应用程序暴露统一的Channel通道,使得应用程序不需要再考虑各种不同的消息中间件实现。
通过定义绑定器Binder作为中间层,实现了应用程序与消息中间件细节之间的隔离。
Binder:
INPUT对应于消费者
OUTPUT对应于生产者
Stream中的消息通信方式遵循了发布-订阅模式
Topic主题进行广播
- 在RabbitMQ就是Exchange
- 在Kakfa中就是Topic
64.Stream编码常用注解简介
Spring Cloud Stream标准流程套路
-
Binder - 很方便的连接中间件,屏蔽差异。
-
Channel - 通道,是队列Queue的一种抽象,在消息通讯系统中就是实现存储和转发的媒介,通过Channel对队列进行配置。
-
Source和Sink - 简单的可理解为参照对象是Spring Cloud Stream自身,从Stream发布消息就是输出,接受消息就是输入。
编码API和常用注解
案例说明
准备RabbitMQ环境(55.Bus之RabbitMQ环境配置有提及)
工程中新建三个子模块
- cloud-consumer-order(80),作为生产者进行发消息模块
- cloud-provider-payment(8001),作为消息接收模块
- cloud-provider-payment(8002),作为消息接收模块
65.Stream消息驱动之生产者
- cloud-consumer-order模块pom文件新增依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rabbit</artifactId>
</dependency>
- yaml文件修改
spring:
profiles:
active: orderEureka
---
#将order服务注册到eureka的配置
server:
port: 80
spring:
application:
name: cloud-consumer-order
profiles: orderEureka
zipkin: #<-------------------------------------关键
base-url: http://localhost:9411
sleuth: #<-------------------------------------关键
sampler:
#采样率值介于 0 到 1 之间,1 则表示全部采集
probability: 1
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:
#表示是否将自己注册进Eurekaserver默认为true。
register-with-eureka: true
#是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetchRegistry: true
service-url:
defaultZone: http://localhost:7001/eureka
# defaultZone: http://eureka7001.com:7001/eureka, http://eureka7002.com:7002/eureka
#设置feign客户端超时时间(OpenFeign默认支持ribbon)(单位:毫秒)
ribbon:
#指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间
ReadTimeout: 5000
#指的是建立连接后从服务器读取到可用资源所用的时间
ConnectTimeout: 5000
logging:
level:
# feign日志以什么级别监控哪个接口
com.chenyc.springcloud.openFeign.PaymentFeignService: debug
#开启
feign:
hystrix:
enabled: true
---
#将order服务注册到zookeeper的配置
server:
port: 80
spring:
application:
name: cloud-consumer-order
profiles: orderZookeeper
cloud:
zookeeper:
connect-string: 172.18.8.112:2181
---
#将order服务注册到consul的配置
server:
port: 80
spring:
application:
name: cloud-consumer-order
profiles: orderConsul
cloud:
consul:
host: localhost
port: 8500
discovery:
#hostname: 127.0.0.1
service-name: ${spring.application.name}
- 业务类
发送消息接口
public interface IMessageProvider {
public String send();
}
发送消息接口实现类
import com.lun.springcloud.service.IMessageProvider;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.messaging.Source;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.messaging.MessageChannel;
import javax.annotation.Resource;
import java.util.UUID;
@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新增方法
@Resource
private IMessageProvider messageProvider;
@GetMapping(value = "/sendMessage")
public String sendMessage() {
return messageProvider.send();
}
66.Stream消息驱动之消费者
- cloud-provider-payment模块修改pom文件
<!--stream-kafka-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-kafka</artifactId>
</dependency>
- 原有基础上增加以下配置
spring:
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 # 设置要绑定的消息服务的具体设置
业务类
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.cloud.stream.messaging.Sink;
import org.springframework.messaging.Message;
import org.springframework.stereotype.Component;
@Component
@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);
}
}
67.stream之kafka
- 修改cloud-consumer-order的pom文件,新增依赖
<!--stream-kafka-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-kafka</artifactId>
</dependency>
- 修改yaml
spring:
profiles:
active: orderEureka
---
#将order服务注册到eureka的配置
server:
port: 80
spring:
application:
name: cloud-consumer-order
profiles: orderEureka
# zipkin: #<-------------------------------------关键
# base-url: http://localhost:9411
# sleuth: #<-------------------------------------关键
# sampler:
# #采样率值介于 0 到 1 之间,1 则表示全部采集
# probability: 1
cloud:
stream:
kafka:
binder:
brokers: 172.xxx.xxx.xxx:9092
bindings:
greetings-out:
destination: greetings
contentType: application/json
eureka:
client:
#表示是否将自己注册进Eurekaserver默认为true。
register-with-eureka: true
#是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetchRegistry: true
service-url:
defaultZone: http://localhost:7001/eureka
# defaultZone: http://eureka7001.com:7001/eureka, http://eureka7002.com:7002/eureka
#设置feign客户端超时时间(OpenFeign默认支持ribbon)(单位:毫秒)
ribbon:
#指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间
ReadTimeout: 5000
#指的是建立连接后从服务器读取到可用资源所用的时间
ConnectTimeout: 5000
logging:
level:
# feign日志以什么级别监控哪个接口
com.chenyc.springcloud.openFeign.PaymentFeignService: debug
#开启
feign:
hystrix:
enabled: true
---
#将order服务注册到zookeeper的配置
server:
port: 80
spring:
application:
name: cloud-consumer-order
profiles: orderZookeeper
cloud:
zookeeper:
connect-string: 172.18.8.112:2181
---
#将order服务注册到consul的配置
server:
port: 80
spring:
application:
name: cloud-consumer-order
profiles: orderConsul
cloud:
consul:
host: localhost
port: 8500
discovery:
#hostname: 127.0.0.1
service-name: ${spring.application.name}
- 新增配置类
package com.chenyc.springcloud.config;
import org.springframework.cloud.stream.annotation.Input;
import org.springframework.cloud.stream.annotation.Output;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.SubscribableChannel;
public interface GreetingsStreams {
String OUTPUT = "greetings-out";
@Output(OUTPUT)
MessageChannel outboundGreetings();
}
- 启动类新增注解@EnableBinding
package com.chenyc.springcloud;
import com.chenyc.myrule.MySelfRule;
import com.chenyc.springcloud.config.GreetingsStreams;
import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.context.annotation.Bean;
/**
* @author chenyc
* @create 2021-03-29 19:55
*/
@SpringBootApplication
@EnableEurekaClient//<--- Enable服务注册添加该标签
@EnableDiscoveryClient//<--- zookeeper服务注册添加该标签
//添加到此处
@RibbonClient(name = "CLOUD-PROVIDER-PAYMENT", configuration = MySelfRule.class)
@EnableFeignClients
@EnableHystrix//添加到此处
@EnableBinding(GreetingsStreams.class)
public class OrderMain {
public static void main(String[] args) {
SpringApplication.run(OrderMain.class, args);
}
/**
*此配置是为了服务监控而配置,与服务容错本身无关,springcloud升级后的坑
*ServletRegistrationBean因为springboot的默认路径不是"/hystrix.stream",
*只要在自己的项目里配置上下面的servlet就可以了
*否则,Unable to connect to Command Metric Stream 404
*/
@Bean
public ServletRegistrationBean getServlet() {
HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
registrationBean.setLoadOnStartup(1);
registrationBean.addUrlMappings("/hystrix.stream");
registrationBean.setName("HystrixMetricsStreamServlet");
return registrationBean;
}
}
- 修改controller,新增方法
@Autowired
GreetingsService greetingsService;
@GetMapping("/greetings")
@ResponseStatus(HttpStatus.ACCEPTED)
public void greetings(@RequestParam("message") String message) {
Greetings greetings = Greetings.builder()
.message(message)
.timestamp(System.currentTimeMillis())
.build();
greetingsService.sendGreeting(greetings);
}
- 新增实体类
package com.chenyc.springcloud.po;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString
@Builder
public class Greetings {
private long timestamp;
private String message;
public Greetings(long timestamp, String message) {
this.timestamp = timestamp;
this.message = message;
}
public Greetings() {
}
}
- 修改cloud-provider-payment的pom依赖新增以下
<!--stream-kafka-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-kafka</artifactId>
</dependency>
- 修改yaml
spring:
profiles:
active: payment8001
---
# 8001和8002测试用eureka作为注册中心
server:
port: 8001
spring:
application:
name: cloud-provider-payment
profiles: payment8001
cloud:
config:
label: master #分支名称
name: application #配置文件名称
profile: dev #读取后缀名称 上述3个综合:master分支上config-dev.yml的配置文件被读取http://config-3344.com:3344/master/config-dev.yml
uri: http://localhost:3344 #配置中心地址k
stream:
kafka:
binder:
brokers: 172.18.8.97:9092
bindings:
greetings-in:
destination: greetings
contentType: application/json
zipkin: #<-------------------------------------关键
base-url: http://localhost:9411
sleuth: #<-------------------------------------关键
sampler:
#采样率值介于 0 到 1 之间,1 则表示全部采集
probability: 1
---
server:
port: 8002
spring:
application:
name: cloud-provider-payment
profiles: payment8002
cloud:
config:
label: master #分支名称
name: application #配置文件名称
profile: dev #读取后缀名称 上述3个综合:master分支上config-dev.yml的配置文件被读取http://config-3344.com:3344/master/config-dev.yml
uri: http://localhost:3344 #配置中心地址k
stream:
kafka:
binder:
brokers: localhost:9092
bindings:
greetings-in:
destination: greetings
contentType: application/json
greetings-out:
destination: greetings
contentType: application/json
default-binder: kafka
zipkin: #<-------------------------------------关键
base-url: http://localhost:9411
sleuth: #<-------------------------------------关键
sampler:
#采样率值介于 0 到 1 之间,1 则表示全部采集
probability: 1
- 增加类
package com.chenyc.springcloud.config;
import org.springframework.cloud.stream.annotation.Input;
import org.springframework.cloud.stream.annotation.Output;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.SubscribableChannel;
public interface GreetingsStreams {
String INPUT = "greetings-in";
@Input(INPUT)
SubscribableChannel inboundGreetings();
}
- 新增了类
package com.chenyc.springcloud.po;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString
@Builder
public class Greetings {
private long timestamp;
private String message;
public Greetings(long timestamp, String message) {
this.timestamp = timestamp;
this.message = message;
}
public Greetings() {
}
}
- 启动类新增注解
package com.chenyc.springcloud;
import com.chenyc.springcloud.config.GreetingsStreams;
import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.context.annotation.Bean;
/**
* @author chenyc
* @create 2021-03-29 16:01
*/
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient//添加该注解
@EnableCircuitBreaker//添加到此处
@EnableBinding(GreetingsStreams.class)
public class PaymentApplication {
public static void main(String[] args) {
SpringApplication.run(PaymentApplication.class, args);
}
/**
*此配置是为了服务监控而配置,与服务容错本身无关,springcloud升级后的坑
*ServletRegistrationBean因为springboot的默认路径不是"/hystrix.stream",
*只要在自己的项目里配置上下面的servlet就可以了
*否则,Unable to connect to Command Metric Stream 404
*/
@Bean
public ServletRegistrationBean getServlet() {
HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
registrationBean.setLoadOnStartup(1);
registrationBean.addUrlMappings("/hystrix.stream");
registrationBean.setName("HystrixMetricsStreamServlet");
return registrationBean;
}
}
- 测试
http://localhost/consumer/greetings?message=“你好”