【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>
项目地址:https://gitee.com/mdxl/blog.git
提前了解:Springboot事件监听配置,本博客以Springboot2.1.5版本集成配置。
1、安装RocketMQ
官网介绍,自己点击按照步骤走:http://rocketmq.apache.org/docs/quick-start/
不过在启动broker的时候,可以更改成如下命令,意思为RocketMQ支持自动创建topic,默认不支持。
nohup sh bin/mqbroker -n localhost:9876 autoCreateTopicEnable=true &
2、pom依赖
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.apache.rocketmq</groupId> <artifactId>rocketmq-client</artifactId> <version>4.4.0</version> </dependency> <dependency> <groupId>org.apache.rocketmq</groupId> <artifactId>rocketmq-common</artifactId> <version>4.4.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency>
3、application.properties
server.port=8081 # rocketMQ配置 myrocket.rocketmq.namesrvAddr=192.168.1.121:9876 myrocket.rocketmq.producer_groupName=user_producer_group myrocket.rocketmq.producer_transaction_groupName=order_transaction myrocket.rocketmq.producer_tranInstanceName=user_producer_transacition myrocket.rocketmq.producer_instanceName=user_producer_instance myrocket.rocketmq.consumer_instanceName=user_consumer_instance myrocket.rocketmq.consumer_groupName=user_consumer_group myrocket.rocketmq.consumer_batchMaxSize=1 myrocket.rocketmq.consumer_broadcasting=false myrocket.rocketmq.subscribe[0]=user-topic:white myrocket.rocketmq.enableHistoryConsumer=false myrocket.rocketmq.enableOrderConsumer=false
4、配置实体类
@Component @Configuration @PropertySource("classpath:application.properties") @ConfigurationProperties(prefix = "myrocket.rocketmq") @Data public class RocketMQProperties { // NameServer地址 private String namesrvAddr; // 生产者group名 private String producer_groupName; // 生产者事务group名 private String producer_transaction_groupName; // 生产者事务实例名称 private String producer_tranInstanceName; // 生产者实例名称 private String producer_instanceName; // 消费者group名 private String consumer_groupName; // 消费者实例名称 private String consumer_instanceName; // 消费者一次最大消费多少数量消息 private int consumer_batchMaxSize; // 广播消费 private boolean consumer_broadcasting; // 启动的时候是否消费历史记录 private boolean enableHistoryConsumer; // 启动顺序消费 private boolean enableOrderConsumer; // 消费的topic:tag private List<String> subscribe = new ArrayList<>(); }
5、事件监听类
public class MessageEvent extends ApplicationEvent { private static final long serialVersionUID = -4468405250074063206L; private DefaultMQPushConsumer consumer; private List<MessageExt> msgs; public MessageEvent(List<MessageExt> msgs, DefaultMQPushConsumer consumer) throws Exception { super(msgs); this.consumer = consumer; this.setMsgs(msgs); } public DefaultMQPushConsumer getConsumer() { return consumer; } public void setConsumer(DefaultMQPushConsumer consumer) { this.consumer = consumer; } public List<MessageExt> getMsgs() { return msgs; } public void setMsgs(List<MessageExt> msgs) { this.msgs = msgs; } }
6、rocketMq配置类
@Configuration @EnableConfigurationProperties(RocketMQProperties.class) public class RocketMQConfiguration { private static final Logger logger = LoggerFactory.getLogger(RocketMQConfiguration.class); @Autowired private RocketMQProperties rocketMQProperties; //事件监听 @Autowired private ApplicationEventPublisher publisher = null; private static boolean isFirstSub = true; private static long startTime = System.currentTimeMillis(); /** * 初始化 */ @PostConstruct public void init() { } /** * 创建普通消息发送者实例 */ @Bean public DefaultMQProducer defaultProducer() throws MQClientException { DefaultMQProducer producer = new DefaultMQProducer( rocketMQProperties.getProducer_groupName()); producer.setNamesrvAddr(rocketMQProperties.getNamesrvAddr()); producer.setInstanceName(rocketMQProperties.getProducer_instanceName()); producer.setVipChannelEnabled(false); producer.setRetryTimesWhenSendAsyncFailed(10); producer.start(); logger.info("rocketmq producer server is starting...."); return producer; } /** * 创建支持消息事务发送的实例 */ @Bean public TransactionMQProducer transactionProducer() throws MQClientException { TransactionMQProducer producer = new TransactionMQProducer( rocketMQProperties.getProducer_transaction_groupName()); producer.setNamesrvAddr(rocketMQProperties.getNamesrvAddr()); producer.setInstanceName(rocketMQProperties .getProducer_tranInstanceName()); producer.setRetryTimesWhenSendAsyncFailed(10); // 事务回查最小并发数 producer.setCheckThreadPoolMinSize(2); // 事务回查最大并发数 producer.setCheckThreadPoolMaxSize(2); // 队列数 producer.setCheckRequestHoldMax(2000); producer.start(); logger.info("rocketmq transaction producer server is starting...."); return producer; } /** * 创建消息消费的实例 */ @Bean public DefaultMQPushConsumer pushConsumer() throws MQClientException { DefaultMQPushConsumer consumer = new DefaultMQPushConsumer( rocketMQProperties.getConsumer_groupName()); consumer.setNamesrvAddr(rocketMQProperties.getNamesrvAddr()); consumer.setInstanceName(rocketMQProperties.getConsumer_instanceName()); //判断是否是广播模式 if (rocketMQProperties.isConsumer_broadcasting()) { consumer.setMessageModel(MessageModel.BROADCASTING); } //设置批量消费 consumer.setConsumeMessageBatchMaxSize(rocketMQProperties .getConsumer_batchMaxSize() == 0 ? 1 : rocketMQProperties .getConsumer_batchMaxSize()); //获取topic和tag List<String> subscribeList = rocketMQProperties.getSubscribe(); for (String sunscribe : subscribeList) { consumer.subscribe(sunscribe.split(":")[0], sunscribe.split(":")[1]); } // 顺序消费 if (rocketMQProperties.isEnableOrderConsumer()) { consumer.registerMessageListener(new MessageListenerOrderly() { @Override public ConsumeOrderlyStatus consumeMessage( List<MessageExt> msgs, ConsumeOrderlyContext context) { try { context.setAutoCommit(true); msgs = filterMessage(msgs); if (msgs.size() == 0) return ConsumeOrderlyStatus.SUCCESS; publisher.publishEvent(new MessageEvent(msgs, consumer)); } catch (Exception e) { e.printStackTrace(); return ConsumeOrderlyStatus.SUSPEND_CURRENT_QUEUE_A_MOMENT; } return ConsumeOrderlyStatus.SUCCESS; } }); } else { // 并发消费 consumer.registerMessageListener(new MessageListenerConcurrently() { @Override public ConsumeConcurrentlyStatus consumeMessage( List<MessageExt> msgs, ConsumeConcurrentlyContext context) { try { //过滤消息 msgs = filterMessage(msgs); if (msgs.size() == 0) return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; publisher.publishEvent(new MessageEvent(msgs, consumer)); } catch (Exception e) { e.printStackTrace(); return ConsumeConcurrentlyStatus.RECONSUME_LATER; } return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; } }); } new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(5000); try { consumer.start(); } catch (Exception e) { e.printStackTrace(); } logger.info("rocketmq consumer server is starting...."); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); return consumer; } /** * 消息过滤 */ private List<MessageExt> filterMessage(List<MessageExt> msgs) { if (isFirstSub && !rocketMQProperties.isEnableHistoryConsumer()) { msgs = msgs.stream() .filter(item -> startTime - item.getBornTimestamp() < 0) .collect(Collectors.toList()); } if (isFirstSub && msgs.size() > 0) { isFirstSub = false; } return msgs; } }
7、实体类
@Data public class User{ private String id; private String userName; }
8、service层
@Component public class ConsumerService { @EventListener(condition = "#event.msgs[0].topic=='user-topic' && #event.msgs[0].tags=='white'") public void rocketmqMsgListener(MessageEvent event) { try { List<MessageExt> msgs = event.getMsgs(); for (MessageExt msg : msgs) { System.err.println("消费消息:"+new String(msg.getBody())); } } catch (Exception e) { e.printStackTrace(); } } }
9、controller层
@RestController public class ProducerController { @Autowired private DefaultMQProducer defaultProducer; @Autowired private TransactionMQProducer transactionProducer; /** * 发送普通消息 */ @GetMapping("/sendMessage") public void sendMsg() { for(int i=0;i<10;i++){ User user = new User(); user.setId(String.valueOf(i)); user.setUserName("osc木九天"+i+"号"); String json = JSON.toJSONString(user); Message msg = new Message("user-topic","white",json.getBytes()); try { SendResult sendResult = defaultProducer.send(msg); System.out.println("消息id:"+sendResult.getMsgId()+":"+","+"发送状态:"+sendResult.getSendStatus()); } catch (Exception e) { e.printStackTrace(); } } } /** * 发送事务消息 * @return */ @GetMapping("/sendTransactionMess") public String sendTransactionMsg() { SendResult sendResult = null; try { // a,b,c三个值对应三个不同的状态 String ms = "c"; Message msg = new Message("user-topic","white",ms.getBytes()); // 发送事务消息 sendResult = transactionProducer.sendMessageInTransaction(msg, (Message msg1, Object arg) -> { String value = ""; if (arg instanceof String) { value = (String) arg; } if (value == "") { throw new RuntimeException("发送消息不能为空..."); } else if (value =="a") { return LocalTransactionState.ROLLBACK_MESSAGE; } else if (value =="b") { return LocalTransactionState.COMMIT_MESSAGE; } return LocalTransactionState.ROLLBACK_MESSAGE; }, 4); System.out.println(sendResult); } catch (Exception e) { e.printStackTrace(); } return sendResult.toString(); } /** * 支持顺序发送消息 */ @GetMapping("/sendMessOrder") public void sendMsgOrder() { for(int i=0;i<10;i++) { User user = new User(); user.setId(String.valueOf(i)); user.setUserName("选手" + i); String json = JSON.toJSONString(user); Message msg = new Message("user-topic", "white", json.getBytes()); try{ SendResult sendResult = defaultProducer.send(msg, new MessageQueueSelector() { @Override public MessageQueue select(List<MessageQueue> mqs, Message msg, Object arg) { int index = ((Integer) arg) % mqs.size(); return mqs.get(index); } },i); System.out.println("消息id:"+sendResult.getMsgId()+":"+","+"发送状态:"+sendResult.getSendStatus()); } catch (Exception e){ e.printStackTrace(); } } } }
10、测试
来源:oschina
链接:https://my.oschina.net/mdxlcj/blog/3153861