• RabbitMQ和Minio实现头像存储


    使用 RabbitMQ 处理用户头像上传任务,同时将用户头像存储在 Minio 中是一个常见的应用场景。该示例将展示如何在 Spring Boot 项目中使用 RabbitMQ 和 Minio 实现此功能。示例包括两个部分:一是将头像上传任务推送到 RabbitMQ 队列中;二是从队列中消费任务并将用户头像上传到 Minio。

    首先,请确保你在 Spring Boot 项目中引入以下依赖:

    1. <dependencies>
    2. <dependency>
    3. <groupId>org.springframework.bootgroupId>
    4. <artifactId>spring-boot-starter-amqpartifactId>
    5. dependency>
    6. <dependency>
    7. <groupId>io.miniogroupId>
    8. <artifactId>minioartifactId>
    9. <version>8.5.2version>
    10. dependency>
    11. <dependency>
    12. <groupId>org.springframework.bootgroupId>
    13. <artifactId>spring-boot-starter-webartifactId>
    14. dependency>
    15. dependencies>

    1. 配置RabbitMQ和Minio

    首先,在 application.properties 文件中配置 RabbitMQ 和 Minio 的连接信息:

    propertiesCopy code

    1. # RabbitMQ 配置
    2. spring.rabbitmq.host=localhost
    3. spring.rabbitmq.port=5672
    4. spring.rabbitmq.username=guest
    5. spring.rabbitmq.password=guest
    6. # Minio 配置
    7. minio.url=http://localhost:9000
    8. minio.accessKey=YOUR_ACCESS_KEY
    9. minio.secretKey=YOUR_SECRET_KEY
    10. minio.bucketName=avatars

    2. 头像上传任务数据模型

    定义一个数据模型来表示头像上传任务,包括用户 ID 和头像文件内容:

    1. import java.io.Serializable;
    2. @Data
    3. public class Avatar implements Serializable {
    4. private String userId;
    5. private byte[] avatarData;
    6. }

    3. 推送头像上传任务到 RabbitMQ

    用户信息导入过程中,将头像上传任务推送到 RabbitMQ 队列:

    1. import org.springframework.amqp.core.AmqpTemplate;
    2. import org.springframework.beans.factory.annotation.Autowired;
    3. import org.springframework.stereotype.Service;
    4. @Service
    5. public class AvatarUploadService {
    6. @Autowired
    7. private AmqpTemplate amqpTemplate;
    8. // 将头像上传任务推送到 RabbitMQ 队列
    9. public void uploadAvatar(String userId, byte[] avatarData) {
    10. Avatar task = new Avatar();
    11. task.setUserId(userId);
    12. task.setAvatarData(avatarData);
    13. // 推送到 RabbitMQ 队列
    14. amqpTemplate.convertAndSend("avatarUploadQueue", task);
    15. }
    16. }

    4. 从 RabbitMQ 队列消费任务并将头像上传到 Minio

    创建一个消费者来从 RabbitMQ 队列中接收任务,并将用户头像上传到 Minio:

    1. import com.example.concurrent_demo.entity.Avatar;
    2. import io.minio.MinioClient;
    3. import io.minio.PutObjectArgs;
    4. import org.springframework.amqp.rabbit.annotation.RabbitListener;
    5. import org.springframework.beans.factory.annotation.Autowired;
    6. import org.springframework.stereotype.Service;
    7. import java.io.ByteArrayInputStream;
    8. @Service
    9. public class AvatarUploadConsumer {
    10. @Autowired
    11. private MinioClient minioClient;
    12. // 从 RabbitMQ 队列消费任务
    13. @RabbitListener(queues = "avatarUploadQueue")
    14. public void consumeAvatarUploadTask(Avatar task) {
    15. byte[] data = task.getAvatarData();
    16. // 创建 PutObjectArgs 对象,指定上传参数
    17. PutObjectArgs putObjectArgs = PutObjectArgs.builder()
    18. .bucket("avatars")
    19. .object(task.getUserId())
    20. .stream(new ByteArrayInputStream(data), data.length, -1)
    21. .contentType("image/jpeg") // 修改此处为 "image/jpeg"
    22. .build();
    23. try {
    24. // 将用户头像上传到 Minio
    25. minioClient.putObject(putObjectArgs);
    26. System.out.println("Avatar uploaded for user: " + task.getUserId());
    27. } catch (Exception e) {
    28. e.printStackTrace();
    29. System.err.println("Failed to upload avatar for user: " + task.getUserId());
    30. }
    31. }
    32. }

    5. 配置 Minio 客户端

    创建一个配置类来初始化 Minio 客户端,并将其作为 Spring Bean:

    1. import io.minio.MinioClient;
    2. import org.springframework.beans.factory.annotation.Value;
    3. import org.springframework.context.annotation.Bean;
    4. import org.springframework.context.annotation.Configuration;
    5. @Configuration
    6. public class MinioConfig {
    7. @Value("${minio.url}")
    8. private String url;
    9. @Value("${minio.accessKey}")
    10. private String accessKey;
    11. @Value("${minio.secretKey}")
    12. private String secretKey;
    13. @Bean
    14. public MinioClient minioClient() {
    15. return MinioClient.builder()
    16. .endpoint(url)
    17. .credentials(accessKey, secretKey)
    18. .build();
    19. }
    20. }

    通过这些步骤,你可以在 Spring Boot 项目中使用 RabbitMQ 和 Minio 实现用户头像的异步上传。你可以根据具体需求进一步调整代码,以满足特定的业务需求。

    使用RabbitMQ作为消息队列系统来实现头像上传与存储具有以下好处:

    1. 解耦性:RabbitMQ可以将生产者和消费者解耦,使它们之间不直接通信。生产者只需将消息发送到RabbitMQ中,而不需要知道具体的消费者是谁,消费者也不需要知道消息的来源。这样,即使生产者或消费者发生变化,系统的其他部分也不会受到影响。

    2. 异步处理:通过使用消息队列,可以实现异步处理任务。在头像上传的场景中,用户上传头像后,可以立即返回给用户,而后台服务可以异步地从消息队列中获取消息,处理头像上传的任务,这样可以提高系统的响应速度和并发能力。

    3. 削峰填谷:消息队列可以平滑处理系统的流量峰值。当大量用户同时上传头像时,消息队列可以缓冲请求,并控制任务的并发处理数量,避免系统因突发流量而崩溃。

    4. 可靠性:RabbitMQ提供了消息持久化和消息确认机制,确保消息的可靠传递和处理。即使消费者在处理消息时发生故障,消息也不会丢失,因为它们仍然存储在消息队列中,等待重新处理。

    5. 灵活性:RabbitMQ支持多种消息传递模式,如点对点、发布/订阅和请求/响应模式,可以根据具体的场景选择合适的消息模式来实现功能。

    综上所述,使用RabbitMQ作为消息队列系统可以提高系统的可扩展性、可靠性和灵活性,从而更好地实现头像上传和存储功能。

    使用Minio对象存储服务相对于直接使用MySQL数据库存储头像有以下好处:

    1. 分布式存储:Minio是一个分布式对象存储服务,可以轻松地扩展存储容量和性能,适用于大规模的数据存储需求。相比之下,MySQL数据库存储受限于单节点的存储容量和性能,难以满足高并发和大容量存储的需求。

    2. 高可用性:Minio支持数据的多副本备份和自动故障转移,确保数据的高可用性和持久性。即使出现存储节点故障,也能保证数据不丢失,对用户透明。而MySQL数据库在单节点故障时需要手动进行故障恢复,并且存在数据丢失的风险。

    3. 数据管理:Minio提供了丰富的数据管理功能,包括数据版本控制、数据加密、数据生命周期管理等,能够更好地管理和保护用户数据。相比之下,MySQL数据库的数据管理功能相对有限。

    4. 存储成本:Minio的存储成本通常比传统的关系型数据库低,尤其是对于大规模的数据存储场景。Minio基于对象存储的方式存储数据,可以根据实际需求按需扩展存储容量,避免了数据库存储的昂贵成本。

    5. 性能优势:Minio专注于对象存储服务,具有优化的性能和吞吐量,特别适用于存储大文件和大数据量。相比之下,MySQL数据库的性能在处理大文件和大数据量时可能受到限制。

    综上所述,使用Minio对象存储服务能够提供更高的存储性能、可用性和灵活性,更适合大规模的数据存储需求,特别是对于头像等大文件的存储和管理。

  • 相关阅读:
    影视广告创意与制作(一)
    多线程可见
    LeetCode 每日一题 2022/11/21-2022/11/27
    智慧园区引领未来产业趋势:科技创新驱动园区发展,构建智慧化产业新体系
    Maven系列第5篇:私服详解
    请收藏!2023年全栈开发人员实战进阶指南终极版
    StarRocks 2.3.0 安装部署
    WEB网页设计期末作业个人主页——基于HTML+CSS制作个人简介网站
    腾讯魏巍:Eunomia云原生资源编排优化
    有赞前端SP毁约后的日子
  • 原文地址:https://blog.csdn.net/lty1392309506/article/details/137921397