RocketMQ——服務啓動時初始化自定義RocketMQ的生產者Producer

需求

  1. 構造RocketMQ生產者。
  2. 在服務啓動時構造生產者,在服務關閉時銷燬生產者。

代碼模板

抽象類

@Slf4j
public abstract class AbstractMqProducer {

    /**
     *  原生默認mq生產者
     */
    protected DefaultMQProducer producer;

    /**
     * 啓動時,構造
     *
     * @throws MQClientException
     */
    @PostConstruct
    public abstract void start() throws MQClientException;

    /**
     * 關閉時,銷燬
     */
    @PreDestroy
    public void shutdown() {
        log.info("AbstractMqProducer shutdown...");
        producer.shutdown();
    }

}

生產者實現類

@Component
@Configuration
@Slf4j
@RequiredArgsConstructor
public class DemoRocketMqProducer extends AbstractMqProducer {

    /**
     * 參數配置
     */
	@Value("${rocketmq.producer.group}")
	private String producerGroup;
	@Value("${rocketmq.name-server}")
    private String nameServer;
	@Value("${rocketmq.producer.send-message-timeout}")
    private String sendMessageTimeout;
   	@Value("${rocketmq.producer.compress-message-body-threshold}")
	private String compressMessageBodyThreshold;
   	@Value("${rocketmq.producer.max-message-size}")
	private String maxMessageSize;
   	@Value("${rocketmq.producer.retry-times-when-send-failed}")
	private String retryTimesWhenSendFailed;
   	@Value("${rocketmq.producer.retry-times-when-send-async-failed}")
	private String retryTimesWhenSendAsyncFailed;
   	@Value("${rocketmq.producer.retry-next-server}")
	private String retryNextServer;
    /**
     * 啓動producer
     *
     * @throws MQClientException
     */
    @Override
    public void start() throws MQClientException {
        //判空
        if (ObjectUtil.isNull(producer)) {
            log.info("init DemoRocketMqProducer begin... ...");
            //構建producer
            producer = new DefaultMQProducer(producerGroup);
            //name server地址
            producer.setNamesrvAddr(nameServer);
            //客戶端實例名稱
            producer.setInstanceName(UtilAll.getPid() + "#" + System.nanoTime());
            //發送消息超時時間,單位毫秒,默認3000
            producer.setSendMsgTimeout(sendMessageTimeout);
            //body超過多大開始壓縮,單位字節,默認4096B
            producer.setCompressMsgBodyOverHowmuch(compressMessageBodyThreshold);
            //客戶端限制的消息大小,單位字節,默認4194304
            producer.setMaxMessageSize(maxMessageSize);
            //如果消息發送失敗,最大重試次數,默認2
            producer.setRetryTimesWhenSendFailed(retryTimesWhenSendFailed);
            //如果消息異步發送失敗,最大重試次數,默認2
            producer.setRetryTimesWhenSendAsyncFailed(retryTimesWhenSendAsyncFailed);
            //如果發送消息返回sendResult,但sendStatus != SEND_OK,是否重試其他broker發送,默認false
            producer.setRetryAnotherBrokerWhenNotStoreOK(retryNextServer);
        }
        //啓動producer
        producer.start();
        log.info("DemoRocketMqProducer is starting...");
    }

    /**
     * 發送消息
     *
     * @param topic
     * @param tag
     * @param key
     * @param dto
     * @param <T>
     * @return
     */
    public <T> boolean send(String topic, String tag, String key, T dto, String hashKey) {
        try {
            //轉換dto爲String類型
            String body = JSON.toJSONString(dto);
            //構建message
            Message message = new Message(topic, tag, key, body.getBytes("utf-8"));
            //發送消息
            SendResult sendResult = producer.send(message, new SelectMessageQueueByHash(), hashKey);
            log.info("DemoRocketMqProducer 消息生產結果:{}", sendResult);
            return true;
        } catch (Exception e) {
            //錯誤日誌
            log.error("DemoRocketMqProducer 消息生產失敗,錯誤信息:{}", e);
            //異常處理
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 關閉producer
     */
    @Override
    @PreDestroy
    public void shutdown() {
        //關閉producer
        producer.shutdown();
        log.warn("DemoRocketMqProducer shutdown...");
    }
}

註解詳解

@PostConstruct

介紹

  1. @PostConstruct註解被用來修飾一個非靜態的void()方法。
  2. @PostConstruct註解修飾的方法會在服務加載Servlet時運行,只會被執行一次。
  3. @PostConstruct註解在init()方法之前、構造函數之後執行。
  4. 上下文啓動順序:服務加載Servlet->Constructor(構造方法) -> @Autowired(依賴注入) -> @PostConstruct(註解修飾的方法)->init()方法

使用場景

  若想在生成對象時完成某些初始化操作,此時這些初始化需要依賴於一些依賴注入,則無法在構造函數中實現。此時,可使用@PostConstruct註解修飾一個方法來完成初始化,@PostConstruct註解修飾的方法將會在依賴注入完成後被自動調用。

源碼

@Documented
@Retention (RUNTIME)
@Target(METHOD)
public @interface PostConstruct {
}

@PreDestroy

介紹

  1. @PreDestroy註解被用來修飾一個非靜態的void()方法。
  2. @PreDestroy註解修飾的方法會在服務卸載Servlet時運行,只會被執行一次。
  3. @PreDestroy註解在Servlet卸載之前,destroy()方法之後執行。
  4. 上下文停止順序:destroy()方法 -> @PreDestroy(註解修飾的方法)-> bean銷燬->服務卸載Servlet

源碼

@Documented
@Retention (RUNTIME)
@Target(METHOD)
public @interface PreDestroy {
}

配置文件詳解

# rocketmq消息隊列
rocketmq:
  # 指定 nameServer
  name-server: 127.0.0.1:9876;127.0.0.1:9877
  # Producer 生產者
  producer:
  	# 生產組
    group: my-group
    # 發送消息超時時間,單位毫秒,默認3000
    send-message-timeout: 3000
    # body超過多大開始壓縮,單位字節,默認4096B
    compress-message-body-threshold: 4096
    # 客戶端限制的消息大小,單位字節,默認4194304
    max-message-size: 4194304
    # 如果消息發送失敗,最大重試次數,默認2
    retry-times-when-send-failed: 2
    # 如果消息異步發送失敗,最大重試次數,默認2
    retry-times-when-send-async-failed: 2
    # 如果發送消息返回sendResult,但sendStatus != SEND_OK,是否重試其他broker發送,默認false
    retry-next-server: false
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章