目录
2、一个请求到来了,nginx使用epoll接收请求的过程是怎样的?
2、通过 stub_status 模块监控 nginx 的工作状态
?Nginx (engine x) 是一个高性能的 HTTP 和 反向代理 服务,也是一个IMAP/POP3/SMTP服务。 ?nginx因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。 ?Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好
Nginx 是一个高性能的 Web 和反向代理服务器, 它具有有很多非常优越的特性:
单机环境下参考服务器配置。 并发连接数在7000+ -8000左右。 集群模式20000+
作为 Web 服务器:相比 Apache,Nginx 使用更少的资源,支持更多的并发连接,体现更高的效率,这点使 Nginx 尤其受到虚拟主机提供商的欢迎。能够支持高达 50,000 个并发连接数的响应,感谢 Nginx 为我们选择了 epoll and kqueue 作为开发模型.
作为负载均衡服务器:Nginx 既可以在内部直接支持 Rails 和 PHP,也可以支持作为 HTTP代理服务器 对外进行服务。Nginx 用 C 编写, 不论是系统资源开销还是 CPU 使用效率都比 Perlbal 要好的多。
作为邮件代理服务器: Nginx 同时也是一个非常优秀的邮件代理服务器(最早开发这个产品的目的之一也是作为邮件代理服务器),Last.fm 描述了成功并且美妙的使用经验。
Nginx 安装非常的简单,配置文件 非常简洁(还能够支持perl语法),Bugs非常少的服务器: Nginx 启动特别容易,并且几乎可以做到7*24不间断运行,即使运行数个月也不需要重新启动。你还能够在 不间断服务的情况下进行软件版本的升级。
第一种方法就是最传统的多进程并发模型 (每进来一个新的I/O流会分配一个新的进程管理。)
第二种方法就是I/O多路复用 (单个线程,通过记录跟踪每个I/O流(sock)的状态,来同时管理多个I/O流 。)
I/O multiplexing 这里面的 multiplexing 指的其实是在单个线程通过记录跟踪每一个Sock(I/O流)的状态来同时管理多个I/O流。发明它的原因,是尽量多的提高服务器的吞吐能力。
在同一个线程里面, 通过拨开关的方式,来同时传输多个I/O流
ngnix会有很多连接进来, epoll会把他们都监视起来,然后像拨开关一样,谁有数据就拨向谁,然后调用相
应的代码处理。
select, poll, epoll 都是I/O多路复用的具体的实现,其实是他们出现是有先后顺序的。
I/O多路复用这个概念被提出来以后, 相继出现了多个方案
select是第一个实现 (1983 左右在BSD里面实现的)。
select 被实现以后,很快就暴露出了很多问题。
? select 会修改传入的参数数组,这个对于一个需要调用很多次的函数,是非常不友好的。
? select 如果任何一个sock(I/O stream)出现了数据,select 仅仅会返回,但是并不会告诉你是那个sock上有数据,于是你只能自己一个一个的找,10几个sock可能还好,要是几万的sock每次都找一遍...
? select 只能监视1024个链接。
? select 不是线程安全的,如果你把一个sock加入到select, 然后突然另外一个线程发现,这个sock不用,要收
回,这个select 不支持的,如果你丧心病狂的竟然关掉这个sock, select的标准行为是不可预测的
于是14年以后(1997年)一帮人又实现了poll, poll 修复了select的很多问题,比如
? poll 去掉了1024个链接的限制,于是要多少链接呢, 主人你开心就好。
? poll 从设计上来说,不再修改传入数组,不过这个要看你的平台了,所以行走江湖,还是小心为妙。
其实拖14年那么久也不是效率问题, 而是那个时代的硬件实在太弱,一台服务器处理1千多个链接简直就是神一样的存在了,select很长段时间已经满足需求。
但是poll仍然不是线程安全的, 这就意味着,不管服务器有多强悍,你也只能在一个线程里面处理一组I/O流。
你当然可以那多进程来配合了,不过然后你就有了多进程的各种问题。
于是5年以后, 在2002, 大神 Davide Libenzi 实现了epoll.
epoll 可以说是I/O 多路复用最新的一个实现,epoll 修复了poll 和select绝大部分问题, 比如:
? epoll 现在是线程安全的。
? epoll 现在不仅告诉你sock组里面数据,还会告诉你具体哪个sock有数据,你不用自己去找了。
?$ pstree |grep nginx ? |-+= 81666 root nginx: master process nginx ? | |--- 82500 nobody nginx: worker process ? | \--- 82501 nobody nginx: worker process
1个master进程,2个work进程
?每进来一个request,会有一个worker进程去处理。但不是全程的处理,处理到什么程度呢?处理到可能发生阻塞的地方,比如向上游(后端)服务器转发request,并等待请求返回。那么,这个处理的worker不会这么一直等着,他会在发送完请求后,注册一个事件:“如果upstream返回了,告诉我一声,我再接着干”。于是他就休息去了。这就是异步。此时,如果再有request 进来,他就可以很快再按这种方式处理。这就是非阻塞和IO多路复用。而一旦上游服务器返回了,就会触发这个事件,worker才会来接手,这个request才会接着往下走。这就是异步回调。
Nginx服务器,以其处理网络请求的高并发、高性能及高效率,获得了行业界的广泛认可,近年已稳居web服务器部署排名第二的位置,并被广泛用于反向代理和负载均衡。
Nginx是如何实现这些目标的呢?答案就是其独特的内部技术架构设计。看懂下面这张图,就明白了Nginx的内部技术架构。
简要说明几点:
1)nginx启动时,会生成两种类型的进程,一个是主进程(Master),一个(windows版本的目前只有一个)或多个工作进程(Worker)。主进程并不处理网络请求,主要负责调度工作进程,也就是图示的三项:加载配置、启动工作进程及非停升级。所以,nginx启动以后,查看操作系统的进程列表,我们就能看到至少有两个nginx进程。
2)服务器实际处理网络请求及响应的是工作进程(worker),在类unix系统上,nginx可以配置多个worker,而每个worker进程都可以同时处理数以千计的网络请求。
3)模块化设计。nginx的worker,包括核心和功能性模块,核心模块负责维持一个运行循环(run-loop),执行网络请求处理的不同阶段的模块功能,如网络读写、存储读写、内容传输、外出过滤,以及将请求发往上游服务器等。而其代码的模块化设计,也使得我们可以根据需要对功能模块进行适当的选择和修改,编译成具有特定功能的服务器。
4)事件驱动、异步及非阻塞,可以说是nginx得以获得高并发、高性能的关键因素,同时也得益于对Linux、Solaris及类BSD等操作系统内核中事件通知及I/O性能增强功能的采用,如kqueue、epoll及event ports。
5)代理(proxy)设计,可以说是nginx深入骨髓的设计,无论是对于HTTP,还是对于FastCGI、memcache、Redis等的网络请求或响应,本质上都采用了代理机制。所以,nginx天生就是高性能的代理服务器
访问nginx的官方网站:nginx news
Nginx版本类型
Mainline version: 主线版,即开发版
Stable version: 最新稳定版,生产环境上建议使用的版本
Legacy versions: 遗留的老版本的稳定版
Yum安装nginx
配置Yum源的官网:nginx: Linux packages
关闭防火墙和selinux:
?[root@nginx-server ~]# getenforce ?Enforcing ?? ?[root@nginx-server ~]# sed -i '/SELINUX/s/enforcing/disabled/' /etc/selinux/config ?? ?[root@nginx-server ~]# systemctl stop firewalld ?[root@nginx-server ~]# systemctl disable firewalld
?[root@nginx-server ~]#yum -y install nginx
?[root@nginx-server ~]#systemctl start nginx
?[root@nginx-server ~]#ss -nplt | grep nginx
?[root@nginx-server ~]# systemctl enable nginx
?nginx -c /path/nginx.conf ? ? # 以特定目录下的配置文件启动nginx: ?nginx -s reload ? ? ? ? ? # 修改配置后重新加载生效 ?nginx -s reopen ? # 重新打开日志文件 ?nginx -s stop # 快速停止nginx ?nginx -s quit # 完整有序的停止nginx ?nginx -t ? # 测试当前配置文件是否正确 ?nginx -t -c /path/to/nginx.conf # 测试特定的nginx配置文件是否正确 ?? ?注意: ?nginx -s reload 命令加载修改后的配置文件,命令下达后发生如下事件 ?1. Nginx的master进程检查配置文件的正确性,若是错误则返回错误信息,nginx继续采用原配置文件进行工作(因为worker未受到影响) ?2. Nginx启动新的worker进程,采用新的配置文件 ?3. Nginx将新的请求分配新的worker进程 ?4. Nginx等待以前的worker进程的全部请求已经都返回后,关闭相关worker进程 ?5. 重复上面过程,直到全部旧的worker进程都被关闭掉
?[root@localhost ~]#yum -y install gcc gcc-c++ make zlib-devel pcre pcre-devel openssl-devel perl-devel perl-ExtUtils-Embed gd-devel
?[root@localhost ~]#useradd -s /sbin/nologin -M nginx
?[root@localhost ~]#tar zxvf nginx-1.25.3.tar.gz -C /usr/local/
?[root@localhost ~]#cd /usr/local/nginx-1.25.3/ ?[root@localhost nginx-1.25.3] ./configure \ ?--user=nginx \ ?--group=nginx \ ?--prefix=/usr/local/nginx \ ?--conf-path=/etc/nginx/nginx.conf \ ?--sbin-path=/usr/sbin/nginx \ ?--error-log-path=/var/log/nginx/nginx_error.log \ ?--http-log-path=/var/log/nginx/nginx_access.log \ ?--pid-path=/usr/local/nginx/run/nginx.pid
?[root@localhost nginx-1.25.3]# make && make install
?[root@localhost nginx-1.25.3]# systemctl start nginx
?[root@localhost nginx-1.25.3]# ss -nplt | grep nginx
?#创建 nginx.service 文件 ?[root@localhost ~]#vim /lib/systemd/system/nginx.service ?[Unit] ?Description=nginx ?After=network.target ?? ?[Service] ?Type=forking ?ExecStart=/usr/sbin/nginx ?ExecReload=/usr/sbin/nginx -s reload ?ExecStop=/usr/sbin/nginx -s quit ?PrivateTmp=true ?? ?[Install] ?WantedBy=multi-user.target
?[root@localhost ~]# pkill nginx ?[root@localhost ~]# systemctl daemon-reload ?[root@localhost ~]# systemctl start nginx
?[root@localhost ~]# systemctl enable nginx
?nginx 日志文件分为 **log_format** 和 **access_log** 两部分 ?? ?log_format 定义记录的格式,其语法格式为 ?? ?log_format ? ? ? 样式名称 ? ? ? 样式详情 ?? ?配置文件中默认有 ?log_format main 'remote_addr - remote_user [time_local] "request" ' ? ? ? ? ? ? ? ? ? 'status body_bytes_sent "$http_referer" ' ? ? ? ? ? ? ? ? ? '"http_user_agent" "http_x_forwarded_for"';
?location /test { ? ? ? ? ? ? alias ? /var/www/qianfeng/; ? ? ? ? ? ? index index.html; ? ? ? ? } ? ? ? ? ? ?location /test { ? ? ? ? ? ? root ? /var/www/qianfeng/; ? ? ? ? ? ? index index.html; ? ? ? ? }
1)、通过 nginx -V 命令查看是否已安装 stub_status 模块
2)、编辑 /etc/nginx/nginx.conf 配置文件
?#添加以下内容~~ ?location /nginx-status { ? ? ? stub_status on; ? ? ? access_log ? /var/log/nginx/nginxstatus.log; ? ?#设置日志文件的位置 ? ? ? auth_basic ? ?"nginx-status"; ? ?#指定认证机制(与location后面的内容相同即可) ? ? ? auth_basic_user_file ? /etc/nginx/htpasswd; ? ? #指定认证的密码文件 ? ? ? }
3).创建认证口令文件并添加用户qianfeng和zdgg,密码用md5加密
?[root@localhost ~]# yum install -y httpd-tools #htpasswd 是开源 http 服务器 apache httpd 的一个命令工具,用于生成 http 基本认证的密码文件 ?htpasswd -c -m /etc/nginx/htpasswd qianfeng ? ? ? ? ? ? # -c 创建解密文件,-m MD5加密 ?htpasswd -m /etc/nginx/htpasswd zsgg
4)、重启服务
5)、客户端访问 http://ip/nginx-status 即可
?Active connections: 2 ?server accepts handled requests ? 27 27 40 ?Reading: 0 Writing: 1 Waiting: 1 ?? ?Active connections – 活跃的连接数量 ?server accepts handled requests — 总共处理了27个连接 , 成功创建27次握手, 总共处理了40个请求。 ?reading — 读取客户端的连接数。 ?writing — 响应数据到客户端的数量。 ?waiting — 开启 keep-alive 的情况下,这个值等于 active – (reading+writing), 意思就是 Nginx 已经处理完正在等候下一次请求指令的驻留连接。
1、编辑/etc/nginx/nginx.conf
?location / { ? ? ? ? ? ? root ? /var/www/nginx/; ? ? ? ? ? ? index index.html index.htm; ? ? ? ? ? ? limit_rate 2k; ?#对每个连接的限速为2k/s ? ? ? ? }
重启服务
注意要点:
配置文件中的每个语句要以 ; 结尾
使用 htpasswd 命令需要先安装 httpd-tools