大家好,我是Leo。
接下来我们聊聊Nginx,文章分类主要是MySQL ,Redis,秒杀系统,RocketMQ,计算机网络,大厂面试,人生, 理财。先整理一下。方便粉丝更好的阅读,同时也方便自己不断的复习沉淀。
2000字先简单看看,我们过好新年,学习从未停止,技术永无止境,我们一起加油让学习成为习惯。如果阅读过程中有任何疑问,可以关注下面公众号联系我。
Nginx应用场景
- 静态资源服务(通过本地文件系统提供服务)
- 反向代理服务
- Nginx的强大性能(高性能场景)
- 缓存
- 负载均衡
- API服务
- OpenResty
为什么会出现Nginx
- 互联网数据量的快速增长
- 全球化
- 物联网
- Apache比较低效,因为一个连接对应一个进程。
Nginx优点
- 高并发,高性能
- 可扩展性好(模块化设计非常好)
- 高可靠性(持续不间断的运行数年)
- 热部署(不停止服务的情况下,升级Nginx)
- 轻量级,启动快
Nginx组成
- Nginx二进制可执行文件(各模块源码编译出的一个文件)
- Nginx.config 配置文件(控制Nginx的行为)
- access.log 访问日志(记录每一条http请求信息)
- error.log 错误日志(定位问题)
Nginx重载,热部署,日志切割,配置静态Web资源,搭建缓存的反向代理
Nginx请求处理流程
Nginx采用MasterWork架构。
- WEB以及TCP流量进入Nginx(Nginx内有传输层状态机,HTTP状态机,MAIL状态机)
- 传输层状态机解析出请求需要访问静态资源时,就可以访问静态资源,如果去做反向代理时,可以做磁盘缓存。
- nginx也作为负载均衡可以通过协议代理传输到后面的服务器
- 每一个处理完的请求都会记录到 Access访问日志和Error错误日志
什么是状态机?
因为Nginx使用的是非阻塞的事件驱动处理引擎。(也就是我们常说的epoll)
这种异步处理请求必须采用状态机
Nginx进程结构
Nginx的单进程结构不适合在生产环境中使用,适合在开发环境与测试环境中使用。
因为在生产环境中必须保证足够的健壮以及Nginx可以利用多核的特性。而单进程做不到这一点。所以默认配置都是打开多进程Nginx。
Nginx它有一个父进程叫 Mater Process 进程,在父进程旗下有子进程,子进程主要分两类
- Worker 进程
- Cache 进程
上面提到了很多子进程,这里聊一下为什么Nginx会使用子进程,而不是子线程来处理!
Nginx主要是为了考虑高可用性和高可靠性。如果多线程结构的话,线程之间是共享同一个地址空间的,当某一个第三方模块引发地址空间导致的段错误时,在地址越界时,会导致整个Nginx进程挂掉。
当采用多进程时,往往就不会出现全部宕机的问题。
Master Process 进程被引用进来,主要是管理旗下的Worker进程以及监控是否需要载入配置文件,是否需要做热部署。
所有的Worker进程是处理真正的请求的。
当缓存进入时,不止是给Worker线程使用的,也是给Cache Loader 和 Cache Manager 使用的。
Cache Loader 进程主要做缓存的导入,Cache Manager 进程主要做缓存的管理。同时也是为反向代理时,后端发来的动态请求做缓存所使用的。进程间的通信主要是用共享内存来解决的。
Nginx信号
信号的主要用途是解决父子进程之间的通信问题,能发送和处理信号的主要有以下三种
- Master 进程
- Worker 进程
- Nginx 指令行
上文进程结构中我们说到了,Master Process进程主要是用来管理与监控Worker进程的,所以这个地方的Worker进程信号我们就不介绍了,我们主要介绍一下Master进程和 Nginx指令行。
Master 进程
监控Worker进程 CHLD
管理Worker进程的接收信息
- TERM,INT
- QUIT(优雅关闭)
- HUP
- USR1
Nginx指令行
- reload:HUP
- reopen:USR1
- stop:TERM
- quit:QUIT
收到 reload Nginx做了哪些
- 向master进程发送HUP信号(reload命令)
- master进程校验配置语法是否正确
- master进程打开新的监听端口
- master进程会用新配置启动新的worker子进程
- 新master进程向老worker子进程发送QUIT信号
- 老worker进程会先关闭监听句柄,处理完当前连接后结束进程
使用reload之后我们会发现,系统进程会越来越多,这里的主要原因是 在老worker进程和新worker进程并存的时候,会逐步关闭退出老worker,但是有些老worker与客户端正在保持请求处理,所以可能不会立即平滑的过度。
在Nginx最新版本中已经解决了这个问题,在新worker和老worker并存的时候,一一对应绑定了定时器,根据我们配置的参数可以平滑的过度。
Nginx热升级流程
- 旧的Nginx文件换成新的Nginx文件(注意备份)
- 向老master进程发送USR2信号
- master进程会修改pid文件名,加后缀.oldbin
- master进程用新的Nginx文件启动新的master进程
- 向老master进程发送QUIT信号,关闭老master进程
老master进程是一直存在的,这是方便我们进行回滚,当发现新的Nginx有问题,这个时候老的Nginx也存在,所以我们就可以通过向老master进程发送HUP信号,向新master发送QUIT信号完成回滚
优雅的关闭worker进程
这里就是reload命令流程底部的定时器细节
- 设置定时器 worker_shutdown_timeout
- 关闭监听句柄(保证所在的worker进程不会处理其他连接了)
- 关闭空闲连接(保证资源最大化,会去连接池关闭空闲没有使用的连接)
- 在循环中等待全部连接关闭(主要分两种,连接处理完,立即干掉。连接正在处理,这个就需要根据第一步的定时器参数去等待关闭)
- 退出进程(最终优雅的退出进程,因为没有影响到用户的使用)
如果不采用这种优雅的关闭worker进程,会导致用户收到错误