需求
- 構造
RocketMQ
生產者。 - 在服務啓動時構造生產者,在服務關閉時銷燬生產者。
代碼模板
抽象類
@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
介紹
@PostConstruct
註解被用來修飾一個非靜態的void()
方法。- 被
@PostConstruct
註解修飾的方法會在服務加載Servlet
時運行,只會被執行一次。 @PostConstruct
註解在init()
方法之前、構造函數之後執行。- 上下文啓動順序:
服務加載Servlet->Constructor(構造方法) -> @Autowired(依賴注入) -> @PostConstruct(註解修飾的方法)->init()方法
使用場景
若想在生成對象時完成某些初始化操作,此時這些初始化需要依賴於一些依賴注入,則無法在構造函數中實現。此時,可使用@PostConstruct
註解修飾一個方法來完成初始化,@PostConstruct
註解修飾的方法將會在依賴注入完成後被自動調用。
源碼
@Documented
@Retention (RUNTIME)
@Target(METHOD)
public @interface PostConstruct {
}
@PreDestroy
介紹
@PreDestroy
註解被用來修飾一個非靜態的void()
方法。- 被
@PreDestroy
註解修飾的方法會在服務卸載Servlet
時運行,只會被執行一次。 @PreDestroy
註解在Servlet
卸載之前,destroy()
方法之後執行。- 上下文停止順序:
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