概述
套接字是通信端点的抽象。正如使用文件描述符访问文件,应用程序用套接字描述符访问套接字。套接字描述符在UNIX系统中被当作是一种文件描述符。事实上,许多处理文件描述符的函数(read和write)可以用于处理套接字描述符。 ——《unix环境高级编程》
WEB应用客户端(浏览器或APP等)与服务端的通信大多数是通过HTTP或HTTPS协议进行的。而套接字(Socket)应该算是OSI七层网络模型中应用层与传输层直接的抽象层,它是面向应用层的一个编程接口。而HTTP/HTTPS则位于应用层,就是通过套接字(Socket)进行信息通信的。所以,WEB应用的每个HTTP链接都与套接字(Socket)息息相关,特别是并发量大的应用,套接字(Socket)的使用至关重要。毕竟,它是应用出入的一个“口”。处理不当,则成为应用系统瓶颈。
套接字(Socket)的瓶颈,大多数情况,还是套接字描述符的一个瓶颈(文件打开数过多)。正如开头所说:套接字是通信端点的抽象,应用对互联网的通讯就是通过对这个抽象进行读写,就像读写普通文件一样。在unix操作系统中,读写文件,就需要系统分配文件标识:文件描述符。套接字(Socket)也不例外。
Talk is cheap,show code:
我在本地(window)用Java写了Socket服务端代码,并启动服务:
public class SocketServer{ public static void main(String[] args) { try{ ServerSocket server=null; server = new ServerSocket(8000); Socket socket=null; while(true){ socket=server.accept(); BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); PrintWriter pw = new PrintWriter(socket.getOutputStream()); System.out.println(br.readLine()); pw.println("ok"); pw.flush(); pw.close(); br.close(); } }catch(Exception e){e.printStackTrace();} } }
另外也用Java写了一个Socket的客户端,用打包成jar放到测试机(SUSE Linux)下进行测试,并观察其对套接字描述符的一个消耗情况:
public class SocketClient{ public static void main(String[] args) throws Exception { Socket socket=new Socket("192.168.22.15",8000); Socket socket2=new Socket("192.168.22.15",8000); BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream())); BufferedReader br2=new BufferedReader(new InputStreamReader(socket2.getInputStream())); PrintWriter pw = new PrintWriter(socket.getOutputStream()); PrintWriter pw2 = new PrintWriter(socket2.getOutputStream()); pw.println("hello"); pw2.println("hello2"); pw.flush(); pw2.flush(); System.out.println(br.readLine()); System.out.println(br2.readLine()); Thread.sleep(20000); br.close(); br2.close(); pw.close(); pw2.close(); socket.close(); socket2.close(); System.out.println("socket close"); Thread.sleep(20000); System.out.println("function close"); } }
以上代码运行期间,我会通过lsof -p <SocketClient进程号>|wc –l命令观察此SocketClient进程消耗的文件描述符数量。
启动SocketClient.jar20秒前(OK):
结果:101
启动SocketClient.jar20秒到40秒之间(socket close):
结果:99
启动SocketClient.jar40秒后(function close):
结果:0
启动SocketClient.jar20秒前lsof -p <SocketClient进程号>详情:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
java 5920 root cwd DIR 8,3 4096 486764 /usr/local/test
java 5920 root rtd DIR 8,3 4096 2 /
java 5920 root txt REG 8,3 59141 878312 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/bin/java
java 5920 root mem REG 8,3 116348 878486 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/amd64/libnet.so
java 5920 root mem REG 8,3 88544 90416 /lib64/libgcc_s.so.1
java 5920 root mem REG 8,3 84914 878492 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/amd64/libzip.so
java 5920 root mem REG 8,3 9975 878465 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/amd64/libdbgwrapper.so
java 5920 root mem REG 8,3 108248 90308 /lib64/libnsl-2.11.3.so
java 5920 root mem REG 8,3 224723 878477 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/amd64/libjava.so
java 5920 root mem REG 8,3 140261 878396 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/amd64/compressedrefs/libj9ute24.so
java 5920 root DEL REG 8,3 2183413 /var/run/nscd/dbZxaX8m
java 5920 root mem REG 8,3 90320 878429 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/amd64/default/libiverel24.so
java 5920 root mem REG 8,3 629488 878451 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/amd64/default/libjclscar_24.so
java 5920 root mem REG 8,3 225264 878449 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/amd64/default/libj9vrb24.so
java 5920 root mem REG 8,3 316148 878441 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/amd64/default/libj9jvmti24.so
java 5920 root mem REG 8,3 187277 878433 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/amd64/default/libj9dyn24.so
java 5920 root mem REG 8,3 841499 878434 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/amd64/default/libj9gc24.so
java 5920 root mem REG 8,3 109715 878430 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/amd64/default/libj9bcv24.so
java 5920 root mem REG 8,3 6235544 878438 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/amd64/default/libj9jit24.so
java 5920 root mem REG 8,3 93053 878446 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/amd64/default/libj9trc24.so
java 5920 root mem REG 8,3 74373 878399 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/amd64/compressedrefs/libj9zlib24.so
java 5920 root mem REG 8,3 205374 878432 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/amd64/default/libj9dmp24.so
java 5920 root mem REG 8,3 35728 436315 /usr/lib64/libnuma.so.1
java 5920 root mem REG 8,3 15691 878377 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/amd64/compressedrefs/libhythr.so
java 5920 root mem REG 8,3 46239 878376 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/amd64/compressedrefs/libhyprtshim24.so
java 5920 root mem REG 8,3 6957 878403 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/amd64/compressedrefs/libvmi.so
java 5920 root mem REG 8,3 47241 90327 /lib64/librt-2.11.3.so
java 5920 root mem REG 8,3 259675 878391 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/amd64/compressedrefs/libj9prt24.so
java 5920 root mem REG 8,3 22489 878385 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/amd64/compressedrefs/libj9hookable24.so
java 5920 root mem REG 8,3 70975 878394 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/amd64/compressedrefs/libj9thr24.so
java 5920 root mem REG 8,3 712429 878448 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/amd64/default/libj9vm24.so
java 5920 root mem REG 8,3 164469 878453 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/amd64/default/libjvm.so
java 5920 root mem REG 8,3 86110 878311 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/bin/j9vm/libjvm.so
java 5920 root mem REG 8,3 541821 90305 /lib64/libm-2.11.3.so
java 5920 root mem REG 8,3 1754140 90297 /lib64/libc-2.11.3.so
java 5920 root mem REG 8,3 19149 90303 /lib64/libdl-2.11.3.so
java 5920 root mem REG 8,3 42772 878460 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/amd64/jli/libjli.so
java 5920 root mem REG 8,3 135690 90323 /lib64/libpthread-2.11.3.so
java 5920 root mem REG 8,3 151051 90290 /lib64/ld-2.11.3.so
java 5920 root mem REG 8,3 217016 2906402 /var/run/nscd/passwd
java 5920 root mem REG 8,3 26050 576479 /usr/lib64/gconv/gconv-modules.cache
java 5920 root mem REG 8,3 257156 576144 /usr/lib/locale/zh_CN.utf8/LC_CTYPE
java 5920 root mem REG 8,3 14684 878401 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/amd64/compressedrefs/libjsig.so
java 5920 root 0u CHR 136,0 0t0 3 /dev/pts/0
java 5920 root 1u CHR 136,0 0t0 3 /dev/pts/0
java 5920 root 2u CHR 136,0 0t0 3 /dev/pts/0
java 5920 root 3r REG 8,3 416697 878426 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/amd64/default/jclSC160/vm.jar
java 5920 root 4r REG 8,3 10160 878493 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/annotation.jar
java 5920 root 5r REG 8,3 189574 878494 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/beans.jar
java 5920 root 6r REG 8,3 435869 878550 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/java.util.jar
java 5920 root 7r REG 8,3 216671 878556 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/jndi.jar
java 5920 root 8r REG 8,3 54586 878558 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/logging.jar
java 5920 root 9r REG 8,3 287085 878567 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/security.jar
java 5920 root 10r REG 8,3 128157 878569 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/sql.jar
java 5920 root 11r REG 8,3 1198418 878542 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/ibmorb.jar
java 5920 root 12r REG 8,3 426065 878543 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/ibmorbapi.jar
java 5920 root 13r REG 8,3 536255 878536 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/ibmcfw.jar
java 5920 root 14r REG 8,3 20511988 878566 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/rt.jar
java 5920 root 15r REG 8,3 9601775 878496 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/charsets.jar
java 5920 root 16r REG 8,3 501898 878565 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/resources.jar
java 5920 root 17r REG 8,3 1161371 878544 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/ibmpkcs.jar
java 5920 root 18r REG 8,3 133770 878534 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/ibmcertpathfw.jar
java 5920 root 19r REG 8,3 27626 878538 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/ibmjgssfw.jar
java 5920 root 20r REG 8,3 60208 878540 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/ibmjssefw.jar
java 5920 root 21r REG 8,3 10966 878545 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/ibmsaslfw.jar
java 5920 root 22r REG 8,3 97697 878537 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/ibmjcefw.jar
java 5920 root 23r REG 8,3 932373 878539 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/ibmjgssprovider.jar
java 5920 root 24r REG 8,3 442208 878541 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/ibmjsseprovider2.jar
java 5920 root 25r REG 8,3 357168 878535 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/ibmcertpathprovider.jar
java 5920 root 26r REG 8,3 152611 878546 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/ibmxmlcrypto.jar
java 5920 root 27r REG 8,3 375 878560 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/management-agent.jar
java 5920 root 28r REG 8,3 8915002 878575 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/xml.jar
java 5920 root 29r REG 8,3 91126 878555 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/jlm.jar
java 5920 root 30r REG 8,3 363834 878551 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/javascript.jar
java 5920 root 31r REG 8,3 240130 886599 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/ext/ibmjcefips.jar
java 5920 root 32r REG 8,3 1273 486857 /usr/local/test/socketClient.jar
java 5920 root 33r REG 8,3 554639 886594 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/ext/dtfj.jar
java 5920 root 34r REG 8,3 153450 886604 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/ext/ibmxmlencprovider.jar
java 5920 root 35r REG 8,3 277912 886606 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/ext/jdmpview.jar
java 5920 root 36r REG 8,3 481038 886589 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/ext/IBMKeyManagementServer.jar
java 5920 root 37r REG 8,3 232590 886601 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/ext/ibmkeycert.jar
java 5920 root 38r REG 8,3 183719 886588 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/ext/CmpCrmf.jar
java 5920 root 39r REG 8,3 206636 886598 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/ext/ibmcmsprovider.jar
java 5920 root 40r REG 8,3 17081 886593 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/ext/dtfj-interface.jar
java 5920 root 41r REG 8,3 50129 886605 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/ext/jaccess.jar
java 5920 root 42r REG 8,3 20228 886590 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/ext/IBMSecureRandom.jar
java 5920 root 43r REG 8,3 23831 886608 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/ext/xmlencfw.jar
java 5920 root 44r REG 8,3 353513 886602 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/ext/ibmpkcs11impl.jar
java 5920 root 45r REG 8,3 1202552 886596 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/ext/gskikm.jar
java 5920 root 46r REG 8,3 148480 886595 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/ext/dtfjview.jar
java 5920 root 47r REG 8,3 8230 886592 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/ext/dnsns.jar
java 5920 root 48r REG 8,3 112283 886597 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/ext/healthcenter.jar
java 5920 root 49r REG 8,3 67395 886603 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/ext/ibmsaslprovider.jar
java 5920 root 50r REG 8,3 992455 886600 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/ext/ibmjceprovider.jar
java 5920 root 51r REG 8,3 67801 886591 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/ext/JavaDiagnosticsCollector.jar
java 5920 root 52r REG 8,3 468772 886607 /usr/lib64/jvm/java-1_6_0-ibm-1.6.0/jre/lib/ext/localedata.jar
java 5920 root 53r REG 8,3 1273 486857 /usr/local/test/socketClient.jar
java 5920 root 54u IPv6 1565663 0t0 TCP node1:48707->192.168.22.15:irdmi (CLOSE_WAIT)
java 5920 root 55u sock 0,7 0t0 1565661 can't identify protocol
java 5920 root 56u IPv6 1571368 0t0 TCP node1:48708->192.168.22.15:irdmi (CLOSE_WAIT)
node为TCP的就是两个SocketClient产生的套接字描述符的消耗,其它的99文件描述符,是跟套接字功能相关的文件打开。当Socket关闭的时候,node为TCP的套接字描述符就会别系统回收。所以,如果万一使用套接字的时候忘记关闭套接字(Scoket),不但消耗内存,更容易把系统对用户的最大文件打开数所消耗完,就会影响应用的正常运行。
转载于:https://www.cnblogs.com/wcd144140/p/4511135.html
最后
以上就是懵懂网络为你收集整理的套接字文件描述符消耗小细节分析的全部内容,希望文章能够帮你解决套接字文件描述符消耗小细节分析所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复