消息中间件是基于队列与消息传递技术,在网络环境中为应用系统提供同步或异步、可靠的消息传输的支撑性软件系统
消息中间件主要解决应用解耦,异步消 息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构。不同的中间件其实现方式,内 部结构是不一样的
1. RabbitMQ
2. kafka
1. 队列消息
2. 发布/订阅消息
中间件的差异性导致我们实际项目开发 给我们造成了一定的困扰,我们如果用了两个消息队列的其中一种,后面的业务需求,我想往另外一种 消息队列进行迁移,这时候无疑就是一个灾难性的,一大堆东西都要重新推倒重新做,因为它跟我们的 系统耦合了,这时候 springcloud Stream 给我们提供了一种解耦合的方式。
Spring Cloud Stream由一个中间件中立的核组成。应用通过Spring Cloud Stream插入的input(相当于 消费者consumer,它是从队列中接收消息的)和output(相当于生产者producer,它是从队列中发送消 息的。)通道与外界交流。通道通过指定中间件的Binder实现与外部代理连接。业务开发者不再关注具 体消息中间件,只需关注Binder对应用程序提供的抽象概念来使用消息中间件实现业务即可。
通过定义绑定器作为中间层,实现了应用程序与消息中间件(Middleware)细节之间的隔离。通过向应用 程序暴露统一的Channel通过,使得应用程序不需要再考虑各种不同的消息中间件的实现
在Spring Cloud Stream中的消息通信方式遵循了发布-订阅模式,当一条消息被投递到消息中间件之 后,它会通过共享的 Topic 主题进行广播,消息消费者在订阅的主题中收到它并触发自身的业务逻辑处 理。
代码中绑定spring内置的提供的通道:
1. Source : output通道
2. Sink: Input通道
配置文件中分别配置:
bindings:
output/input:
Spring Cloud Stream 内置了两种接口,分别定义了 binding 为 “input” 的输入流,和 “output” 的输出流,而在我们实际使用中,往往是需要定义各种输入输出流。使用方法也很简单。
demo:
public interface OrderProcessor {
String INPUT_ORDER = "inputOrder";
String OUTPUT_ORDER = "outputOrder";
@Input(INPUT_ORDER)
SubscribableChannel inputOrder();
@Output(OUTPUT_ORDER)
MessageChannel outputOrder();
}
通常在生产环境,我们的每个服务都不会以单节点的方式运行在生产环境,当同一个服务启动多个实例 的时候,这些实例都会绑定到同一个消息通道的目标主题(Topic)上。默认情况下,当生产者发出一 条消息到绑定通道上,这条消息会产生多个副本被每个消费者实例接收和处理,但是有些业务场景之 下,我们希望生产者产生的消息只被其中一个实例消费,这个时候我们需要为这些消费者设置消费组来 实现这样的功能。
有一些场景需要满足, 同一个特征的数据被同一个实例消费, 比如同一个id的传感器监测数据必须被同一 个实例统计计算分析, 否则可能无法获取全部的数据。又比如部分异步任务,首次请求启动task,二次 请求取消task,此场景就必须保证两次请求至同一实例.
SpringBoot的application.yml文件,但是在微服务架构中全部手动修改的话很麻烦而且不易维护,所以就需要一个叫做配置中心概念
1、集中配置管理,一个微服务架构中可能有成百上千个微服务,所以集中配置管理是很重要的。
2、 不同环境不同配置,比如数据源配置在不同环境(开发,生产,测试)中是不同的。
3、 运行期间可动态调整。例如,可根据各个微服务的负载情况,动态调整数据源连接池大小等
4、配置修改后可自动更新。如配置内容发生变化,微服务可以自动更新配置
Spring Cloud Config项目是一个解决分布式系统的配置管理方案。它包含了Client和Server两个部分, server提供配置文件的存储、以接口的形式将配置文件的内容提供出去,client通过接口获取数据、并 依据此数据初始化自己的应用
文件命名规则
application}-{profile}.yml
{application}-{profile}.properties
application为应用名称 profile指的开发环境(用于区分开发环境,测试环境、生产环境等)
我们已经在客户端取到了配置中心的值,但当我们修改GitHub上面的值时,服务端(Config Server) 能实时获取最新的值,但客户端(Config Client)读的是缓存,无法实时获取最新值。SpringCloud已 经为我们解决了这个问题,那就是客户端使用post去触发refresh,获取最新数据,需要依赖spring- boot-starter-actuator
management:
endpoints:
web:
exposure:
include: /bus-refresh
客户端和服务端的耦合性太高,如果server端要做集群,客户端只能通过原始的方式来路由, server端改变IP地址的时候,客户端也需要修改配置,不符合springcloud服务治理的理念。
springcloud提供了这样的解决方案,我们只需要将(多个)server端当做一个服务注册到eureka中,client端去 eureka中去获取配置中心server端的服务既可。
在微服务架构中,通常会使用轻量级的消息代理来构建一个共用的消息主题来连接各个微服务实例,它 广播的消息会被所有在注册中心的微服务实例监听和消费,也称消息总线。SpringCloud中也有对应的解决方案,SpringCloud Bus 将分布式的节点用轻量的消息代理连接起来, 可以很容易搭建消息总线,配合SpringCloud config 实现微服务应用配置信息的动态更新。
1. 提交代码触发post请求给bus/refresh
2. server端接收到请求并发送给Spring Cloud Bus
3. Spring Cloud bus接到消息并通知给其它客户端
4. 其它客户端接收到通知,请求Server端获取最新配置
5. 全部客户端均获取到最新的配置
server:
port: 10000 #服务端口
spring:
application:
name: config-server #指定服务名 cloud:
config:
server:
git:
uri: https://gitee.com/it-lemon/config-repo.git
rabbitmq:
host: 127.0.0.1
port: 5672
username: guest
password: guest
management:
endpoints:
web:
exposure:
include: bus-refresh
eureka:
client:
serviceUrl:
defaultZone: http://127.0.0.1:8761/eureka/
instance:
preferIpAddress: true
instance-id: ${spring.cloud.client.ip-address}:${server.port} #spring.cloud.client.ip-address:获取ip地址
需要在码云对应的配置文件中添加rabbitmq的配置信息
server:
port: 9002
eureka:
client:
serviceUrl:
defaultZone: http://127.0.0.1:8761/eureka/
spring:
cloud:
config:
name: product
profile: dev
label: master
discovery:
enabled: true
service-id: config-server
apollo(阿波罗)是携程框架部门研发的开源配置管理中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性
1. 统一管理不同环境、不同集群的配置
2. 配置修改实时生效(热发布)
3. 版本发布管理
4. 灰度发布
5. 权限管理、发布审核、操作审计
6. 客户端配置信息监控
7. 提供Java和.Net原生客户端
8. 提供开放平台API
9. 部署简单
1. 客户端和服务端保持了一个长连接,从而能第一时间获得配置更新的推送。
2. 客户端从Apollo配置中心服务端获取到应用的最新配置后,会保存在内存中
在遇到服务不可用,或网络不通的时候,依然能从本地恢复配置
3. 客户端会把从服务端获取到的配置在本地文件系统缓存一份
4. 应用程序从Apollo客户端获取最新的配置、订阅配置更新通知
1、启动apollo命令
./demo.sh start :运行apollo
2、客户端集成apollo中配置文件的修改
配置文件中编写:
apollo:
bootstrap:
enabled: true
meta: http://127.0.0.1:8080
app:
id: product-service