【声明】本博客所有内容均为个人业余时间创作,所述技术案例均来自公开开源项目(如Github,Apache基金会),不涉及任何企业机密或未公开技术,如有侵权请联系删除
背景
上篇 blog
【Ubuntu】【Gitlab】拉出内网 Web 服务:Nginx 事件驱动分析(一)
分析了 Nginx 用的是事件驱动,配合异步非阻塞 I/O 架构,下面继续分析
Nginx 事件驱动分析
OK,上篇 blog 分析了事件驱动模型,下面来对比下事件驱动和多线程两种模型:
-
事件驱动模型 :并发能力强 ,可同时处理几万~百万级别的连接请求,而内存占用极低 ,每个连接几百字节,CPU 利用率高,几乎无需切换上下文,可高效利用 CPU ,适合反向代理,高并发等场景

-
多线程模型 :并发能力弱 ,一般支持几百~几千的并发连接(性能上有瓶颈,后面分析),内存占用高 (每个线程 2~8MB 栈空间),CPU 利用率低,需反复切换上下文,开销大 ,适合动态内容分发

此外,Nginx 是用 C 语言写的状态机和事件循环,能把性能榨到极致,用单线程 + 非阻塞 I/O + epoll(Linux) 构建一个高效事件循环,只有在连接有数据时才处理,从而用极少资源扛住海量并发 (借用上篇 blog 的 c 示例代码,这里再解释一遍)

OK,下面在终端输入
bash
nproc
可以查看服务器的 CPU 核心数量,比如

当前服务器上的 CPU 可用核心是 16 个,再严谨一点 ,终端输入 man nproc,查看该命令的详细信息

- 首先,CPU 核心是操作系统调度任务的基本单位,上面显示有 16 个核,意味着同一时刻最多只有 16 个在物理 CPU 上执行的任务
- 其次,
nproc不是简单地返回机器总共有多少核,而是返回当前进程被允许使用的 CPU 核心数量 ,在资源受限环境下(比如容器环境,或者用taskset命令限制 ),进程可能看不到全部 CPU,所以nproc会返回更小的值,但是当然,如果没有特别去限制的话,nproc返回的就是全部的 CPU 核心数
OK,查看完当前服务器的 CPU 核心数,下面在终端再输入
bash
ps aux | grep nginx
可以查看 Nginx 实例配置的 worker 进程如下(这里涉及到 Nginx 实例,有个小冗余问题,后面分析 )

- 首先,这里最上面可以看到 PID 为
2815的 master 进程,路径是/opt/gitlab...,这是 Gitlab 自带 Nginx 启动的进程(Gitlab 默认会自带 Nginx,PostgreSQL,Redis 等组件,形成一个一体化服务栈) - 然后,接下来是 16 个 worker 进程,这个就是之前 blog 【Ubuntu】【Gitlab】拉出内网 Web 服务:Nginx 事件驱动分析(一) 提到的,Nginx 在启动时,会创建几个 worker 进程(一般为 CPU 核数)
从这里可以看到 Nginx 的高性能设计,首先是多进程模型(注意,不是上面的多线程) ,默认 worker 数量为 CPU 核心数(当然也可以手动配置更多,但实际其物理极限是 CPU 核心数,再多也快不了 ),每个 worker 进程是个单线程,用 epoll(Linux)处理成千上万连接,这些 worker 进程之间相互隔离,一个进程崩溃不会影响其他进程,并且能充分利用多核 CPU
OK,本篇先到这里,如有疑问,欢迎评论区留言讨论,祝各位功力大涨,技术更上一层楼!!!更多内容见下篇 blog
【Ubuntu】【Gitlab】拉出内网 Web 服务:http.server 单/多线程分析(一)