• 【开发篇】十七、消息:模拟订单短信通知



    相关文章: 【同步通讯与异步通讯】

    1、消息

    消息的发送方,即生产者。消息的接收方,即消费者。同步通信就行打视频,等着对方接电话才能继续往下,而异步通信就像发消息,发完我就干其他事儿了,啥时候回随你。

    在这里插入图片描述

    这种异步的模式,对应在生产中就是:

    在这里插入图片描述

    2、JMS

    JMS(Java Message Service):它是一个规范,等同于JDBC规范,提供了与消息服务相关的API接口

    JMS的消息模型有:

    • peer-2-peer:点对点模型,消息发送到一个队列中,队列保存消息。队列的消息只能被一个消费者消费,或超时
    • publish-subscribe:发布订阅模型,消息可以被多个消费者消费,生产者和消费者完全独立,不需要感知对方的存在

    JMS的消息种类有:

    • TextMessage
    • MapMessage
    • BytesMessage
    • StreamMessage
    • ObjectMessage
    • Message (只有消息头和属性)

    JMS的实现技术有(类比实现JDBC的各个数据库驱动):ActiveMQ、Redis、HornetMQ、RabbitMQ、RocketMQ(没有完全遵守JMS规范)

    3、AMQP

    AMQP(advanced message queuing protocol):一种协议(高级消息队列协议,也是消息代理规范),规范了网络交换的数据格式,兼容JMS。优点是具有跨平台性,服务器供应商,生产者、消费者可以使用不同的语言来实现

    AMQP消息模型有:

    • direct exchange
    • fanout exchange
    • topic exchange
    • headers exchange
    • system exchange

    AMQP消息种类有:

    • byte[](byte跨平台,字节哪儿都能通)

    AMQP的实现技术有:RabbitMQ、StormMQ、RocketMQ

    4、案例:模拟订单短信通知

    正常的一个购物订单业务,包含流程很多,比如:

    • 登录状态检测
    • 生成主单
    • 生成子单
    • 库存检测与变更
    • 积分变更
    • 支付
    • 短信通知
    • 购物车维护
    • 运单信息初始化
    • 商品库存维护
    • 会员维护

    这里模拟下单后给用户异步发送通知短信,先不用MQ,用一个集合模拟MQ来实现这个业务:首先写消息处理的Service层,模拟消费队列中的信息,发送短信给用户

    public interface MessageService {
        /**
         * 模拟往队列里放消息
         * @param id
         */
        void sendMessage(String id);
    
        /**
         * 模拟取消息,消费
         */
        String  doMessage();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    @Service
    @Slf4j
    public class MessageServiceImpl implements MessageService {
    
        private List<String> msgQueue = new ArrayList<>();  //用它模拟队列
    
        @Override
        public void sendMessage(String id) {
            msgQueue.add(id);
            log.info("待发送短信的订单已纳入处理队列,id:" + id);
    
        }
    
        @Override
        public String doMessage() {
            String id = msgQueue.remove(0);
            log.info("已完成发送短信业务,订单id:" + id);
            return id;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    写订单业务的Service层,模拟下单后,把订单编号等信息放到队列中

    public interface OrderService {
    
        void order(String id);
    }
    
    • 1
    • 2
    • 3
    • 4
    @Service
    @Slf4j
    public class OrderServiceImpl implements OrderService {
    
        @Resource
        private MessageService messageService;
    
        @Override
        public void order(String id) {
            //一系列操作,调用其他服务,处理业务
            //...
    
            log.info("订单处理开始...");
            //短信消息处理
            messageService.sendMessage(id);
            log.info("订单处理结束...");
            System.out.println(); //换行一下
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    完善下Controller层:

    @RestController
    @RequestMapping("/order")
    public class OrderController {
    
        @Resource
        private OrderService orderService;
    
        @PostMapping("{id}")
        public void order(@PathVariable String id){
            orderService.order(id);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    @RestController
    @RequestMapping("/msg")
    public class MessageController {
    
        @Resource
        private MessageService messageService;
    
        @PostMapping
        public String doMsg(){
            return messageService.doMessage();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    看下效果,调用订单接口,处理业务并且订单编号被扔进队列:

    在这里插入图片描述
    消费,完成短信发送:
    在这里插入图片描述

    再往下是整合各种MQ技术实现消息的发送与接收,分别为:

    • ActiveMQ
    • RabbitMQ
    • RocketMQ
    • Kafka

    对上面的代码,换一个实现类,重写sendMessage和doMessage这两个消息发送与处理的方法,就相当于换了一种MQ的实现技术

  • 相关阅读:
    flutter 移动应用程序中打开URL
    RabbitMQ实战宝典:从新手到专家的全面探索
    MSQL中DATETIME或TIMESTAMP的区别
    四、守护线程 deamon
    [附源码]计算机毕业设计JAVA音乐交流平台
    IDOC的状态
    6_ROS话题消息(Topic)
    FlinkSql之TableAPI详解
    Java 面试真题
    《Go Web 编程》之第2章 ChitChat论坛
  • 原文地址:https://blog.csdn.net/llg___/article/details/133615302