快生活 - 生活常识大全

网站的优化技术建议


  CSDN:Https优化方案与测试结果
  背景
  https 是基于http 和 ssl(安全套接字层) 的安全传输协议,使用ssl 协议作为会话层协议。这个协议最早是由网景公司 开发,但是随着网景的没落,现在由ietf负责维护,最初的版本也已经重新冠名(re-banded)tls(安全传输层协议) 1.0(1999年)。因此现在大部分协议是基于TLS的,尽管是相似的东西。
  针对https,能够保证数据更加安全,但是副作用是访问会变慢(相对于http),因为服务端增加了更多的计算,客户端和服务端之间多了一层协议协商过程。因此,我们要做的优化主要是针对这里
  优化点和优化方案
  大概阐述了优化的几个方向,下面我来具体的展开讨论下。如有疏漏请指正。
  同时,我也整理了一份针对https 的握手过程详解,可以帮助大家科普下。
  客户端优化
  客户端优化是针对发起 ssl client hello 的一端进行的优化。主要有两个大的方向:
  减少请求次数,提高效率
  优化加密效率
  规避完整握手
  针对减少请求次数,主要的一个点是 SSL Session 的复用,Client Hello 请求中的 Session ID可以唯一的区分一个ssl 会话的ID。这个ID在Client Say Hello的时候被填写,
  如果是第一次与server发生会话,那么Session ID可以是空。 如果之前与ssl 服务器建立过会话,而且客户端开启了Session Ticket;并且Server cache了这个Session Ticket的时候,服务端与客户端的握手就会简化,省略掉pre master 交换的过程,直接复用之前的ssl 会话
  优化加密效率
  这里是一个比较复杂的点,我们先来看下有哪些过程可能耗时:
  密钥协商阶段的非对称加密
  协商过后的针对通信的对称加密
  @协商密钥阶段
  密钥协商过程中,客户端的计算量相对小:
  生成 random1
  生成 pre-master (填充过的随机数)
  根据服务端的 random2 和自己的 random1 还有 pre-master 生成 master-secret
  使用服务端通知的(经过验证的)公钥加密 pre-master
  这个过程中大部分是在生成随机数,只有生成 master-secret 和 使用公钥加密 是消耗cpu 的。
  @加密通信阶段
  再看下ssl协商之后的过程中的加密方式,因为是采用之前协商后的secret 来进行对称加密通信,因此这里的加密算法显得尤为重要,基本上协商ssl之后的过程中一直会使用这个算法在进行加密和解密。目前采用的大部分是AES 128位密钥的方式,但是在某些不支持硬件AES加速的处理器上,性能还是有一定的限制
  另一种加密方式是 chacha20.
  ChaCha20-Poly1305是Google所采用的一种新式加密算法,性能强大,在CPU为精简指令集的ARM平台上尤为显著(ARM v8前效果较明显),在同等配置的手机中表现是AES的4倍(ARM v8之后加入了AES指令,所以在这些平台上的设备,AES方式反而比chacha20-Poly1305方式更快,性能更好),可减少加密解密所产生的数据量进而可以改善用户体验,减少等待时间,节省电池寿命等。
  因此作为一个可选的方案,chacha20 可能对于一些老旧的机型(据连荣讲,还有很多在使用arm v7 的硬件),chacha20 更具优势。
  服务端优化
  服务端的优化有几个方向
  规避完全握手
  优化加密效率
  优化证书验证流程
  因为针对的是ssl 服务端优化,所以下面结合我们常用的http server Nginx(Tenginx)来详细的讨论下优化点
  规避完整握手
  服务端规避完全握手也是通过回复会话的方式,但是对于如何成功命中Session ID恢复会话,有两个点:
  开启 session ticket
  配置session cache
  对于1来说,服务端基本都会开启。对于nginx来说,session ticket 默认就是开启的状态。
  session cache 这里就会涉及到很多问题。当前互联网场景下,大部分web服务采取了分布式的服务方式。如何共享session cache 使得经过负载均衡的请求无论落到哪个节点都可以命中cache 就是我们的一个目标。限于篇幅和验证的目的,这里就不做过多的展开。附带一篇文章可以了解
  在这里我们先配置session cache 参数和cache 过期时间。确保单机可以命中cache
  优化加密效率
  第一个阶段是我们ssl 握手中的重点阶段,根据资料,密钥协商阶段基本占据了90%的时间。
  在没有办法规避完全握手的时候,我们要尝试进行算法的优化。目前来看可以采用的非对称加密方式大约有以下的选择:
  * RSA:算法实现简单,诞生于1977年,历史悠久,经过了长时间的破解测试,安全性高。缺点就是需要比较大的素数(目前常用的是2048位)来保证安全强度,很消耗CPU运算资源。RSA是目前唯一一个既能用于密钥交换又能用于证书签名的算法。
  * DH:diffie-hellman密钥交换算法,诞生时间比较早(1977年),但是1999年才公开。缺点是比较消耗CPU性能。
  * ECDHE:使用椭圆曲线(ECC)的DH算法,优点是能用较小的素数(256位)实现RSA相同的安全等级。缺点是算法实现复杂,用于密钥交换的历史不长,没有经过长时间的安全攻击测试。
  * ECDH:不支持PFS,安全性低,同时无法实现false start。
  针对业内的选择,大部分是使用RSA加密的方式+椭圆曲线优化的DH加密
  百度的加密算法:TLS_ECDHE_RAS_WITH_AES_128_GCM_SHA256,128位秘钥 TLS1.2
  google的加密算法:TLS_ECDHE_RAS_WITH_AES_128_GCM_SHA256,128位秘钥 TLS1.2
  因此我们可优化的空间不太大,目前来看有两个优化点:
  针对椭圆曲线,选择更高效优化过的曲线模型。调优openssl 编译参数。
  采用硬件加速的方式来优化,这就涉及到采用加速卡或专门硬件。
  优化证书验证 OCSP
  证书验证是客户端验证服务端的过程。
  通常服务端会发送site的证书,这个证书是由可信机构签发的。clent在认证这个证书的时候,会先向可信机构查询站点证书的上一级中间证书的权威。然后再查询中间证书对应的根证书的权威。这个过程就是证书链查询
  OCSP 是server 把自己的站点证书和中间证书以及根证书打包一起下发到客户端,省去客户端查询的过程。
  测试中,我们使用了域名 varycloud.com ,这个域名对应申请了symentic证书。我们生成了相关的证书链。
  测试
  测试方案
  采用压力测试的方式,对比不同配置下,相同压力服务端的服务能力和延迟表现。
  服务端配置
  CPU Info E5 6核心 12线程(超线程)
  vendor_id : GenuineIntel
  cpu family : 6
  model : 62
  model name : Intel(R) Xeon(R) CPU E5-2620 v2 @ 2.10GHz
  stepping : 4
  microcode : 0x428
  cpu MHz : 1331.367
  cache size : 15360 KB
  RAM 8G * 2
  Array Handle: 0x0032
  Error Information Handle: Not Provided
  Total Width: 72 bits
  Data Width: 64 bits
  Size: 8192 MB
  Form Factor: DIMM
  Set: None
  Locator: DIMM_A1
  Bank Locator: DIMM_A1
  Type: DDR3
  Type Detail: Registered (Buffered)
  Speed: 1333 MHz
  Manufacturer: Kingston
  Serial Number: 43153456
  Asset Tag: DIMM_A1_AssetTag
  Part Number: 9965433-091.A00
  NCI 万兆网卡
  Ethernet controller: Intel Corporation 82574L Gigabit Network Connection
  Advertised pause frame use: No
  Advertised auto-negotiation: Yes
  Speed: 1000Mb/s
  Duplex: Full
  Port: Twisted Pair
  PHYAD: 1
  Transceiver: internal
  Auto-negotiation: on
  MDI-X: off (auto)
  Supports Wake-on: pumbg
  Wake-on: g
  Link detected: yes
  测试服务器 版本
  nginx version: nginx/1.10.2
  压测工具 wrk
  wrk 是一款压测工具,基于c开发
  https://github.com/wg/wrk
  测试使用 24线程 保持24链接 压测1分钟获得数据
  nginx 配置
  server {
  listen 443 ssl;
  server_name varycloud.com;
  access_log off;
  ssl_certificate cert.pem;
  ssl_certificate_key cert.key;
  # session tacket session cache option
  ssl_session_timeout 1d;
  ssl_session_cache shared:SSL:50m;
  ssl_session_tickets on;
  ssl_session_ticket_key tls_session_ticket.key;
  # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
  # ssl_dhparam /path/to/dhparam.pem;
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_ciphers ECDHE-RSA-AES256-SHA384:AES256-SHA256:RC4:HIGH:!aNULL:!MD5;
  ssl_prefer_server_ciphers on;
  # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
  add_header Strict-Transport-Security max-age=15768000;
  # 认证证书链
  # OCSP Stapling
  # fetch OCSP records from URL in ssl_certificate and cache them
  ssl_stapling on;
  ssl_stapling_verify on;
  resolver 114.114.114.114 8.8.8.8 8.8.4.4 223.5.5.5 valid=300s;
  resolver_timeout 5s;
  ssl_trusted_certificate chain.pem;
  location / {
  root html;
  index index.html index.htm;
  }
  基准测试过程
  测试使用是
  172.16.200.11(client)
  172.16.200.21(server)
  两台机器之间延迟大约在 0.2ms 左右
  64 bytes from 172.16.200.21: icmp_seq=1 ttl=64 time=0.186 ms
  64 bytes from 172.16.200.21: icmp_seq=2 ttl=64 time=0.229 ms
  64 bytes from 172.16.200.21: icmp_seq=3 ttl=64 time=0.204 ms
  原始数据
  针对未开启任何优化的测试数据,作为对比的基础。对于请求主动关闭这种情况测试了两次
  不主动关闭链接
  ./wrk -c 24 -t 24 -d 3m https://varycloud.com
  Running 3m test @ https://varycloud.com
  24 threads and 24 connections
  Thread Stats Avg Stdev Max +/- Stdev
  Latency 0.92ms 3.07ms 170.27ms 96.54%
  Req/Sec 1.73k 248.31 2.64k 69.64%
  7448946 requests in 3.00m, 2.25GB read
  Non-2xx or 3xx responses: 7448946
  Requests/sec: 41360.72
  Transfer/sec: 12.78MB
  每次请求链接关闭
  ./wrk -c 24 -t 24 -d 3m -H "Connection: Close" https://varycloud.com
  Running 3m test @ https://varycloud.com
  24 threads and 24 connections
  Thread Stats Avg Stdev Max +/- Stdev
  Latency 4.76ms 8.34ms 174.25ms 97.01%
  Req/Sec 51.91 10.48 90.00 69.50%
  223479 requests in 3.00m, 67.99MB read
  Non-2xx or 3xx responses: 223479
  Requests/sec: 1240.95
  Transfer/sec: 386.58KB
  开启session ticket 和 session cache
  ./wrk -c 24 -t 24 -d 3m https://varycloud.com
  Running 3m test @ https://varycloud.com
  24 threads and 24 connections
  Thread Stats Avg Stdev Max +/- Stdev
  Latency 468.71us 2.69ms 160.11ms 99.67%
  Req/Sec 2.60k 343.14 3.50k 71.52%
  11189348 requests in 3.00m, 3.38GB read
  Non-2xx or 3xx responses: 11189348
  Requests/sec: 62148.92
  Transfer/sec: 19.20MB
  ./wrk -c 24 -t 24 -d 3m -H "Connection: Close" https://varycloud.com
  Running 3m test @ https://varycloud.com
  24 threads and 24 connections
  Thread Stats Avg Stdev Max +/- Stdev
  Latency 1.71ms 10.17ms 165.85ms 98.78%
  Req/Sec 360.06 53.23 545.00 82.35%
  1544216 requests in 3.00m, 469.78MB read
  Non-2xx or 3xx responses: 1544216
  Requests/sec: 8574.25
  Transfer/sec: 2.61MB
  相比基准数据 提升大约 49% 和 64%
  开启ECDH + session ticket
  ./wrk -c 24 -t 24 -d 3m https://varycloud.com
  Running 3m test @ https://varycloud.com
  24 threads and 24 connections
  Thread Stats Avg Stdev Max +/- Stdev
  Latency 405.62us 558.95us 37.73ms 97.87%
  Req/Sec 2.61k 349.92 3.57k 71.27%
  11200203 requests in 3.00m, 3.38GB read
  Non-2xx or 3xx responses: 11200203
  Requests/sec: 62206.96
  Transfer/sec: 19.22MB
  ./wrk -c 24 -t 24 -d 3m -H "Connection: Close" https://varycloud.com
  Running 3m test @ https://varycloud.com
  24 threads and 24 connections
  Thread Stats Avg Stdev Max +/- Stdev
  Latency 1.28ms 7.68ms 166.22ms 99.27%
  Req/Sec 361.23 46.59 545.00 79.26%
  1549916 requests in 3.00m, 471.52MB read
  Non-2xx or 3xx responses: 1549916
  Requests/sec: 8606.01
  Transfer/sec: 2.62MB
  相比基准数据 提升大约 56% 和 72.9%
  相比开启 session ticket 提升大约 13.4% 和 25.1%
  开启OCSP + session ticket
  ./wrk -c 24 -t 24 -d 3m https://varycloud.com
  Running 3m test @ https://varycloud.com
  24 threads and 24 connections
  Thread Stats Avg Stdev Max +/- Stdev
  Latency 538.57us 3.79ms 162.60ms 99.62%
  Req/Sec 2.61k 369.00 3.55k 74.30%
  11219121 requests in 3.00m, 3.38GB read
  Non-2xx or 3xx responses: 11219121
  Requests/sec: 62318.07
  Transfer/sec: 19.25MB
  ./wrk -c 24 -t 24 -d 3m -H "Connection: Close" https://varycloud.com
  Running 3m test @ https://varycloud.com
  24 threads and 24 connections
  Thread Stats Avg Stdev Max +/- Stdev
  Latency 0.91ms 4.58ms 162.55ms 99.61%
  Req/Sec 368.12 40.66 540.00 74.09%
  1582284 requests in 3.00m, 481.37MB read
  Non-2xx or 3xx responses: 1582284
  Requests/sec: 8785.82
  Transfer/sec: 2.67MB
  相比基准数据 提升大约 41% 和 80%
  相比开启session ticket后的数据 提升大约 -14.8% 和 46.8%
  测试中资源消耗变化图
  cpu 资源变化图 从左至右对应4种测试情况:
  raw, session ticket, ECDH + session ticket , OCSP + session ticket
  这里写图片描述
  对于session ticket命中,cpu消耗降低了很多
  网络消耗如下
  这里写图片描述
  由于session ticket 命中,节约了cpu计算资源,因此服务能力有了提升,贷款增加明显
  测试总结
  数据已经能很明确的说明问题了,简单总结下:
  session ticket 可以简化握手,更重要的是,减少了服务端的计算量,如果能命中并且复用session ticket,会有很大的优化
  ECDH 对于生成密钥有提升,而且消耗的资源并不太明显
  OCSP 测试中有一定的抖动,但是总体趋向于降低了时延
  疑惑
  测试过程中,出现了一定的抖动。每次测试的结果都有一定的抖动,这个是困惑的点,还没有找到原因
网站目录投稿:痴瑶