Rabbitmq调用FeignClient接口失败

文章目录

  • 一、框架及逻辑介绍
    • 1.背景服务介绍
    • 2.问题逻辑介绍
  • 二、代码
    • 1.A服务
    • 2.B服务
    • 3.C服务
  • 三、解决思路
    • 1.确认B调用C服务接口是否能正常调通
    • 2.确认B服务是否能正常调用A服务
    • 3.确认消息能否正常消费
    • 4.总结
  • 四、修改代码验证
    • 1.B服务异步调用C服务接口——失败
    • 2.将消费消息放到C服务中,消费时直接调用service——成功
  • 五、结论

走过路过大神帮忙给个正确解决方案~~~~~

一、框架及逻辑介绍

1.背景服务介绍

微服务结构,目前有A、B、C三个服务。

  • A服务:做一些工具类的功能
  • B服务:类似于门户,调用A、C服务来给到前端
  • C服务:基础模块,日志、权限、数据维护

2.问题逻辑介绍

  • A服务:实现blast功能,该功能是异步任务,需要几分钟的时间才能执行完成,所以采用了消息队列的方式通知功能完成,可查看数据。当代码执行完成之后通过rabbitmq发送消息到B服务
  • B服务:消费消息,调用C服务存储完成通知数据
  • C服务:提供FeignClient接口

二、代码

1.A服务

业务代码,详细的逻辑部分就不列出代码部分了, 测试确认无问题。

@Api(tags = "blast工具")
@RequiredArgsConstructor
@RequestMapping("blast")
@RestController
public class BlastController {private final BlastService blastService;@PostMapping("uniport")@ApiOperation("蛋白质序列对比")public ApiResponse<Boolean> check(@RequestBody BlastEntity blastEntity) {boolean flag = blastService.check(blastEntity);if(flag){return ApiResponse.success(flag);}else{return ApiResponse.failure("序列比对失败");}}@GetMapping("uniportDetail")@ApiOperation("蛋白质序列对比详情")public ApiResponse<BlastLogEntity> selectDetailById(@ApiParam("主键") @RequestParam("id") Integer id){return ApiResponse.success(blastService.selectDetailById(id));}
}

通过FeignClient提供功能接口给B服务(门户)

@FeignClient(name = "tool", url = "${customer.tool-url}")
public interface DataClient {@PostMapping("/blast/uniport")@ApiOperation("蛋白质序列对比")ApiResponse<Boolean> checkBlastUniprot(@RequestBody BlastEntity blastEntity);@GetMapping("/blast/uniportDetail")@ApiOperation("蛋白质序列对比详情")ApiResponse<BlastLogEntity> selectDetailById(@ApiParam("主键") @RequestParam("id") Integer id);
}

通过Rabbitmq发送消息

@Configuration
public class DirectRabbitMQConfig {//创建一个名为TestDirectExchange的Direct类型的交换机@BeanDirectExchange directExchange(){// durable:是否持久化,默认是false,持久化交换机。// autoDelete:是否自动删除,交换机先有队列或者其他交换机绑定的时候,然后当该交换机没有队列或其他交换机绑定的时候,会自动删除。// arguments:交换机设置的参数,比如设置交换机的备用交换机(Alternate Exchange),当消息不能被路由到该交换机绑定的队列上时,会自动路由到备用交换机return new DirectExchange(RabbitMqConstants.EXCHANGE_NAME,true,false);}//创建一个名为insertChassisDirectQueue的队列@Beanpublic Queue insertBlastDirectQueue(){// durable:是否持久化,默认是false,持久化队列:会被存储在磁盘上,当消息代理重启时仍然存在,暂存队列:当前连接有效// exclusive:默认也是false,只能被当前创建的连接使用,而且当连接关闭后队列即被删除。此参考优先级高于durable// autoDelete:是否自动删除,有消息者订阅本队列,然后所有消费者都解除订阅此队列,会自动删除。// arguments:队列携带的参数,比如设置队列的死信队列,消息的过期时间等等。return new Queue(RabbitMqConstants.INSERT_BLAST_NAME,true);}//绑定交换机和队列@BeanBinding insertBlastDirect(){return BindingBuilder.bind(insertBlastDirectQueue()).to(directExchange()).with(RabbitMqConstants.INSERT_BLAST_KEY);}
}

2.B服务

消费消息,根据输出日志,可以看到消费消息成功。
但是走到apiClient.addLogMessage(logMessageEntity);不报错,C服务无响应,断点查看apiClient是可以看到C服务的信息localhost:8080的。

	@RabbitHandler@RabbitListener(bindings = {@QueueBinding(value = @Queue(value = INSERT_BLAST_NAME, durable = "true"),exchange = @Exchange(value = RabbitMqConstants.EXCHANGE_NAME),key = INSERT_BLAST_KEY)})public void insertBlast(Map map, Channel channel, Message message) {try {LOGGER.info("【生成的消息-blast序列比对结果】:{}", map.toString());channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);BlastLogEntity blastLogEntity = TypeSwitchUtil.toSnakeObject(JSON.toJSONString(map), BlastLogEntity.class);if (null == blastLogEntity || StringUtils.isEmpty(blastLogEntity.getContent())) {LOGGER.warn("【生成的消息-blast序列比对结果】:{}", map.toString());} else {LogMessageEntity logMessageEntity = new LogMessageEntity();logMessageEntity.setTargetId(blastLogEntity.getId());logMessageEntity.setUserId(String.valueOf(blastLogEntity.getUserId()));logMessageEntity.setMsgType(MsgStatusEnum.BLAST.getCode());logMessageEntity.setContent(MsgStatusEnum.BLAST.getMsg());apiClient.addLogMessage(logMessageEntity);}} catch (Exception e) {LOGGER.error(e.getMessage());}}

3.C服务

@FeignClient(name = "api", url = "${customer.url}", configuration = FeignConfig.class)
public interface ApiClient {@PostMapping("/cms/logMessage/add")@ApiOperation("新增系统通知发送记录")ApiResponse<Boolean> addLogMessage(@RequestBody LogMessageEntity logMessageEntity);
}

三、解决思路

1.确认B调用C服务接口是否能正常调通

在B服务中,通过Controller暴露接口,调用C服务FeignClient的@PostMapping("/cms/logMessage/add") 接口,通过swagger测试,数据成功存储到数据库中。

——接口没有问题,服务之间通信也没有问题

2.确认B服务是否能正常调用A服务

在B服务中,调用A服务接口,测试成功。

——服务之间通信没有问题

3.确认消息能否正常消费

在B服务中,调用A服务接口,A服务输出发送消息日志。B服务消费输出日志。

——消息无问题

4.总结

在这里插入图片描述

  • 服务之间通信没有问题
    在这里插入图片描述

  • 消息提供和消费没有问题

综合猜测可能是线程或事务问题。

四、修改代码验证

1.B服务异步调用C服务接口——失败

	@RabbitHandler@RabbitListener(bindings = {@QueueBinding(value = @Queue(value = INSERT_BLAST_NAME, durable = "true"),exchange = @Exchange(value = RabbitMqConstants.EXCHANGE_NAME),key = INSERT_BLAST_KEY)})public void insertBlast(Map map, Channel channel, Message message) {try {LOGGER.info("【生成的消息-blast序列比对结果】:{}", map.toString());channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);BlastLogEntity blastLogEntity = TypeSwitchUtil.toSnakeObject(JSON.toJSONString(map), BlastLogEntity.class);if (null == blastLogEntity || StringUtils.isEmpty(blastLogEntity.getContent())) {LOGGER.warn("【生成的消息-blast序列比对结果】:{}", map.toString());} else {LogMessageEntity logMessageEntity = new LogMessageEntity();logMessageEntity.setTargetId(blastLogEntity.getId());logMessageEntity.setUserId(String.valueOf(blastLogEntity.getUserId()));logMessageEntity.setMsgType(MsgStatusEnum.BLAST.getCode());logMessageEntity.setContent(MsgStatusEnum.BLAST.getMsg());CompletableFuture.runAsync(() -> {apiClient.addLogMessage(logMessageEntity);});}} catch (Exception e) {LOGGER.error(e.getMessage());}}

经测试,未能解决问题。

2.将消费消息放到C服务中,消费时直接调用service——成功

	@RabbitHandler@RabbitListener(bindings = {@QueueBinding(value = @Queue(value = "blast.insert.queue", durable = "true"),exchange = @Exchange(value = "tool"),key = "blast.insert")})public void insertBlast(Map map, Channel channel, Message message) {try {LOGGER.info("【生成的消息-blast序列比对结果】:{}", map.toString());channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);if (null == map || StringUtils.isEmpty(map.get("id").toString())) {LOGGER.warn("【生成的消息-blast序列比对结果】:{}", map.toString());} else {LogMessageEntity logMessageEntity = new LogMessageEntity();logMessageEntity.setTargetId(Integer.valueOf(map.get("id").toString()));logMessageEntity.setUserId(String.valueOf(map.get("user_id")));logMessageEntity.setMsgType(MsgStatusEnum.BLAST.getCode());logMessageEntity.setContent(MsgStatusEnum.BLAST.getMsg());logMessageService.save(logMessageEntity);}} catch (Exception e) {LOGGER.error(e.getMessage());}}

在这里插入图片描述

五、结论

在使用消息队列(MQ)调用FeignClient服务时,采取以下步骤:

  • 配置消息队列:首先,确保已正确配置和启动您所使用的消息队列,例如 RabbitMQ 或者 Kafka。

  • 创建消息生产者:创建一个消息生产者,用于将消息发送到消息队列。您可以使用消息队列的客户端库或框架来实现此功能。

  • 发送消息:在需要调用FeignClient服务的地方,将消息发送到消息队列。消息中包含请求的相关信息,例如服务名称、路径、参数等。

  • 创建消息消费者:创建一个消息消费者,用于从消息队列接收消息并处理。

  • 处理消息:在消息消费者中,处理接收到的消息。根据消息中的请求信息,使用FeignClient来调用相应的服务。

虽然通过直接调用service的方式成功进行数据存储了,这样做也没有违背原有的逻辑。
但是问题仍然没有一个正确的解决方式,希望走过路过的大神能指点一二,在线求助。

走过路过大神帮忙给个正确解决方案~~~~~

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

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

相关文章

分布式id-Leaf算法

一、介绍 由美团开发&#xff0c;开源项目链接&#xff1a;https://github.com/Meituan-Dianping/Leaf Leaf同时支持号段模式和snowflake算法模式&#xff0c;可以切换使用。ID号码是趋势递增的8byte的64位数字&#xff0c;满足上述数据库存储的主键要求。 Leaf的snowflake模…

基于springboot的房屋交易系统

文章目录 项目介绍主要功能截图&#xff1a;部分代码展示设计总结项目获取方式 &#x1f345; 作者主页&#xff1a;超级无敌暴龙战士塔塔开 &#x1f345; 简介&#xff1a;Java领域优质创作者&#x1f3c6;、 简历模板、学习资料、面试题库【关注我&#xff0c;都给你】 &…

Unity 适配器模式(实例详解)

文章目录 简介1. **Input Adapter 示例**2. **Component Adapter 示例**3. **网络数据解析适配器**4. **物理引擎适配**5. **跨平台服务适配** 简介 Unity中的适配器模式&#xff08;Adapter Pattern&#xff09;主要用于将一个类的接口转换为另一个接口&#xff0c;以便于原本…

循环测试之旅——深度解析Pytest插件 pytest-repeat

在软件开发中,测试的重要性不言而喻。而为了提高测试的鲁棒性和可靠性,Pytest插件 pytest-repeat 应运而生。这个插件可以帮助你轻松实现测试用例的循环运行,以更全面地评估代码的稳定性。本文将深入介绍 pytest-repeat 插件的基本用法和实际案例,助你更好地利用循环测试,…

短视频矩阵系统软件/电脑pc企业版/手机端双开发~~源头

短视频矩阵系统软件开发的属性主要包含以下几个方面&#xff1a; 开发属性&#xff1a; 1. 功能属性&#xff1a;功能是短视频矩阵系统的核心属性&#xff0c;包括短视频的采集、编辑、发布、推广、互动等功能。此外&#xff0c;系统的个性化定制也是考虑的重要因素&#xff0…

云计算中的弹性是什么?

云弹性是指当客户需求增加或减少时&#xff0c;自动从数据中心配置和取消配置资源。这使得云资源(包括计算、存储和内存资源)能够根据需求变化快速重新分配。CPU/处理、内存、输入/输出带宽和存储容量等计算资源可以根据需要增加或减少&#xff0c;而不会影响系统性能。 它旨在…

如何在前端项目里接入Sentry监控系统并通过企业微信通知

能不能让用户录个屏过来呀&#xff1f; 用户使用的是什么机型的手机&#xff1f; 用户使用的什么浏览器呀&#xff1f; 用户的网络是什么情况&#xff1f; … … 线上出现问题时&#xff0c;技术部和业务部同学之间的对话诸如此类…业务同学也很栓Q呀&#xff0c;硬着头皮去问客…

预训练语言模型transformer

预训练语言模型的学习方法有三类&#xff1a;自编码&#xff08;auto-encode, AE)、自回归&#xff08;auto regressive, AR&#xff09;&#xff0c;Encoder-Decoder结构。 决定PTM模型表现的真正原因主要有以下几点&#xff1a; 更高质量、更多数量的预训练数据增加模型容量…

插槽(64-67)

文章目录 插槽1.插槽 - 默认插槽(组件内可以定制一处结构)2.插槽 - 后备内容&#xff08;默认值&#xff09;3.插槽 - 具名插槽(组件内可以定制多处结构)4.作用域插槽(插槽的一个传参语法) 插槽 插槽分类:默认插槽和具名插槽 1.插槽 - 默认插槽(组件内可以定制一处结构) 作用…

【CSS】字体效果展示

测试时使用了Google浏览器。 1.Courier New 2.monospace 3.Franklin Gothic Medium 4.Arial Narrow 5.Arial 6.sans-serif 7.Gill Sans MT 8.Calibri 9.Trebuchet MS 10.Lucida Sans 11.Lucida Grande 12.Lucida Sans Unicode 13.Geneva 14.Verdana 15.Segoe UI 16.Tahoma 17.…

AWS 专题学习 P11 (Machine Learning)

文章目录 专题总览机器学习服务1. Amazon Rekognition2. Amazon Rekognition - Content Moderation3. Amazon Transcribe4. Amazon Polly5. Amazon Polly - Lexicon & SSML6. Amazon TranscribeAmazon Translate7. Amazon Lex & Connect8. Amazon Comprehend9. Amazon …

大数据期望最大化(EM)算法:从理论到实战全解析

文章目录 大数据期望最大化&#xff08;EM&#xff09;算法&#xff1a;从理论到实战全解析一、引言概率模型与隐变量极大似然估计&#xff08;MLE&#xff09;Jensen不等式 二、基础数学原理条件概率与联合概率似然函数Kullback-Leibler散度贝叶斯推断 三、EM算法的核心思想期…

环形链表的检测与返回

环形链表 王赫辰/c语言 - Gitee.com 快慢指针的差距可以为除一以外的数吗&#xff1f;不可以如果差奇数则无法发现偶数环&#xff0c;是偶数无法发现奇数环&#xff0c;本题思路为指针相遇则为环&#xff0c;而以上两种情况会稳定差一&#xff0c;导致指针永不相遇 最终返回…

Discuz论坛搭建:Linux宝塔面板一键部署,固定地址畅享公网访问

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;网络奇遇记、Cpolar杂谈 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 &#x1f4cb;前言一. 安装基础环境二. 一键部署Discuz三. 安装cpolar工具四. 配置域名访问Discuz…

Android SharedPreferences源码分析

文章目录 Android SharedPreferences源码分析概述基本使用源码分析获取SP对象初始化和读取数据写入数据MemoryCommitResultcommitToMemory()commit()apply()enqueueDiskWrite()writeToFile() 主动等待写回任务结束 总结 Android SharedPreferences源码分析 概述 SharedPrefer…

Parallels Desktop 19 for Mac虚拟机 一键激活版

Parallels Desktop是一款功能强大的虚拟机软件&#xff0c;它允许用户在Mac电脑上同时运行Windows、Linux和其他操作系统。Parallels Desktop提供了直观易用的界面&#xff0c;使用户可以轻松创建、配置和管理虚拟机&#xff0c;该软件具有快速启动和关闭虚拟机的能力&#xff…

Servlet 与 MVC

主要内容 Servlet 重点 MVC 重点 Filter 重点 章节目标 掌握 Servlet 的作用 掌握 Servlet 的生命周期 掌握 JSP 的本质 掌握 MVC 的设计思想 掌握 Filter 的作用及使用场景 第一节 Servlet 1. Servlet 概念 Servlet 是在服务器上运行的能够对客户端请求进行处理&a…

从零开发短视频电商 Tesseract OCR识别增强

文章目录 概要图像预处理阶段默认反转图像重新缩放二值化噪音消除膨胀/腐蚀旋转/偏移校正边框缺少边框边框太大扫描边框去除 透明度/Alpha通道 引擎处理阶段语言模型配置提高识别速度词典、单词列表和模式表格识别 使用 Tesseract OCR 的 GUI 和其他项目 原文如下&#xff1a; …

【网络协议测试】畸形数据包——圣诞树攻击(DOS攻击)

简介 TCP所有标志位被设置为1的数据包被称为圣诞树数据包&#xff08;XMas Tree packet&#xff09;&#xff0c;之所以叫这个名是因为这些标志位就像圣诞树上灯一样全部被点亮。 标志位介绍 TCP报文格式&#xff1a; 控制标志&#xff08;Control Bits&#xff09;共6个bi…

安全基础~通用漏洞1

文章目录 知识补充Acess数据库注入MySQL数据库PostgreSQL-高权限读写注入MSSQL-sa高权限读写执行注入Oracle 注入Mongodb 注入sqlmap基础命令 知识补充 order by的意义&#xff1a; union 操作符用于合并两个或多个 select语句的结果集。 union 内部的每个 select 语句必须拥有…