RabbitMq实战之(一)介绍原理

tech2024-11-20  15

RabbitMQ

概述典型的应用场景介绍异步通信和服务解耦接口限流和消息分发延迟处理 基于Spring的事件驱动模型实战

概述

redis的主要作用是提升高并发请求下的查询性能,减少查询数据库的次数,从而减轻数据库的压力。 但是随着流量的增长,传统应用在系统接口和服务处理模块层面仍然是高耦合,同步的处理方式,导致了接口由于线程堵塞而延长了整体的响应性能,即产生了高延迟。RabbitMQ就是为了解决这一问题 使用领域,服务模块解耦,异步通信,高并发限流,超时服务,数据延迟处理等。这些内容在下面会有提及

典型的应用场景介绍

异步通信和服务解耦

以注册登录为例,传统的业务逻辑如下 上述业务流程中,判断用户是否合法并写入数据库是其主要核心业务,而邮箱验证和发送短信验证并不是核心流程(因为你登录了,你可以后续验证),所以我们可以将邮箱验证和发送短息解耦出来,这是服务解耦

接口限流和消息分发

以抢购为例,抢购主要在于流量在某一时刻爆发 引入RabbitMQ后

(1)接口限流,前端对后端的请求不会立即到达后端系统,而是进入队列 (2)异步分发,当抢到商品的时候,异步发送信息

延迟处理

如抢火车票,如果下单后30分钟未付款,系统会自动取消该笔订单,传统的业务开发,会采用定时器的方式,每隔10秒从数据库拉取状态为0(未支付)的数据,判断当前时间是否大于30分钟,如果是就取消。 引入RabbitMQ

基于Spring的事件驱动模型实战

spring的事件驱动,就是事件驱动实现业务之间的交互,交互的方式有同步和异步两种,事件也可称之为消息

在传统的spring应用系统中,没有RabbitMQ之前,是就是通过事件驱动模型解耦业务和异步通信的,这个现在的RabbitMQ有着几分相似之处

接下来要实现一个Spring的事件驱动,需求为,用户登录成功后的相关信息封装成实体对象,由生产者采用异步的方式发布给消费者,当消费者监听到消息时,执行相应的业务处理逻辑。

package com.learn.boot.event; import lombok.Data; import lombok.ToString; import org.springframework.context.ApplicationEvent; import java.io.Serializable; /** * zlx * 用户登录成功后的消息 */ @ToString public class LoginEvent extends ApplicationEvent implements Serializable { /** * 登录名 */ private String userName; /** * 登录ip */ private String ip; /** * 登录时间 */ private String loginTime; public LoginEvent(Object source) { super(source); } /** 重构构造方法 * @param source * @param ip * @param loginTime * @param userName */ public LoginEvent(Object source,String ip,String loginTime,String userName) { super(source); this.ip = ip; this.loginTime = loginTime; this.userName = userName; } } package com.learn.boot.event; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationListener; import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.stereotype.Component; /** * 事件模型的消费者 */ @Component @EnableAsync //允许异步执行 public class Consumer implements ApplicationListener<LoginEvent> { private static final Logger log = LoggerFactory.getLogger(Consumer.class); /** 监听的方法 * @param loginEvent */ @Override @Async public void onApplicationEvent(LoginEvent loginEvent) { //输出日志信息 log.info("Spring事件驱动模型-接收消息:{}",loginEvent); //TODO:后续为实现自身的业务逻辑,如写入数据库等 } } package com.learn.boot.event; import org.apache.catalina.core.ApplicationPushBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Component; import java.text.SimpleDateFormat; import java.util.Date; /** zlx * 事件模型发送者 */ @Component public class Producer { private static final Logger log= LoggerFactory.getLogger(Producer.class); @Autowired private ApplicationEventPublisher pushBuilder; public void sendMesg() throws Exception { // 构造登录以后的实体对象 LoginEvent event=new LoginEvent(this,"debug",new SimpleDateFormat ("yyyyy-MM-dd HH:mm:ss").format(new Date()),"127.0.0.1"); //发送消息 pushBuilder.publishEvent(event); log.info("发送者发送对象{}",event); } } package com.learn.boot; import com.learn.boot.event.Producer; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest class BootApplicationTests { @Autowired Producer producer; @Test void contextLoads() throws Exception { // 调用发送者测试 producer.sendMesg(); } }
最新回复(0)