Nginx是 HTTP 和反向代理服务器,邮件代理服务器,以及 Igor Sysoev 最初编写的通用 TCP/UDP 代理服务器。
Nginx具备如下功能:
Nginx是一个主和几个工作进程;工作进程在非特权用户下运行。Nginx可以灵活配置, 重新配置和升级可执行文件,而不会中断客户端服务。
经过测试的操作系统和平台:
Nginx用在哪里(应用场景)?互联网应用很多都有使用到nginx,是最外层的网关‘;比如腾讯课堂、网易邮箱等。
Nginx使用可扩展的事件驱动架构,而不是更传统的过程驱动架构。这需要更低的内存占用,并且当并发连接扩大时,使内存使用更可预测。
Nginx开发的目标是实现 10 倍以上的性能,优化服务器资源的使用,同时也能够扩展和支持网站的动态增长。 因此,Nginx成为最知名的模块化,事件驱动,异步,单线程 Web 服务器和 Web 代理之一。
Nginx 是一个高性能的 Web 和反向代理服务器, 它具有很多非常优越的特性:
(1)作为 Web 服务器:相比 Apache,Nginx 使用更少的资源,支持更多的并发连接,体现更高的效率,这点使 Nginx 尤其受到虚拟主机提供商的欢迎。
(2)作为负载均衡服务器:Nginx 既可以在内部直接支持 Rails 和 PHP,也可以支持作为 HTTP 代理服务器 对外进行服务。Nginx 用 C 编写, 不论是系统资源开销还是 CPU 使用效率都比 Perlbal 要好的多。
(3)作为邮件代理服务器:Nginx 同时也是一个非常优秀的邮件代理服务器,能够在 不间断服务的情况下进行软件版本的升级。
从一开始 nginx 就是一个专门的工具,可以实现更高性能,更密集和经济地使用服务器资源,同时实现网站的动态发展,所以它采用了不同的模式。 随着发展变成是一个模块化的,事件驱动的,异步的,单线程的非阻塞架构的 nginx 代码基础。
nginx 大量使用复用和事件通知,并专门用于分离进程的特定任务。 连接在有限数量的单线程进程称为工作(worker)的高效运行循环中处理。 在每个工作(worker)中,nginx 可以处理每秒数千个并发连接和请求。
Apache也是HTTP服务器,也可以做网关,早期使用Apache比较多,但随着Nginx的发展,Nginx越来越用的多。
可以通过系统命令安装:
sudo apt-get install nginx
也可以通过如下的源码方式安装:
准备第三方支持库源码:
(1)nginx-1.13.7.tar.gz :Nginx的源码。
(2)openssl-1.1.0g.tar.gz :Nginx支持https,需要这个库做一些加密和解密。
(3)pcre-8.41.tar.gz :正则表达式的库,Nginx用来做正则式匹配。
(4)zlib-1.2.11.tar.gz :压缩库。
wget https://sourceforge.net/projects/pcre/files/pcre/8.41/pcre-8.41.tar.gz
--no-check-certificate
wget https://nchc.dl.sourceforge.net/project/libpng/zlib/1.2.11/zlib-1.2.11.tar.gz
--no-check-certificate
wget https://www.openssl.org/source/openssl-1.1.0g.tar.gz --no-check-certificate
wget http://nginx.org/download/nginx-1.13.7.tar.gz
解压每个包:
tar xzvf nginx-1.13.7.tar.gz
tar xzvf openssl-1.1.0g.tar.gz
tar xzvf pcre-8.41.tar.gz
tar xzvf zlib-1.2.11.tar.gz
编译Nginx:
./configure --prefix=/usr/local/nginx --with-http_realip_module
--with-http_addition_module --with-http_gzip_static_module
--with-http_secure_link_module --with-http_stub_status_module
--with-stream --with-pcre=/home/fly/workspace/pcre-8.41
--with-zlib=/home/fly/workspace/zlib-1.2.11
--with-openssl=/home/fly/workspace/openssl-1.1.0g
注意zlib、pcre、openssl的路径要改为自己的路径。
执行结果:
checking for OS
...
Configuration summary
+ using PCRE library: /home/fly/workspace/pcre-8.41
+ using OpenSSL library: /home/fly/workspace/openssl-1.1.0g
+ using zlib library: /home/fly/workspace/zlib-1.2.11
nginx path prefix: "/usr/local/nginx"
nginx binary file: "/usr/local/nginx/sbin/nginx"
nginx modules path: "/usr/local/nginx/modules"
nginx configuration prefix: "/usr/local/nginx/conf"
nginx configuration file: "/usr/local/nginx/conf/nginx.conf"
nginx pid file: "/usr/local/nginx/logs/nginx.pid"
nginx error log file: "/usr/local/nginx/logs/error.log"
nginx http access log file: "/usr/local/nginx/logs/access.log"
nginx http client request body temporary files: "client_body_temp"
nginx http proxy temporary files: "proxy_temp"
nginx http fastcgi temporary files: "fastcgi_temp"
nginx http uwsgi temporary files: "uwsgi_temp"
nginx http scgi temporary files: "scgi_temp"
安装Nginx:
make
sudo make install
在/usr/local/目录下面,产生了 nginx 的目录。
conf html logs sbin
Nginx的配置文件存放于conf/nginx.conf,bin文件是位于sbin目录下的nginx文件,logs是存放的启动日志、错误日志、运行日志等。
启动Nginx(需要sudo权限):
cd /usr/loacal/nginx
sudo ./sbin/nginx -c ./conf/nginx.conf
打开浏览器访问此机器的IP,如果浏览器出现 Welcome to nginx! 则表示 Nginx 已经安装并运行成功:
要启动 nginx,请运行可执行文件。 当 nginx 启动后,可以通过使用-s 参数调用可执行文件来控制它。 使用以下语法:
nginx -s signal
信号(signal)的值可能是以下之一:
(1)stop - 快速关闭服务:要等待工作进程完成服务当前请求,该命令应该在启动 nginx 的同一用户下执行。
(2)quit - 正常关闭服务
(3)reload - 重新加载配置文件
(4)reopen - 重新打开日志文件
要重新加载配置文件,请执行:
nginx -s reload
当主进程收到要重新加载配置的信号,它将检查新配置文件的语法有效性,并尝试应用其中提供的配置。 如果这是成功的,主进程将启动新的工作进程,并向旧的工作进程发送消息,请求它们关闭。 否则,主进程回滚更改,并继续使用旧配置。 老工作进程,接收关闭命令,停止接受新连接,并继续维护当前请求,直到所有这些请求得到维护。 之后,旧的工作进程退出。
Nginx 由配置文件中指定的指令控制的模块组成。 指令分为简单指令和块指令。 一个简单的指令由空格分隔的名称和参数组成,并以分号(;)结尾。
块指令具有与简单指令相同的结构,但不是以分号结尾,而是以大括号({和})包围的一组附加指令结束。 如果块指令可以在大括号内部有其他指令,则称为上下文(例如:events,http,server 和 location)。
配置文件中放置在任何上下文之外的伪指令都被认为是主上下文。events 和 http 指令驻留在主上下文中,server 在 http 中的,而 location 在 http 块中。#号之后的一行的部分被视为注释。
手写一个简单的配置文件:
# test.conf
worker_processes 4; #工作进程数量
events {
worker_connections 1024;
}
http {
server {
listen 8888; #监听端口
}
}
这里没有配置自己的服务器目录,所以会默认访问/usr/local/nginx/html/index
# ls /usr/local/nginx/html/index
50x.html index.html
worker_processes 4;配置的是工作进程数量。
$ ps -aux | grep nginx
root 11122 0.0 0.0 20676 384 ? Ss 11:45 0:00 nginx: master process
/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/fly.conf
nobody 11123 0.0 0.0 21100 2424 ? S 11:45 0:00 nginx: worker process
nobody 11124 0.0 0.0 21100 2424 ? S 11:45 0:00 nginx: worker process
nobody 11125 0.0 0.0 21100 2424 ? S 11:45 0:00 nginx: worker process
nobody 11126 0.0 0.0 21100 2428 ? S 11:45 0:00 nginx: worker process
Nginx可以放多个server,如下示例:
# test.conf
worker_processes 4;
events {
worker_connections 1024;
}
http {
server {
listen 8888;
}
server {
listen 8889;
}
server {
listen 8890;
}
server {
listen 8891;
}
}
服务器的状态:
fly@fly-virtual-machine:/usr/local/nginx$ sudo netstat -anop | grep 8888
tcp 0 0 0.0.0.0:8888 0.0.0.0:* LISTEN 11536/fly.conf 关闭 (0.00/0/0)
fly@fly-virtual-machine:/usr/local/nginx$ sudo netstat -anop | grep 8889
tcp 0 0 0.0.0.0:8889 0.0.0.0:* LISTEN 11536/fly.conf 关闭 (0.00/0/0)
fly@fly-virtual-machine:/usr/local/nginx$ sudo netstat -anop | grep 8890
tcp 0 0 0.0.0.0:8890 0.0.0.0:* LISTEN 11536/fly.conf 关闭 (0.00/0/0)
fly@fly-virtual-machine:/usr/local/nginx$ sudo netstat -anop | grep 8891
tcp 0 0 0.0.0.0:8891 0.0.0.0:* LISTEN 11536/fly.conf 关闭 (0.00/0/0)
可以看到所有的服务器都在一个进程里面,该进程就是Nginx的master的主进程。也就是说四个server都是被Nginx的master进程监听。
$ ps -aux | grep nginx
root 11536 0.0 0.0 20684 408 ? Ss 14:25 0:00 nginx: master process
./sbin/nginx -c conf/fly.conf
nobody 11537 0.0 0.0 21116 2396 ? S 14:25 0:00 nginx: worker process
nobody 11538 0.0 0.0 21116 2396 ? S 14:25 0:00 nginx: worker process
nobody 11539 0.0 0.0 21116 2396 ? S 14:25 0:00 nginx: worker process
nobody 11540 0.0 0.0 21116 2400 ? S 14:25 0:00 nginx: worker process
nginx 有一个主进程和几个工作进程。 主进程的主要目的是读取和评估配置,并维护工作进程。 工作进程对请求进行实际处理。 nginx 采用基于事件的模型和依赖于操作系统的机制来有效地在工作进程之间分配请求。 工作进程的数量可在配置文件中定义,并且可以针对给定的配置进行修改,或者自动调整到可用 CPU 内核的数量。
在配置文件中确定 nginx 及其模块的工作方式。默认情况下,配置文件名为 nginx.conf,并放在目录:/usr/local/nginx/conf, /etc/nginx, 或 /usr/local/etc/nginx 中。
Nginx是由master进程监听,所有的请求都在worker进程处理。
那么如何做到在master进程监听,让 listen() 得到的listen fd进入到worker进程,然后可以在worker进程处理呢?
在master进行listen,listen之后进行fork()出子进程,这样master创建的 listen fd就可以被子进程继承了。
既然Nginx是有多个worker进程处理连接的,也就是存在多线程/多进程、多端口的情况,那么就势必会有惊群问题。这是客观问题。
Nginx内部是这么解决惊群问题的:在同一时刻,只有一个进程把listen fd加入epoll中,具体详见nginx惊群处理