1. 消息的概念

从广义角度来说,消息其实就是信息,但是和信息又有所不同。信息通常被定义为一组数据,而消息除了具有数据的特征之外,还有消息的来源与接收的概念。通常发送消息的一方称为消息的生产者,接收消息的一方称为消息的消费者。这样比较后,发现其实消息和信息差别还是很大的。

为什么要设置生产者和消费者呢?这就是要说到消息的意义了。信息通常就是一组数据,但是消息由于有了生产者和消费者,就出现了消息中所包含的信息可以被二次解读,生产者发送消息,可以理解为生产者发送了一个信息,也可以理解为生产者发送了一个命令;消费者接收消息,可以理解为消费者得到了一个信息,也可以理解为消费者得到了一个命令。

总的来说,消息其实也是一组信息,只是为其赋予了全新的含义,因为有了消息的流动,并且是有方向性的流动带来了基于流动的行为产生的全新解读。开发者就可以基于消息的这种特殊解,将其换成代码中的指令
在这里插入图片描述
MQ(message queue) 消息队列,也叫做消息中间件,根据指令进行业务分发处理。

2. 消息的模式

对于消息的生产者与消费者的工作模式,还可以将消息划分成两种模式,同步消息异步消息

所谓同步消息就是生产者发送完消息,等待消费者处理,消费者处理完将结果告知生产者,然后生产者继续向下执行业务。这种模式过于卡生产者的业务执行连续性,在现在的企业级开发中,上述这种业务场景通常不会采用消息的形式进行处理。

所谓异步消息就是生产者发送完消息,无需等待消费者处理完毕,生产者继续向下执行其他动作。比如生产者发送了一个日志信息给日志系统,发送过去以后生产者就向下做其他事情了,无需关注日志系统的执行结果。

3. Java处理消息的标准规范

目前企业级开发中广泛使用的消息处理技术共三大类,具体如下:

  • JMS
  • AMQP
  • MQTT

​ 为什么是三大类,而不是三个技术呢?因为这些都是规范,就像JDBC技术,是个规范,开发针对规范开发,运行还要靠实现类,例如MySQL提供了JDBC的实现,最终运行靠的还是实现。并且这三类规范都是针对异步消息进行处理的,也符合消息的设计本质,处理异步的业务。

3.1 JMS

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

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

  • JMS实现:
    ActiveMQ、Redis、HornetMQ、RabbitMQ、RocketMQ(没有完全遵守JMS规范)

3.2 AMQP

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

3.3 MQTT

  • MQTT(Message Queueing Telemetry Transport)消息队列遥测传输,专为小设备设计,是物联网(IOT)生
    态系统中主要成分之一

3.4 kafka

  • Kafka,一种高吞吐量的分布式发布订阅消息系统,提供实时消息功能。Kafka技术并不是作为消息中间件为主要功能的产品,但是其拥有发布订阅的工作模式,也可以充当消息中间件来使用.

4. 购物订单发送手机短信案例

为了便于下面演示各种各样的消息中间件技术,我们创建一个购物过程生成订单时为用户发送短信的案例环境,模拟使用消息中间件实现发送手机短信的过程。

​ 手机验证码案例需求如下:

  • 执行下单业务时(模拟此过程),调用消息服务,将要发送短信的订单id传递给消息中间件

  • 消息处理服务接收到要发送的订单id后输出订单id(模拟发短信)

4.1 订单业务

  1. 业务层接口
public interface OrderService {
    void order(String id);
}
  1. 业务层实现
    调用短信处理业务的senMsg方法,将订单加入消息队列
@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private MsgService msgService;

    @Override
    public void order(String id) {

        System.out.println("开始处理订单");
        msgService.sendMsg(id);
        System.out.println("订单处理结束");
        System.out.println();
    }
}

  1. 表现层开发
@RestController
@RequestMapping("/orders")
public class ServiceController {

    @Autowired
    private OrderService orderService;

    @PostMapping("{id}")
    public void order(@PathVariable String id){
        orderService.order(id);
    }
}

4.2 短信处理业务

  1. 短信业务层接口
    接口定义了两个方法,分别是将消息加入消息队列,一个是模拟发送短信。模拟短信目前是手动发送,使用mq技术后,我们就能通过监听实现自动发送功能。
public interface MsgService {
    void sendMsg(String id);
    String doMsg();
}
  1. 短信业务层实现
@Service
public class MsgServiceImpl  implements MsgService {

    private ArrayList<String> msgList = new ArrayList<>();

    @Override
    public void sendMsg(String id) {

        System.out.println("已将待处理消息加入队列,id :"+id);
        msgList.add(id);

    }

    @Override
    public String doMsg() {
        String id = msgList.remove(0);
        System.out.println("已完成短信发送业务,id :"+id);
        return id;
    }
}
  1. 表现层开发
@RestController
@RequestMapping("/msgs")
public class MsgServiceController {

    @Autowired
    private MsgService msgService;

    @GetMapping
    private String doMsg(){
        String id = msgService.doMsg();
        return id;
    }
}

为了方便测试,我们在yml配置文件中将端口配置为80

server: 
	port:80

ok,接下来我们运行程序,使用postman进行测试。
在这里插入图片描述
在这里插入图片描述
这里我们没有使用消息中间件,因此短信发送业务是我们手动完成,在接下去的blog中我们会讲解springboot整合robbitMQ,rockerMQ,kafka等。到时候就能实现自动发送。
在这里插入图片描述
在这里插入图片描述
好的,本篇就写到这里,对消息中间件感兴趣的我们下一篇见。

Logo

Kafka开源项目指南提供详尽教程,助开发者掌握其架构、配置和使用,实现高效数据流管理和实时处理。它高性能、可扩展,适合日志收集和实时数据处理,通过持久化保障数据安全,是企业大数据生态系统的核心。

更多推荐