热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

针对容器的nginx优化

背景容器技术越来越普遍,很多公司已经将容器技术作为基础架构的一部分,容器中可以运行任何软件,包括WebServer、ApplicationServer、数据库和存储系统等,其中Ng

背景

容器技术越来越普遍,很多公司已经将容器技术作为基础架构的一部分,容器中可以运行任何软件,包括 Web Server、Application Server、数据库和存储系统等,其中 Nginx 作为 Web Server 使用也非常的普遍,接下来本文简要分析下 Nginx 在容器内使用遇到的一点小问题。

我们在物理机上配置 Nginx 时通常会将 Nginx 的 worker 进程数配置为 CPU 核心数并且会将每个 worker 绑定到特定 CPU 上,这可以有效提升进程的 Cache 命中率,从而减少内存访问损耗,不放过任何能够榨取系统性能的机会;对于需要手动配置 Nginx 进程个数的场景不在本文的探讨范畴内,例如:磁盘 IO 密集型业务可能会导致 Nginx 进程阻塞,我们通常会将 Nginx 的进程数设置为 CPU 核数的 2 倍,用于提高整体的并发。

在 Nginx 配置中指定 worker_processes 指令的参数为 auto 来自动检测系统的 CPU 核心数从而启动相应个数的 worker 进程,那么在 Linux 系统上 Nginx 是怎么获取 CPU 核心数的呢?答案是通过系统调用 sysconf(_SC_NPROCESSORS_ONLN) 获取到系统当前可用的 CPU 核心数。假如我们在一个 CPU 是 32 cores 的物理机上启动 Nginx,那么 sysconf(_SC_NPROCESSORS_ONLN) 返回值为 32。

存在问题

如果我们将 Nginx 放进 Docker 启动的容器内,sysconf(_SC_NPROCESSORS_ONLN) 的返回值是多少呢?

通过 docker run 启动一个带有 Nginx 的容器,暂时不对此容器的 CPU 资源做任何限制也就是可以使用物理机上的所有资源,我们来观察 Nginx 进程启动的进程数(确认 Nginx 配置中的 worker_processes 指令设置为 auto),答案其实大家都清楚的 Nginx 启动了 32 个 worker 进程。

接下来我们对容器的 CPU 资源做限制,通过 docker run 时指定 --cpuset-cpus="0,1" 参数绑定容器内的进程到 CPU-0 和 CPU-1 上,而后再来观察 Nginx 进程启动的进程数,同样还是 32 个 worker 进程;对容器设置 cpu-shares 和 cpu-quota 也会得到同样的结果。

那么问题来了:

1. 与我们预期的相符吗?

2. 指定了 --cpuset-cpus 能使用的核心数为 2 个,为什么获取到的 CPU 核心数还是 32 呢?

第 1 个问题:

很多人都是知道的,我们更期望的结果对于上边的设置只启动两个 worker 进程,进程得到的 CPU 时间片期望被 2 个进程分摊,现在需要被 32 个进程分摊;从 Nginx 角度来看想要取得更多的时间片就需要减少在这个 CPU 上运行的进程,这样整体性能才会提升。对于 Nginx 来说也就是期望根据可用的 CPU 核数启动相应的进程数,而不是根据物理机上可用的 CPU 核数来设置进程数。

第 2 个问题:

对于容器来说目前还只是一个轻量级的隔离环境,它并不是一个真正的操作系统,那么在容器中获取可用 CPU 核心数和 Memory 大小均是物理机配置。在没有容器的时候很多软件依赖于操作系统的资源进行初始化配置的,例如:JVM 根据 CPU 核数启动相应的 gc 线程,根据物理机的 memroy 设置堆大小。

压测比照

我们通过一个简单的压测比照一下在容器中 Nginx 启动不同 worker 进程对 QPS 和 Latency 影响有多大。

物理机:32cores

容器参数

cpu-quota=400000(即容器内的进程最多可以使用 400% 的 CPU)

压测指令

wrk -t 32 -c 500 -d 180 http://container_ip

提前准备

容器内安装 Openresty、将 worker_processes 修改为 4 和 32,关闭 access 日志,响应数据为 541byte。

以下是 Nginx 的 QPS 和 Latency 压测结果,QPS 从 12 万 + 降到了 4 万 +,Latency 也从 6+ms 降到了 25+ms。

针对容器的nginx优化

处理方法

从以上压测数据可以看出,Nginx 在设置 worker 进程数为 4 和 32 时 QPS 和 Latency 有很大的差距的,理解了以上问题我们该如何处理呢?

方法 1

先来说一下普遍使用的 Lxcfs,对于上边提到的场景是不适用的,Lxcfs 目前仅支持改变容器的 CPU 视图(/proc/cpuinfo 文件内容)并且只有 --cpuset-cpus 参数可以生效,对于系统调用 sysconf(_SC_NPROCESSORS_ONLN) 返回的同样还是物理机的 CPU 核数。

方法 2

通过创立引导程序根据容器可以使用的物理资源自动计算出正当值并设置应用程序的启动参数,例如:通过 shell 脚本动态修改 Nginx 的 worker 进程数。

方法 3

应用程序自行解析容器内的 cgroup 信息,并设置程序的启动参数。Docker 在 1.8 版本以后将容器分配的 cgroup 信息挂载进了容器内部,在容器内可以通过解析 cgroup 信息获取到当前容器可以使用的资源信息。例如:JDK 10 中引入了支持 Docker 容器的资源检测并配置 JVM 的运行时参数,它的原理就是解析容器内的 cgroup 信息配置 gc 线程数以及堆大小。

方法 4

劫持系统调用 sysconf,在类 Unix 系统上可以通过 LD_PRELOAD 这种机制预先加载个人编写的的动态链接库,在动态链接库中劫持系统调用 sysconf 并根据 cgroup 信息动态计算出可用的 CPU 核心数。

小结

我们团队也参考了 JVM 的实现并根据 Nginx 的代码风格给 Nginx 打了一个 patch,使 Nginx 的 worker_processes auto 参数能够根据当前容器的可用资源自动计算出正当的 worker 进程数,同时也提交给了 Nginx 社区,但是很遗憾 Nginx 社区负责人 Maxim 并不愿意接受这种实现方式,他更希望的是容器能透明支持 sysconf(_SC_NPROCESSORS_ONLN) 系统调用的功能,而不是用这种解析 cgroup 文件的方式实现,于是我们就实现了一个可以劫持系统调用 sysconf 的动态链接库。

可能有人会有疑问,为什么 JVM 能接受解析 cgroup 文件这种方式,而 Nginx 却不能接受这种方式呢?

根据我的了解目前这个小问题对 Nginx 不是最痛的,不支持也不妨碍使用,另一点是 Nginx 作者以及现在的主要维护者 Maxim 都有重度代码洁癖,从代码风格以及代码中几乎无注释可以感受的到,Nginx 推崇的是代码即文档,要求写代码的人像写文档一样使代码的可读性非常高,对于这种用几百行代码处理的问题他们更不能忍受。而 JVM 支持的这种方式很大起因是这个问题确实很痛,网上有很多人都有报 JVM 在容器内的配置不正当导致运行时出现各种问题,所以目前通用的处理方案也只能是解析 cgroup 文件来自动化支持。

来源:微信公众号 小米运维


推荐阅读
  • Nginx使用AWStats日志分析的步骤及注意事项
    本文介绍了在Centos7操作系统上使用Nginx和AWStats进行日志分析的步骤和注意事项。通过AWStats可以统计网站的访问量、IP地址、操作系统、浏览器等信息,并提供精确到每月、每日、每小时的数据。在部署AWStats之前需要确认服务器上已经安装了Perl环境,并进行DNS解析。 ... [详细]
  • Skywalking系列博客1安装单机版 Skywalking的快速安装方法
    本文介绍了如何快速安装单机版的Skywalking,包括下载、环境需求和端口检查等步骤。同时提供了百度盘下载地址和查询端口是否被占用的命令。 ... [详细]
  • 如何在服务器主机上实现文件共享的方法和工具
    本文介绍了在服务器主机上实现文件共享的方法和工具,包括Linux主机和Windows主机的文件传输方式,Web运维和FTP/SFTP客户端运维两种方式,以及使用WinSCP工具将文件上传至Linux云服务器的操作方法。此外,还介绍了在迁移过程中需要安装迁移Agent并输入目的端服务器所在华为云的AK/SK,以及主机迁移服务会收集的源端服务器信息。 ... [详细]
  • flowable工作流 流程变量_信也科技工作流平台的技术实践
    1背景随着公司业务发展及内部业务流程诉求的增长,目前信息化系统不能够很好满足期望,主要体现如下:目前OA流程引擎无法满足企业特定业务流程需求,且移动端体 ... [详细]
  • Linux如何安装Mongodb的详细步骤和注意事项
    本文介绍了Linux如何安装Mongodb的详细步骤和注意事项,同时介绍了Mongodb的特点和优势。Mongodb是一个开源的数据库,适用于各种规模的企业和各类应用程序。它具有灵活的数据模式和高性能的数据读写操作,能够提高企业的敏捷性和可扩展性。文章还提供了Mongodb的下载安装包地址。 ... [详细]
  • 一句话解决高并发的核心原则
    本文介绍了解决高并发的核心原则,即将用户访问请求尽量往前推,避免访问CDN、静态服务器、动态服务器、数据库和存储,从而实现高性能、高并发、高可扩展的网站架构。同时提到了Google的成功案例,以及适用于千万级别PV站和亿级PV网站的架构层次。 ... [详细]
  • svnWebUI:一款现代化的svn服务端管理软件
    svnWebUI是一款图形化管理服务端Subversion的配置工具,适用于非程序员使用。它解决了svn用户和权限配置繁琐且不便的问题,提供了现代化的web界面,让svn服务端管理变得轻松。演示地址:http://svn.nginxwebui.cn:6060。 ... [详细]
  • 本文介绍了互联网思维中的三个段子,涵盖了餐饮行业、淘品牌和创业企业的案例。通过这些案例,探讨了互联网思维的九大分类和十九条法则。其中包括雕爷牛腩餐厅的成功经验,三只松鼠淘品牌的包装策略以及一家创业企业的销售额增长情况。这些案例展示了互联网思维在不同领域的应用和成功之道。 ... [详细]
  • 本文介绍了在rhel5.5操作系统下搭建网关+LAMP+postfix+dhcp的步骤和配置方法。通过配置dhcp自动分配ip、实现外网访问公司网站、内网收发邮件、内网上网以及SNAT转换等功能。详细介绍了安装dhcp和配置相关文件的步骤,并提供了相关的命令和配置示例。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • 本文介绍了在Mac上搭建php环境后无法使用localhost连接mysql的问题,并通过将localhost替换为127.0.0.1或本机IP解决了该问题。文章解释了localhost和127.0.0.1的区别,指出了使用socket方式连接导致连接失败的原因。此外,还提供了相关链接供读者深入了解。 ... [详细]
  • 本文介绍了RPC框架Thrift的安装环境变量配置与第一个实例,讲解了RPC的概念以及如何解决跨语言、c++客户端、web服务端、远程调用等需求。Thrift开发方便上手快,性能和稳定性也不错,适合初学者学习和使用。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
author-avatar
zifei84589
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有