阿里云消息队列mq(消费者)如何集成springboot,并能使用services

创建一个消息队列的数据库维护表:

CREATE TABLE `consumer_local` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `version` bigint(20) NOT NULL,
  `topic` varchar(30) NOT NULL COMMENT '消费者所属的主题',
  `consumer_id` varchar(50) NOT NULL COMMENT '消费者Consumer_id',
  `access_key` varchar(60) NOT NULL COMMENT '阿里云身份验证',
  `secre_key` varchar(300) NOT NULL COMMENT '阿里云身份验证,在阿里云服务器管理控制台创建',
  `ons_address` varchar(300) NOT NULL COMMENT '设置的TCP接入域名',
  `suspend_time_millis` varchar(10) NOT NULL COMMENT '顺序消息消费失败进行重试前的等待时间(毫秒)',
  `max_reconsume_times` varchar(10) NOT NULL COMMENT '消息消费失败时的最大重试次数',
  `sharding_key` varchar(30) NOT NULL COMMENT '顺序消息的区间',
  `tag` varchar(30) NOT NULL COMMENT '处理消息的类型',
  `investor` varchar(50) NOT NULL COMMENT '消费监控的类名',
  `status` varchar(30) NOT NULL COMMENT '消费者的状态(stop,running,init)',
  `state` int(1) DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

然后再springboot的配置文件中添加配置的数据库Id:1

aliyun:
  consumerId: 1

然后创建使用springboot配置的配置文件类:

package com.ryhui.properties;

import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.PropertyKeyConst;
import com.aliyun.openservices.ons.api.bean.OrderConsumerBean;
import com.aliyun.openservices.ons.api.bean.Subscription;
import com.aliyun.openservices.ons.api.order.ConsumeOrderContext;
import com.aliyun.openservices.ons.api.order.MessageOrderListener;
import com.aliyun.openservices.ons.api.order.OrderAction;
import com.ryhui.model.ConsumerLocal;
import com.ryhui.service.modelService.ConsumerLocalService;
import com.ryhui.utils.MessageListenerUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * Created by 10351 on 2018/7/4.
 */
@Component
@ConfigurationProperties(prefix="aliyun")
@Slf4j
public class AliMQConfig {
    @Autowired
    private MessageListenerUtil messageListenerUtil;

    @Autowired
    private ConsumerLocalService consumerLocalService;

    private String consumerId;

    public String getConsumerId() {
        return consumerId;
    }

    public void setConsumerId(String consumerId) {
        this.consumerId = consumerId;
    }

    @Bean(initMethod = "start", destroyMethod = "shutdown")
    public OrderConsumerBean getConsumer() {
        ConsumerLocal consumerLocal = consumerLocalService.selectById(Long.valueOf(consumerId));
        if(consumerLocal!=null&&consumerLocal.getStatus().equals("stop")){

            OrderConsumerBean consumerBean = new OrderConsumerBean();
            Properties properties = new Properties();
            properties.put(PropertyKeyConst.ConsumerId, consumerLocal.getConsumerId());
            // AccessKey 阿里云身份验证,在阿里云服务器管理控制台创建
            properties.put(PropertyKeyConst.AccessKey, consumerLocal.getAccessKey());
            // SecretKey 阿里云身份验证,在阿里云服务器管理控制台创建
            properties.put(PropertyKeyConst.SecretKey, consumerLocal.getSecreKey());
            //消息处理失败后多久重新发送消息
            properties.put(PropertyKeyConst.SuspendTimeMillis, consumerLocal.getSuspendTimeMillis());
            //重发的次数
            properties.put(PropertyKeyConst.MaxReconsumeTimes, consumerLocal.getMaxReconsumeTimes());
            //消费者的线程数
            properties.put(PropertyKeyConst.ConsumeThreadNums,"1");
            //消费者的介入地址
            properties.put(PropertyKeyConst.ONSAddr, consumerLocal.getOnsAddress());
            consumerBean.setProperties(properties);
            Subscription subscription = new Subscription();
            subscription.setTopic(consumerLocal.getTopic());
            subscription.setExpression(consumerLocal.getTag());
            Map<Subscription, MessageOrderListener> map = new HashMap();
            map.put(subscription, new MessageOrderListener(){
                @Override
                public OrderAction consume(Message message, ConsumeOrderContext consumeOrderContext) {
                    log.info("【{}】有消息进入,开始处理",message.getMsgID());
                    messageListenerUtil.sendMessage(message);
                    log.info("【{}】消息处理结束",message.getMsgID());
                    return OrderAction.Success;
                }
            });
            consumerBean.setSubscriptionTable(map);
            consumerLocal.setStatus("running");
            consumerLocalService.update(consumerLocal);
            return consumerBean;
        }else{
            return new OrderConsumerBean();
        }
    }
}

监听使用内部类格式,能够使用再配置文件中引入的spring管理类。spring管理类如下:

package com.ryhui.utils;

import com.aliyun.openservices.ons.api.Message;
import com.ryhui.model.ConsumerLocal;
import com.ryhui.model.ConsumerMessage;
import com.ryhui.service.modelService.ConsumerLocalService;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * Created by 10351 on 2018/7/4.
 */
@Component
public class MessageListenerUtil {
    @Resource
    private ConsumerLocalService consumerLocalService;

    public String sendMessage(Message message){
        System.out.println(message.toString());
        ConsumerLocal consumerLocal = consumerLocalService.selectByTopicAndTag(message.getTopic(),message.getTag());
        if(consumerLocal!=null){
            ConsumerMessage consumerMessage = consumerLocalService.selectByMessageUid(message.getMsgID());
            if(consumerMessage==null){
                consumerMessage = consumerLocalService.handlerMessage(message,consumerLocal.getId());
            }
            consumerLocalService.updateMessage(consumerMessage.getId(),"success");
        }
        System.out.println(message.toString()+"end");
        return "hello";
    }
}

项目启动后会自动开启消费者,如果需要多个消费者,就需要在数据库多配置一条数据,然后把配置的id写入到配置文件中。然后再配置类中引用。然后根据这个配置写一个消费者逻辑。模式同上。

内部类能使用spring的组件的原理:注意到 Inner 类可以访问 Outer 类的变量,即使是私有变量。那么,显然该内部类是与实例联系的,因为它可以访问实例的变量。对外层实例的显式引用为OuterClass.this
里面有详细解释,如果有更专业的请回复。

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值