zoukankan      html  css  js  c++  java
  • 第四章 连接管理

    需要学习的内容

    1,http是如何使用tcp连接的

    2,tcp连接的时延,瓶颈以及存在的障碍

    3,http的优化,包括并行连接,keep-alive(持久连接) 和 管道化连接

    4,管理连接时应该以及不应该做的事情

    浏览器如何解析url

    1,解析主机名

    2,查询主机名对应的ip地址(DNS)

    3,解析获取端口号

    4,浏览器根据主机和端口发起连接

    5,连接建立后,浏览器向服务端发送一条http get报文

    6,浏览器读取服务端回送的响应报文

    7,浏览器关闭连接

    在1-3步,浏览器或获取到连接路径

    第4步,建立tcp连接

    第五步,通过这个tcp连接发送报文和接收报文

    tcp会建立一个可靠的字节流传输通道,从tcp连接的一端流入,会从听从连接的另一端有序的流出

    http协议栈如下

    tcp流分段,ip分组传输

    http传输报文,会以流的的形式通过一条打开tcp连接按序传输,tcp接收到数据流会将这个流分成小数据块,

    并将这些块封装到ip分组中,通过因特网传输

    IP分组 IP分组首部,tcp段首部,tcp数据块

    ip首部包含有<源ip地址,源端口号,目的ip地址,目的端口号>

    ip分组图示

    tcp套接字编程

    操作系统向上层编码人员提供套接字接口,该接口屏蔽了tcp ip的所有细节

    函数如下

    s = socket(<parameters>);  创建套接字

    bind(s,<local ip:port>)    套接字绑定端口和ip

    connect(s,<remote ip:port>);  套接字连接远程主机端口

    listern(s,...)          套接字监听,接收连接

    s2 = accept(s)          等待连接建立

    n=read(s,buffer,n)        从套接字读取数据到缓冲区

    n=write(s,buffer,n)        将缓冲区数据写入套接字

    close(s)            完全关闭套接字

    shutdown(s,<side>)      关闭套接字的输入端或输出端        

    getsocket(s,...)          获取套接字的配置信息

    setsocket(s,...)          设置套接字的配置信息

    图示tcp通信步骤

    tcp性能

    http事务时延

    串行事务事件线

     时延原因

    1,url解析时延,因为当客户首次解析url需要通过DNS解析系统来解析url的主机地址 

    2,tcp建立连接时延

    3,报文发送时延

    4,报文处理时延

    5,报文回送时延

    tcp的一些时延

    tcp连接握手: tcp建立连接三次握手,客户端请求连接,服务端验证连接回送验证消息,客户端确认验证消息

    tcp慢启动拥塞控制: tcp在连接建立时,发送速度会比较慢,在发送数据和会慢慢变快,

              这样可以防止网络拥塞和过载,(tcp 会首先发送一个分组,然后发送两个分组,在发送4个分组,以此类推)。

              所以新建立的连接比已发送过数据的连接要慢

    数据聚集Nagle算法: (每个tcp分组会包含至少40个字节的标记和首部),所以如果将很多包含少量数据的分组,nagle算法会将这些数据捆绑在一起发送,可以使用TCP_NODELAY来配置禁用nagle算法,但需要确保会向tcp写入大块数据

    tcp数据验证时延:每个tcp段都有一个序列号和数据完整性校验和,每个段在接收后都会回送确认分组,

              如果发送方没有在规定时间内收到确认信息,则认为数据坏了,重发数据

    TIME_WAIT时延和端口耗尽:time_wait时延导致端口耗尽,某个连接关闭tcp连接时,会将这个连接信息保存在内存中一段时间,这个时间在过去一般为2分钟,现在回很小大概在几秒钟,但在这个保存的时间内,是不会创建具有相同的地址和端口号的新连接。但是在客户端连接服务端的过程中虽然目的主机和端口不变,但是源端口是会变,这样如果请求频繁,就会不断的消耗端口地址,比如时延为2s,连接数为60000多个,这样在每秒的的请求连接数不能超过30000个,不然会造成端口资源耗尽。

    http连接处理:

    connection首部:该首部可以承载几种类型的标签,http首部字段,任意标签,其他属性

    http接收到一条connection首部报文,会解析这些选项。(没太弄懂,以后弄懂了再修改)

    串行时延

    浏览器访问某个web页面,可能会向同一服务端请求多个资源,这样就会造成多个连接时延和慢启动时延叠加。并且浏览器也会有处理的延迟(提前设置布局,可以加快速度)(多个相同连接目的的连接,消除了解析url时查询dns的时间)

    为了应对这种情况可以有如下几种处理

    1,并行连接:多条tcp连接发起并发的http请求

    2,持久连接:重用tcp连接,消除创建连接和启动延时

    3,管道化连接:通过共享tcp连接发起并发http请求

    4,复用连接:交替传送请求和响应报文

    并行连接:虽然并行连接可以加快获取资源的速度,但是在有些情况下并不如意,比如带宽不足。

          这种情况实际上并不能提高速度。反而会增加服务端的负载,并不提倡。

    持久连接:持久连接可以避免并行连接创建过多的连接,避免了在新建连接和慢启动造成的时延,但该链接也可能会造成大量的空闲连接,耗费资源

    keep-alive首部(http1.1前大量使用):参数timeout:响应报文首部,服务器希望保持的活跃时间,max:服务器还能处理多少个事务,其他任意参数

    报文样式

    connection:keep-alive

    keep-alive:max=5,timeout=120

    处理限制:

    1,http1.0非默认,http1.1默认 keep-alive置于connection字段,才会处理

    2,客户端可以通过connection这个字段判断连接是否已关闭

    3,只有报文主体长度确定在content-lenght中一致,连接保证打开,否则会导致糟糕情况(不知道报文结束)

    4,代理和网关必须执行connection首部规则,即在将报文转发出去之前,删除在connection中已存在的首部字段和connection自身

    5,不应该和代理服务器建立keep-alive连接,防止哑代理出现。但实际应用做不到

    6,一般不使用这个字段,客户端获取到报文便断开

    keep-alive和哑代理

    客户端和服务端对话,请求报文首部connection:keep-alive来保持长连接,服务端返回这条信息,表示支持,否则不支持

    代理:在有些不支持处理connection字段的代理上,如果有keep-alive会发生一些糟糕情况

    就是客户端发送一个connection:keep-alive,而代理将这些数据一字不漏的传给了服务端,服务端

    认为这个连接为长连接,会保持这个连接,于是回送connection:keep-alive,代理将这个数据回送

    客户端,客户端便认为长连接建立。但问题是,代理不认为这个是长连接,于是便将该连接挂起。

    于是客户端再次发送数据是到不了服务端的。所以现在的代理服务器,都不会将connection中的首部字段

    原样发送给服务端的。都会删除掉

    proxy-connection:作用既是,在单个代理的情况下,让聪明的代理支持connection字段,让不聪明的代理不支持connection字段

    http1.1默认所有连接都是持久的,要实现非持久的可以在connection用close代理keep-alive

    持久连接限制:

    1,发送connection:close 之后,不能再在这个连接上发送信息了

    2,如果客户端不想保持长连接了,就必须在最后一次请求发送设置connection:close

    3,只有报文字段都正确的前提下才能保持长连接,如content-lenght长度和主体长度一致

    4,http1.1的代理必须能够分别管理客户端和服务端的持久连接,持久连接只适用于一跳

    5,代理服务器http1.1不应该和http1.0的客户端保持长连接

    6,http1.1的客户端可以任意时刻关闭连接

    7,http1.1能够从异常关闭中回复。只要没有副作用,客户端需重试这一连接

    8,除非重复请求有副作用,否则客户端收到响应之前关闭连接,客户端必须重新发起请求

    9,一个客户端某个服务端只能维持两个持久连接,防止服务端过载

    管道连接:

    就是在持久连接中,将许多请求队列放入管道中,当第一条请求发送到服务端后,其他请求开始发送,可以节省网络回环时间

    但也有相纸

    1,必须持久连接才能使用管道

    2,回送消息必须有序,按照接收的请求消息顺序发送

    3,客户端必须在连接关闭时的异常处理,比如发送完5条,连接关闭,客户端必须重新发送请求

    4,客户端不发送有风险的请求,比如post防止幂等情况出现(因为客户端不清楚哪些请求被服务端处理了)

    连接关闭:

    在持久连接中,可能在半路就把连接关闭了,导致报文没有发送,或发送一部分

    正确设置content-lenght长度。不重试幂等处理

    使用半关闭代替完全关闭

      

  • 相关阅读:
    Idea导出jar包运行报错:找不到主清单属性解决方法
    Java开发桌面程序学习(一)——JavaFx+Jfoenix初始以及搭建
    JavaFx出现错误Caused by: java.lang.NullPointerException: Location is required的解决方法
    IDEA maven设置配置
    oracle学习笔记(十九) 子程序——存储过程
    ASP.NET Core 指定环境发布(hosting environment)
    解决Visual Studio 2017隐藏“高级保存选项”命令
    【亲测可用,亦可配置同一平台的不同账号,例如阿里云的两个不同账号】Windows下Git多账号配置,同一电脑多个ssh-key的管理
    Xshell5 评估过期,需要采购,不能使用
    linux上mongodb的安装与卸载
  • 原文地址:https://www.cnblogs.com/feicheng/p/6641345.html
Copyright © 2011-2022 走看看