整合 RabbitMQ 使用

安装 RabbitMQ

使用 Docker 安装 RabbitMQ:

docker run -d -p 5672:5672 -p 15672:15672 --name rabbitmq rabbitmq:management

访问管理台

http://ip:15672
RabbitMQ管理台界面

默认用户名密码:

用户名密码
guestguest

代码整合

添加依赖

目标服务增加 amqp 依赖:

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

配置连接信息

Nacos 对应的服务配置文件增加链接相关信息:

spring:
  rabbitmq:
    host: 172.16.1.199
    port: 5672
    username: guest
    password: guest

创建队列

配置服务启动时创建队列 hello:

@Configuration(proxyBeanMethods = false)
public class RabbitQueueConfiguration {

    /**
     * 启动时创建队列
     * @return
     */
    @Bean
    public Queue queue() {
        return new Queue("hello");
    }
}

配置监听器

配置服务监听 hello 队列:

@Component
public class RabbitQueueListener {

    /**
     * 监听 hello 队列的处理器
     * @param message
     */
    @RabbitListener(queues = "hello")
    @RabbitHandler
    public void onMessage(Message message) {
        log.info("消费端Payload: " + message.getPayload().toString());
    }
}

发送消息

代码中向指定队列发送消息:

@Autowired
private AmqpTemplate amqpTemplate;

amqpTemplate.convertAndSend("队列名称","信息");

特殊说明

Feign 调用

在 MQ 消费监听逻辑中调用 Feign,参考:pigx token 传递及 feign 调用

A 服务并没有 token 去请求 B 服务,pigx 也对这种情况进行了兼容。类似于 A 对外暴露 API,但是又安全限制。参考日志插入情况。

FeignClient 需要带一个请求 token,FROM_IN 声明是内部调用:

remoteLogService.saveLog(sysLog, SecurityConstants.FROM_IN);

目标接口对内外调用进行限制 @Inner 注解,这样就避免接口对外暴露的安全问题。只能通过内部调用才能使用,浏览器不能直接访问该接口:

@Inner
@PostMapping
public R save(@Valid @RequestBody SysLog sysLog) {
    return new R<>(sysLogService.save(sysLog));
}

租户处理

在 MQ 消费监听逻辑中调用数据库查询,需要手动指定租户编号查询指定租户的信息,不然均是查询的租户 1:

TenantContextHolder.set(id);

数据权限

在 MQ 消费监听逻辑中不能使用数据权限等功能。