Spring Cloud Bus

时间:2022-11-29 11:20:58

Spring Cloud Bus

Spring Cloud总线用轻量级消息链接分布式系统的节点 代理。然后,可以使用此代理广播状态更改(例如配置 变更)或其他管理说明。一个关键的想法是,公共汽车就像一个 用于横向扩展的 Spring 引导应用程序的分布式执行器。但是,它可以 也可用作应用程序之间的通信渠道。该项目为以下项目提供了入门 AMQP 代理或 Kafka 作为传输。

Spring Cloud 是在非限制性 Apache 2.0 许可证下发布的。如果您想为文档的这一部分做出贡献,或者如果您发现错误,请在github 的项目中找到源代码和问题跟踪器。

1. 快速入门

Spring Cloud Bus 的工作原理是添加 Spring Boot autconfig,如果它在 类路径。要启用总线,请添加到依赖项管理中。春云照顾 其余的。确保代理(RabbitMQ 或 Kafka)可用并已配置。什么时候 在本地主机上运行,您无需执行任何操作。如果您远程运行,请使用 Spring Cloud 用于定义代理凭据的连接器或 Spring 引导约定,如 以下兔子示例:​​spring-cloud-starter-bus-amqp​​​​spring-cloud-starter-bus-kafka​

应用程序.yml

spring:
rabbitmq:
host: mybroker.com
port: 5672
username: user
password: secret

总线当前支持向所有侦听的节点或所有节点发送消息 特定服务(由尤里卡定义)。执行器命名空间有一些 HTTP 端点。目前,有两个正在实施。第一个,,将键/值对发送到 更新每个节点的 Spring 环境。第二个,,重新加载每个 应用程序的配置,就好像它们都已在其端点上被 ping 一样。​​/bus/*​​​​/bus/env​​​​/bus/refresh​​​​/refresh​

Spring Cloud Bus 的启动器涵盖了 Rabbit 和 Kafka,因为这是两个最 常见实现。不过,春云流相当灵活,活页夹 与。​​spring-cloud-bus​

2. 总线端点

Spring Cloud Bus 提供了两个端点,分别对应于 Spring Cloud Commons 中的各个执行器端点。​​/actuator/busrefresh​​​​/actuator/busenv​​​​/actuator/refresh​​​​/actuator/env​

2.1. 总线刷新端点

端点清除缓存并重新绑定。请参阅刷新范围文档 更多信息。​​/actuator/busrefresh​​​​RefreshScope​​​​@ConfigurationProperties​

若要公开终结点,需要将以下配置添加到 应用:​​/actuator/busrefresh​

management.endpoints.web.exposure.include=busrefresh

2.2. 总线环境端点

端点使用指定的 跨多个实例的键/值对。​​/actuator/busenv​

若要公开终结点,需要将以下配置添加到 应用:​​/actuator/busenv​

management.endpoints.web.exposure.include=busenv

端点接受具有以下形状的请求:​​/actuator/busenv​​​​POST​

{
"name": "key1",
"value": "value1"
}

3. 寻址实例

应用程序的每个实例都有一个服务 ID,其值可以设置,其值应为冒号分隔的列表 标识符,按从最不具体到最具体的顺序排列。默认值为 从环境构造为与(或,如果设置)的组合。ID 的默认值为 构造形式为,其中:​​spring.cloud.bus.id​​​​spring.application.name​​​​server.port​​​​spring.application.index​​​​app:index:id​

  • ​app​​是,如果存在,或vcap.application.namespring.application.name
  • ​index​​是,如果存在,,,,或(按该顺序)。vcap.application.instance_indexspring.application.indexlocal.server.portserver.port0
  • ​id​​是,如果存在,或随机值。vcap.application.instance_id

HTTP 终结点接受“目标”路径参数,例如,其中是服务 ID。如果 ID 由总线上的实例拥有,它处理消息和所有其他实例 忽略它。​​/busrefresh/customers:9000​​​​destination​

4. 寻址服务的所有实例

“目标”参数用于 Spring(带有路径分隔符 作为冒号 —) 来确定实例是否处理消息。使用示例 从前面开始,以 “客户”服务,而不考虑其余的服务 ID。​​PathMatcher​​​​:​​​​/busenv/customers:**​

5. 服务 ID 必须是唯一的

总线尝试两次来消除对事件的处理 — 一次来自原始事件,一次来自队列。为此,它会检查发送服务 ID 针对当前服务 ID。如果服务的多个实例具有相同的 ID, 不处理事件。在本地计算机上运行时,每个服务位于不同的 端口,并且该端口是 ID 的一部分。Cloud Foundry 提供了一个索引来区分。 要确保 ID 在 Cloud Foundry 之外是唯一的,请将 服务的每个实例都有独特的内容。​​ApplicationEvent​​​​spring.application.index​

6. 自定义消息代理

春云总线使用春云流 广播消息。因此,要使消息流动,您只需要包含活页夹 在类路径中实现您选择的内容。巴士有方便的启动器 与AMQP(RabbitMQ)和Kafka()。一般 说,Spring Cloud Stream 依赖于 Spring Boot 自动配置约定 配置中间件。例如,可以使用配置属性更改 AMQP 代理地址。春云总线有少数 本机配置属性 in(例如,是要用作外部的主题的名称 中间件)。通常,默认值就足够了。​​spring-cloud-starter-bus-[amqp|kafka]​​​​spring.rabbitmq.*​​​​spring.cloud.bus.*​​​​spring.cloud.bus.destination​

要了解有关如何自定义消息代理设置的更多信息,请参阅 Spring Cloud 流文档。

7. 跟踪总线事件

总线事件(子类)可以通过设置进行跟踪。如果这样做,Spring 引导(如果存在)将显示发送的每个事件以及来自每个服务实例的所有确认。这 以下示例来自端点:​​RemoteApplicationEvent​​​​spring.cloud.bus.trace.enabled=true​​​​TraceRepository​​​​/trace​

{
"timestamp": "2015-11-26T10:24:44.411+0000",
"info": {
"signal": "spring.cloud.bus.ack",
"type": "RefreshRemoteApplicationEvent",
"id": "c4d374b7-58ea-4928-a312-31984def293b",
"origin": "stores:8081",
"destination": "*:**"
}
},
{
"timestamp": "2015-11-26T10:24:41.864+0000",
"info": {
"signal": "spring.cloud.bus.sent",
"type": "RefreshRemoteApplicationEvent",
"id": "c4d374b7-58ea-4928-a312-31984def293b",
"origin": "customers:9000",
"destination": "*:**"
}
},
{
"timestamp": "2015-11-26T10:24:41.862+0000",
"info": {
"signal": "spring.cloud.bus.ack",
"type": "RefreshRemoteApplicationEvent",
"id": "c4d374b7-58ea-4928-a312-31984def293b",
"origin": "customers:9000",
"destination": "*:**"
}
}

前面的跟踪显示 awas 从所有服务发送、广播到所有服务,以及接收(acked)byand。​​RefreshRemoteApplicationEvent​​​​customers:9000​​​​customers:9000​​​​stores:8081​

要自己处理确认信号,您可以向应用程序添加 anfor theand类型(并启用 描摹)。或者,您可以利用并从中挖掘数据 那里。​​@EventListener​​​​AckRemoteApplicationEvent​​​​SentApplicationEvent​​​​TraceRepository​

任何总线应用程序都可以跟踪确认。但是,有时它是 在可以执行更复杂的*服务中执行此操作很有用 查询数据或将其转发到专用跟踪服务。

8. 广播您自己的活动

总线可以承载任何类型的事件。默认传输为 JSON 和反序列化程序需要提前知道将使用哪些类型。 若要注册新类型,必须将其放入 的子包中。​​RemoteApplicationEvent​​​​org.springframework.cloud.bus.event​

若要自定义事件名称,可以在自定义类上使用或依赖 默认策略,即使用类的简单名称。​​@JsonTypeName​

生产者和使用者都需要访问类定义。

8.1. 在自定义软件包中注册事件

如果不能或不想使用自定义事件的子包,则必须使用注释指定要扫描哪些包以查找类型的事件。包 指定包括子包。​​org.springframework.cloud.bus.event​​​​RemoteApplicationEvent​​​​@RemoteApplicationEventScan​​​​@RemoteApplicationEventScan​

例如,请考虑以下自定义事件,称为:​​MyEvent​

package com.acme;

public class MyEvent extends RemoteApplicationEvent {
...
}

可以通过以下方式向反序列化程序注册该事件:

package com.acme;

@Configuration
@RemoteApplicationEventScan
public class BusConfiguration {
...
}

如果不指定值,则注册所使用的类的包。在此示例中,是使用包注册的。​​@RemoteApplicationEventScan​​​​com.acme​​​​BusConfiguration​

还可以使用 ,orproperties on 显式指定要扫描的包,如 以下示例:​​value​​​​basePackages​​​​basePackageClasses​​​​@RemoteApplicationEventScan​

package com.acme;

@Configuration
//@RemoteApplicationEventScan({"com.acme", "foo.bar"})
//@RemoteApplicationEventScan(basePackages = {"com.acme", "foo.bar", "fizz.buzz"})
@RemoteApplicationEventScan(basePackageClasses = BusConfiguration.class)
public class BusConfiguration {
...
}

前面的所有示例都是等效的,因为包是通过显式指定包来注册的。​​@RemoteApplicationEventScan​​​​com.acme​​​​@RemoteApplicationEventScan​

您可以指定要扫描的多个基本包。