java脚手架系列11-消息队列、对象存储(OSS)

之所以想写这一系列,是因为之前工作过程中有几次项目是从零开始搭建的,而且项目涉及的内容还不少。在这过程中,遇到了很多棘手的非业务问题,在不断实践过程中慢慢积累出一些基本的实践经验,认为这些与业务无关的基本的实践经验其实可以复刻到其它项目上,在行业内可能称为脚手架,因此决定将此java基础脚手架的搭建总结下来,分享给大家使用。

注意由于框架不同版本改造会有些使用的不同,因此本次系列中主要使用基本框架是 spring-boo-2.3.12.RELEASE和spring-cloud.-Hoxton.SR12,所有代码都在commonFramework项目上:https://github.com/forever1986/commonFramework/tree/master

目录

  • 1 消息队列
    • 1.1 基本概念
    • 1.2 spring-boot-starter-amqp的组件
    • 1.3 代码示例
  • 2 对象存储(OSS)
    • 2.1 代码演示
      • 2.1.1 配置自动化的OSS对象存储公共包
      • 2.1.2 business-biz引用
      • 2.1.3 注意坑点
    • 2.2 实践经验

1 消息队列

消息队列在我们实际应用中的作用包括提高响应速度、流量控制和系统解耦,因此在我们实际中还是比较重要的。这里通过脚手架集成方式展现RabbitMQ在实践中的使用。

1.1 基本概念

RabbitMQ是一个比较常用的消息队列,有关它的几个概念可能要弄清楚:
交换机(Exchange):交换机是消息的分发中心,它接收生产者发送的消息并根据一定的规则将消息路由到一个或多个队列中。(记住:生产者就是发送消息给交换机)RabbitMQ提供了不同类型的交换机,包括:

  • 直连交换机(Direct Exchange):根据消息的路由键将消息发送到特定队列。
  • 主题交换机(Topic Exchange):根据消息的路由键和通配符匹配将消息发送到多个队列。
  • 扇出交换机(Fanout Exchange):将消息广播到与交换机绑定的所有队列。
  • 头交换机(Headers Exchange):根据消息的自定义头部属性进行匹配路由。
    队列(Queue):队列是消息的容器,它存储消息直到消费者准备好接收和处理它们。消息通过交换机路由到队列,消费者可以从队列中读取消息。(记住:消费者就是从队列获取消息)每个队列都有一个名称,它们可以绑定到一个或多个交换机,并指定了消息的路由规则。
    路由键(Routing Key):路由键是生产者在发布消息时指定的一个关键字,它告诉交换机将消息路由到哪个队列。路由键的意义取决于交换机的类型。(记住:主要是Direct Exchange和Topic Exchange使用)在直连交换机中,路由键通常与队列的绑定键一致;在主题交换机中,路由键可以使用通配符进行匹配。
    头部信息(Headers):保存在消息的头部信息,在headers Exchange中可以通过头部信息进行分发到不同队列。较少使用,其原理和使用场景与routing key没有太大区别

1.2 spring-boot-starter-amqp的组件

SpringBoot 已经提供了对 AMQP 协议完全支持的 spring-boot-starter-amqp 依赖,引入此依赖即可快速方便的在 SpringBoot 中使用 RabbitMQ。它提供了编程式和注解式的使用方式,但是有些核心组件还是要弄清楚:

  • RabbitAdmin:主要用于交换机、队列的创建、删除,它们之间的绑定作用
  • RabbitTemplate:是 SpringBoot AMQP 提供的快速发 RabbitMQ 消息的模板类,与 RestTemplate 有类似之处,意指方便、简单、快速的发 RabbitMQ 消息。
  • MessageConverter:就是用来在收发消息时自动转换 AMQP 内部消息和 Java 对象的。
  • @RabbitListener:注解式的使用消费者监听,用于标记一个方法或一个类,使其成为消息队列的监听器,即这个方法或类负责接收来自RabbitMQ的消息。
  • @Rabbithandler:注解式的使用消费者监听,注解用于标记一个方法,作为特定类型的消息的处理器。

1.3 代码示例

下面以spring-boot-starter-amqp为基础,再次封装更为方便使用的生产者和消费者。

参考common-amqp子模块和business-biz子模块

1)在common子模块下创建子模块common-amqp,该子模块以spring.factories方式发布
2)定义RabbitmqSender封装生产者的配置
3)定义ConfigurationProperties和QueueInfo读取receivers接收者的配置信息(配置在yaml文件中)
4)在RabbitmqConfig中注册队列并绑定队列到交换机,其配置在yaml文件中说明

receivers: # 本示例配置消费者信息test-direct-queue:queueName: test-direct-queue  # 队列名称exchange: test-direct  # 队列绑定交换机exchangeType: DIRECT   # 交换机类型DIRECT、HEADER、TOPIC、FANOUTroutingKey: error, info  # routingKey,只有DIRECT和TOPIC有效acknowledgeMode: MANUAL  # 手动还是自动确认

5)子模块business-biz引用common-amqp子模块
6)在子模块business-biz中,配置生产者:在yaml文件中配置senders,同时直接使用类似以下代码即可发生消息:

TestMessage testMessage = new TestMessage(1,str,new Timestamp((new Date()).getTime()));
rabbitmqSender.send(testMessage, test_direct, "error");

7)在子模块business-biz中,配置消费者:在yaml文件中配置receiver,同时直接使用类似以下代码即可发生消息:

/*** Direct消息消费者,同时手动确认模式*/
@RabbitListener(queues="${spring.rabbitmq.receivers.test-direct-queue.queueName}", ackMode = "${spring.rabbitmq.receivers.test-direct-queue.acknowledgeMode}")
public void receive(TestMessage testMessage, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag) throws IOException {log.info("handleDirectMessage:{}", JSON.toJSONString(testMessage));channel.basicAck(tag,true);
}

2 对象存储(OSS)

对象存储(Object Storage)是一种存储架构,它以对象为单位来处理、存储和检索数据。与传统的文件存储和块存储不同,对象存储将数据作为对象进行管理,每个对象都包含了数据本身、元数据以及一个全局唯一的标识符。这种独特的存储方式使得对象存储在处理大量、非结构化的数据时具有明显的优势。
对象存储通过API(应用程序编程接口)调用进行数据的读写,通常基于HTTP或HTTPS协议。对象存储系统将数据分布在多个硬件设备上,并且能够自动处理数据的冗余备份和扩展性问题,这使得它在大规模数据存储方面表现出色。
下面以minIO为基础,引入io.minio依赖,封装一个对象存储的公共包

2.1 代码演示

参考common-oss子模块和business-biz子模块

2.1.1 配置自动化的OSS对象存储公共包

1)在common子模块下新建common-oss子模块,以spring.factories发布
2)引入以下依赖:

<dependency><groupId>io.minio</groupId><artifactId>minio</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId>
</dependency>
<dependency><groupId>org.example</groupId><artifactId>common-core</artifactId><version>${project.version}</version>
</dependency>
<dependency><groupId>org.example</groupId><artifactId>common-exception</artifactId><version>${project.version}</version>
</dependency>

3)配置OssProperties读取yaml文件的对象存储相关配置
4)配置MinioConfiguration,注册OssTemplate(访问oss)和OssEndpoint(对外接口)
5)新建OssTemplate,作为封装oss底层操作
6)新建OssEndpoint,作为对外的API接口

2.1.2 business-biz引用

1)引入common-oss子模块

<dependency><groupId>org.example</groupId><artifactId>common-oss</artifactId><version>${project.version}</version>
</dependency>

2)在yaml文件配置以下信息

oss:enabled: true  # 是否开启oss存储配置api: true  # 自动开启API接口endpoint: http://127.0.0.1:9005  # MinIO服务器的URLaccess-key: minioadmin      # 访问密钥secret-key: minioadmin      # 密钥密码bucket-name: works     # 默认的Bucket名称

3)直接就可以使用OssEndpoint的接口操作oss

2.1.3 注意坑点

1)坑1:okhttp版本冲突,如果项目引入openfeign或者springcloud中使用okhttp与io.minio里面的okhttp可能会发生冲突,需要在父项目commonFramework声明okhttp统一版本

<dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId><version>${okhttp.version}</version>
</dependency>

2)坑2:调创建等操作oss时,报错:DateTimeParseException: TemporalAccessor。

这是jdk1.8早期版本的一个bug,需要升级到jdk1.8的小版本到22之后,比如我原先是jdk-8u5,升级为jdk-8u431即可

2.2 实践经验

对象存储的优势就是使用其简单的API方式即可进行存储操作,而且在我们实际项目应用中,往往是用来存储图片、音频、视频、文件等信息。所以其操作流程其实更是直接在前端对对象存储进行操作,然后将存储信息存入后端才是一种比较好的实践方式。
比如AWS中有一个案例就是将图片存储到OSS中,利用CDN加速,前端直接操作图片和加载图片。除非有更深层的业务操作,才会经过后端接口,不然往往只是增加网络流量以及后端服务压力。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Python(包和模块)

包 定义 包是将模块以文件夹的组织形式进行分组管理的方法&#xff0c;以便更好地组织和管理相关模块。 包是一个包含一个特殊的__init__.py文件的目录&#xff0c;这个文件可以为空&#xff0c;但必须存在&#xff0c;以标识目录为Python包。 包可以包含子包&#xff08;子…

ClickHouse安装

一&#xff0c;ClickHouse介绍 ClickHouse 是一个开源的列式数据库管理系统&#xff08;Column-Oriented DBMS&#xff09;&#xff0c;由俄罗斯的 Yandex 公司开发。它最初是为 Yandex 的 Metrica 分析服务设计的&#xff0c;用于处理大规模的数据分析任务。ClickHouse 能够提…

网络设置:静态IP与动态IP,何去何从?

在配置网络设备时&#xff0c;一个基础而重要的选择便是决定使用静态IP地址还是动态IP地址。这一决策直接影响到网络的连接性、管理便捷性以及安全性。静态IP与动态IP各有其独特的优势与适用场景&#xff0c;选择何种方式&#xff0c;需根据实际需求与网络环境来权衡。本文旨在…

po、dto、vo的使用场景

现在项目中有两类模型类&#xff1a;DTO数据传输对象、PO持久化对象&#xff0c;DTO用于接口层向业务层之间传输数据&#xff0c;PO用于业务层与持久层之间传输数据&#xff0c;有些项目还会设置VO对象&#xff0c;VO对象用在前端与接口层之间传输数据&#xff0c;如下图&#…

不用买PSP,画质甚至更好,这款免费神器让你玩遍经典游戏

作为掌机游戏爱好者的福音&#xff0c;PPSSPP模拟器为玩家带来了前所未有的PSP游戏体验&#xff0c;彻底改变了掌机游戏的体验方式。这款精湛的软件不仅完美复刻了PSP主机的游戏体验&#xff0c;更通过先进的模拟技术&#xff0c;将经典游戏提升到了全新的高度。对于那些珍藏PS…

如何新建CANoe工程

本文将从启动CANoe软件开始&#xff0c;一步步引导您完成新工程的创建与基本配置&#xff0c;确保您的仿真测试工作能够顺利进行。 启动CANoe软件&#xff1a;打开CANoe软件&#xff0c;进入主界面。 新建工程&#xff1a;点击菜单栏的 File --> New --> CAN FD&#x…

Facebook群控策略详解

Facebook群控早在前几年就很火爆了&#xff0c;对于做Facebook营销或者电商的跨境选手来说&#xff0c;这是个不错的提高效率扩大增长的办法。具体来说&#xff0c;Facebook群控是一种通过同时管理多个Facebook账户进行自动化推广活动的方法&#xff0c;它可以实现自动发布帖子…

通讯概念-全双工、串行、同步等

1.单工&#xff0c;半双工&#xff0c;双工概念 2.串行和并行&#xff1a; 并行多根数据总线同时传输&#xff0c;需要考虑波特率情况&#xff0c;串行波特率可以很大&#xff0c;不需要考虑传输总线限制 3.同步和异步概念&#xff1a; 同步需要时钟同步&#xff0c;发送和接收…

经济下行,电商人效通过小程序快速实现多端引流

中国经济下行周期&#xff0c;消费者趋向于理性消费&#xff0c;更注重产品的实用性和性价比。中端商品的需求减少&#xff0c;低端消费人群的消费能力下降&#xff0c;导致“消费降级”现象明显。 许多线下实体店以及传统电商&#xff0c;仅仅依靠现在的模式&#xff0c;很难…

Fish Agent:集成 ASR 和 TTS 的端到端语音处理模型,支持多语言转换

❤️ 如果你也关注大模型与 AI 的发展现状&#xff0c;且对大模型应用开发非常感兴趣&#xff0c;我会快速跟你分享最新的感兴趣的 AI 应用和热点信息&#xff0c;也会不定期分享自己的想法和开源实例&#xff0c;欢迎关注我哦&#xff01; &#x1f966; 微信公众号&#xff…

软件测试工程师面试整理 —— 编程与自动化!

在软件测试领域&#xff0c;编程与自动化是提升测试效率、覆盖率和可靠性的关键因素。掌握编程技术和自动化测试框架&#xff0c;能够帮助测试人员有效地执行大量重复性测试任务&#xff0c;并迅速反馈软件的质量状况。以下是编程与自动化在测试中的主要应用及相关技术介绍&…

04字符串算法/代码随想录

四、字符串 反转字符串 力扣344 遇到数组双指针真是太好用了&#xff0c;左右指针不断逼近即可&#xff0c;代码也很简单 class Solution {public void reverseString(char[] s) {int fast s.length - 1;int slow 0;while (slow < fast) {char temp s[fast];s[fast] s[…

Unreal5从入门到精通之如何使用C++实现一个剧情系统

前言 说到剧情系统,大家可能会说,UE的关卡序列Sequencer,做剧情不是很方便吗?没错,Sequencer确实方便,而且它可以让你为场景中的角色,物体等创建精确的动画,并使用关键帧来控制他们的运动和状态变化。 它还可以做相机的移动,剪辑,音效,特效等故事情节,相机特效,多…

袋鼠云产品功能更新报告12期|让数据资产管理更高效

本期&#xff0c;我们更新和优化了数据资产平台相关功能&#xff0c;为您提供更高效的产品能力。以下为第12期袋鼠云产品功能更新报告&#xff0c;请继续阅读。 一、【元数据】重点更新 &#xff5c;01 元数据管理优化&#xff0c;支持配置表生命周期 之前系统中缺少一个可以…

将多个commit合并成一个commit并提交

0 Preface/foreword 1 压缩多个commit方法 1.1 git merge --squash 主分支&#xff1a;main 开发分支&#xff1a;test 当前在test分支提交了8个commits&#xff0c;功能已经开发完成&#xff0c;需要将test分支合并到main分支&#xff0c;但是不想在合并时候&#xff0c;看…

大数据新视界 -- 大数据大厂之提升 Impala 查询效率:重写查询语句的黄金法则(下)(4/30)

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

我想让AI帮我生成一点不正经的东西……

前言 最近突发奇想&#xff1a;为啥我一定要不断得翻找各种壁纸呢&#xff1f;为啥就不能让AI给我生成一张专属的壁纸&#xff0c;上面有我喜欢的内容&#xff0c;这样&#xff0c;我这张壁纸就是独一无二的了&#xff01; 说干就干&#xff0c;小白默默打开了AI工具…… 点我…

17、电话号码的字母组合-cangjie

题目 17、电话号码的字母组合 思路 输入处理&#xff1a; 接收一个字符串 digits&#xff0c;表示手机键盘上的数字&#xff0c;数字可以对应不同的字母组合。 边界检查&#xff1a; 如果输入字符串 digits 为空&#xff0c;返回一个空的结果列表。 按钮映射&#xff1a; 初…

ZYNQ: AXI DMA 环路测试

环境 vivado 2022 vitis 2022 简介 DMA&#xff0c;即Direct Memory Access&#xff0c;指直接存储器访问。这是一种内存访问技术&#xff0c;允许某些计算机内部的硬件子系统&#xff08;如计算机外设&#xff09;独立地直接读写系统内存&#xff0c;而无需中央处理器&…

动态规划 01背包(算法)

现有四个物品&#xff0c;小偷的背包容量为8&#xff0c;怎么可以偷得价值较多的物品 如: 物品编号&#xff1a; 1 2 3 4 物品容量&#xff1a; 2 3 4 5 物品价值&#xff1a; 3 4 5 8 记f(k,w) ,当背包容量为w,可以偷k件物品…