当前位置: 首页 > news >正文

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的方式成功进行数据存储了,这样做也没有违背原有的逻辑。
但是问题仍然没有一个正确的解决方式,希望走过路过的大神能指点一二,在线求助。

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

相关文章:

Rabbitmq调用FeignClient接口失败

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

专业120+总分400+海南大学838信号与系统考研高分经验海大电子信息与通信

今年专业838信号与系统120&#xff0c;总分400&#xff0c;顺利上岸海南大学&#xff0c;这一年的复习起起伏伏&#xff0c;但是最后还是坚持下来的&#xff0c;吃过的苦都是值得&#xff0c;总结一下自己的复习经历&#xff0c;希望对大家复习有帮助。首先我想先强调一下专业课…...

如何区分 html 和 html5?

HTML&#xff08;超文本标记语言&#xff09;和HTML5在很多方面都存在显著的区别。HTML5是HTML的最新版本&#xff0c;引入了许多新的特性和元素&#xff0c;以支持更丰富的网页内容和更复杂的交互。以下是一些区分HTML和HTML5的关键点&#xff1a; 新特性与元素&#xff1a;H…...

Ps:将文件载入堆栈

Ps菜单&#xff1a;文件/脚本/将文件载入堆栈 Scripts/Load Files into Stack 将文件载入堆栈 Load Files into Stack脚本命令可用于将两个及以上的文件载入到同一个 Photoshop 新文档中。 载入的每个文件都将成为独立的图层&#xff0c;并使用其原始文件名作为图层名。 Photos…...

【格密码基础】:补充LWE问题

目录 一. LWE问题的鲁棒性 二. LWE其他分布选择 三. 推荐文献 四. 附密码学人心中的顶会 一. LWE问题的鲁棒性 robustness&#xff0c;翻译为鲁棒性 已有的论文表明&#xff0c;及时敌手获取到部分关于秘密和error的信息&#xff0c;LWE问题依旧是困难的&#xff0c;这能…...

【C++入门到精通】特殊类的设计 |只能在堆 ( 栈 ) 上创建对象的类 |禁止拷贝和继承的类 [ C++入门 ]

阅读导航 引言一、特殊类 --- 不能被拷贝的类1. C98方式&#xff1a;2. C11方式&#xff1a; 二、特殊类 --- 只能在堆上创建对象的类三、特殊类 --- 只能在栈上创建对象的类四、特殊类 --- 不能被继承的类1. C98方式2. C11方法 总结温馨提示 引言 在面向对象编程中&#xff0…...

VMware虚拟机部署Linux Ubuntu系统

本文介绍基于VMware Workstation Pro虚拟机软件&#xff0c;配置Linux Ubuntu操作系统环境的方法。 首先&#xff0c;我们需要进行VMware Workstation Pro虚拟机软件的下载与安装。需要注意的是&#xff0c;VMware Workstation Pro软件是一个收费软件&#xff0c;而互联网中有很…...

RFID标签:数字时代的智能身份

在数字时代&#xff0c;RFID标签&#xff08;Radio-Frequency Identification&#xff09;成为物联网&#xff08;IoT&#xff09;中不可或缺的一环。作为一种小巧却功能强大的设备&#xff0c;RFID标签在各个领域的应用不断扩展&#xff0c;为我们的生活和工作带来了新的可能性…...

《动手学深度学习(PyTorch版)》笔记3.2

注&#xff1a;书中对代码的讲解并不详细&#xff0c;本文对很多细节做了详细注释。另外&#xff0c;书上的源代码是在Jupyter Notebook上运行的&#xff0c;较为分散&#xff0c;本文将代码集中起来&#xff0c;并加以完善&#xff0c;全部用vscode在python 3.9.18下测试通过。…...

elasticsearch8.x版本docker部署说明

前提&#xff0c;当前部署没有涉及证书和https访问 1、环境说明,我采用三个节点&#xff0c;每个节点启动两个es&#xff0c;用端口区分 主机角色ip和端口服务器Amaster192.168.2.223:9200服务器Adata192.168.2.223:9201服务器Bdata,master192.168.2.224:9200服务器Bdata192.1…...

使用scyllaDb 或者cassandra存储聊天记录

一、使用scyllaDb的原因 目前开源的聊天软件主要还是使用mysql存储数据&#xff0c;数据量大的时候比较麻烦&#xff1b; 我打算使用scyllaDB存储用户的聊天记录&#xff0c;主要考虑的优点是&#xff1a; 1&#xff09;方便后期线性扩展服务器&#xff1b; 2&#xff09;p…...

Visual Studio如何修改成英文版

1、打开 Visual Studio Installer 2、点击修改 3、找到语言包&#xff0c;选择需要的语言包&#xff0c;而后点击修改 4、等待下载 5、 安装完成后启动Visual Studio 6、在工具-->选项-->环境-->区域设置-->English并确定 7、重启 Visual Studio&#xff0c;配置…...

gin中使用swagger生成接口文档

想要使用gin-swagger为你的代码自动生成接口文档&#xff0c;一般需要下面三个步骤&#xff1a; 按照swagger要求给接口代码添加声明式注释&#xff0c;具体参照声明式注释格式。使用swag工具扫描代码自动生成API接口文档数据使用gin-swagger渲染在线接口文档页面 第一步&…...

最新AI创作系统ChatGPT网站系统源码,Midjourney绘画V6 ALPHA绘画模型,ChatFile文档对话总结+DALL-E3文生图

一、前言 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;那么如何搭建部署AI创作ChatGPT&#xff1f;小编这里写一个详细图文教程吧。已支持GPT…...

解析dapp:从底层区块链看DApp的脆弱性和挑战

每天五分钟讲解一个互联网只是&#xff0c;大家好我是啊浩说模式Zeropan_HH 在Web3时代&#xff0c;去中心化应用程序&#xff08;DApps&#xff09;已成为数字经济的重要组成部分。它们的同生性&#xff0c;即与底层区块链网络紧密相连、共存亡的特性&#xff0c;为DApps带来…...

机器学习整理

绪论 什么是机器学习&#xff1f; 机器学习研究能够从经验中自动提升自身性能的计算机算法。 机器学习经历了哪几个阶段&#xff1f; 推理期&#xff1a;赋予机器逻辑推理能力 知识期&#xff1a;使机器拥有知识 学习期&#xff1a;让机器自己学习 什么是有监督学习和无监…...

RISC-V常用汇编指令

RISC-V寄存器表&#xff1a; RISC-V和常用的x86汇编语言存在许多的不同之处&#xff0c;下面将列出其中部分指令作用&#xff1a; 指令语法描述addiaddi rd,rs1,imm将寄存器rs1的值与立即数imm相加并存入寄存器rdldld t0, 0(t1)将t1的值加上0,将这个值作为地址&#xff0c;取…...

第二篇:数据结构与算法-链表

概念 链表是线性表的链式存储方式&#xff0c;逻辑上相邻的数据在计算机内的存储位置不必须相邻&#xff0c; 可以给每个元素附加一个指针域&#xff0c;指向下一个元素的存储位 置。 每个结点包含两个域&#xff1a;数据域和指针域&#xff0c;指针域存储下一个结点的地址&…...

低代码配置-小程序配置

数据结构 {"data": {"layout": {"api":{"pageApi":{//api详情}},"config":{"title":"页面标题"&#xff0c;},"listLayout": {"fields": [{"componentCode": "grid…...

第十八讲_HarmonyOS应用开发实战(实现电商首页)

HarmonyOS应用开发实战&#xff08;实现电商首页&#xff09; 1. 项目涉及知识点罗列2. 项目目录结构介绍3. 最终的效果图4. 部分源码展示 1. 项目涉及知识点罗列 掌握HUAWEI DevEco Studio开发工具掌握创建HarmonyOS应用工程掌握ArkUI自定义组件掌握Entry、Component、Builde…...

GD32F103C8T6烧录方式全解析:串口ISP、ST-Link Utility、Keil在线,哪种最适合你?

GD32F103C8T6烧录方案深度评测&#xff1a;从原型开发到量产部署的全场景指南 在嵌入式开发领域&#xff0c;选择正确的程序烧录方式往往决定着开发效率和生产成本。作为STM32F103的国产替代方案&#xff0c;GD32F103C8T6凭借其出色的性价比赢得了广泛关注。但许多开发者在迁移…...

OSINT自动化平台ClawShield:模块化架构与安全运营实战解析

1. 项目概述&#xff1a;一个面向安全运营的公开情报收集与分析平台最近在整理自己的开源项目收藏夹&#xff0c;发现一个挺有意思的仓库&#xff0c;叫SleuthCo/clawshield-public。乍一看这个名字&#xff0c;“ClawShield”&#xff0c;爪子与盾牌&#xff0c;就透着一股子攻…...

Applite:告别命令行!macOS软件管理的图形化终极解决方案

Applite&#xff1a;告别命令行&#xff01;macOS软件管理的图形化终极解决方案 【免费下载链接】Applite User-friendly GUI macOS application for Homebrew Casks 项目地址: https://gitcode.com/gh_mirrors/ap/Applite 还在为Homebrew复杂的命令行操作而头疼吗&…...

高效浏览器视频嗅探工具:猫抓扩展完整使用指南

高效浏览器视频嗅探工具&#xff1a;猫抓扩展完整使用指南 【免费下载链接】cat-catch 猫抓 浏览器资源嗅探扩展 / cat-catch Browser Resource Sniffing Extension 项目地址: https://gitcode.com/GitHub_Trending/ca/cat-catch 猫抓&#xff08;Cat-Catch&#xff09;…...

DLSS Swapper终极指南:免费开源的游戏DLSS智能管理工具

DLSS Swapper终极指南&#xff1a;免费开源的游戏DLSS智能管理工具 【免费下载链接】dlss-swapper 项目地址: https://gitcode.com/GitHub_Trending/dl/dlss-swapper DLSS Swapper是一款革命性的免费开源工具&#xff0c;专为PC游戏玩家设计&#xff0c;能够智能管理、…...

3分钟上手RePKG:轻松提取Wallpaper Engine壁纸资源的终极指南

3分钟上手RePKG&#xff1a;轻松提取Wallpaper Engine壁纸资源的终极指南 【免费下载链接】repkg Wallpaper engine PKG extractor/TEX to image converter 项目地址: https://gitcode.com/gh_mirrors/re/repkg 你是否曾经遇到过这样的困扰&#xff1f;在Wallpaper Engi…...

合宙Air153C看门狗芯片:嵌入式系统可靠性的硬件守护方案

1. 项目概述&#xff1a;一颗“小而美”的国产看门狗芯片最近在做一个低功耗的户外监测设备项目&#xff0c;主控用的就是合宙的Air系列MCU。在调试过程中&#xff0c;最让我头疼的就是系统偶尔的“死机”问题。设备部署在野外&#xff0c;不可能每次都跑过去手动重启。正当我琢…...

本地化AI代码助手LLMDog:模块化框架与开源模型集成实践

1. 项目概述&#xff1a;一个为开发者设计的本地化AI代码助手最近在GitHub上闲逛&#xff0c;发现了一个挺有意思的项目叫“LLMDog”&#xff0c;作者是doganarif。乍一看这个名字&#xff0c;可能会联想到“AI狗”或者某种宠物&#xff0c;但它的全称其实是“Large Language M…...

LC正弦波振荡器原理、设计与调试:从巴克豪森判据到电路实战

1. 从直流到交流&#xff1a;正弦波振荡器的核心价值与分类在电子电路的世界里&#xff0c;我们常常需要将稳定的直流电源&#xff0c;转换成特定频率和幅度的交流信号。这个看似“无中生有”的过程&#xff0c;正是正弦波振荡器的核心使命。无论是你手机里的无线通信模块、收音…...

CI/CD安全最佳实践:保护软件交付流程

CI/CD安全最佳实践&#xff1a;保护软件交付流程 一、CI/CD安全最佳实践概述 1.1 CI/CD安全最佳实践的定义 CI/CD安全最佳实践是指在持续集成和持续部署流程中实施的安全策略和措施。它涵盖代码提交、构建、测试、部署等各个阶段的安全防护。 1.2 CI/CD安全最佳实践的价值 安全…...