Spring Cloud Bus-用法和意义

前言

Spring Cloud Bus用轻量级消息代理连接分布式系统的节点。然后可以使用此代理广播状态更改(如配置更改)或其他管理指令。一个关键的想法是,总线就像一个扩展的Spring引导应用程序的分布式执行器。不过,它也可以用作应用程序之间的通信通道。该项目为AMQP经纪人或Kafka提供启动器作为运输工具。

快速启动

如果Spring Cloud Bus检测到自己在类路径上,那么它通过添加Spring Boot autconfiguration来工作。要启用总线,请将A或B添加到依赖项管理中。其余的工作由Spring Cloud完成。确保代理(RabbitMQ或Kafka)可用并已配置。在本地主机上运行时,不需要做任何事情。如果您远程运行,请使用Spring Cloud连接器或Spring引导约定来定义代理凭据,如下面的Rabbit示例所示:

application.yml

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

总线目前支持向侦听特定服务的所有节点或所有节点发送消息(由Eureka定义)。/bus/*执行器名称空间有一些HTTP端点。目前,已经实现了两个。第一个,/bus/env,发送键/值对来更新每个节点的Spring环境。第二次是/bus/refresh,它重新加载每个应用程序的配置,就像它们都在它们的/refresh端点上被选中一样。

总线的端点

Spring Cloud Bus提供了两个端点,/actuator/bus-refresh/actuator/bus-env,分别对应于Spring Cloud Commons中的单个执行器端点,/actuator/refresh/actuator/env

总线刷新端点

/actuator/bus-refresh端点清除RefreshScope缓存并重新绑定@ConfigurationProperties。有关更多信息,请参见RefreshScope文档。

要公开/actuator/bus-refresh端点,需要在应用程序中添加以下配置:

management.endpoints.web.exposure.include=bus-env

总线Env端点

/actuator/bus-env端点使用指定的键/值对跨多个实例更新每个实例环境。

要公开/actuator/bus-env端点,您需要在应用程序中添加以下配置:

management.endpoints.web.exposure.include=bus-env

/actuator/bus-env端点接受以下形状的POST请求:

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

寻址一个实例

应用程序的每个实例都有一个service ID,它的值可以用spring.cloud.bus.id设置,它的值应该是一个以冒号分隔的标识符列表,按照从最不特定到最特定的顺序排列。默认值由环境构造为spring.application.name和server.port(或spring.application.index,如果设置了)的组合。ID的默认值构建为app:index:id的形式,其中:

  • app是vcap.application.name(如果存在),或者spring.application.name
  • index是vcap.application.instance_index(如果存在),则为spring.application.index,local.server.port,server.port,或0(按顺序)。
  • id是vcap.application.instance_id(如果存在)或一个随机值。

HTTP端点接受一个“destination”路径参数,例如/bus-refresh/customers:9000,其中destination是一个服务ID。如果该ID为总线上的实例所拥有,它将处理该消息,而所有其他实例将忽略它。

寻址服务的所有实例

“destination”参数在Spring PathMatcher中使用(路径分隔符为冒号-:)来确定实例是否处理消息。使用前面的示例,/bus-env/customers:**针对“customers”服务的所有实例,而不考虑服务ID的其余部分。

服务ID必须是唯一的

总线尝试两次消除处理事件—一次从原始ApplicationEvent中删除,另一次从队列中删除。为此,它检查发送服务ID和当前服务ID。如果一个服务的多个实例具有相同的ID,则不处理事件。在本地机器上运行时,每个服务位于不同的端口上,该端口是ID的一部分。Cloud Foundry提供一个index来区分。为了确保这个ID在Cloud Foundry外部是唯一的,设置spring.application.index为服务的每个实例建立唯一的索引。

定制消息代理

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

要了解关于如何定制message broker设置的更多信息,请参阅Spring Cloud Stream文档。

跟踪总线事件

通过设置spring.cloud.bus.trace.enabled=true,可以跟踪总线事件(RemoteApplicationEvent的子类)。如果这样做,Spring Boot TraceRepository(如果存在)将显示发送的每个事件和来自每个服务实例的所有ack。下面的示例来自/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": "*:**"
  }
}

前面的跟踪显示,RefreshRemoteApplicationEvent从customers:9000发送,广播到所有服务,并由customers:9000和stores:8081接收(发送)。

要自己处理ack信号,可以为AckRemoteApplicationEvent和SentApplicationEvent类型添加一个@EventListener(并启用跟踪)。或者,您可以访问TraceRepository并从中挖掘数据。

任何总线应用程序都可以跟踪acks。但是,有时在中央服务中执行这些操作是很有用的,因为中央服务可以对数据执行更复杂的查询,或者将数据转发到专门的跟踪服务。

广播自定义活动

总线可以携带RemoteApplicationEvent类型的任何事件。默认传输是JSON,反序列化器需要提前知道将使用哪些类型。要注册一个新类型,必须将其放在org.springframework.cloud.bus.event的子包中。

要定制事件名,可以在定制类上使用@JsonTypeName,或者依赖于默认策略,即使用简单的类名。

生产者和消费者都需要访问类定义。

在自定义包中注册事件

如果您不能或不想使用org.springframework.cloud.bus的子包。对于您的自定义事件,您必须通过使用@RemoteApplicationEventScan注释来指定要扫描哪些包来获取类型为RemoteApplicationEvent的事件。用@RemoteApplicationEventScan指定的包包括子包。

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

package com.acme;

public class MyEvent extends RemoteApplicationEvent {
    ...
}

你可以用下面的方法向反序列化器注册那个事件:

package com.acme;

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

如果不指定值,则注册使用@RemoteApplicationEventScan的类的包。在这个例子中,com.acme是使用BusConfiguration包注册的。

你也可以通过@RemoteApplicationEventScan上的值basePackages或basePackageClasses来显式指定要扫描的包,如下面的例子所示:

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上指定包来注册的。

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

配置属性

要查看所有总线相关配置属性的列表,请查看附录页

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值