HarmonyOS开发者限时福利来啦!最高10w+现金激励等你拿~ 了解详情
写点什么

浅谈高并发系统性能调优

  • 2019-11-20
  • 本文字数:4048 字

    阅读完需:约 13 分钟

浅谈高并发系统性能调优

今天带来的是一个篇长文,主要讲解高并发系统架构指标及调优测试经验,希望能对您的研究有所帮助。本文最先发布于 OpsDev,转载已获取作者授权。


高并发系统的优化一直以来都是一个很重要的问题,下面基于笔者的实践,和大家聊聊高并发系统的一些调优和优化策略。

1 系统性能的关键指标

  • 吞吐量(Throughput)系统单位时间内处理任务的数量

  • 延迟(Latency)系统对单个任务的平均响应时间


一般来说,考量一个系统的性能主要看这两个指标。而这两个指标之间又存在着一些联系:对于指定的系统来说,系统的吞吐量越大,处理的请求越多,服务器就越繁忙,响应速度就会慢下来;而延迟越低的系统,能够承载的吞吐量也相应的更高一些。


一方面,我们需要提高系统的吞吐量,以便服务更多的用户,另一方面我们需要将延迟控制在合理的范围内,以保证服务质量。

2 系统性能测试

  • 业务场景

  • 对于不同的业务系统,可以接受的延迟(Latency)也有所不同,例如邮件服务可以忍受的延迟显然要比 Web 服务高得多,所以首先我们需要根据业务场景的不同来定义理想的 Latency 值。

  • 测试工具

  • 我们需要一个能够制造高吞吐的工具来测试系统的性能,本文中使用的 Tsung,它是一个开源的支持分布式的压力测试工具,它功能丰富,性能强大,配置简单,并支持多种协议(HTTP、MySQL、LDAP、MQTT、XMPP 等)。

  • 测试流程

  • 测试的过程中需要不断加大吞吐量,同时注意观察服务端的负载,如果负载没有问题,那就观察延迟。一般这个过程需要反复很多次才能测出系统的极限值,而每次测试消耗的时间也比较长,需要耐心一些。

3 通用的系统参数调优

Linux 内核默认的参数考虑的是最通用的场景,不能够满足高并发系统的需求。

4 服务器参数调优

编辑文件/etc/sysctl.conf,添加以下内容:


fs.nr_open = 100000000  fs.file-max = 100000000
复制代码


关于这两项配置的含义可以查看系统手册:



可以看到 file-max 的含义:它是系统所有进程一共可以打开的文件数量,它是系统级别的,因此应该尽量将它调的大一些,这里将它修改为一亿。 这里说到需要增大/proc/sys/fs/inode-max 的值,但是执行如下命令时发现没有该配置项:


$ cat /proc/sys/fs/inode-max  cat: /proc/sys/fs/inode-max: No such file or directory
复制代码


再看 inode-max 说明:



可以看到有的系统中没有这个参数,所以先不管了。


对于 nr_open,系统手册里没有找到关于它的定义,不过我们可以参考kernel文档


nr_open:      This denotes the maximum number of file-handles a process can      allocate. Default value is 1024*1024 (1048576) which should be      enough for most machines. Actual limit depends on RLIMIT_NOFILE      resource limit.
复制代码


可以看到 nr_open 的描述与 file-max 十分相近,不仔细看几乎分辨不出区别。重点在于,file-max 是对所有进程(all processes)的限制,而 nr_open 是对单个进程(a process)的限制。这里给出了 nr_open 的默认值:


1024*1024 = 1048576


编辑文件/etc/security/limits.conf,添加如下内容:


编辑文件/etc/sysctl.conf,添加以下内容:



    关于这两项配置的含义可以查看系统手册:



    这里的意思很明确:hard 意为硬资源限制:一旦被 superuser 设置后不能增加;soft 为软资源设置:设置后在程序运行期间可以增加,但不能超过 hard 的限制。程序读取的是 soft,它是一个告警值。 nofile 意为用户打开最大文件描述符数量,在 Linux 下运行的网络服务器程序,每个 tcp 连接都要占用一个文件描述符,一旦文件描述符耗尽,新的连接到来就会返回"Too many open files"这样的错误,为了提高并发数,需要提高这项配置的数值。


    这里有一点需要特别注意,而手册里面也没有细说:在 CentOS7 下(其他系统还未测试过),nofile 的值一定不能高于 nr_open,否则用户 ssh 登录不了系统,所以操作时务必小心:可以保留一个已登录的 root 会话,然后换个终端再次尝试 ssh 登录,万一操作失败,还可以用之前保留的 root 会话抢救一下。


    修改完毕执行:


    # sysctl -p
    复制代码


    通过以上,我们修改了/etc/security/limits.conf 和/etc/sysctl.conf 两个配置文件,它们的区别在于 limits.conf 是用户层面的限制,而 sysctl.conf 是针对整个系统层面的限制。

    5 压测客户机参数调优

    对于压测机器来说,为了模拟大量的客户端,除了需要修改文件描述符限制外,还需要配置可用端口范围,可用端口数量决定了单台压测机器能够同时模拟的最大用户数量。


    • 文件描述符数量:修改过程同服务器

    • 可用端口数量:1024 以下的端口是操作系统保留的,我们可用的端口范围是 1024-65535,由于每个 TCP 连接都要用一个端口,这样单个 IP 可以模拟的用户数大概在 64000 左右 修改/etc/sysctl.conf 文件,添加如下内容:


    net.ipv4.ip_local_port_range = 1024 65535
    复制代码


    修改完毕执行:


    # sysctl -p
    复制代码


    需要注意的是,服务器最好不要这样做,这是为了避免服务监听的端口被占用而无法启动。如果迫于现实(例如手头可用的机器实在太少),服务器必须同时用作压测机器的话,可以将服务监听端口添加到 ip_local_reserved_ports 中。下面举例说明:


    修改/etc/sysctl.conf 文件,添加如下内容:


    net.ipv4.ip_local_reserved_ports = 5222, 5269, 5280-5390
    复制代码


    修改完毕执行:


    # sysctl -p
    复制代码


    TCP/IP 协议栈从 ip_local_port_range 中选取端口时,会排除 ip_local_reserved_ports 中定义的保留端口,因此就不会出现服务端口被占用而无法启动的情况。

    6 程序调优

    对于不同的业务系统,需要有针对性的对其进行调优,本文中测试的目标服务使用 Erlang/OTP 写就,Erlang/OTP 本身带有许多的限制,对于一般场景来说这些默认的设置是足够的;但是为了支持高并发,需要对 Erlang 虚拟机进行一些必要的参数调优,具体可以参考官方性能指南

    7 服务程序参数调优

    进程(process)数量

    Erlang 虚拟机默认的进程数量限制为 2^18=262144 个,这个值显然是不够的,我们可以在 erl 启动时添加参数+P 来突破这个限制


    $ erl +P 10000000
    复制代码


    需要注意的是:这样启动,erlang 虚拟机的可用进程数量可能会比 10000000 大,这是因为 erlang 通常(但不总是)选择 2 的 N 次方的值作为进程数量上限。

    原子(atom)数量

    Erlang 虚拟机默认的原子数量上限为 1048576,假如每个会话使用一个原子,那么这个默认值就不够用了,我们可以在 erl 启动时添加参数+t:


    $ erl +t 10000000
    复制代码


    从另一个角度来说,我们在编写 Erlang 程序时,使用原子需要特别小心:因为它消耗内存,而且不参与 GC,一旦创建就不会被移除掉;一旦超出原子的数量上限,Erlang 虚拟机就会 Crash,参见 How to Crash Erlang


    端口(port)数量 端口提供了与外部世界通讯的基本机制(这里的端口与 TCP/IP 端口的概念不同,需要注意区别),每个 Socket 连接需要消耗 1 个端口,官方文档里面说默认端口上限通常是 16384,但根据实测,Linux 系统默认为 65536,Windows 系统默认为 8192,无论多少,在这里都是需要调整的:在 erl 启动时添加参数+Q Number,其中 Number 取值范围是[1024-134217727]:


     $ erl +Q 10000000
    复制代码

    8 压测脚本调优

    压测工具使用 Tsung。Tsung 支持多种协议,有着丰富的功能,并且配置简单灵活。下面是几点需要注意的地方:

    内存

    对于单个 Socket 连接来说消耗内存不多,但是几万甚至几十万个连接叠加起来就非常可观了,配置不当会导致压测端内存成为瓶颈。


    • TCP 发送、接收缓存 Tsung 默认的 TCP/UDP 缓存大小为 32KB,本例中我们测试的服务采用 MQTT 协议,它是一种非常轻量级的协议,32KB 还是显得过大了,我们将它设置为 4KB 大小就足够了:


    <option name="tcp_snd_buffer" value="4096"></option>  <option name="tcp_rcv_buffer" value="4096"></option>
    复制代码


    • Tsung 能够让模拟用户的进程在空闲时间(thinktime)进入休眠,用以降低内存消耗,默认空闲 10 秒触发,我们可以将它降低到 5 秒:


    <option name="hibernate" value="5"></option>
    复制代码

    IO

    • 不要启用 dumptraffic,除非用于调试,因为它需要将客户机和服务器往来的协议写入磁盘日志中,是一个 IO 开销非常大的行为。笔者曾经遇到过一次这样的问题,测试部门的同事使用 JMeter,压测过程中,服务端一直处于较低的负载,但 JMeter 最终得出的压测报告却包含很多超时错误。经过仔细排查,才定位到原来是压测端默认开启了 debug 日志,海量的 debug 日志生生拖垮了压测机器。所以遇到这种情况时,可以先检查一下压测端配置是否正确。


    <tsung loglevel="error" dumptraffic="false" version="1.0">
    复制代码


    日志等级要调高一些,日志等级过低会打印很多无用信息:一方面会加大 IO 开销,另一方面会让有用的 ERROR 信息淹没在海量的调试日志中。


    如果 Tsung 从 CSV 文件读取用户名密码,那么该 CSV 文件不能过大,否则读取该 CSV 将会变成一个极其耗时的操作,特别是当压测程序需要每秒产生大量用户时。

    网络

    有时候为了避免网络拥塞,需要限制压测客户机的带宽,使流量以比较平滑的速率发送和接收。


    <option name="rate_limit" value="1024"></option>
    复制代码


    其采用令牌桶算法(token bucket),单位 KB/s,目前只对流入流量有效。

    9 定位系统性能瓶颈

    当系统吞吐和延迟上不去时,首先需要定位问题,而不是急于修改代码。


    常见的性能瓶颈包括 CPU/内存/磁盘 IO/网络带宽等,其中每一项都有一到多个简单实用的工具: 对于 CPU 和内存,我们只要使用 top 就可以了;对于磁盘 IO,可以用 iotop 或 iostat;对于网络带宽,可以使用 iftop。


    如果依然没能定位到问题,可能系统配置不当,参考通用的系统参数调优。


    最后检查代码是否有单点瓶颈,例如程序被阻塞了:在笔者实测过程中,发现每个用户创建会话进程都需要对同一个 supervisor 发起同步请求,同时登录的用户数量很大时,这些同步请求会排队,甚至引发超时。

    10 结束语

    以上就是笔者做压力测试时遇到的一些问题以及应对办法,鉴于笔者水平有限,错漏难免。抛砖引玉,欢迎交流指正。


    本文转载自公众号 360 云计算(ID:hulktalk)。


    原文链接:


    https://mp.weixin.qq.com/s/4LclaIGDBj4y6xZQRFiDeg


    2019-11-20 17:101531

    评论

    发布
    暂无评论
    发现更多内容

    豆包MarsCode初体验,用 React 创建一个最经典的贪吃蛇游戏

    豆包MarsCode

    人工智能 编程 程序员 AI 代码

    2024-09-25:用go语言,给定一个长度为 n 的整数数组 nums 和一个正整数 k, 定义数组的“能量“为所有和为 k 的子序列的数量之和。 请计算 nums 数组中所有子序列的能量和,并对

    福大大架构师每日一题

    福大大架构师每日一题

    Windows Server 2022 中文版、英文版下载 (updated Sep 2024)

    sysin

    windows Server 2022

    Lightroom Classic 2022(lrc2022)支持(Win&Mac)版

    你的猪会飞吗

    LRC2022 mac破解软件下载 lrc2022下载

    ChatGPT 向更多用户推出高级语音模式:支持 50 种语言;字节发布两款新视频生成大模型丨 RTE 开发者日报

    声网

    如何借助SD-WAN实现简单且经济的组网?

    Ogcloud

    SD-WAN 企业组网 SD-WAN组网 SD-WAN服务商 SDWAN

    天池云上智能降雨量预测总决赛-优胜奖RIOFGROUP队攻略分享

    阿里云天池

    企业如何通过ETL工具实现主数据的同步

    RestCloud

    数据处理 ETL 主数据 企业数据

    洞察药监局数据,挖掘万亿价值

    八爪鱼采集器︱RPA机器人

    爬虫 采集

    爬虫如何帮助构建比价系统|涨姿势

    八爪鱼采集器︱RPA机器人

    爬虫 采集

    AI加速数字员工智能化落地——中国数字员工市场发展及企业数字员工落地建议

    易观分析

    Windows 11 version 23H2 中文版、英文版 (x64、ARM64) 下载 (updated Sep 2024)

    sysin

    windows 11

    Databend 为什么能帮用户降低 90% 成本?

    Databend

    客户成功案例(1):新闻媒体/招投标/行业资讯数据聚合

    八爪鱼采集器︱RPA机器人

    爬虫 采集 爬虫软件

    Windows 10 on ARM, version 22H2 (updated Sep 2024) ARM64 AArch64 中文版、英文版下载

    sysin

    windows arm 10

    JMeter的运行

    霍格沃兹测试开发学社

    火山引擎数据飞轮面向企业大模型业场景务提供数智服务

    字节跳动数据平台

    大模型 数智化 数智化转型

    性能测试 | JMeter的运行

    测试人

    软件测试

    Windows 10 version 22H2 (updated Sep 2024) 中文版、英文版下载

    sysin

    windows 10

    客户成功案例3:企业数据模型搭建、灾害预警解决方案

    八爪鱼采集器︱RPA机器人

    爬虫 采集

    CVPR2021 安全AI挑战者计划第六期赛道一第二名方案分享 (UM-SIAT队)

    阿里云天池

    面试官:谈谈你对 IoC 和 AOP 的理解!

    JavaGuide

    Java spring aop ioc

    鸿蒙智行首款轿跑SUV智界R7上市,小艺化身贴心随行的用车顾问

    Geek_2d6073

    TEDxDUTH 使用 NocoBase 实现革新

    NocoBase

    低代码 TED 管理工具 无代码 创新管理

    链藏“万亿金矿”的新能源,汽车企业如何抓住客户体验数字化新机遇?

    八爪鱼采集器︱RPA机器人

    爬虫 采集

    Spark“数字人体”AI挑战赛_脊柱疾病智能诊断大赛_GPU赛道亚军比赛攻略_triple-Z团队

    阿里云天池

    如何根据拍立淘API返回值进行商品数据分析

    技术冰糖葫芦

    API Gateway api 货币化 API 接口 API 测试 pinduoduo API

    第一届POLARDB数据库性能大赛-亚军0xCC☣☢比赛攻略

    阿里云天池

    体验3A云游戏,无需购买高端显卡

    Ogcloud

    云游戏 3A云游戏 云游戏发行 游戏云化

    手工测试用例转Web自动化测试生成

    霍格沃兹测试开发学社

    面试官:项目中如何实现布隆过滤器?

    王磊

    浅谈高并发系统性能调优_文化 & 方法_OpsDev- 杨玉东_InfoQ精选文章