直接上找个最终版本的。
另一个:
shop发消息,coupon接受消息。
第一步:依赖
第二步:
rocketmq.producer.groupName=shop
rocketmq.producer.namesrvAddr=192.168.244.140:9876
rocketmq.producer.default=true
第三步:
@Configuration
public class ProducerConfigure {
private static final Logger log = LoggerFactory.getLogger(ProducerConfigure.class);
@Value("${rocketmq.producer.groupName}")
private String groupName;
@Value("${rocketmq.producer.namesrvAddr}")
private String namesrvAddr;
@Bean
public DefaultMQProducer defaultMQProducer() throws MQClientException {
DefaultMQProducer producer = new DefaultMQProducer(groupName);
producer.setNamesrvAddr(namesrvAddr);
producer.setRetryTimesWhenSendAsyncFailed(10);// 发送端重试次数薇10
producer.start();
log.info("start rocketmq producer success!");
return producer;
}
}
异步发送:
@RestController
@RequestMapping("/test")
public class TestController {
private static final Logger log = LoggerFactory.getLogger(TestController.class);
@Autowired
private DefaultMQProducer producer;
@GetMapping("/test")
public void test(String info) throws Exception {
Message message = new Message("TopicTest", "Tag1", "12345", "rocketmq测试成功".getBytes());
// 这里用到了这个mq的异步处理,类似ajax,可以得到发送到mq的情况,并做相应的处理
//不过要注意的是这个是异步的
producer.send(message, new SendCallback() {
@Override
public void onSuccess(SendResult sendResult) {
log.info("传输成功");
log.info(JSON.toJSONString(sendResult));
}
@Override
public void onException(Throwable e) {
log.error("传输失败", e);
}
});
}
}
两个坑:
1.不能自动创建topic:https://blog.csdn.net/zixiao217/article/details/89844003
2.网卡:https://blog.csdn.net/qq_14853889/article/details/81053145
-----------------------------------------------------17-1-------------------------------------------------
coupon:消费端
第一步:
rocketmq:
# 消费者配置
consumer:
pay:
groupName: payResult
namesrvAddr: 192.168.244.140:9876
order:
groupName: saveOrder
namesrvAddr: 192.168.244.140:9876
第二步:
@Configuration
public abstract class DefaultConsumerConfig {
private static final Logger log = LoggerFactory.getLogger(DefaultConsumerConfig.class);
@Value("${rocketmq.consumer.groupName}")
private String groupName;
@Value("${rocketmq.consumer.namesrvAddr}")
private String namesrvAddr;
public void consumer(String topic,String tag) throws MQClientException {
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(groupName);
consumer.setNamesrvAddr(namesrvAddr);
consumer.subscribe(topic,tag);
consumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
return DefaultConsumerConfig.this.dealBody(msgs);
}
});
consumer.start();
log.info("rocketmq启动成功-----------------------");
}
public abstract ConsumeConcurrentlyStatus dealBody(List<MessageExt> msgs) ;
}
package com.xdclass.couponapp.service;
import com.xdclass.couponapp.config.DefaultConsumerConfig;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.common.message.MessageExt;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Service;
import java.io.UnsupportedEncodingException;
import java.util.List;
@Service
public class TestListener extends DefaultConsumerConfig implements ApplicationListener<ContextRefreshedEvent> {
private static final Logger log = LoggerFactory.getLogger(TestListener.class);
@Override
public ConsumeConcurrentlyStatus dealBody(List<MessageExt> msgs) {
msgs.forEach(msg -> {
byte[] bytes = msg.getBody();
try {
String msgStr = new String(bytes, "utf-8");
log.info(msgStr);
} catch (UnsupportedEncodingException e) {
log.error("body转字符串失败");
}
});
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
@Override
public void onApplicationEvent(ContextRefreshedEvent arg0) {
try {
super.consumer("TopicTest", "Tag1");
} catch (MQClientException e) {
log.error("消费者监听器启动失败", e);
}
}
}
收到消息了:
spring的观察者模式:
1.写consumer
2.写监听器,监听启动事件,调用consumer方法,实现抽象类。
-----------------------------------------------------17-2-------------------------------------------------
下单如何通知,关联关系如何通知?
不同系统的互调,涉及到不同组的开发,用到协议。
-----------------------------------------------------17-3-------------------------------------------------
代码:
创建实体类。
发消息绑定人 优惠券 订单
//用户下单跟新coupon和order关联关系
private void updateCouponCode(int orderId,int userId,String couponCode){
OrderCouponDto dto = new OrderCouponDto(couponCode,orderId,userId);
Message message = new Message("TopicTest", "Tag1", "12345", dto.toString().getBytes());
// 这里用到了这个mq的异步处理,类似ajax,可以得到发送到mq的情况,并做相应的处理
//不过要注意的是这个是异步的
try {
producer.send(message, new SendCallback() {
@Override
public void onSuccess(SendResult sendResult) {
log.info("传输成功");
log.info(JSON.toJSONString(sendResult));
}
@Override
public void onException(Throwable e) {
log.error("传输失败", e);
}
});
} catch (Exception e) {
log.error("传输失败", e);
}
}
下单完毕。
-----------------------------------------------------17-4-------------------------------------------------
支付流程:shop中
private void payResutlt(int orderId, int userId) {
OrderCouponDto dto = new OrderCouponDto(orderId, userId,0);
Message message = new Message("payResult", "Tag1", "12345", dto.toString().getBytes());
// 这里用到了这个mq的异步处理,类似ajax,可以得到发送到mq的情况,并做相应的处理
//不过要注意的是这个是异步的
send(message);
}
public void pay(Integer orderId) {
Order order = orderDao.findOne(orderId);
order.setStatus(Constants.OrderStatus.PAYED);
order.setPayTime(new Date());
orderDao.save(order);
payResutlt(orderId,order.getUser().getId());
log.info("send pay result success");
}
-----------------------------------------------------17-5-------------------------------------------------
注意要设置两个消费者,在一个消费者组。
-----------------------------------------------------17-6-------------------------------------------------