OJ在线评测系统 微服务 用分布式消息队列 RabbitMQ 解耦判题服务和题目服务 手搓交换机和队列 实现项目异步化

消息队列解耦 项目异步化

分布式消息队列

分布式消息队列是一种用于异步通信的系统,它允许不同的应用程序或服务之间传递消息。消息队列的核心理念是将消息存储在一个队列中,发送方可以将消息发送到队列,而接收方则可以在适当的时候从队列中读取消息。这种机制有助于解耦应用程序,提高系统的可扩展性和可靠性。

主要特点:

  1. 异步通信:发送方和接收方可以在不同的时间工作,不必直接交互。

  2. 负载均衡:通过将消息分发到多个消费者,可以有效利用系统资源。

  3. 消息持久化:许多消息队列系统支持将消息存储在磁盘上,以防数据丢失。

  4. 顺序处理:某些队列支持按顺序处理消息,确保消息的处理顺序。

  5. 容错性:分布式架构增强了系统的容错能力,可以在部分组件故障时继续工作。

常见的分布式消息队列系统:

  • Apache Kafka:高吞吐量、可扩展的消息队列,常用于大数据处理。

  • RabbitMQ:支持多种消息协议,易于使用,适合复杂的路由场景。

  • ActiveMQ:功能丰富,支持多种编程语言和消息协议。

分布式消息队列在微服务架构、事件驱动架构等场景中广泛应用,可以有效提高系统的灵活性和可维护性。

我们就用RabbitMQ去改造项目 解耦判题服务 题目服务

题目服务只需要向消息队列中发信息

判题服务从消息队列中取消息去执行判题

然后异步更新数据库即可

我们的题目服务和判题服务需要引入rabbitMQ

先引入消息队列的Java客户端

先引入依赖 amqp的客户端

        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency>

配置一下

  rabbitmq:host: localhostport: 5672password: guestusername: guest

我们要创建交换机和队列

先启动生产者 的消息队列

package com.yupi.yuojbackendjudgeservice.rabbitmq;import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import lombok.extern.slf4j.Slf4j;/*** 用于创建测试程序用到的交换机和队列(只用在程序启动前执行一次)*/
@Slf4j
public class InitRabbitMq {public static void doInit() {try {ConnectionFactory factory = new ConnectionFactory();factory.setHost("localhost");Connection connection = factory.newConnection();// 创建交换机 用于发 收信息Channel channel = connection.createChannel();String EXCHANGE_NAME = "code_exchange";channel.exchangeDeclare(EXCHANGE_NAME, "direct");// 创建队列 随机分配一个队列名称String queueName = "code_queue";channel.queueDeclare(queueName, true, false, false, null);channel.queueBind(queueName, EXCHANGE_NAME, "my_routingKey");log.info("消息队列启动成功");} catch (Exception e) {log.error("消息队列启动失败");}}public static void main(String[] args) {doInit();}
}

在启动类里面可以看见

package com.yupi.yuojbackendjudgeservice;import com.yupi.yuojbackendjudgeservice.rabbitmq.InitRabbitMq;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.scheduling.annotation.EnableScheduling;@SpringBootApplication
@EnableScheduling
@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
@ComponentScan("com.yupi")
@EnableDiscoveryClient
@EnableFeignClients(basePackages = {"com.yupi.yuojbackendserviceclient.service"})
public class YuojBackendJudgeServiceApplication {public static void main(String[] args) {// 初始化消息队列,先注释掉,改用 Bean 的方式初始化消息队列(InitRabbitMqBean.java)
//        InitRabbitMq.doInit();SpringApplication.run(YuojBackendJudgeServiceApplication.class, args);}}

接下来要把生产者的消息扔到交换机里面

package com.yupi.yuojbackendquestionservice.rabbitmq;import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;import javax.annotation.Resource;@Component
public class MyMessageProducer {@Resourceprivate RabbitTemplate rabbitTemplate;/*** 发送消息* @param exchange* @param routingKey* @param message*/public void sendMessage(String exchange, String routingKey, String message) {rabbitTemplate.convertAndSend(exchange, routingKey, message);}}

写一个接收消息的代码

package com.yupi.yuojbackendjudgeservice.rabbitmq;import com.rabbitmq.client.Channel;
import com.yupi.yuojbackendjudgeservice.judge.JudgeService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;import javax.annotation.Resource;@Component
@Slf4j
public class MyMessageConsumer {@Resourceprivate JudgeService judgeService;// 指定程序监听的消息队列和确认机制@SneakyThrows@RabbitListener(queues = {"code_queue"}, ackMode = "MANUAL")public void receiveMessage(String message, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag) {log.info("receiveMessage message = {}", message);long questionSubmitId = Long.parseLong(message);try {judgeService.doJudge(questionSubmitId);channel.basicAck(deliveryTag, false);} catch (Exception e) {channel.basicNack(deliveryTag, false, false);}}}

要传递的消息

是什么

传递的数据

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/55841.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

系统架构设计师论文《论企业集成平台的理解与应用》精选试读

论文真题 企业集成平台&#xff08;Enterprise Imtcgation Plaform,EIP)是支特企业信息集成的像环境&#xff0c;其主要功能是为企业中的数据、系统和应用等多种对象的协同行提供各种公共服务及运行时的支撑环境。企业集成平台能够根据业务模型的变化快速地进行信息系统的配置…

面试(十)

目录 一. 单元测试 二. FreeRTOS和裸机哪个实时性好&#xff1f; 三. 怎么判断某个程序的运行时间 四. 函数指针 五. 全局变量被线程使用冲突 5.1 使用互斥锁 5.2 使用读写锁 5.3 使用原子操作 六. 局部变量没有初始化是什么值 七. uint_8 n 255 , n等于多少 八. …

如何优化低计算密集度神经网络在GPU和NPU上的性能

在深度学习领域&#xff0c;GPU 和 NPU 是常用的硬件加速器&#xff0c;它们凭借强大的并行计算能力显著提升了深度神经网络&#xff08;DNN&#xff09;的训练和推理速度。然而&#xff0c;并不是所有模型在 GPU 和 NPU 上都能得到理想的性能提升。对于一些计算密集度较低的任…

单体到微服务架构服务演化过程

单体到微服务架构服务演化过程 架构服务化 聊聊从单体到微服务架构服务演化过程 单体分层架构 在 Web 应用程序发展的早期&#xff0c;大部分工程是将所有的服务端功能模块打包到单个巨石型&#xff08;Monolith&#xff09;应用中&#xff0c;譬如很多企业的 Java 应用程序…

3、Docker搭建MQTT及Spring Boot 3.x集成MQTT

一、前言 本篇主要是围绕着两个点&#xff0c;1、Docker 搭建单机版本 MQTT&#xff08;EMQX&#xff09;&#xff0c;2、Spring Boot 3.x 集成 MQTT&#xff08;EMQX&#xff09;&#xff1b; 而且这里的 MQTT&#xff08;EMQX&#xff09;的搭建也只是一个简单的过程&#x…

数据结构单向链表

单向链表的转置 转置的思想&#xff1a; (1) 将头节点与当前链表断开&#xff0c;断开前保存下头节点的下一个节点&#xff0c;保证后面链表能找得到&#xff0c;定义一个q保存头节点的下一个节点&#xff0c;断开后前面相当于一个空的链表&#xff0c;后面是一个无头的单向链表…

uni-app之旅-day03-搜索

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 5. 搜索5.0 创建 search 分支5.1 自定义搜索组件5.1.2 my-search.vue组件通过自定义属性增强组件的通用性5.1.3 为自定义组件封装 click 事件 5.2 搜索建议5.2.1 渲…

C++拾趣——绘制Console中DropdownMenu

大纲 居中显示窗口清屏并重设光标绘制窗口绘制窗口顶部绘制下拉行绘制下拉框选项绘制按钮行绘制窗口底部 修改终端默认行为对方向键的特殊处理过程控制Tab键的处理Enter键的处理上下左右方向键的处理 完整代码代码地址 这次我们要绘制下拉菜单&#xff0c;如下图。 居中显示窗口…

【JavaEE】【多线程】Thread类讲解

目录 Thread构造方法Thread 的常见属性创建一个线程获取当前线程引用终止一个线程使用标志位使用自带的标志位 等待一个线程线程休眠线程状态线程安全线程不安全原因总结解决由先前线程不安全问题例子 Thread构造方法 方法说明Thread()创建线程对象Thread(Runnable target)使用…

论文速读:基于渐进式转移的无监督域自适应舰船检测

这篇文章的标题是《Unsupervised Domain Adaptation Based on Progressive Transfer for Ship Detection: From Optical to SAR Images》基于渐进式转移的无监督域自适应舰船检测:从光学图像到SAR图像&#xff0c;作者是Yu Shi等人。文章发表在IEEE Transactions on Geoscience…

pg if条件语句

1.语法&#xff1a; 2.区别 IF 语句&#xff1a; 只能在 PL/pgSQL 中使用&#xff0c;不适合在直接的 SQL 查询中使用。没有返回值&#xff0c;仅仅是控制逻辑流程。适合用在存储过程、函数和触发器中。 CASE 语句&#xff08;在 PL/pgSQL 中&#xff09;&#xff1a; 可以在 P…

Comfyui segmentAnythingUltra V2报错

&#x1f385;问题表现及解决方案 Comfyui segmentAnythingUltra V2报错&#xff0c;找不到VITMatte模型&#xff0c;这个报错报的比较模糊&#xff0c;所以花了一点时间找模型。 简单来说&#xff0c;到huggingface上&#xff1a; https://huggingface.co/hustvl/vitmatte-s…

线性回归损失函数的推导

要推导损失函数公式 ℓ ( θ ) 1 2 n ( y ^ − y ) ⊤ ( y ^ − y ) \ell(\boldsymbol{\theta}) \frac{1}{2n}(\hat{\boldsymbol{y}} - \boldsymbol{y})^\top(\hat{\boldsymbol{y}} - \boldsymbol{y}) ℓ(θ)2n1​(y^​−y)⊤(y^​−y)&#xff0c;我们可以从几个基础概念开…

2024 Mysql基础与进阶操作系列之MySQL触发器详解(20)作者——LJS[你个小黑子这都还学不会嘛?你是真爱粉嘛?真是的 ~;以后请别侮辱我家鸽鸽]

欢迎各位彦祖与热巴畅游本人专栏与博客 你的三连是我最大的动力 以下图片仅代表专栏特色 [点击箭头指向的专栏名即可闪现] 专栏跑道一 ➡️ MYSQL REDIS Advance operation 专栏跑道二➡️ 24 Network Security -LJS ​ ​ ​ 专栏跑道三 ➡️HCIP&#xff1b;H3C-SE;CCIP——…

Qt 图片显示 动态选择图片显示

在 Qt 中&#xff0c;显示图片通常使用 QLabel 和 QPixmap 进行图像的加载和显示。QPixmap 是专门用于显示图像的类&#xff0c;而 QLabel 则是一个可以容纳图片的小部件。 1、使用 QLabel 和 QPixmap 来显示图片&#xff1a; #include <QApplication> #include <QL…

windows配置java环境变量

windows如何配置java环境变量&#xff08;java环境变量配置教程&#xff09;_windowsjava环境变量配置-CSDN博客

Redis接口访问优化

说明&#xff1a;之前写过一篇使用Redis接口访问的博客&#xff0c;如下。最近有相关需求&#xff0c;把代码拿出来后&#xff0c;做了一些优化&#xff0c;挺有意思的&#xff0c;本文介绍在原基础上 使用Redis实现接口防抖 优化 总的来说&#xff0c;这次使用Redis实现接口…

【尚硅谷】RocketMQ 消息队列学习笔记

RocketMQ 和 Kafka 消息队列概念比较&#xff1f; 好的&#xff01;RocketMQ 和 Kafka 都是分布式消息队列系统&#xff0c;它们的核心概念有很多相似之处&#xff0c;但在具体实现和命名上有所不同。下面我通过一个表格来对比 RocketMQ 和 Kafka 中的五个概念&#xff1a;消息…

操作系统 | 学习笔记 | 王道 | 4.1 文件系统基础

4.文件管理 4.1 文件系统基础 4.1.1 文件的基本概念 定义 文件是以计算机硬盘为载体的存储在计算机上的信息集合&#xff0c;在用户进行的输入、输出中&#xff0c;以文件位基本单位。 文件管理系统是实现的文件的访问、修改和保存&#xff0c;对文件维护管理的系统。 文件的…

2024重生之回溯数据结构与算法系列学习(11)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丟脸好嘛?】

欢迎各位彦祖与热巴畅游本人专栏与博客 你的三连是我最大的动力 以下图片仅代表专栏特色 [点击箭头指向的专栏名即可闪现] 专栏跑道一 ➡️ MYSQL REDIS Advance operation 专栏跑道二➡️ 24 Network Security -LJS ​ ​ ​ 专栏跑道三 ➡️HCIP&#xff1b;H3C-SE;CCIP——…