SpringBoot2.x RabbitMQ Nacos Nacos-Config

在这里插入图片描述

文章目录

          • 一、依赖配置
            • 1. 引入依赖
            • 2. 配置文件
            • 3. 主配置
          • 二、生产者代码代码Conding
            • 2.1. 发送客户端
            • 2.2. 确认机制
            • 2.3. 消息 return机制
            • 2.4. controller
            • 2.5. MQ工具类
            • 2.6. 常量类
          • 三、消费端
            • 3.2. 消费者代码
            • 3.2. RabbitMQ常用命令

一、依赖配置
1. 引入依赖
<!--服务注册发现--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!-- SpringCloud Alibaba Nacos Config --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><!--springboot整合RabbitMQ依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency>
2. 配置文件

项目内部配置bootstrap.yml,

server:port: 8001
spring:application:# 应用名称name: ly-rabbitmqprofiles:# 环境配置active: devcloud:nacos:discovery:# 服务注册地址server-addr: nacos.server.com:8848config:# 配置中心地址server-addr: nacos.server.com:8848# 配置文件格式file-extension: yml# 共享配置shared-configs:- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}

nacos-config服务端配置

在这里插入代码片
3. 主配置
package com.gblfy.lyrabbitmq.config;import com.gblfy.lyrabbitmq.consts.MQPrefixConst;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** RabbitMQ 交换机和队列绑定配置类** @author gblfy* @Date 2021-09-28 9:59*/
@Configuration
public class RabbitTopicConfig {@BeanTopicExchange topicExchange() {return new TopicExchange(MQPrefixConst.WS_EXCEHANGE, true, false);}@BeanQueue hisUQ() {return new Queue("ly_mq_fai_q");}@BeanBinding hisUQBinding() {//ly-his.# 代表路由规则 表示如果路由的 routingKey 是以ly-his 开头就会发送到 ly_mq_his_u_q 这个队列上return BindingBuilder.bind(hisUQ()).to(topicExchange()).with("ly-fai.#");}
}
二、生产者代码代码Conding
2.1. 发送客户端
package com.gblfy.lyrabbitmq.provider;import com.alibaba.fastjson.JSON;
import com.gblfy.common.entity.Order;
import com.gblfy.lyrabbitmq.consts.MQPrefixConst;
import com.gblfy.lyrabbitmq.utils.MQSendMsgUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.time.LocalDateTime;/*** RabbitMQ发送消息** @author gblfy* @Date 2021-09-28 9:59*/
@Service
public class RabbitMQProvider {private final static Logger log = LoggerFactory.getLogger(RabbitMQProvider.class);@Autowiredprivate MQSendMsgUtils mqSendMsgUtils;/*** 发送补偿MQ消息** @param orderId    订单编码* @param orderNum   订单数量* @param createTime 订单时间* @return 发送标识*/public void sendMQContent(long orderId, String orderNum, LocalDateTime createTime) {Order order = Order.builder().orderId(orderId).orderNum(orderNum).createTime(createTime).build();// 发送MQ消息到交换机通过指定消息路由key路由到指定队列中mqSendMsgUtils.snedStrMQMsg(MQPrefixConst.LY_MQ_FAI_QUERY, JSON.toJSONString(order));log.info("MQ消息发送成功");}
}
2.2. 确认机制
package com.gblfy.lyrabbitmq.confirms;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;/*** Confirm 消息确认机制* 消息发送成功和失败都会记录** @author gblfy* @Date 2021-09-28 9:59*/
@Component("confirmCallback")
public class ConfirmCallBackListener implements RabbitTemplate.ConfirmCallback {//日志输出private final static Logger log = LoggerFactory.getLogger(ConfirmCallBackListener.class);/*** 生产者消息发送成功与失败确认机制* <p>* 1. ack*      true : 标志生产者将消息发出成功*      false: 标志生产者将消息发出失败* 2. ack :true 意味着消息发送成功 有2种场景*      第一种:生产者将消息成功发送到指定队列中,等待消费者消费消息*      第两种:生产者将消息发送成功,但是,由于无法路由到指定的消息*             队列,这种场景的消息,会被return机制监听到,后续进行补偿机制,做消息补发处理* </p>** @param correlationData 队列消息的唯一标识ID,消息做补偿机制会用到* @param ack             ack 消息是否发送成功的标识* @param cause           消息发送失败的原因*/@Overridepublic void confirm(CorrelationData correlationData, boolean ack, String cause) {log.info("消息队列标识ID: {}", correlationData.getId());/***对消息发送成功/失败状态做不同的处理* 1. 第一种场景 发送消息成功*     1>发送消息成功,交换机路由队列成功*     2>发送消息成功,交换机路由队列不成功* 2. 发送消息失败*/if (ack) {log.info("发送消息成功: {}", ack);} else {log.info("发送消息失败: {}", ack);}}
}
/*** !ack 场景结果示例:* <p>* correlationData: CorrelationData [id=a37285dc-5dd6-4e22-8cc4-5c0fbf67b568]* ack: false* 异常处理....* 消息: CorrelationData [id=a37285dc-5dd6-4e22-8cc4-5c0fbf67b568],* nack,失败原因是:channel error;* protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no exchange 'FIS-TRACE-COMMON-EXCHANGE' in vhost '/admin',* class-id=60, method-id=40)*/
2.3. 消息 return机制
package com.gblfy.lyrabbitmq.returns;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;/*** 消息 return机制* 路由失败的消息会先走这,然后到ConfirmCallBackListener记录异常错误信息** @author gblfy* @Date 2021-09-28 9:59*/
@Component("returnCallBackListener")
public class ReturnCallBackListener implements RabbitTemplate.ReturnCallback {//打印日志 实时定位private final static Logger log = LoggerFactory.getLogger(ReturnCallBackListener.class);/*** 消息无法路由 触发消息 return机制* <p>* 1. 消费者在消息没有被路由到合适队列情况下会被return监听,而不会自动删除* 2. 会监听到生产者发送消息的关键信息* 3. 根据关键信息,后续进行补偿机制,做消息补发处理* </p>** @param message    消息实体* @param replyCode  应答码312* @param replyText  NO_ROUTE* @param exchange   交换机* @param routingKey 路由routingKey*/@Overridepublic void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {log.info("DeliveryTag: {}", message.getMessageProperties().getDeliveryTag());log.info("ContentType: {}", message.getMessageProperties().getContentType());log.info("ContentEncoding: {}", message.getMessageProperties().getContentEncoding());log.info("消息发送的指定交换机: {}", exchange);log.info("队列路由的routingKey: {}", routingKey);log.info("队列的响应码replyCode: {}", replyCode);log.info("队列的响应信息: {}", replyText);//TODO 消息发送交换机成功 路由失败 保存轨迹记录}
}
/*** 场景结果示例:* return exchange: FIS-TRACE-COMMON-EXCHANGE, routingKey: fis-str.user, replyCode: 312, replyText: NO_ROUTE* correlationData: CorrelationData [id=30d924db-77b4-41df-bbe6-9a8f0eb3fe7a]* ack: true* 消息: CorrelationData [id=30d924db-77b4-41df-bbe6-9a8f0eb3fe7a],已经被ack成功*/
2.4. controller
package com.gblfy.lyrabbitmq.controller;import com.gblfy.lyrabbitmq.provider.RabbitMQProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.time.LocalDateTime;@RestController
@RequestMapping("/mq")
public class MQProviderController {@Autowiredprivate RabbitMQProvider mqProvider;@GetMapping("/sendMQ")public String sendMQContent() {mqProvider.sendMQContent(0001, "10", LocalDateTime.now());return "OK";}
}
2.5. MQ工具类
package com.gblfy.lyrabbitmq.utils;import com.gblfy.lyrabbitmq.confirms.ConfirmCallBackListener;
import com.gblfy.lyrabbitmq.consts.MQPrefixConst;
import com.gblfy.lyrabbitmq.returns.ReturnCallBackListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.util.UUID;/*** MQ发送消息(公用工具类)** @author gblfy* @Date 2021-09-28 9:59*/
@Component
public class MQSendMsgUtils {private final static Logger log = LoggerFactory.getLogger(MQSendMsgUtils.class);@Autowired//注入发送消息模板private RabbitTemplate rabbitTemplate;@Autowiredprivate ConfirmCallBackListener confirmCallback;@Autowiredprivate ReturnCallBackListener returnCallback;/*** 发送MQ STRING类型消息 第1种** @param queueRouteKey 路由routingKey* @param msg           MQ STRING类型消息*/public void snedStrMQMsg(String queueRouteKey, String msg) {try {log.info("交换机名称: {}, 路由routingKey: {}, 发送的消息: {} ", "EXCHANGE-CMIIP", queueRouteKey, msg);String mID = UUID.randomUUID().toString();CorrelationData correlationId = new CorrelationData(mID);// Confirm 消息确认策略rabbitTemplate.setConfirmCallback(confirmCallback);// Return 消息确认策略rabbitTemplate.setReturnCallback(returnCallback);log.info("发送消息的路由key: {}", queueRouteKey);log.info("发送消息的标识ID: {}", mID);//发送消息到MQ的交换机,通知其他系统rabbitTemplate.convertAndSend(MQPrefixConst.WS_EXCEHANGE, queueRouteKey, msg, correlationId);} catch (Exception e) {e.printStackTrace();}}
}
2.6. 常量类
package com.gblfy.lyrabbitmq.consts;/*** 消息路由规则前缀(常量类)** @author gblfy* @Date 2021-09-28 9:59*/
public class MQPrefixConst {//交换机名称//回归环境public static final String WS_EXCEHANGE = "LY-REPORT-EXCHANGE";// 路由keypublic static final String LY_MQ_FAI_QUERY = "ly-fai.query";
}
三、消费端
3.2. 消费者代码
package com.gblfy.lyrabbitmq.consumer;import com.gblfy.lyrabbitmq.consts.MQPrefixConst;
import com.rabbitmq.client.Channel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
import org.springframework.stereotype.Component;/*** RabbitMQ消费端处理** @author gblfy* @Date 2021-09-28 9:59*/
@Component
public class RabbitMQHandler implements ChannelAwareMessageListener {//打印日志 实时定位private final static Logger log = LoggerFactory.getLogger(RabbitMQHandler.class);/*** 接收字符串类型MQ消息** @param message* @param channel* @throws Exception*/@Override@RabbitListener(bindings = @QueueBinding(value = @Queue(value = "${spring.rabbitmq.listener.str1.queue.name}",durable = "${spring.rabbitmq.listener.str1.queue.durable}"),exchange = @Exchange(value = "${spring.rabbitmq.listener.str1.exchange.name}",durable = "${spring.rabbitmq.listener.str1.exchange.durable}",type = "${spring.rabbitmq.listener.str1.exchange.type}",ignoreDeclarationExceptions = "${spring.rabbitmq.listener.str1.exchange.ignoreDeclarationExceptions}"),key = "${spring.rabbitmq.listener.str1.key}"))@RabbitHandlerpublic void onMessage(Message message, Channel channel) throws Exception {//TODO 接收消息成功 创建一个消费端轨迹表来存储消息的轨迹数据String jsonMsg = new String(message.getBody());log.info("响应报文 mResXml: {}", jsonMsg);// 同一时刻服务器只会发一条消息给消费者channel.basicQos(1);// 反馈消息的消费状态channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);// 反馈消息的消费状态System.err.println("--------------------------------------");//------------------------------根据约定解析指定的标签--------------------------------------------// JSONObject jsonObject = new JSONObject();// jsonObject = JSON.parseObject(jsonMsg);// String msgID = jsonObject.getString("msgID");// log.info("接收的消息ID: {}", msgID);//// String tResXml = jsonObject.getString("tResXml");// log.info("解析后的zip路径: {}", tResXml);String queueRouteKey = message.getMessageProperties().getReceivedRoutingKey();log.info("接收的路由key: {}", queueRouteKey);if (MQPrefixConst.LY_MQ_FAI_QUERY.equals(queueRouteKey)) {//TODO  监听查询接口逻辑//TODO 保存数据到数据库} else {log.error("无此路由key: {}", queueRouteKey);}}
}
3.2. RabbitMQ常用命令
# 启动MQ
rabbitmq-server -detatched

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

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

相关文章

考拉海购技术支持的前世今生

本文来自考拉海购技术支持中心负责人--书渊的分享&#xff0c;想和大家聊一聊考拉技术支持的前世今生&#xff0c;在这个发展历程的介绍当中&#xff0c;大家也可以此对考拉窥一斑而知全豹。当然&#xff0c;既然是聊我们的家常(“黑历史”)&#xff0c;我会从这几年在考拉供应…

PHP 依赖镜像出问题后,阿里工程师的一顿“神操作“令人叫绝!

阿里妹导读&#xff1a;上个月&#xff0c;PHP开发者在网上纷纷反映出现 Composer 镜像无法访问的问题。阿里云内部一位 90 后工程师顾咏连夜开工排查&#xff0c;快速解决问题后&#xff0c;他在问题群里收到了一大波来自用户的红包。顾咏最后谢绝了红包&#xff0c;接受了阿里…

Elasticsearch SkyWalking 分布式链路追踪

文章目录1. 安装包下载2. 解压3. 修改配置文件4. 启动5. 测试验证1. 安装包下载 https://www.apache.org/dyn/closer.cgi/skywalking/8.8.0/apache-skywalking-apm-8.8.0.tar.gzhttps://archive.apache.org/dist/skywalking 2. 解压 tar -zxvf apache-skywalking-apm-8.8.0…

为什么HR 20分钟就淘汰了一个前端高级工程师?

最近HR小姐姐面了一个前端开发&#xff0c;4 年经验&#xff0c; 应聘的是前端高级开发工程师。他的简历中提到很多技术点&#xff0c;从 HTML、CSS、JavaScript 再到 Vue.js 和 React 一个都不缺&#xff0c;跨平台PC、移动端、小程序也都经历过&#xff0c;看着像个实战派。深…

angular图片上传

html代码&#xff1a; 当input出发change事件会调用touchUpdateImg方法&#xff0c;传入file对象和需要展示得到imgsmall属性&#xff0c;通过FileReader对象读取文件对象&#xff0c;我使用了apply进行了监听&#xff0c;之前不使用apply进行了监听&#xff0c;之前不使用app…

千万创业者的自白:踩过坑才明白这些真相!

“大众创业、万众创新”的浪潮正兴&#xff0c;随着国家对自主创业扶持力度的加强&#xff0c;中国的初创企业正在蓬勃发展&#xff0c;据统计&#xff0c;最近五年中国新注册的公司约有3000万家。 而另一方面&#xff0c;在轰轰烈烈的创业大潮中&#xff0c;市场竞争指数也急…

SpringBoot2 集成 skywalking 实现链路追踪

文章目录1. 启动skywalking2. 配置探针3. 启动项目4. 测试验证5. 效果图1. 启动skywalking cd D:\apache-skywalking-apm-bin\binwindows环境&#xff1a; 双击startup.bat linux环境&#xff1a; startup.sh2. 配置探针 -javaagent:D:\apache-skywalking-apm-bin\agen…

以“基”取胜:戴尔科技云平台 释放企业新动能

2020年春天&#xff0c;以云计算、5G、人工智能为代表的“新基建”蔚然成风&#xff0c;不仅助力中国产业智能化、信息化进入加速推进的快车道&#xff0c;促使全产业链迈开高质量发展的新步伐。更是面向长远&#xff0c;构筑数字经济创新发展之基。可以说&#xff0c;没有任何…

Nexus协议,闲鱼一体化开发的幕后玩家

Serverless是这几年兴起的一个概念&#xff0c;Serverless可以帮助开发者减轻甚至摆脱传统后端应用开发所需要的服务器设备的设置和运维工作&#xff0c;并以服务接口的方式为开发者提供所需要的功能。它希望开发者更加专注于应用逻辑本身&#xff0c;而不是被琐碎的基础设施细…

angular封装富文本编辑器指令

这个富文本编辑器的基本用法可以去该编辑器作者的github看下 (https://github.com/echosoar/medit) html代码和css 原版&#xff1a; 改版的&#xff1a; /*富文本编辑器*/#meditToolBar {position:fixed;z-index:100;width:100%;left: 0;bottom: 0;height:40px;background:…

日处理数据量超10亿:友信金服基于Flink构建实时用户画像系统的实践

导读&#xff1a;当今生活节奏日益加快&#xff0c;企业面对不断增加的海量信息&#xff0c;其信息筛选和处理效率低下的困扰与日俱增。由于用户营销不够细化&#xff0c;企业 App 中许多不合时宜或不合偏好的消息推送很大程度上影响了用户体验&#xff0c;甚至引发了用户流失。…

玛莎拉蒂“跨界”腾讯车联打造车载互联系统,新Ghibli “触电新生”

7月17日&#xff0c;玛莎拉蒂首款“触电”车型新Ghibli正式发布&#xff0c;与新亚太区代言人——锋芒玩家陈伟霆先生共同亮相&#xff0c;诠释年轻无畏的先锋态度。在创新科技方面&#xff0c;新Ghibli率先搭载了玛莎拉蒂与腾讯车联共同打造的全新车载互联系统。 【玛莎拉蒂新…

认识Java异步编程

一 、认识异步编程 通常Java开发人员喜欢使用同步代码编写程序,因为这种请求(request)/响应(response)的方式比较简单&#xff0c;并且比较符合编程人员的思维习惯;这种做法很好&#xff0c;直到系统出现性能瓶颈&#xff1b;在同步编程方式时由于每个线程同时只能发起一个请求…

云原生应用万节点分钟级分发协同实践

导读&#xff1a;2019 年天猫 双11&#xff0c;阿里巴巴核心系统首次实现 100% 上云。面对全球最大的交易洪峰&#xff0c;阿里云扛住了每秒 54.4 万笔的交易峰值&#xff0c;这是“云原生”与“天猫全球狂欢节”的一次完美联名。 &#xff08;图为 2019 年天猫 双11 成交额&am…

为啥Underlay才是容器网络的最佳落地选择

导语&#xff1a; 几年前&#xff0c;当博云启动自研容器网络研发的时候&#xff0c;除了技术选型的考虑&#xff0c;我们对于先做 Underlay 还是 Overlay 网络也有过深度的讨论。当时的开源社区以及主流容器厂商&#xff0c;多数还是以 Overlay 网络方案为主&#xff0c;但在我…

oracle用户编辑文件中文乱码

文章目录一、分析定位1. 现象2. 查看当前编码3. 配置文件现状二、解决方案2.1. 编辑配置文件2.2. 调整2.3. 刷新环境变量2.4. 效果图2.5. 配置文件源码一、分析定位 1. 现象 2. 查看当前编码 登录oracle用户&#xff0c;查看当前oracle用户下的编码 [oraclelocalhost ~]$ ec…

今年圣诞,麋鹿第一次请假

年末的圣诞节来啦~~&#xff01; 但我们的圣诞老人为什么有点低落&#xff1f;&#xff1f; 是在愁信太多&#xff1f;没地儿放&#xff1f; 不会是看不懂我信上的“鬼画符”吧.. 难道是在忌惮空中的雾霾&#xff1f;哈哈~ 圣诞老人&#xff1a;o(╥﹏╥)o 不不不&#xf…

高德网络定位算法的演进

1.导读 GPS定位精度高&#xff0c;且早已成为移动设备标配&#xff0c;但GPS也具有一些难以克服的缺陷&#xff0c;包括&#xff1a; 冷启动时间长。GPS启动时&#xff0c;需要进行搜星&#xff0c;锁定卫星信号&#xff0c;然后再进行位置技术&#xff0c;这个过程可能会达到…

疫情之下网络安全如何保障?Akamai防护方案前来“保驾护航”

2020年春天&#xff0c;以5G、人工智能、云计算为代表的“新基建”蔚然成风&#xff0c;着眼国家数字经济体系建设&#xff0c;打造数字经济体系底座的“新基建”&#xff0c;无疑成为中国经济整体应对未来发展的核心方案。然而&#xff0c;面临“新基建”与企业数字化进程的突…

2020将至,谈谈中小企业创业的那些事儿

2019正迎来尾声&#xff0c;在创业这场轰轰烈烈的旅途中&#xff0c;有的人名利双收&#xff0c;有的人饱受非议。一入创业深似海&#xff0c;在创业赛道上&#xff0c;很多公司完成了从0到1&#xff0c;却死在从1到100的路上。而小程序的出现&#xff0c;让移动互联网创业走向…