原创

彻底解决SocketException打开的文件过多

错误日志
Caused by: java.net.SocketException: 打开的文件过多
  at java.net.Socket.createImpl(Socket.java:460)
  at java.net.Socket.connect(Socket.java:587)
  at java.net.Socket.connect(Socket.java:538)
  at sun.net.NetworkClient.doConnect(NetworkClient.java:180)
  at sun.net.www.http.HttpClient.openServer(HttpClient.java:463)
  at sun.net.www.http.HttpClient.openServer(HttpClient.java:558)
  at sun.net.www.http.HttpClient.<init>(HttpClient.java:242)
  at sun.net.www.http.HttpClient.New(HttpClient.java:339)
  at sun.net.www.http.HttpClient.New(HttpClient.java:357)
  at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:1220)
  at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1156)
  at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1050)
  at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:984)
  at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(HttpURLConnection.java:1334)
  at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1309)
  at cn.hutool.http.HttpConnection.getOutputStream(HttpConnection.java:458)
  at cn.hutool.http.HttpRequest.sendFormUrlEncoded(HttpRequest.java:1368)
  at cn.hutool.http.HttpRequest.send(HttpRequest.java:1343)
  ... 79 common frames omitted"
查询服务器每个进程允许打开的文件个数
# ulimit -n
1024
查询进程已打开的文件个数
# lsof -p 28904 |wc -l
4134
查询进程已打开的文件列表
# lsof -p 28904 
COMMAND   PID    USER   FD      TYPE             DEVICE  SIZE/OFF       NODE NAME
java    28904 test  cwd       DIR              253,0       170   67520991 /home/test/finance
java    28904 test  rtd       DIR              253,0       261         64 /
java    28904 test  txt       REG              253,0      8712  102170955 /usr/java/jdk1.8.0_261-amd64/bin/java
java    28904 test  mem       REG              253,0    204456     268044 /usr/java/jdk1.8.0_261-amd64/jre/lib/amd64/libdcpr.so
java    28904 test 4069r      REG              253,0     41250  102725188 /home/test/202805_119.pdf (deleted)
java    28904 test 4070r      REG              253,0     41250  102725192 /home/test/202805_143.pdf (deleted)
java    28904 test 4071r      REG              253,0     41250  102725192 /home/test/202805_143.pdf (deleted)
java    28904 test 4072r      REG              253,0     41250  102725192 /home/test/202805_143.pdf (deleted)
java    28904 test 4073r      REG              253,0     41250  102725192 /home/test/202805_143.pdf (deleted)
java    28904 test 4074r      REG              253,0     41250  102725193 /home/test/202805_169.pdf
java    28904 test 4075r      REG              253,0     41250  102725193 /home/test/202805_169.pdf
查询进程已打开的文件信息
# ll /proc/28904/fd
总用量 0
lr-x------. 1 test test 64 7月   9 19:47 0 -> /dev/null
lrwx------. 1 test test 64 7月   9 19:47 1 -> socket:[1554335923]
lr-x------. 1 test test 64 7月   9 19:47 10 -> /dev/urandom
lr-x------. 1 test test 64 7月   9 19:59 100 -> /home/test/195926_875.pdf (deleted)
lr-x------. 1 test test 64 7月   9 20:12 1000 -> /home/test/201225_556.pdf (deleted)
lr-x------. 1 test test 64 7月   9 20:12 1001 -> /home/test/201225_556.pdf (deleted)
问题原因

PDDocument没有释放导致的问题,pdf文件虽然已经删除,但是PDDocument没有释放,依然关联着pdf文件,导致打开的文件过多
解决办法:
使用try-with-resources释放PDDocument对象

    public static String readPdfText(File pdf) {
         try (PDDocument document = Loader.loadPDF(pdf)) {
            PDFTextStripper stripper = new PDFTextStripper();
            String text = stripper.getText(document);
            return text;
        } catch (IOException e) {
            log.error("readPdfText file error: ", e);
        }
        return null;
    }
正文到此结束