Recently, the number of SFTP connections for online monitoring frequently exceeds the threshold. By restarting a system, the number of connections decreases rapidly, and the system can be restored to normal. The initial conclusion is that the application connection is not closed.
LZ checks through IDE global search, SFTP connection uses JSCH package, there are some function points that use SFTP connection and do not close, or do not close properly in finally block.
After the rectification went online, SFTP is still off the charts……
After the operation and maintenance mentality is broken, operation and maintenance actively wrote a SFTP connection monitoring, when the connection is more than 5 minutes idle will actively disconnect.
But this is only temporary processing, the real reason is certainly not the normal closure of the application, so serious investigation under the program, finally found out the culprit.
Here is the sample code:
Session session = null; ChannelSftp channel = null; try{for(...). {... JSch JSch = new JSch(); jsch.getSession(host, username); session = jsch.getSession(username, host, port); session.setPassword(password); session.connect(); // create SFTP connection channel = session.openChannel("sftp"); channel.connect(); . }} catch(...) {... } finally{if(null ! = channel && channel.isConnected()) { channel.disconnect(); }if(null ! = session && session.isConnected()) { session.disconnect(); }}Copy the code
Does everybody see the problem?
I checked the program twice and solved the problem after three days of troubleshooting.
Write this code, my colleague is really a talent!!
At first glance, the connection does close, and it does close in the finally block. Why is there a problem?
The reason is that the connection is created in the damn for loop, which is closed in finally, but the connection variable is rebuilt and replaced in the loop, so it is always the last connection that is closed.
In addition, it is also a function to download Excel details, when there is a lot of data, a single operation can cause the connection to burst the table.
The solution is definitely to put the connection creation part in front of the for loop, create the connection once, and use it again and again.
In JDK 7+, you can omit the finally statement and use a try(…). It is automatically turned off.
This JSCH connection package is really not good, we look at its source code, otherwise it is a pit you have no discussion pit.
Com. Jcraft. JSCH. The Session:
Com. Jcraft. JSCH. Channel:
These two classes only implement the Runnable interface, not the java.lang.AutoCloseable interface, so it does not comply with the try-with-resources automatic shutdown principle.
At this point, the problem of online SFTP connection has been solved and I can have a good sleep at ease. At the same time, I also feel that our colleagues are too awesome and let me increase my knowledge.
Everyone take warning, also welcome to forward!