SpringCloud Bus实现自定义发布、消费事件

本文详细介绍了如何使用SpringCloudBus和RabbitMQ实现分布式应用间的事件发布与消费。首先,解释了SpringCloudBus的作用和工作原理,接着创建了两个项目A和B,项目A负责发布事件,项目B负责消费事件。在项目中,自定义了事件类并配置了监听器。通过调用项目A的API发布事件,然后观察项目B的日志确认事件已被正确消费。
摘要由CSDN通过智能技术生成

1. spring cloud bus介绍

Spring cloud bus通过轻量消息代理连接各个分布的节点。这会用在广播状态的变化(例如配置变化)或者其他的消息指令。Spring cloud bus的一个核心思想是通过分布式的启动器对spring boot应用进行扩展,也可以用来建立一个多个应用之间的通信频道。目前唯一实现的方式是用AMQP消息代理作为通道,同样特性的设置(有些取决于通道的设置)在更多通道的文档中。看源码会发现spring cloud bus是在spring cloud stream的基础上做的封装。

2. 创建项目

我们创建两个项目A、B使用rabbitmq作为中间件,项目A用来发布事件,项目B用来消费事件,两个项目都需要引入依赖如下:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>

bootstrap.yml中添加连接rabbitmq的配置:

spring:
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: test
    password: test123

3. 两个项目的公共代码

3.1 创建事件

事件需要继承RemoteApplicationEvent类:

import lombok.Getter;
import org.springframework.cloud.bus.event.RemoteApplicationEvent;

/**
 * @author mazhen
 * @className RouteEvent
 * @Description TODO
 * @date 2020/11/20 15:54
 */
public class RouteEvent extends RemoteApplicationEvent {
    @Getter
    private String message;
    public RouteEvent() {super();}
    public RouteEvent(Object body,String originService, String destinationService, String message) {
        super(body,originService,destinationService);
        this.message = message;
    }
    public RouteEvent(Object body,String originService, String message) {
        super(body,originService);
        this.message = message;
    }
}
3.2 添加配置类
import org.springframework.cloud.bus.jackson.RemoteApplicationEventScan;
import org.springframework.context.annotation.Configuration;

/**
 * @author mazhen
 * @className BusExtConfiguration
 * @Description TODO
 * @date 2020/11/20 16:15
 */
@Configuration
@RemoteApplicationEventScan(basePackageClasses = RouteEvent.class)
public class BusExtConfiguration {
}

@RemoteApplicationEventScan(basePackageClasses = CustomEvent.class)用来告诉bus自己实现的事件在哪个包下,也可直接写在启动类上。

4. 项目A的事件发布代码

4.1 事件发布service
public interface BusEventService {
    Boolean publishRouteEvent(String route);
}
4.2 事件发布serviceImpl
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.bus.BusProperties;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;

/**
 * @author mazhen
 * @className BusEventServiceImpl
 * @Description TODO
 * @date 2020/11/20 16:32
 */
@Log4j2
@Service
public class BusEventServiceImpl implements BusEventService {

    @Autowired
    private ApplicationEventPublisher applicationEventPublisher;

    @Autowired
    private BusProperties busProperties;

    @Override
    public Boolean publishRouteEvent(String route) {
        RouteEvent routeEvent = new RouteEvent(this,busProperties.getId(),"GATEWAY-PORTAL",route);
        try {
            log.info("Bus start publishing event");
            applicationEventPublisher.publishEvent(routeEvent);
            log.info("Bus publish event success");
            return true;
        } catch (Exception e) {
            log.error("Bus publish event fail:",e);
        }
        return false;
    }
 }
4.3 事件发布controller
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author mazhen
 * @className GatewayRoutesApiController
 * @Description 
 * @date 2020/11/20 19:42
 */
@Slf4j
@RestController
@RequestMapping("/bus/publish")
public class GatewayRoutesApiController {
    @Autowired
    private BusEventService busEventService;

    @GetMapping("/test")
    public Boolean testGateway(@RequestParam("routeNo") String routeNo){
        return busEventService.publishRouteEvent(routeNo);
    }
}

5. 项目B的事件消费代码

项目B的事件消费代码即事件监听器:

import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

/**
 * @author mazhen
 * @className BusRoutesRefreshEventListener
 * @Description TODO
 * @date 2020/11/20 17:00
 */
@Log4j2
@Component
public class BusRoutesRefreshEventListener implements ApplicationListener<RouteEvent> {

    @Autowired
    private RefreshRoutesEventProcessor processor;

    @Override
    public void onApplicationEvent(RouteEvent routeEvent) {
        String message = routeEvent.getMessage();
        log.info("接受数据,message:{}",message);
        //具体的业务逻辑
    }
}

6. 测试

6.1 调用项目A的发布事件controller

执行http://localhost:8080/bus/publish/test?routeNo=this is a test data
在这里插入图片描述
看日志,项目A发布事件成功。

6.2 项目B的消费事件

在这里插入图片描述
看日志,项目B消费事件成功。

参考:https://blog.csdn.net/weixin_38312502/article/details/105975490

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Cloud Bus是一个用于在分布式系统中传播状态变化的消息总线。它基于Spring Cloud Stream和Spring Cloud Config构建,可以将消息广播到整个系统中的所有服务实例。通过使用Spring Cloud Bus,可以实现配置的动态刷新、事件的传播和集群中的状态同步。 下面是使用Spring Cloud Bus自定义消息总线的步骤: 1. 添加依赖:在项目的pom.xml文件中添加Spring Cloud Bus的依赖: ```xml <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency> ``` 2. 配置消息代理:在应用的配置文件中配置消息代理,例如使用RabbitMQ作为消息代理: ```yaml spring: rabbitmq: host: localhost port: 5672 username: guest password: guest ``` 3. 发送自定义消息:在需要发送自定义消息的地方,使用Spring Cloud Bus提供的API发送消息。例如,可以使用`/actuator/bus-refresh`端点发送刷新配置的消息: ```shell curl -X POST http://localhost:8080/actuator/bus-refresh ``` 4. 接收自定义消息:在需要接收自定义消息的地方,使用Spring Cloud Bus提供的注解和监听器来接收消息。例如,可以使用`@RefreshScope`注解来刷新配置: ```java @RefreshScope @RestController public class ConfigController { // ... } ``` 通过以上步骤,您可以使用Spring Cloud Bus自定义消息总线来实现配置的动态刷新、事件的传播和集群中的状态同步。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值