前端日拱一卒D4——网络基础与HTTP

前言

余为前端菜鸟,感姿式水平匮乏,难观前端之大局。遂决定循前端知识之脉络,以兴趣为引,辅以几分坚持,望于己能解惑致知、于同道能助力一二,岂不美哉。css

本系列代码及文档均在 此处html

网络层级

20170516149490559398728.png

  • 实体层(物理层):链接计算机(光纤、电缆线、无线电波、双绞线等)。前端

  • 连接层(数据链路层):肯定0 1的分组形式。nginx

    • 以太网协议git

      一组电信号组成一帧,一帧分为head和data两部分,head中包含接收方MAC地址信息,以广播的方式向本网络内全部计算机发送数据包,由接收方本身比对MAC地址判断是否接收。github

  • 网络层:主机到主机的通讯。web

    • 互联网由许多子网络组成,在同一子网中能够经过MAC地址以广播形式找到目标,可是不一样子网广播不过去,因此须要在网络层引入新的地址用于查找子网络,即网址。算法

    • IP协议chrome

      IPV4规定网络地址由32个二进制位组成,以IP地址与子网掩码相加是否相等判断是否位于同一个子网络。IP数据包放入到以太网数据包的data部分,IP数据包一样包含head和data两部分。浏览器

    • ARP协议

      经过IP地址获取MAC地址(不在同一子网交由网关处理),在同一个子网络中广播发出数据包包含目标IP地址,MAC地址为FF:FF:FF:FF:FF:FF目标主机接收到后比对成功后报告本身的MAC地址,因而获取到了MAC地址,能够把数据包发送到子网络里任一主机。

  • 传输层:端口到端口的通讯。(端口为每一个使用网卡的程序的编号)

    • UDP协议

      数据包放入到IP数据包的data中,一样由head和data组成,head主要定义发出端口和接收端口,data为具体内容。

    • TCP协议

      有确认机制的UDP,每一个数据包须要确认,过程复杂,消耗更多的资源。

  • 应用层:规定应用程序的数据格式。(DHCP,DNS,HTTP,FTP,SSH等)

20170516149490921439572.png

用户角度

  • 网络通讯是主机间数据包交换,要交换数据须要知道双方的MAC地址和IP地址。

  • 用户能够经过静态IP和动态IP两种方式实现网络通讯配置。

    • 设置本机静态IP、子网掩码从而肯定本机所处子网络,设置网关用于跨子网通讯,设置DNS服务器地址用于DNS解析。
    • 利用DHCP协议,以广播形式向DHCP服务器获取动态的IP地址。
  • 实例:访问页面。

    • 浏览器中输入URL,从本地(浏览器->OS)DNS缓存中获取目标服务器IP地址,本地没有则向DNS服务器请求,获取到IP地址后缓存到本地。
    • 判断是否为同一子网络,是则数据包应包含本机和目标主机的MAC、IP地址,不然目标主机的MAC地址应改成网关MAC地址。
    • 组装数据包,如上图。
    • 创建TCP链接,经历三次握手后在第三次将数据包发送到目标服务器,服务器取出完整的TCP数据包后作处理,定位资源,将资源复本写到TCP套接字作出HTTP响应,而后借由TCP协议再发送回来到客户端。
    • 客户端收到响应,进行页面处理、展现。

HTTP

基础

应用层协议,无状态。

  • 请求/响应模型

    客户端向服务端发送请求,服务端根据接收到的请求,处理后向客户端返回响应信息。

  • url

    协议类型:[//[访问资源须要的凭证信息@]服务器地址[:端口号]][/资源层级UNIX文件路径]文件名[?查询][#片断ID]

    用于定位资源,输入url->客户端展现的过程再也不赘述

  • 请求/响应结构

    • 请求:请求行、请求头、请求正文(只有POST有)
    • 响应:状态行、响应头、响应正文
    • 头域:重点关注缓存相关,这里不赘述

    get和post区别在于前者参数在url后,后者在请求正文;前者有大小限制,后者无,后者有请求体,前者无

    关于状态码,通常来讲简单记忆以下:1XX 可续发 2XX 成功 3XX 重定向 4XX 客户端错误 5XX 服务端错误

HTTP1.1

  • 长链接

    // 请求头、响应头中包含
    Connection: keep-alive
    复制代码

    1.1默认开启长链接,使得链接在一段时间内维持开启,后续请求可复用,减小创建链接的成本

  • 协议升级

    // 请求头中包含
    Connection: Upgrade
    Upgrade: websocket
    复制代码

    升级为websocket协议,后续会谈到

  • 缓存控制

    cache-rule

    • 1.0的expires -> 1.1的cache-control

      后者是相对时间,二者都存在时,之后者为判断过时依据(浏览器判断)

    • Etag与Last-Modified

      若是上次返回头中有Etag,则带上if-none-match信息请求到服务端,服务端进行判断Etag是否修改,选择304/200

      若是上次返回头中有Last-Modified,则带上if-modified-since信息请求道服务端,服务端判断是否失效,返回304/200

  • 痛点

    • 明文传输,不安全
    • header过大,且不少时候header变化不大,资源浪费
    • keep-alive给服务端带来性能问题
  • 需优化点

    • 带宽
      • pay more
    • 延迟
      • DNS解析:解决:预解析与缓存。
      • 创建链接消耗:基于TCP,每次创建链接都须要经历三次握手,最快也要在第三次才能将报文发送到服务端。解决:keep-alive/HTTP2
      • 浏览器阻塞:因为浏览器单域名下最大链接限制(6个),达到限制后会致使后续请求阻塞,解决:将域名分区,提升并行资源下载能力;合并资源,减小请求个数。

HTTPS

图解

HTTPS运行在SSL/TLS上,SSL/TLS运行在TCP上,全部传输内容都是须要加密的,能够有效防劫持

握手阶段:

  • 客户端给出协议版本、客户端生成的随机数、支持的加密方法
  • 服务端收到后确认加密方法,返回数字证书,以及一个服务端生成的随机数
  • 客户端确认证书有效,生成一个随机数,用证书汇总的公钥加密随机数,发送给服务端
  • 服务端使用私钥得到客户端发送的随机数
  • 根据约定的加密算法,使用前面的三个随机数生成会话密钥,用来加密后续整个会话过程

加密解密

  • 公钥和私钥只用于加密/解密 对话密钥(非对称)
  • 安全与否取决于三个随机数中的第三个可否被破解

对称加密/非对称加密

  • 使用一对密钥,公钥用来加密,私钥不公开,用于解密,慢,可是更安全 ----> 非对称加密
  • 密钥在网络中传输,快可是不安全 ----> 对称加密
  • 解决:用非对称加密的公钥加密对称加密的密钥,接收方用私钥解密获得对称密钥,用于加密信息(减小复杂度,下降服务器压力)

升级至HTTPS

  • github免费的github pages用来搭建我的博客很是方便,感兴趣的能够参考这里

    在项目设置下选择开启HTTPS便可

    小绿锁很醒目

  • 我的站点升级HTTPS

    • 从域名服务商获取免费的SSL证书

      按照流程填写

    • 下载证书到服务器(个人是一年免费的谷歌gce)

    • 修改nginx配置

      server {
          listen 80;
          server_name pandora.derekz.cn;
          # 重定向到https
          rewrite ^(.*)$  https://$host$1 permanent;
      
          location / {
              root html;
              index index.html index.htm;
          }
      }
      server {
          # 顺便换http2吧
          listen 443 ssl http2;
          server_name pandora.derekz.cn;
          root html;
          index index.html index.htm;
      
          # 你的证书路径
          ssl_certificate   /etc/nginx/cert/xxxxxxx.pem;
          ssl_certificate_key  /etc/nginx/cert/xxxxxxx.key;
      
          ssl_session_timeout 5m;
          ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
          ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
          ssl_prefer_server_ciphers on;
      }
      复制代码
    • 重启nginx,稍稍等待访问我的网站

HTTP2

SPDY

SPDY与HTTP2区别在于前者强制使用SSL传输协议,以及二者在首部算法上有所区别,SPDY出现于HTTP2前,特色与HTTP2相似:多路复用、服务器推送、头部压缩等。这里暂不讨论。

核心——二进制分帧

  • HTTP2采用彻底二进制的格式传输数据。二进制数据在网络中传输单位通常为帧
  • 一个帧包含有:类型Type、长度Length、标记Flag、流标识Stream和Frame payload(帧有效载荷)
  • 多个帧造成帧的传输网络流,能够认为HTTP2是流式传输。

  • 不改变HTTP的语义,方法、首部、动词都不受影响
  • 在应用层(HTTP2.0)和传输层(TCP)之间多了一个二进制分帧层
  • 将请求的内容分割为帧,头部信息放入headers帧,body放入data帧
  • HTTP2.0全部的通讯都在一个链接上完成,每一个数据流以消息形式发送,一个消息包含一个或多个帧,能够乱序,到达目的地后根据帧首部的流标识符重组

首部压缩

  • 客户端和服务器端使用“首部表”来跟踪和存储以前发送的键-值对
  • 若是首部不发生变化,那么首部0开销,此时首部自动使用以前请求的首部
  • 若是发生变化,只须要将变化的部分填入首部,同时更新两端维护的首部表便可
  • 因而,并不会有分帧后多加了不少首部帧带来的性能问题,反而提高了性能
  • 合并资源减小请求并不适用与HTTP2,由于都在一个链接上

双向并行

不须要域名分区,由于不限制,并且能够双向并行多个请求/响应

HTTP2的多路复用与1.x的keep-alive本质上有区别,一个位于传输层,一个位于应用层,且后者是串行的,前者容许多个文件传输帧在图个TCP链接中同时流式传输

服务端推送

location / {
  root   /usr/share/nginx/html;
  index  index.html index.htm;
  http2_push /style.css;
  http2_push /example.png;
}
复制代码

http2_push字段,只请求了/index.html 却返回了style.css等额外数据。待研究

迁移HTTP2

细心的小伙伴也许发现了上面的nginx conf文件内有这么一行

listen 443 ssl http2;
复制代码

从HTTPS迁移到HTTP2很是简单,只须要修改nginx配置便可,最后打开chrome能够看到http2的链接状况

思考

咱们说一个网页的性能多好,最直接的一个表现是从enter敲下到页面展现花的时间多短,也就是咱们追求的低延迟高带宽。带宽随着网络基础建设不断提升,因此性能瓶颈主要在于低延迟的难实现。

想一想看,咱们又要DNS解析,又要创建链接,还要加密解密,历经千难万险才能把请求信息送到服务器上。完了之后那一头的人还得礼尚往来,这之间每一个步骤都是咱们实现低延迟的障碍,也是咱们优化的方向。

好比DNS预解析、HTTP2的多路复用使用一条链接、头部压缩、对称加密+非对称加密、缓存策略等等。理解这样一个过程之后,要怎么作就得实际动手处理问题中积累经验啦。

虽发表于此,却毕竟为一人之言,又是每日学有所得之笔记,内容未必详实,看官老爷们还望海涵。

相关文章
相关标签/搜索