zoukankan      html  css  js  c++  java
  • Tomcat长连接是如何实现的

      浏览器在向服务器发送请求时,有的会带上Connection:keep-alive参数,如下图所示:

    http1.1开始支持长连接。请求的头部会带上keep-alive参数。长连接的作用是减少断开连接和重新连接的开销,提高网络请求效率。http只是1个协议规范,具体的实现请见下文。

    TCP是由操作系统实现的。而socket是由JVM封装的。所以java可以使用socket相关的api进行网络请求操作。下面给出测试代码:

    erverSocket serverSocket  = new ServerSocket(8080, 1,  InetAddress.getByName(“localhost”));  
    Socket socket = null;  
    InputStream is = null;  
    OutputStream os = null;  
    try {  
        socket = serverSocket.accept();//1.监听到客户端的连接  
        is = socket.getInputStream();  
        os = socket.getOutputStream();  
        Request request = Util.getRequest(is);//2.从输入流中读取数据,并根据Http协议转换成请求  
        Response response = Util.service(request);//服务器内部根据请求信息给出响应信息  
        os.writeResponse(response);//3.将响应信息写到输出流  
    } catch (Exception e) {  
        e.printStackTrace();  
    } finally {//4.关闭输入输出流及连接  
        if (is != null) {  
            is.close();  
        }  
        if (os != null) {  
            os.close();  
        }  
        socket.close();  
    }  

    后面的内容参考:https://www.jianshu.com/p/09e2f32a74dd  By飞行员舒克_ed03

    按图索骥研究tomcat

    linux下tomcat的启动我们只要运行startup.sh
    我们研究下这个文件,其中的内容如下,运行startup.sh的实际结果是运行catalina.sh还带了参数start

    #
    EXECUTABLE=catalina.sh
    #
    exec "$PRGDIR"/"$EXECUTABLE" start "$@"
    接着我们看下catalina.sh,可以看到我们运行的java的入口类是org.apache.catalina.startup.Bootstrap,接着我们找Bootstrap源码的main函数,main函数启动项目,开启端口,处于等待状态。main还解析了tomcat的server.xml文件,进行初始化。tomcat的处理http协议的类是Http11Processor。这个类有个service方法。
    方法中有个while循环,还有个keepAlive参数。其中有一段对keepalive的赋值改变
    if (maxKeepAliveRequests == 1) {
        keepAlive = false;
     } else if (maxKeepAliveRequests > 0 && socketWrapper.decrementKeepAlive() <= 0) {
        keepAlive = false;
    }

    这里的maxKeepAliveRequests 就是server配置文件里的

    web.xml
     <Connector port="8080" protocol="HTTP/1.1"
                   connectionTimeout="20000"
                   redirectPort="8443"
                  maxKeepAliveRequests = 10000 />

    这个参数的意思是最多经过多少个请求之后将Connection有keep-alive改为close的。
    当keepAlive设为false以后,会退出循环并返回SocketState.CLOSED给调用者。调用者收到这个状态后会关闭socket。结束连接,tcp会进行4次挥手结束会话。

    假设keepAlive一开始就未设置,那么就不会进入循环,直接返回调用者SocketState.CLOSED。
    如果keepAlive还没到最大值,会一直在while的循环中,持续处理socket中的内容,直到keepAlive失效,或者连接中断。

    了解了原理之后,我们来看看我们的问题。keepAlive开启会一直占用一个连接,直到socket关闭。tomcat有最大连接数参数是maxConnections,这个值表示最多可以有多少个socket连接到tomcat上。BIO模式下默认最大连接数是它的最大线程数(缺省是200),NIO模式下默认是10000,APR模式则是8192(windows上则是低于或等于maxConnections的1024的倍数)。如果设置为-1则表示不限制。当请求过多时,新的请求不会被接受,老的请求受网络io的影响。但老的请求的会话被关闭的可能性还比较小。所以在抢票之类的程序中,先登入服务所在的tomcat还是有优势的。从另一个方面来说关闭keepalive的功能对抢票人来说较公平。



  • 相关阅读:
    Python运行时遇到UnicodeDecodeError: 'ascii' codec can't decode byte 0xb0 in position 1: ordinal not in range(128)的问题
    Android 网络通信架构学习
    将Windows MyEclipse的web项目移植到Debian下
    build-essential : Depends: libc6-dev but it is not going to be installed or libc-dev 解决办法
    Debian可用的源 —— 23% waiting for headers解决办法
    将访问服务器的工作交由Service承担
    Servlet回传的数据显示在界面上
    Android客户端和Servlet服务器端通过JSON交互
    Welcome to My Blog!
    【三木夜话】无穷级的恐惧
  • 原文地址:https://www.cnblogs.com/yibao/p/14118731.html
Copyright © 2011-2022 走看看