【异常】原来提示SocketTimeoutException:connect timed out还可能是外部因素导致

news2025/1/18 6:54:21

一、现象截图

一大早收到ELK的邮件提醒,让我来看看,又是哪个妖怪在作孽?
在这里插入图片描述

二、问题定位

2.1 SocketTimeoutException:connect timed out

经验告诉我,这个问题一般是第三方平台的问题,大部分原因是发起Http请求,但是请求超时导致,很多HTTP framework(如本文中涉及的Hutool工具中的HttpUtil,底层是HttpURLConnection)本身有超时机制的,实现超时,就是在应用层代码里启动一个Timer,如果Timer超时,则手动取消请求。比如用户现在网络环境较差,当客户端发起一个请求时,通信层开始请求与服务器建立连接(包括在重试),如果在5S之内还没有连接到服务器,那么就会判定为超时。Http请求超时一般与我们的代码无关。

2.2 ICardServiceImpl的代码第122行出错了

啊?ICardServiceImpl是对接第三方平台,用于积分充值的功能,是组内大神写的代码,按理是不会出问题,而且已经上线了快1年了都,最近又没有变更,所以,第一直觉,故障的原因是因为外部变更导致的。

122行,那不就是这段代码吗?也就是下面这段方法中第三行中的代码逻辑
在这里插入图片描述

private void recharge2ICard(String workNo, Integer amount) {
		String icardPoint = String.format("%d.%02d", amount / 100, amount % 100);
		ICardRechargeReq req = new ICardRechargeReq(null, workNo, null, iCardRechargeKey, icardPoint);
		String respStr = HttpUtil.post(iCardRechargeUrl, JSONUtil.toJsonStr(req), 30 * 1000);
		ICardRechargeResp resp = JSONUtil.toBean(respStr, ICardRechargeResp.class);
		Assert.isTrue(resp.getHead().get(0).checkMac(iCardRechargeKey), "充值失败:一卡通返回信息校验失败!");
		String retCode = resp.getHead().get(0).getRcode();
		Assert.isTrue(Objects.equals(ICardReturnCode.OK.getCode(), retCode), "充值失败:" + ICardReturnCode.getMsg(retCode));
	}

这段逻辑中会超时,而且超时时间设置的是,底层逻辑如下,即在30000毫秒(30 秒)无响应,将提示超时,上面的报错提示,就是这一段它在超时后提示的异常。
在这里插入图片描述
这段代码中存在以下问题
(1)错误提示不友好,超时了没有给反馈结果给前端。用户体验不好
(2)错误日志Assert.isTrue的方式可读性不高,而且容易逻辑判断出错
(3)没有考虑到返回不是json的情况,下面这个错误也是频发的。在这里插入图片描述

三、问题深入分析

经过咨询运维同事还有网络同事之后,他们用了一堆很专业的网络命令,比如ping、tracepath命令在我们的服务器层面去排查,发现确实有问题,最后发现了是线路欠费断了导致???什么?没有监控的吗?这种欠费的低级错误也会犯??算了,外部原因不深究了,那就来一波网络排查指令语法知识干货科普吧~

3.1 tracepath指令

指令作用:

追踪数据到达目标主机的路由信息,同时还能够发现MTU值。
它跟踪路径到目的地,沿着这条路径发现MTU。它使用UDP端口或一些随机端口。
它类似于Traceroute命令,只是不需要超级用户特权,并且没有花哨的选项。
它用于检测网络延迟,但是,它不需要 root 权限,并且默认安装在 Ubuntu 中。
它跟踪到指定目的地的路由并识别其中的每一跳。
如果您的网络较弱,它会识别出网络较弱的点。

指令适用范围:

RedHat、RHEL、Ubuntu、CentOS、SUSE、openSUSE、Fedora。

指令语法:

tracepath <destination>
tracepath [ -n] [ -l pktlen] destination [ port]

指令选项列表:

选项说明
-p后面跟设置要使用的初始目标端口
-n不查看主机名字,以数字形式只显示 IP 地址。
-4仅使用IPv4
-6仅使用IPv6
-b同时显示 IP 地址和主机名
-l设置初始化的数据包长度,IPv4 默认为 65535,IPv6 默认为 128000
-m后面跟<max_hops> 设置最大 TTL 值,默认为 30
-V打印版本并退出

输出解答

核心:后面看不到地址,是超时,就代表断了

在这里插入图片描述

1?[LOCALHOST]pmtu 1500
第一列第二列行的其余部分
显示探针的TTL,后面是冒号。通常TTL的值是从网络中得到的,但有时回复并不包含必要的信息,我们不得不猜测它。在这种情况下,数字后面跟着?。显示网络跳,对探测作出答复。如果探测未发送到网络,则为路由器地址或者[localhost]地址。显示了有关到达相关工作跳的路径的各种信息。作为规则,它包含RTT的值。此外,它可以显示路径MTU,当它改变。如果路径是不对称的,或者探测在到达指定跳之前完成,则显示前向和后向跳数之间的差异。这一信息不可靠。F.E.第三行显示1的不对称性,这是因为第一次TTL为2的探针在第一跳时由于路径MTU发现而被拒绝。

最后一行总结了到达目的地的所有路径的信息,显示了检测到的路径MTU、到达目的地的跳数以及我们对从目的地到我们的跳数的猜测,这在路径不对称时可能有所不同。

四、优化与重构现有代码逻辑

既然发现了问题,就应该着手修改问题了,刚好趁着这个契机,重构这一段代码,然后让测试同学重新测试下,嘿嘿。告别不好的用户体验,以及再见了无用的告警!

4.1 核心逻辑1:重构充值到一卡通的逻辑

    private Pair<Boolean, String> recharge2ICard(String workNo, Integer amount) {
        Pair<Boolean, String> handleResult;
        String iCardPoint = String.format("%d.%02d", amount / 100, amount % 100);
        ICardRechargeReq req = new ICardRechargeReq(null, workNo, null, iCardRechargeKey, iCardPoint);
        String respStr;
        try {
            respStr = HttpUtil.post(iCardRechargeUrl, JSONUtil.toJsonStr(req), 30 * 1000);
        } catch (Exception e) {
            log.error("充值失败! 无法链接一卡通提供的URL = 【{}】,请检查网络配置!", iCardRechargeUrl);
            handleResult = new Pair<>(Boolean.FALSE, "充值失败! 无法链接一卡通提供的URL!请检查网络配置!");
            return handleResult;
        }
        log.info("充值信息:user={},amount={},respStr={}", workNo, amount, respStr);
        if (StrUtil.isBlank(respStr)) {
            log.error("充值失败! respStr是空的 respStr= 【{}】,可能原因是网络阻塞导致!", respStr);
            handleResult = new Pair<>(Boolean.FALSE, respStr);
            return handleResult;
        }
        ICardRechargeResp resp = JSONUtil.toBean(respStr, ICardRechargeResp.class);
        if (!resp.getHead().get(0).checkMac(iCardRechargeKey)) {
            String err = "充值失败:一卡通返回信息校验失败!";
            handleResult = new Pair<>(Boolean.FALSE, err);
            return handleResult;
        }
        String retCode = resp.getHead().get(0).getRcode();
        if (!ObjectUtil.equals(ICardReturnCode.OK.getCode(), retCode)) {
            String err = "充值失败:" + ICardReturnCode.getMsg(retCode);
            handleResult = new Pair<>(Boolean.FALSE, err);
            return handleResult;
        }
        return new Pair<>(Boolean.TRUE, null);
    }

4.2 核心逻辑2:服务调用逻辑

        Pair<Boolean, String> handleResult = recharge2ICard(userInfo.getWorkNo(), body.getAmount());
        if (Boolean.FALSE.equals(handleResult.getKey())) {
            return R.failed("充值到一卡通失败,请联系客服处理!");
        }

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

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

相关文章

惠普M329打印机更换副厂硒鼓后提示墨粉不足并无法打印

买了一个惠普M329打印机,打印效果不错,速度快,大量复印比较方便。因为最近打印和复印比较多,很快原装墨粉用完了。又买了一个副厂(带芯片)的硒鼓换上。不到一个月,又用光了,这次买了同一个副厂的硒鼓(不带芯片)。将原来的芯片(副厂的)拆下来,装在新硒鼓上。装到M3…

喜讯!华秋电子荣获千峰奖“2022年度产业互联网百强”,持续为电子产业增效降本!

12月28日&#xff0c;2022全球数字贸易大会专题活动“跨境产业互联网峰会暨2022年度千峰之夜”在武汉隆重举行&#xff0c;大会聚集了全国产业互联网、跨境电商平台、数字经济、资本市场等嘉宾&#xff0c;共同探讨产业互联网公司出海的机会和路径。 亿邦动力董事长郑敏介绍&am…

数字IC设计、验证、FPGA笔试必会 - Verilog经典习题 (三)奇偶校验

数字IC设计、验证、FPGA笔试必会 - Verilog经典习题 &#xff08;三&#xff09;奇偶校验 &#x1f508;声明&#xff1a; &#x1f603;博主主页&#xff1a;王_嘻嘻的CSDN博客 &#x1f9e8;未经作者允许&#xff0c;禁止转载 &#x1f511;系列专栏&#xff1a;牛客Verilog习…

房产管理系统平台架构安全需求分析

数图互通高校房产管理系统是基于公司自主研发的FMCenterV5.0平台&#xff0c;是针对中国高校房产的管理特点和管理要求&#xff0c;研发的一套标准产品&#xff1b;通过在中国100多所高校的成功实施和迭代&#xff0c;形成了一套成熟、完善、全生命周期的房屋资源管理解决方案。…

JavaAccessBridge(Java访问桥)详细介绍

Java Access Bridge 通过 Java 访问桥 API&#xff0c;您可以给使用Java应用程序编写的在windows系统上运行的图形化系统开发辅助技术应用程序。它包含本机方法&#xff0c;使您能够查看和操作有关 Java 应用程序中 GUI 元素的信息&#xff0c;这些信息将通过 Java 访问桥转发…

二维数组中各个三角形的关系,三角形的打印同理

给你一个n*n矩阵&#xff0c;按照顺序填入1到n*n的数&#xff0c;例如n5&#xff0c;该矩阵如下 (这是一个题目&#xff0c;但是我这个写法在牛客刷题中是不能正确的得分的&#xff0c;但是我找到了各个关系&#xff0c;然后分享给大家) 然后再对其进行求和处理&#xff0c;是…

在IntelliJ IDEA中使用.ignore插件忽略Git不必要提交的文件

第一步&#xff1a; 点击File->Settings&#xff0c;在左侧菜单找到Plugins&#xff0c;点击搜索栏搜索.ignore&#xff0c;点击Install 第二步&#xff1a; 重启idea -->在项目上右键->New ->.ignore file ->.gitignore file(Git) 第三部&#xff1a; 在项目中…

http协议的简单总结

目录 1.http协议的特性 2.http协议的请求 3.get请求和post请求的区别 4.http协议的响应 1.http协议的特性 http协议是建立在TCP/IP协议之上应用层协议&#xff0c;默认端口为80,8080 http协议的的特点是无状态&#xff0c;无连接&#xff08;短连接&#xff09; 2.http协…

【面试题】京东面试查漏补缺

目录一&#xff1a;笔试题1.如何获取URL中的参数方法一方法二2.怎么平铺多维数组方法一方法二&#xff1a;递归方法三&#xff1a; flat() 和 flatMap()二&#xff1a;面试题1.promise相关问题2.vue nextTick的作用和原理3.http状态码304缓存相关问题4.其他常规问题省略wh零售事…

在线学习(online learning)——Chapter 2 Problem Formulations and Related Theory

在线学习(online learning)——Chapter 2 Problem Formulations and Related Theory 本章中&#xff0c;我们将首先给出一个经典的在线学习问题的形式化描述&#xff0c;即在线二分类(online binary classification)&#xff0c;然后介绍统计学习理论、在线凸优化和博弈论的基…

Zabbix“专家坐诊”第179期问答汇总

欢迎大家加入乐维社区zabbix问答专栏&#xff0c;除了在论坛发帖求问外&#xff0c;还可以在QQ群里交流进步&#xff0c;并且每周三我们会进行免费的技术答疑活动。 问题一&#xff1a; Q&#xff1a;Zabbix alert syncer processes more than 75% busy&#xff0c;这个告警&…

Live800:优秀的在线客服系统配置哪些功能模块?

在线客服系统是企业客服解决客户疑惑的软件系统&#xff0c;是企业统一对外联系的窗口。为了提升客户服务质量&#xff0c;提高客服人员工作效率&#xff0c;越来越多的企业配置了在线客服系统。那一款优秀的在线客服系统需要配置哪些功能模块呢&#xff1f;一、在线沟通模块在…

简明精要Android IPC通信

目录 一、Android应用层IPC通信方式 二、IPC通信数据拷贝次数 这里指的从应用层角度&#xff0c;IPC通信方式。简单记录一下。 一、Android应用层IPC通信方式 Bundle&#xff1a;四大组件中的三大组件&#xff08;Activity、Service、Receiver&#xff09;都是支持在Intent中…

MySQL学习之一条SQL更新语句的执行

文章目录前言一、MySQL更新操作大致流程二、redo log介绍三、binlog介绍四、MySQL更新操作的具体流程前言 今天我们通过一条SQL更新语句&#xff0c;了解MySQL的日志系统 一、MySQL更新操作大致流程 更新数据库表上的操作&#xff0c;跟这个表有关的查询缓存会失效。这条语句…

MyBatisPlus(MP)学习记录(分页查询的开启+日志打印配置+乐观锁+映射匹配+字段匹配和表名匹配+null值判定+代码生成器等等)

MP介绍&#xff08;官网链接&#xff09; MyBatis-Plus&#xff08;简称 MP&#xff09;是一个 MyBatis 的增强工具&#xff0c;在 MyBatis 的基础上只做增强不做改变&#xff0c;为简化开发、提高效率而生。 前言 本篇文章展示的MP教学中涉及到的版本如下&#xff1a; IDE…

Unity 之 Addressable可寻址系统 -- 可寻址系统概念介绍 -- 入门(一)

可寻址系统面板概念 -- 入门&#xff08;一&#xff09;一&#xff0c;可寻址系统概念介绍1.1 官方话术1.2 几个概念二&#xff0c;可寻址系统目录介绍2.1 导入工程2.2 目录介绍概述&#xff1a;本片文章带大家了解可寻址系统的相关概念&#xff0c;为大家介绍可寻址系统导入方…

Elasticsearch:如何在 Docker 上运行 Elasticsearch 8.x 进行本地开发

对于 Elasticsearch 的新主要版本 (8.x.x)&#xff0c;有关于在 Docker 上运行 Elasticsearch 和 Kibana 的重大更新。 过去适用于以前版本的 Docker 和 Docker Compose 的命令和语法需要更新才能适用于最新版本。 在这篇文章中&#xff0c;我们将介绍如何使用 Docker 和 Docke…

Hudi系列5:Hudi与Spark集成

文章目录一. Spark操作Huid概述二. Spark-Shell方式三. pyspark方式四. SparkSQL方式参考:一. Spark操作Huid概述 Hudi各个版本支持Spark版本情况: 将hudi集成spark的jar包&#xff0c;放到spark的jars目录 -- 同步到其它节点 cd /home/hudi-0.12.0/packaging/hudi-spark-b…

【设计模式】UML类图

设计模式学习之旅(一) 查看更多可关注后查看主页设计模式DayToDay专栏 一.UML概述 统一建模语言&#xff08;Unified Modeling Language&#xff0c;UML&#xff09;&#xff0c;是一种用于软件系统分析和设计的语言工具。特点是简单、统一、图形化、能表达软件设计中的动态与静…

Matlab论文插图绘制模板第72期—金字塔图

前段时间&#xff0c;有朋友觉得一篇文章里的插图看着不错&#xff0c;问Matlab能不能实现&#xff1a; 想了想&#xff0c;Matlab中并没有现成的画图代码。 但本质上&#xff0c;这种图其实就是横向柱状图的变体&#xff0c;而横向柱状图的绘制模板之前有分享过&#xff1a; …