您现在的位置是:主页 > news > 公众号关注推广/如何优化网站快速排名

公众号关注推广/如何优化网站快速排名

admin2025/5/23 14:14:10news

简介公众号关注推广,如何优化网站快速排名,摄影招聘网站,wordpress英文版教程项目中通过jsch中的sftp实现上传下载文件。在压测过程中,由于调用到sftp,下载文件不存在时,系统不断抛出异常,内存飙升,逐渐把swap区也占满,通过top监控未发现占用内存的进程,通过查找sshd进程&…

公众号关注推广,如何优化网站快速排名,摄影招聘网站,wordpress英文版教程项目中通过jsch中的sftp实现上传下载文件。在压测过程中,由于调用到sftp,下载文件不存在时,系统不断抛出异常,内存飙升,逐渐把swap区也占满,通过top监控未发现占用内存的进程,通过查找sshd进程&…

项目中通过jsch中的sftp实现上传下载文件。在压测过程中,由于调用到sftp,下载文件不存在时,系统不断抛出异常,内存飙升,逐渐把swap区也占满,通过top监控未发现占用内存的进程,通过查找sshd进程,发现服务器多了很多sftp的进程没有被关闭。

e44cf4531587e697e2d03d3b4b4acc5c.png

刚开始以为是sftp公共方法设计的有问题,每次创建连接都未释放,下面是部分代码片段

@Repository("SftpClient")

public class SftpClient {

private Logger logger = LoggerFactory.getLogger(SftpClient.class);

private ThreadLocal sessionLocal = new ThreadLocal();

private ThreadLocal channelLocal = new ThreadLocal();

//初始化连接

public SftpClient init() {

try {

String host = SFTP_HOST;

int port = Integer.valueOf(SFTP_PORT);

String userName = SFTP_USER_NAME;

String password = SFTP_USER_PASSWORD;

Integer timeout = Integer.valueOf(SFTP_TIMEOUT);

Integer aliveMax = Integer.valueOf(SFTP_ALIVEMAX);

// 创建JSch对象

JSch jsch = new JSch();

Session session = jsch.getSession(userName, host, port);

// 根据用户名,主机ip,端口获取一个Session对象

if (password != null) {

// 设置密码

session.setPassword(password);

}

// 为Session对象设置properties

session.setConfig("StrictHostKeyChecking", "no");

if (timeout != null) {

// 设置timeout时间

session.setTimeout(timeout);

}

if (aliveMax != null) {

session.setServerAliveCountMax(aliveMax);

}

// 通过Session建立链接

session.connect();

// 打开SFTP通道

ChannelSftp channel = (ChannelSftp) session.openChannel("sftp");

// 建立SFTP通道的连接

channel.connect();

channelLocal.set(channel);

sessionLocal.set(session);

logger.debug("SSH Channel connected.session={},channel={}", session, channel);

} catch (JSchException e) {

throw new SystemException(ImageExceptionCode.FTP_SEND_ERROR);

}

return this;

}

//断开连接

public void disconnect() {

ChannelSftp channel = channelLocal.get();

Session session = sessionLocal.get();

//断开sftp连接

if (channel != null) {

channel.disconnect();

logger.debug("SSH Channel disconnected.channel={}", channel);

}

//断开sftp连接之后,再断开session连接

if (session != null) {

session.disconnect();

logger.debug("SSH session disconnected.session={}", session);

}

channelLocal.remove();

sessionLocal.remove();

}

}

因为使用jsch的sftp有一个要注意的地方,当调用ChannelSftp.disconnect()断开sftp的连接之后,该连接的session还存在,这时,需要显式调用Session.disconnect()来断掉session。程序设计的时候也考虑到这一点了,公共方法设计的是没问题的,那么问题在哪呢?

f63b891c4c07a996a0cd9827d795c0d0.png

调整日志级别,通过查看日志定位出问题所在,业务层在调用时,执行两次init()创建了两个sftp连接,但当遇到异常时,仅仅执行了一次disconnect()释放了第二次创建的,第一个连接一直没有得到释放。

try {

sftpClient.init();

for(XxxDto is:list){

/*********业务代码,略*************/

try {

/*********业务代码,略*************/

try {

/*********业务代码,略*************/

} catch (Exception e) {

throw new BusinessException(XxxExceptionCode.UNDER_USERID_FAIL);

}

/*********下载业务代码,问题所在,此处抛出异常*************/

} catch (Exception e) {

throw new BusinessException( XxxExceptionCode.FTP_DOWNLOAD_LOCAL_FAIL);

}

}

} finally {

sftpClient.disconnect();

}

下载业务代码如下:

try {

sftpClient.init();

/*************下载业务代码,此处抛出异常被上层捕获,该方法创建的连接被释放,但上层的连接 enenenenene *****************/

} finally {

sftpClient.disconnect();

}

业务层的代码不规范,sftp连接在第一次初始化之后就不需要再在方法层里执行初始化了,这不但加剧了资源的消耗,而且由于在业务层有嵌套try,最里面抛出异常未将第一个连接释放就再次执行初始化,导致未释放的sftp原来越多。

将下载业务代码里的init()和disconnect()方法去掉,把sftp的连接和断开只交给上一层的业务层进行控制。

修改后的下载业务代码如下:

/*************下载业务代码,只专注业务 *****************/

附:问题排查过程中部分命令如下:

Linux文件删除空间未释放

当系统空间使用量过大需要清理空间或者清理某个文件时,有时会出现执行了删除命令之后磁盘空间并没有释放,很多人首次遇到该情况时会比较困惑,在考虑是不是像windows系统的回收站一样,删除只是逻辑删除到回 ...

go的mgo,连接未释放问题,连接泄露。

api启动几天后,卡住(连接失败,超时) 异常原因 mongo连接被占满,无法建立mgo连接,返回信息 查询点用端口可知,97%的连接被api项目占用. api项目的mongodb连接“泄露”,某处的 ...

【转】Linux下tcp连接断开后不释放的解决办法

问题:在开发测试时发现断开与服务器端口后再次连接时拒绝连接. 分析:服务器上查看端口占用情况,假设端口为8888. netstat -anp |grep 8888 发现端口8888端口显示被占用(ip ...

Linux下TCP连接断开后不释放的解决办法

问题:在开发测试时发现断开与服务器端口后再次连接时拒绝连接. 分析:服务器上查看端口占用情况,假设端口为8888. netstat -anp |grep 8888 发现端口8888端口显示被占用(ip ...

关于连接sftp以及本地配置sftp的事情

1.window下配置sftp服务器 参考:https://blog.csdn.net/zhangliang_571/article/details/45598939 下载:http://www.fr ...

putty连接linux as5 输入密码后连接中断

putty连接linux as5 输入密码后连接中断 1.修改putty首页的设置,选择“close session on exit” 为 “never”,之后发现输入密码后,“session clo ...

TCP建立连接三次握手和释放连接四次握手

TCP建立连接三次握手和释放连接四次握手     [转载]http://blog.csdn.net/guyuealian/article/details/52535294   在谈及TCP建立连接和释 ...

【转】TCP建立连接三次握手和释放连接四次握手

在谈及TCP建立连接和释放连接过程,先来简单认识一下TCP报文段首部格式的的几个名词(这里只是简单说明,具体请查看相关教程) 序列号seq:占4个字节,用来标记数据段的顺序,TCP把连接中发送的所有数 ...

随机推荐

thinkphp自定义分页效果

TP自带了一个分页函数,挺方便使用的. 下面是我的使用方法: /*****************分页显示start*************************/ $arr_page=$this ...

JavaWeb---图书馆管理系统

写在开头,以后每天写记录. 今天,初步了解了一下,项目需求,用现在自己所学的知识,很多还不能做出来. 先用目前的知识,一步步的做出来,不断的完善,今天遇到的问题: 任务分析: 01.list页面的ad ...

了解 Nginx 基本概念

前言 本篇是我学习 Nginx 的一些笔记,主要内容讲述了一些了解 Nginx 需要的基本概念.然后探讨一下 Nginx 的模块化的组织架构,以及各个模块的分类.工作方式.职责和提供的相关指令. 主要 ...

OFBIZ安装

1. 安装SVN客户端,从Apache OFBiz Source Repository获取OFBIZ下载地址.此处以12.04为例,下载地址为http://svn.apache.org/repos/a ...

POJ2096 概率dp 入门

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=118282#problem/B 挺好的一个题目: 不过刚开始嘛,看别人题解长知识.这个人写 ...

Unity3d获取游戏对象的几种方法

1.GameObject.Find() 通过场景里面的名子或者一个路径直接获取游戏对象. GameObject root = GameObject.Find("GameObject&quot ...

button 和input 的区别及在表单form中的用法

先说一下button 和input的定义:  标签定义的是一个按钮 1.在 元素内部,您可以放置任何内容,比如文本或图像.这是该元素与使用 & ...

实验与作业(Python)-04 数据类型、数学函数与字符串

截止日期 实验目标 继续熟悉for循环与turtle 数值运算符 math库常用函数 字符串转化为数值类型(int, float, complex) 字符串常用函数 实验内容 任务1.使用for代替w ...

hdu 1151 Air Raid - 二分匹配

Consider a town where all the streets are one-way and each street leads from one intersection to ano ...

border&background1

1.border-radius border-top-left-radius:10px; = border-top-left-radius:10px 10px; (水平10px 竖直10px 被正圆切 ...