使用RabbitMq推模式,消费者调用Dubbo服务踩坑记录

使用RabbitMq推模式,消费者调用Dubbo服务踩坑记录

问题描述:

需求开发中需要使用到队列,且对实时性要求比较高,因此选择推模式,也就是mq主动向消费者投递消息,为此需要使用SimpleMessageListenerContainer,作为bean初始化注入ioc容器中,用来监听队列,配置了消费方法consumeTags(),消费者会调用该方法消费

@Configuration
public class RabbitReceiverConfig {
    @Bean
    public SimpleMessageListenerContainer qyWechat(ConnectionFactory connectionFactory, QyWeChatService qyWeChatService) {

        // 配置在webapp.properties中,false表示不消费 true表示消费
        boolean marketingMailConsume = Configurations.getBoolean("qy.wechat.consume", Configurations.isEnvPro());
        if (!marketingMailConsume) {
            return null;
        }

        MessageListenerAdapter messageListenerAdapter = new MessageListenerAdapter(qyWeChatService);

        Map<String, String> args = Maps.newHashMap();
        args.put(MQConfig.QUEUE_QY_WECHAT_SYNC, "consumeTags");
        messageListenerAdapter.setQueueOrTagToMethodName(args);

        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.setQueueNames(MQConfig.QUEUE_QY_WECHAT_SYNC);
        container.setPrefetchCount(0);
        container.setMessageListener(messageListenerAdapter);

        return container;
    }
}
@DubboReference(version = Versions.DUBBO_SERVICE, timeout = 15000)
private LogService logService;

public void consumeTags(byte[] message) {
	String messageStr = new String(message, StandardCharsets.UTF_8);
    logService.xxx();
}

我的消费方法中,需要远程调用LogService服务的方法,这时候坑就出现了:
因为我前面实现推模式用的@Bean去初始化对象,而@DubboReference的初始化在这之后,这样就导致了我消费的时候,logService服务对象直接是null。

解决方法:

尝试了延迟引用(@DubboReference里面加check = false),懒加载(@Lazy),优先级(@Order),@DependOn都解决不了这个问题,最后想到了重新初始化
方法一:用QyWeChatService类实现InitializingBean接口的afterPropertiesSet()方法,重新初始化一次

@Override
public void afterPropertiesSet() throws Exception {
   Object qyWechat = BeanProvider.getBean("qyWechat");

   if (qyWechat == null)
      return;
   SimpleMessageListenerContainer container = (SimpleMessageListenerContainer) qyWechat;
   Object messageListener = container.getMessageListener();
   MessageListenerAdapter adapter = (MessageListenerAdapter) messageListener;
   adapter.setDelegate(this);
}

后续新方案待补充。。。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
RabbitMQ是一个开源的消息中间件,它实现了高效的消息传递机制,可以在分布式系统中进行消息的发布和订阅。生产者消费者模式是一种常见的消息通信模式,其中生产者负责发送消息,消费者负责接收和处理消息。 在RabbitMQ中,生产者和消费者之间通过交换机(Exchange)和队列(Queue)进行通信。生产者将消息发送到交换机,交换机根据指定的路由规则将消息路由到一个或多个队列中,消费者从队列中接收消息并进行处理。 在单机模式下,RabbitMQ的生产者和消费者都运行在同一台机器上。以下是单机模式RabbitMQ生产者消费者的基本步骤: 1. 安装RabbitMQ:首先需要在机器上安装RabbitMQ服务。 2. 创建连接:生产者和消费者都需要创建与RabbitMQ服务器的连接。连接包括主机名、端口号、用户名和密码等信息。 3. 创建通道:连接成功后,生产者和消费者都需要创建一个通道。通道是进行消息传递的通道,可以在同一个连接上创建多个通道。 4. 声明交换机:生产者需要声明一个交换机,用于将消息发送到指定的队列。交换机有不同的类型,如直连交换机、主题交换机、扇形交换机等。 5. 声明队列:消费者需要声明一个队列,用于接收生产者发送的消息。队列可以绑定到交换机上,以便接收特定类型的消息。 6. 发布消息:生产者通过通道将消息发送到交换机,指定消息的路由键和其他属性。 7. 消费消息:消费者通过通道从队列中接收消息,并进行处理。可以设置回调函数来处理接收到的消息。 8. 关闭连接:当生产者和消费者完成任务后,需要关闭与RabbitMQ服务器的连接。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值