如何构建高性能服务器(以Nginx为例)

谭英智 2020-11-11 10:15:09
服务器 服务 性能 高性能 构建


方法论

软件层面

增大CPU利用率
  • 使用全部CPU, worker进程数等于CPU

  • 进程间不做无用的切换

  • 繁忙时不主动让出CPU

  • worker进程之间不争抢CPU

  • CPU切换需要5us,如果大量进程需要切换,则CPU会浪费大量的时间切换,做无用功

  • worker进程绑定CPU

    pidstat -w可以查看某个进程的切换次数

  • 不被其他进程抢占资源

  • 提高进程优先级,获得更大的CPU时间片

  • 减少其他进程

  • 减少惊群

    场景:多个worker进程accept同一个端口时

    • 默认accept_mutex on

      多个worker进程争抢锁获得连接,同时只有一个worker获得连接

    • accept_mutex off

      一个连接请求唤醒所有worker进程,同时只有一个worker获得连接,存在惊群问题,当worker进程数不多时,影响不大,少了争锁,高并发时可以提高系统响应能力

    • SO_REUSEPORT

      内核3.9+处理大并发连接新特性,开启后,连接通过内核分配worker进程,性能最好

  • 提高CPU缓存命中率

    绑定worker到指定CPU: worker_cpu_affinity cpumask...

增大内存利用率
  • 使用tcmalloc

    减少内存碎片

    并发能力高于glibc,并发数越多,性能越能体现(小内存分配)

    google-perftools/.../tcmalloc.html

    需要手动编译到nginx

增大IO利用率
  • 对比

    机械硬盘

    • 价格低
    • 存储量大
    • BPS大,适合顺序读写
    • IOPS小,不适合随机读写
    • 寿命长

    固态应胖

    • 价格高
    • 存储量小
    • BPS大
    • IOPS大
    • 写寿命短
  • 优化读取

    • sendfile零拷贝

      文件直接从内核态的文件到socket的传递

      location /video/{
      sendfile on;
      aio on;
      directio 8m;
      }
      
    • gzip_static

      提前压缩文件,加快gzip报文的返回

    • 内存盘/SSD盘

  • 减少写入

    • empty_gif

      使用返回一张1*1的空白图片,以减少http的返回报文长度

    • AIO

      在磁盘读写时,进程可以处理其他事情

      aio on|off|threads=[pool]

    • 直接IO,减少一次缓存的读写

      directio size|off 超过size则使用直接io,适合大文件

    • 增大error_log级别

    • error.log输出到内存

      error_log memory: 32m debug

      日志在32m的内存进行循环输出,只能看到32m的调试日志,可以提高性能

    • 关闭access_log

    • 压缩access_log

      access_log path [format] [gzip]

    • 是否开启proxy buffering

    • syslog替代本地io

      使用UDP写入代替io写入,提高性能

  • 线程池thread pool

    当某些io会阻塞时,使用线程池

增大网络宽带利用率
  • syn重试次数

    net.ipv4.tcp_syn_retries = 6

  • 本地端口可用范围

    net.ipv4.ip_local_port_range=32768 60999

    可以放大

  • 连接超时

    proxy_connect_timeout

  • 接收连接最大个数(syn未完成握手)

    net.ipv4.tcp_max_syn_backlog = 262144

    可以适当放大

  • 已完成握手

    net.core.somaxconn:系统最大backlog队列长度

  • 超出队列可以接收报文直接回RST

    net.ipv4.tcp_abort_on_overflow

  • 未被内核处理的报文队列长度

    net.core.netdev_max_backlog

  • syn/ack重试次数

    net.ipv4.tcp_synack_retries

  • 处理syn攻击

    net.ipv4.tcp_syncookies=1

    当syn队列满后,新的syn不进入队列,计算出cookie返回客户端,客户端携带cookie重新连接,服务器验证cookie,通过则建立连接。回导致TCP可选功能失效,例如扩充窗口/时间戳等

  • 操作系统最大句柄

    fs.file-max: 操作系统可以使用最大句柄数

    使用fs.file-nr可以查看当前已分配/正使用/上限

  • 用户最大句柄数

    /etc/security/limits.conf

    root soft nofile 63535

    root har nofile 65535

  • 进程限制最大句柄数

    worker_rlimit_nofile number

  • 进程最大连接数

    worker_connections number

  • Tcp Fast Open

    当TCP再次连接时,通过携带cookie,减少一次syn/ack的rtt时间,达到快速建立TCP连接的目的

nginxperformace-tfo
net.ipv4.tcp_fastopen 0|1|2|3

listen address [:port] [fastopen=number];

fastopen=number为了防止带数据的syn攻击,限制最大长度,指定TFO连接队列的最大长度

  • TCP缓冲区

    net.ipv4.tcp_rmen = 4096 87380 6291456

    net.ipv4.tcp_wmen = 4096 87380 6291456

    net.ipv4.tcp_men = 1541646 2055528 3083292

    net.ipv4.tcp_moderate_rcvbuf=1开启自动调节缓存模式

    listen address [:port] [recvbuf=size] [sndbuf=size]

    net.ipv4.tcp_adv_win_scale = 1

    应用缓存 = buffer / (2^tcp_adv_win_scale)

    接收窗口 = buffer - buffer/(2^tcp_adv_win_scale)

    BDP = 带宽* RTT/2

    buffer=BDP

  • Nagle算法

    网络中只存在一个未被确认的小报文ACK

    目的:避免一个连接上存在大量的小报文,提高网络利用率

    吞吐量优先:启用Nagle tcp_nodelay off

    低延时优先:禁用Nagle tcp_nodelay on

  • 拥塞窗口

    实际流量=拥塞窗口和接收窗口的最小值

  • 慢启动

    指数扩展拥塞窗口cwnd = cwnd*2

  • 拥塞避免

    窗口大于threshold线性增大

  • 拥塞发生

    发生丢包,

    RTO超时,threshold = cwnd/2, cwnd=1

    Fast Retransmit: cwnd=cwnd/2, threshold=cwnd

  • 快速恢复

    当Fast Retransmit出现时,cwnd调整为threshold+3*MSS

  • 优化慢启动

    增大初始cwnd=10

  • TCP keep-alive

    开启keepalive可以探测到失去连接的socket,并即时关闭,节省系统资源

    net.ipv4.tcp_keepalive_time = 7200

    net.ipv4.tcp_keepalive_intvl = 75

    net.ipv4.tcp_keepalive_probes = 9

  • timewait

    net.ipv4.tcp_orphan_retries = 0

    net.ipv4.tcp_fin_timeout = 60

    net.ipv4.tcp_max_tw_buckets = 262144 最大timewait连接数,超出直接关闭连接

  • lingering_close延迟关闭

    当接收缓冲依然接收到客户端的内容,服务器如果马上发送RST关闭连接,会导致客户端由于接收到RST而忽略http response

    lingering_close off|on|always

    reset_timedout_connection on|off; 当读写超时生效依法连接关闭,通过发送RST马上关闭连接,以释放资源

  • TLS/SLL优化握手

    ssl_session_cache

  • TLS/SSL会话票证tickets

    Nginx将会话session中的信息作为tickets加密发送给客户端,当客户端再次建立连接时带上tickets,Nignx验证复用session

    优点可以减少对称加解密的次数,提高性能

    缺点降低安全性,需要经常更换tickets密钥

    ssl_seesion_tickets on|off

    ssl_session_ticket_key file

  • 使用HTTP长连接

    keepalive_request number;

  • gzip压缩

    提高网络传输效率

    gzip on|off

  • 使用http2

统计函数调用统计

google-perltool

pprof --text|pdf

goodle_perftools_profiles file

硬件

  • 网卡:万兆网卡,例如10G/25G/40G
  • 磁盘:固态硬盘,关注IOPS/BPS指标
  • CPU:更快的主频,更大的缓存,更优的架构
  • 内存:更快的访问速度

DNS

版权声明
本文为[谭英智]所创,转载请带上原文链接,感谢
https://www.cnblogs.com/kukafeiso/p/13957174.html

  1. [front end -- JavaScript] knowledge point (IV) -- memory leakage in the project (I)
  2. This mechanism in JS
  3. Vue 3.0 source code learning 1 --- rendering process of components
  4. Learning the realization of canvas and simple drawing
  5. gin里获取http请求过来的参数
  6. vue3的新特性
  7. Get the parameters from HTTP request in gin
  8. New features of vue3
  9. vue-cli 引入腾讯地图(最新 api,rocketmq原理面试
  10. Vue 学习笔记(3,免费Java高级工程师学习资源
  11. Vue 学习笔记(2,Java编程视频教程
  12. Vue cli introduces Tencent maps (the latest API, rocketmq)
  13. Vue learning notes (3, free Java senior engineer learning resources)
  14. Vue learning notes (2, Java programming video tutorial)
  15. 【Vue】—props属性
  16. 【Vue】—创建组件
  17. [Vue] - props attribute
  18. [Vue] - create component
  19. 浅谈vue响应式原理及发布订阅模式和观察者模式
  20. On Vue responsive principle, publish subscribe mode and observer mode
  21. 浅谈vue响应式原理及发布订阅模式和观察者模式
  22. On Vue responsive principle, publish subscribe mode and observer mode
  23. Xiaobai can understand it. It only takes 4 steps to solve the problem of Vue keep alive cache component
  24. Publish, subscribe and observer of design patterns
  25. Summary of common content added in ES6 + (II)
  26. No.8 Vue element admin learning (III) vuex learning and login method analysis
  27. Write a mini webpack project construction tool
  28. Shopping cart (front-end static page preparation)
  29. Introduction to the fluent platform
  30. Webpack5 cache
  31. The difference between drop-down box select option and datalist
  32. CSS review (III)
  33. Node.js学习笔记【七】
  34. Node.js learning notes [VII]
  35. Vue Router根据后台数据加载不同的组件(思考->实现->不止于实现)
  36. Vue router loads different components according to background data (thinking - & gt; Implementation - & gt; (more than implementation)
  37. 【JQuery框架,Java编程教程视频下载
  38. [jQuery framework, Java programming tutorial video download
  39. Vue Router根据后台数据加载不同的组件(思考->实现->不止于实现)
  40. Vue router loads different components according to background data (thinking - & gt; Implementation - & gt; (more than implementation)
  41. 【Vue,阿里P8大佬亲自教你
  42. 【Vue基础知识总结 5,字节跳动算法工程师面试经验
  43. [Vue, Ali P8 teaches you personally
  44. [Vue basic knowledge summary 5. Interview experience of byte beating Algorithm Engineer
  45. 【问题记录】- 谷歌浏览器 Html生成PDF
  46. [problem record] - PDF generated by Google browser HTML
  47. 【问题记录】- 谷歌浏览器 Html生成PDF
  48. [problem record] - PDF generated by Google browser HTML
  49. 【JavaScript】查漏补缺 —数组中reduce()方法
  50. [JavaScript] leak checking and defect filling - reduce() method in array
  51. 【重识 HTML (3),350道Java面试真题分享
  52. 【重识 HTML (2),Java并发编程必会的多线程你竟然还不会
  53. 【重识 HTML (1),二本Java小菜鸟4面字节跳动被秒成渣渣
  54. [re recognize HTML (3) and share 350 real Java interview questions
  55. [re recognize HTML (2). Multithreading is a must for Java Concurrent Programming. How dare you not
  56. [re recognize HTML (1), two Java rookies' 4-sided bytes beat and become slag in seconds
  57. 【重识 HTML ,nginx面试题阿里
  58. 【重识 HTML (4),ELK原来这么简单
  59. [re recognize HTML, nginx interview questions]
  60. [re recognize HTML (4). Elk is so simple