【java】升级jetty-client解决Too many open files问题

news2024/12/24 8:40:08

文章目录

  • 升级jetty-client解决Too many open files问题
    • 问题背景
    • 排查
    • 原因
    • 解决
    • lsof命令拓展

升级jetty-client解决Too many open files问题

问题背景

生产环境的采集经过一段时间就会报错 Too many open files,导致接下来的采集都会失败,已经严重影响到生产业务,于是抽空对此问题进行排查。
在这里插入图片描述

排查

看到日志报错的第一感觉是采集脚本每次都会去打开conf/application.properties文件,导致文件句柄占满没有被释放。于是先去排查定时调度的sdk源码,发现访问conf/application.properties文件的地方都会关流。

既然访问conf/application.properties文件的地方都会关流,就将注意力放在采集业务逻辑上,有可能是业务采集文件时候没有关流,导致文件句柄占满,进而导致访问conf/application.properties文件报错。

观察业务代码,采集中用到文件流的对象都放在try()中,代码执行完毕会自动关流,此处没有找到可疑点。但是业务中除了下载文件会打开文件流外,就只有保存文件时候会打开文件流。但是业务中保存文件是常用的sdk封装方法,其他系统业务也会用到,不可能会是这个地方有问题呀~

于是又再次去过一遍采集代码逻辑,排查是否有没关流的地方。排查未果。

让运维使用lsof -p PID命令观察正式环境采集程序打开文件句柄情况,得到大量以下日志。(具体可参考文章最后面的lsof拓展说明)

COMMAND     PID USER   FD      TYPE             DEVICE  SIZE/OFF       NODE NAME
java    2686219 root *455r      REG               0,49    207988 3442057181 /opt/file1.txt
java    2686219 root *456r      REG               0,49    149821 3442057183 /opt/file2.txt

从日志分析可以看到FD(文件描述符)中的值为r说明采集文件处于被打开并处于只读模式
而采集中唯一读文件的地方为保存文件的sdk方法。至此,排查方向改为研究sdk保存文件的方法。

原因

以下为文件保存方法的伪代码

import org.eclipse.jetty.client.util.MultiPartContentProvider;
import org.eclipse.jetty.client.util.PathContentProvider;
import org.eclipse.jetty.client.util.StringContentProvider;

@Override
	public CompletableFuture<Boolean> uploadAsync(String tableName, List<FileEntry> entryList) throws Exception {
		HttpRequest request = HttpUtils.newRequest("POST", url).timeout(timeoutInMills, TimeUnit.MILLISECONDS).header(HEADER_TOKEN_NAME, token);
		
		MultiPartContentProvider multiPart = new MultiPartContentProvider();
		for(FileEntry fileEntry : entryList) {
			
			String filePath = fileEntry.getLocalPath();
			File sourceFile = new File(filePath);
			String remotepath = fileEntry.getRemotePath();
			Map<String, Object> properties = fileEntry.getEntry().getProperties()==null? new HashMap<String, Object>() : fileEntry.getEntry().getProperties();
			properties.put(FILE_PATH, remotepath);
			
			multiPart.addFieldPart(ENTRY_NAME, new StringContentProvider(JsonUtils.obj2str(fileEntry.getEntry(), false)), null);
			multiPart.addFilePart(FILE_NAME, sourceFile.getName(), new PathContentProvider(Paths.get(filePath)), null);
		}
		
		multiPart.close();
		request.body(multiPart, null);
		.......
		}

其中multiPart.addFilePart()方法会打开文件,此处使用到了jetty-client进行文件读。
遇事不决问google,找到了一个类似没关句柄的issue:https://github.com/jetty/jetty.project/issues/3512
大致意思是jetty-client-v9.4.25之前的MultiPartIterator在遍历读文件时,content.iterator() 一直返回新的Iterator 对象。遍历后并没有将MultiPartIterator.iterator关闭,因此造成了文件句柄没有释放

在这里插入图片描述

解决

在这里插入图片描述
issue提及以及在jetty 9.4.25已经修复了该bug。升级jetty-client,查看源码,如下图:
在这里插入图片描述
可以发现升级后的jetty加上了关流代码。

测试环境升级jetty相关包,测试没有复现问题,至此问题解决。

lsof命令拓展

命令参数

-a 列出打开文件存在的进程
-c<进程名> 列出指定进程所打开的文件
-g 列出GID号进程详情
-d<文件号> 列出占用该文件号的进程
+d<目录> 列出目录下被打开的文件
+D<目录> 递归列出目录下被打开的文件
-n<目录> 列出使用NFS的文件
-i<条件> 列出符合条件的进程。(4、6、协议、:端口、 @ip )
-p<进程号> 列出指定进程号所打开的文件
-u 列出UID号进程详情
-h 显示帮助信息
-v 显示版本信息

lsof输出各列信息的意义如下

  • COMMAND:进程的名称

  • PID:进程标识符

  • PPID:父进程标识符(需要指定-R参数)

  • USER:进程所有者

  • PGID:进程所属组

  • FD:文件描述符,应用程序通过文件描述符识别该文件。如cwd、txt等:
    (1)cwd:表示current work dirctory,即:应用程序的当前工作目录,这是该应用程序启动的目录,除非它本身对这个目录进行更改
    (2)txt :该类型的文件是程序代码,如应用程序二进制文件本身或共享库,如上列表中显示的 /sbin/init 程序
    (3)lnn:library references (AIX);
    (4)er:FD information error (see NAME column);
    (5)jld:jail directory (FreeBSD);
    (6)ltx:shared library text (code and data);
    (7)mxx :hex memory-mapped type number xx.
    (8)m86:DOS Merge mapped file;
    (9)mem:memory-mapped file;
    (10)mmap:memory-mapped device;
    (11)pd:parent directory;
    (12)rtd:root directory;
    (13)tr:kernel trace file (OpenBSD);
    (14)v86 VP/ix mapped file;
    (15)0:表示标准输入
    (16)1:表示标准输出
    (17)2:表示标准错误
    一般在标准输出、标准错误、标准输入后还跟着文件状态模式:r、w、u等
    (1)u:表示该文件被打开并处于读取/写入模式
    (2)r:表示该文件被打开并处于只读模式
    (3)w:表示该文件被打开并处于
    (4)空格:表示该文件的状态模式为unknow,且没有锁定
    (5)-:表示该文件的状态模式为unknow,且被锁定
    同时在文件状态模式后面,还跟着相关的锁
    (1)N:for a Solaris NFS lock of unknown type;
    (2)r:for read lock on part of the file;
    (3)R:for a read lock on the entire file;
    (4)w:for a write lock on part of the file;(文件的部分写锁)
    (5)W:for a write lock on the entire file;(整个文件的写锁)
    (6)u:for a read and write lock of any length;
    (7)U:for a lock of unknown type;
    (8)x:for an SCO OpenServer Xenix lock on part of the file;
    (9)X:for an SCO OpenServer Xenix lock on the entire file;
    (10)space:if there is no lock.

  • TYPE:文件类型,如DIR、REG等,常见的文件类型:

    (1)DIR:表示目录
    (2)CHR:表示字符类型
    (3)BLK:块设备类型
    (4)UNIX: UNIX 域套接字
    (5)FIFO:先进先出 (FIFO) 队列
    (6)IPv4:网际协议 (IP) 套接字

  • DEVICE:指定磁盘的名称

  • SIZE:文件的大小

  • NODE:索引节点(文件在磁盘上的标识)

  • NAME:打开文件的确切名称

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

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

相关文章

NSSCTF练习记录:[SWPUCTF 2021 新生赛]include

题目&#xff1a; 随便传入一个file 因为存在include_once函数&#xff0c;可以使用php伪协议获取flag.php源码&#xff0c;再通过base64解码得到flag。 php:// 访问各个输入/输出流&#xff0c;常用php://filter和php://input&#xff0c;php://filter用于读取源码&#xff…

gin框架 自定义404错误页面,自定义500等服务端异常,业务异常,根据不同异常类型显示不同的异常页面方法 整理

在gin框架中&#xff0c;要显示自定义的异常页面&#xff0c;首先需要通过gin路由对象中的LoadHTMLFiles或者LoadHTMLGlob方法加载自定义的错误页面模板文件&#xff0c; 然后定义符合 gin.HandlerFunc 类型的路由处理函数/方法 &#xff0c;即只有一个参数(c *ginx.XContext)的…

如何理解供应链控制塔?详解供应链控制塔类型与架构!

随着经济全球化的不断深入&#xff0c;企业供应链的复杂性也在不断增加。从供应商到制造商&#xff0c;再到分销商和消费者&#xff0c;全球供应链网络的每一个环节都充满了动态变化和不确定性。在这样的背景下&#xff0c;传统的供应链管理模式已难以满足现代企业的需求&#…

Ackites/Killwxapkg

自动化反编译微信小程序&#xff0c;小程序安全评估工具&#xff0c;发现小程序安全问题&#xff0c;自动解密&#xff0c;解包&#xff0c;可还..自动化反编译微信小程序&#xff0c;小程序安全评估工具&#xff0c;发现小程序安全问题&#xff0c;自动解密&#xff0c;解包&a…

【消息队列】kafka如何保证消息不丢失?

&#x1f44f;大家好&#xff01;我是和风coding&#xff0c;希望我的文章能给你带来帮助&#xff01; &#x1f525;如果感觉博主的文章还不错的话&#xff0c;请&#x1f44d;三连支持&#x1f44d;一下博主哦 &#x1f4dd;点击 我的主页 还可以看到和风的其他内容噢&#x…

查看有无XSS漏洞验证

实验环境 操作机&#xff1a;Win10 用户名&#xff1a;wangan 密码&#xff1a;123靶机&#xff1a;Apache PHP实验地址&#xff1a;http://ip/xss/level1.php?nametest 实验原理 构造弹窗的代码提交&#xff0c;浏览器在执行该代码后就会执行弹框的操作&#xff0c;弹框的目…

Python请求API的简明教程

前言 随着微服务流行开来&#xff0c;API正在成为数据获取的主要渠道&#xff0c;我们可以通过Java的HttpClient完成数据请求&#xff0c;当然也可以通过Python工具完成数据请求。 本博将对Python如何请求API进行举例&#xff0c;保你一文掌握。 1. 准备工具 在使用Python请…

Java面试题--JVM大厂篇之针对频繁的Minor GC问题,有哪些优化对象创建与使用的技巧可以分享?

目录 引言&#xff1a; 正文&#xff1a; 1. 了解Minor GC的痛点 2. 使用对象池&#xff08;Object Pool&#xff09; 3. 避免不必要的对象创建 4. 使用StringBuilder替代字符串拼接 5. 合理设置对象的作用域 6. 使用软引用和弱引用 结束语&#xff1a; 引言&#xff…

Python | Leetcode Python题解之第330题按要求补齐数组

题目&#xff1a; 题解&#xff1a; class Solution:def minPatches(self, nums: List[int], n: int) -> int:patches, x 0, 1length, index len(nums), 0while x < n:if index < length and nums[index] < x:x nums[index]index 1else:x << 1patches …

分享一款老软件RealPlayer 16.0.1.18

一款怀旧老软件&#xff0c;功能还算强大测试系统win7/10&#xff0c;win11以上系统自行测试&#xff01;这种老软件非常适合配置低的老电脑&#xff0c;尤其是单位办公电脑。

LVS实战演练

一.LVS简介 LVS&#xff08;Linux Virtual Server&#xff09;是Linux虚拟服务器的简称&#xff0c;是一种基于Linux内核的开源负载均衡技术。 <1>.工作原理 LVS&#xff08;Linux Virtual Server&#xff09;的工作原理可以概括为通过负载均衡技术将客户端的请求分发到…

论文解读 | ACL 2024:自我蒸馏在语言模型微调中架起分布差异的桥梁

点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入&#xff01; 杨兆瑞 浙江大学CAD&CG全国重点实验室博士生 导师为陈为教授 概述 大型语言模型&#xff08;LLMs&#xff09;的兴起彻底改变了自然语言处理领域&#xff0c;但对它们进行特定任务的微调常常面临在平衡性能…

MySQL数据分析进阶(九)触发器

※食用指南&#xff1a;文章内容为‘CodeWithMosh’SQL进阶教程系列学习笔记&#xff0c;笔记整理比较粗糙&#xff0c;主要目的自存为主&#xff0c;记录完整的学习过程。&#xff08;图片超级多&#xff0c;慎看&#xff01;&#xff09; 【中字】SQL进阶教程 | 史上最易懂S…

Oracle: oracle大小写敏感问题

oracle大小写敏感含义&#xff1a;比如创建表A和a&#xff0c;A和a是两个不同的表&#xff08;表名不同&#xff09;。 oracle大小写不敏感含义&#xff1a;比如创建了A表就不能创建a表&#xff0c;将A和a看成是相同的表&#xff08;表名相同&#xff09;。 1、查询用户是否存…

嵌入式人工智能(47-Pycharm通过SSH远程连接调试树莓派4B服务器)

用过Pycharm的同学都知道&#xff0c;这个IDE非常强大&#xff0c;强大到写个Helloworld都不值当运行它&#xff0c;等我打开的功夫&#xff0c;sublime都运行结束了。但是往往写大项目&#xff0c;尤其是web前后端的程序用Pycharm非常爽了&#xff0c;多标签页&#xff0c;前后…

AI Agent Market: Soverin - 引领未来的AI工具中心

随着人工智能技术的快速发展,AI代理正在成为企业不可或缺的新入口。最近,扎克伯格和黄仁勋的对话强调了AI代理的重要性,将其视为继电子邮件、网站和社交媒体之后的第四大企业必备工具。在这个背景下,Soverin作为一个成熟的AI应用和代理市场平台,正引领着AI工具市场的未来趋…

Android平台RTMP直播推送模块技术接入说明

技术背景 大牛直播SDK跨平台RTMP直播推送模块&#xff0c;始于2015年&#xff0c;支持Windows、Linux&#xff08;x64_64架构|aarch64&#xff09;、Android、iOS平台&#xff0c;支持采集推送摄像头、屏幕、麦克风、扬声器、编码前、编码后数据对接&#xff0c;功能强大&…

XCode15.4真机运行调试

更新Xcode后&#xff0c;没有模拟器内容&#xff0c;而且真机也不显示&#xff0c;编译按钮无法点击&#xff0c;设备在管理运行目标中可见&#xff0c;但无法选中 解决方案&#xff1a;下载iOS17.5模拟器&#xff0c;但最坑的是直接点击“Get”下载总是中断&#xff0c;且无…

mysql幻读现象及其避免策略

mysql幻读现象及其避免策略 1、幻读是什么&#xff1f;2、快照读与当前读3、如何避免幻读&#xff1f;3.1 快照读3.2 当前读 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 1、幻读是什么&#xff1f; 幻读是事务中第二次查询返回了之前不…

Spring Boot 3.x gradle脚手架工程build.gradle详解

为了让读者轻松掌握gradle项目构建脚本中各种配置&#xff0c;我们将从0开始一点点启用配置&#xff0c;以做实验的尝试方式&#xff0c;让大家对各种配置的作用有比较深的印象。如果觉得对你有帮助&#xff0c;记得点赞收藏&#xff0c;关注小卷&#xff0c;后续更精彩&#x…