先看个例子:
系统解耦(解决不同重要程度、不同能力级别系统之间依赖导致一死全死)
解耦 -异步 -并行-最终一致
为什么使用rocketmq
1.面向分布式
2.集群
支付成功后,把支付后的结果通知给了mq,这个时候已经和支付系统没有关系了,剩下的就是交易系统的事情了,解决了耦合的问题。
消息去重,服务者重复发送同样的消息,消费者进行幂等操作---最多只能重试几次
消息失败,进行补偿重试,rocketmq,自身重试机制,限制次数,--但是消息本身错误,之后人工处理。
如果,消息提供者发送消息,消息订阅者接受到了消息,但是突然宕机了,我们应该怎么处理?
比如我们保存数据到数据库成功之后:看下面的伪代码。
boolean res=dao.save(data);
if(res){
sendMessage(msg);
}
解决方案:
在发送消息之前把我们需要发的消息的事件保存到数据库里,让保存数据和保存事件在同一个事务中,保存数据之后,我们统一提交事务
fastdfs--分布式文件系统 https://juejin.im/post/5a5ddf1d518825734501890b
redis分布式缓存
商户接口
支付网关
门户系统
运营系统
报表分析
队列监听
缓存系统
文件系统
互联网支付
第三方通道
邮件服务
账户
交易
成本
计费
通知
基础库
账户库
订单库
分布式系统中消息中间件:完成消息的发送和接收的基础软件mq
redis
fastdfs 分布式文件系统--可以保存商户的一些材料图片
window搭建rocketmq(linux两天了,用java程序连不上,反正是自己玩的(哭))
1下载解压
2配置环境变量 ROCKETMQ_HOME --(没有空格--bin和config的上一级目录)
3Cmd命令框执行进入至‘MQ文件夹\bin’下,然后执行‘start mqnamesrv.cmd’,启动NAMESERVER。成功后会弹
出提示框,此框勿关闭。
4
Cmd命令框执行进入至‘MQ文件夹\bin’下,然后执行‘start mqbroker.cmd -n 127.0.0.1:9876
autoCreateTopicEnable=true’,启动BROKER。成功后会弹出提示框,此框勿关闭。
5. 假如弹出提示框提示‘错误: 找不到或无法加载主类 xxxxxx’。打开runbroker.cmd,然后
将‘%CLASSPATH%’加上英文双引号。保存并重新执行start语句。
依赖
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-client</artifactId>
<version>4.3.0</version>
</dependency>
生产者发送一条消息
public class Producer {
public static void main(String[] args) throws Exception{
DefaultMQProducer producer = new DefaultMQProducer("producer_demo");
producer.setNamesrvAddr("localhost:9876");
producer.start();
Message message = new Message("demo-topic", "demo-tag", "这是一条测试消息".getBytes());
SendResult result = producer.send(message);
System.out.println(result);
producer.shutdown();
}
}
消费消息
public class Consumer {
public static void main(String[] args) throws Exception{
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("consumer_demo");
consumer.setNamesrvAddr("localhost:9876"); //修改为自己的
consumer.subscribe("demo-topic","*");
consumer.setMessageListener(new MessageListenerConcurrently() {//消息监听
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list,
ConsumeConcurrentlyContext consumeConcurrentlyContext) {
// 消息迭代
for(Message msg:list){
String tags = msg.getTags();
String topic = msg.getTopic();
byte[] body = msg.getBody();
try {
System.out.println(new String(body,
RemotingHelper.DEFAULT_CHARSET)+"tag"+tags+","+topic);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return ConsumeConcurrentlyStatus.RECONSUME_LATER; //稍后再试
}
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
//开启consumer
consumer.start();
}
}
//顺序消息
每一次只往一个队列中发送消息
//事务消息
//批量发送
发送方:发送一个消息集合 消费方:将消息的模式改成广播模式,默认是集群模式。