springboot整合rocketMq

一、消息队列

前面一篇博文提到消息队列的三大作用:
(1)解耦
(2)异步
(3)削峰限流
当下主流的消息队列主要有Kafka、ActiveMQ、RabbitMQ、RocketMQ
springboot整合rocketMq_第1张图片
rocketMq以其高吞吐量,支持分布式,可支撑大量的topic而成为一些公司的首选(实习的公司用的rocketMq),下面就做一个Springboot整合rocketMq的实践吧

二、下载安装、启动rocketMq

  • 下载地址:下载地址
  • 安装:
    unzip rocketmq-all-4.8.0-bin-release.zip
    cd rocketmq-all-4.8.0-bin-release
  • 启动
    启动NameServer
    nohup sh bin/mqnamesrv
    启动broker
    nohup sh bin/mqbroker -n localhost:9876

三、pom依赖

    
        
            org.springframework.boot
            spring-boot-starter-thymeleaf
        
        
            org.springframework.boot
            spring-boot-starter-web
        

        
            org.springframework.boot
            spring-boot-starter-test
            test
        
        
            org.apache.rocketmq
            rocketmq-spring-boot-starter
            2.2.0
        
        
            org.projectlombok
            lombok
        
    

四、配置

在application.yml里引入rocketMq配置

rocketmq:
  name-server: 127.0.0.1:9876
  producer:
    group: zju-rocket-mq
  consumer:
    group: zju-rocket-mq

项目整体架构
springboot整合rocketMq_第2张图片

五、生产者

@PostConstruct注解在服务器加载Servlet初始化生产者,配置jvm钩子函数优雅的关闭消息队列

@Service
public class Producer {

    @Value("${rocketmq.producer.group}")
    private String groupName;
    @Value("${rocketmq.name-server}")
    private String nameServerAddress;
    private static DefaultMQProducer producer = null;
    private static final Integer DEFAULT_TIMEOUT = 500;
    @PostConstruct
    public void init(){
        producer = new DefaultMQProducer(groupName);
        producer.setNamesrvAddr(nameServerAddress);
        producer.setInstanceName("TestForProducer");
        try {
            producer.start();
            Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {

                //钩子函数随jvm销毁关闭mq
                @Override
                public void run() {
                    producer.shutdown();
                }
            }));
        } catch (MQClientException e) {
            e.printStackTrace();
        }

    }

    public static String sendMessage(String topic, String tag, String mes){
        byte[] messageByte = mes.getBytes();
        Message message = new Message(topic, tag, messageByte);
        SendResult sendResult = null;
        try {
            sendResult = producer.send(message);
        } catch (MQClientException e) {
            e.printStackTrace();
        } catch (RemotingException e) {
            e.printStackTrace();
        } catch (MQBrokerException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return sendResult.getMsgId();
    }

}

六、消费者

@PostConstruct初始化消费者,消费者订阅topic配置相应的handler

@Service
public class Consumer {

    @Value("${rocketmq.producer.group}")
    private String groupName;
    @Value("${rocketmq.name-server}")
    private String nameServerAddress;
    @Autowired
    private TestHandler handler;

    @PostConstruct
    public void init(){
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(groupName);
        consumer.setNamesrvAddr(nameServerAddress);
        consumer.registerMessageListener(handler);
        consumer.setInstanceName("TestForConsumer");
        try {
            consumer.subscribe("topic", "tag");
            consumer.start();
        } catch (MQClientException e) {
            e.printStackTrace();
        }
    }
}

七、handler

TestHandler实现MessageListenerConcurrently接口,覆写consumeMessage方法

@Slf4j
@Service
public class TestHandler implements MessageListenerConcurrently {

    @Override
    public ConsumeConcurrentlyStatus consumeMessage(List list, ConsumeConcurrentlyContext consumeConcurrentlyContext) {
        if(list == null || list.isEmpty()){
            log.info("the message received is empty");
        }

        log.info("receive message, start to consume");
        try{
            for(MessageExt msg:list){
                String body = new String(msg.getBody(),"UTF-8");
                log.info("the topic={},the message={}",msg.getTopic(),body);
            }
        }catch(UnsupportedEncodingException e){
            e.printStackTrace();
            return ConsumeConcurrentlyStatus.RECONSUME_LATER;
        }

        return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
    }
}

八、Controller层往消息队列写数据

@RestController
@RequestMapping("/test")
public class TestController {


    @PostMapping("/writeMessage")
    public void writeMessage() throws InterruptedException {
        Producer.sendMessage("topic", "tag", "hello, RocketMq");
    }
}

gitHub地址:github

你可能感兴趣的:(java后端)