01 Nginx WEB 服务器企业实战

Nginx WEB 服务器企业实战

万维网 (WORLD WIDE WEB,WWW)服务器,也称之为 WEB 服务器,主要功能是提供网 上信息浏览服务。目前主流的 WEB 服务器软件包括:Apache、Nginx、Lighttpd、IIS、 Resin、Tomcat、WebLogic、Jetty。

本章向读者介绍 Nginx 高性能 WEB 服务器、Nginx 工作原理、安装配置及升级、Nginx 配置文件深入剖析、Nginx 虚拟主机、Location 案例演示、Nginx Rewirte 企业案例实战、HTTPS 安全 WEB 服务器及 Nginx 高性能集群实战等。

14.1 Nginx WEB 入门简介

Nginx ("engine x") 是一个高性能 HTTP 和 反向代理 服务器、IMAP、POP3、 SMTP 服务器。 Nginx 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开 发的,第一个公开版本 0.1.0 发布于 2004 年 10 月 4 日。其将源代码以类 BSD 许可证的 形式发布,因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。

由于 Nginx 的高性能、轻量级,目前越来越多的互联网企业开始使用 Nginx WEB 服 务器。据 Netcraft 统计,在 2017 年 4 月份,世界上最繁忙的网站中有 28.72 %使用 Nginx 作为其服务器或者代理服务器。

Nginx 相对于 Apache 优点如下:
❑ 高并发响应性能非常好,官方 Nginx 处理静态文件并发 5w/s; ❑ 负载均衡及反向代理性能非常强;
❑ 系统内存和 CPU 占用率低;
❑ 可对后端服务进行健康检查;
❑ 支持 PHP cgi 方式和 FastCGI 方式;
❑ 可以作为缓存服务器、邮件代理服务器;
❑ 配置代码简洁且容易上手。

14.2 Nginx 工作原理

Nginx WEB 服务器最主要就是各种模块的工作,模块从结构上分为核心模块、基础模 块和第三方模块,其中三类模块分别如下:

  • 核心模块:HTTP 模块、EVENT 模块和 MAIL 模块等;

  • ❑ 基础模块:HTTP Access 模块、HTTP FastCGI 模块、HTTP Proxy 模块和 HTTP Rewrite 模块;

  • ❑ 第三方模块:HTTP Upstream Request Hash 模块、Notice 模块和 HTTP Access Key模块、Limit_req 模块等;

    Nginx 的模块从功能上分为如下三类。

  • ❑ Handlers(处理器模块):此类模块直接处理请求,并进行输出内容和修改 headers 信息等操作,Handlers 处理器模块一般只能有一个;

  • ❑ Filters (过滤器模块):此类模块主要对其他处理器模块输出的内容进行修 改操作,最后由 Nginx 输出;

  • ❑ Proxies (代理类模块):此类模块是 Nginx 的 HTTP Upstream 之类的模块, 这些模块主要与后端一些服务比如 FastCGI 等进行交互,实现服务代理和负载 均衡等功能。

Nginx 由内核和模块组成,其中内核的设计非常微小和简洁,完成的工作也非常简单, 仅仅通过查找配置文件将客户端的请求映射到一个 location block,而 location 是 Nginx 配置中的一个指令,用于访问的 URL 匹配,而在这个 location 中所配置的每个指令将会 启动不同的模块去完成相应的工作.

Nginx 的高并发得益于其采用了 epoll 模型,与传统的服务器程序架构不同,epoll

是 Linux 内核 2.6 以后才出现的,Nginx 采用 epoll 模型,异步非阻塞,而 apache 采用 的是 select 模型:

Select 特点:select 选择句柄的时候,是遍历所有句柄,也就是说句柄有事件响应 时,select 需要遍历所有句柄才能获取到哪些句柄有事件通知,因此效率是非常低。

epoll 的特点:epoll 对于句柄事件的选择不是遍历的,是事件响应的,就是句柄上 事件来就马上选择出来,不需要遍历整个句柄链表,因此效率非常高。

Nginx 默认以 80 端口监听在服务器上,并且启动一个 master 进程,同时有 master 进程生成多个工作进程,当浏览器发起一个 HTTP 连接请求,每个进程都有可能处理这个 连接,怎么做到的呢?怎么保证同一时刻一个 HTTP 请求被一个工作进程处理呢。

首先每个 worker 进程都是从 Master 进程 fork 出来,在 Master 进程里面,建立好 需要 listen 的 socket(listenfd)之后,会 fork 出多个 worker 进程。

所有 worker 进程的 listenfd 会在新连接到来时变得可读,为保证只有一个进程处 理该连接,所有 worker 进程在注册 listenfd 读事件前抢 accept_mutex,抢到互斥锁的 那个进程注册 listenfd 读事件,在读事件里调用 accept 接受该连接。

当一个 worker 进程在 accept 这个连接之后,就开始读取请求、解析请求、处理请 求,产生数据后,再返回给客户端,最后才断开连接,这样形成一个完整的请求流程。 如图 14-2 所示:

图 14-2 Nginx Worker 进程工作原理

14.3 Nginx 安装配置

Nginx WEB 安装时可以指定很多的模块,默认需要安装 Rewrite 模块,也即是需要系 统有 PCRE 库,安装 Pcre 支持 Rewrite 功能。如下为安装 Nginx WEB 服务器方法: 源码的路径,而不是编译后的路径,否则会报错。

#安装 PCRE 库支持
yum install pcre-devel pcre -y

下载 Nginx 源码包

cd /usr/src

wget -c http://nginx.org/download/nginx-1.12.0.tar.gz #解压 Nginx 源码包
tar -xzf nginx-1.12.0.tar.gz
#进入解压目录,然后 sed 修改 Nginx 版本信息为 JWS

cd nginx-1.12.0 ; sed -i -e 's/1.12.0//g' -e 's/nginx//JWS/g' -e 's/"NGINX"/"JWS"/g' src/core/nginx.h
#预编译 Nginx
useradd www ;./configure --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module

#.configure 预编译成功后,执行 make 命令进行编译 make
#make 执行成功后,执行 make install 正式安装 make install

yum -y install openssl openssl-devel

#至此 Nginx WEB 服务器安装完毕。

测试 Nginx 服务安装是否正确,同时启动 Nginx WEB 服务,代码命令如下:

/usr/local/nginx/sbin/nginx -t 检查 nginx 配置文件是否正确,返回 OK 即正确.

[root@localhost ~]# /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful [root@localhost ~]#

然后启动 nginx,/usr/local/nginx/sbin/nginx 回车即可。查看进程是否已启动:

[root@localhost ~]# ps -ef |grep nginx
nobody 5381 30285 0 May16 ? 09:04:31 nginx: worker process
root 30285 1 0 2017 ? 00:00:00 nginx: master process /usr/local/nginx/sbin/nginx

root 32260 32220 0 12:34 pts/0 00:00:00 grep nginx [root@localhost ~]#

通过浏览器访问 Nginx 默认测试页面

14.4 Nginx 管理及升级

Nginx WEB 服务器安装完毕,可以执行如下命令对其进管理和维护,命令如下:

#查看 nginx 进程
ps -ef|grep nginx
#平滑启动 nginx
kill -HUP cat /var/run/nginx.pid
或者
nginx -s reload
其中进程文件路径在配置文件 nginx.conf 中可以找到。
平滑启动的意思是在不停止 nginx 的情况下,重启 nginx,重新加载配置文件,启动新 的工作线程,完美停止旧的工作线程。
#完美停止 nginx
kill -QUIT cat /var/run/nginx.pid
#快速停止 nginx

kill -TERM cat /var/run/nginx.pid 或者
kill -INT cat /var/run/nginx.pid #完美停止工作进程(主要用于平滑升级) kill -WINCH cat /var/run/nginx.pid #强制停止 nginx

pkill -9 nginx
#检查对 nginx.conf 文件的修改是否正确
nginx -t -c /etc/nginx/nginx.conf 或者 nginx -t #停止 nginx 的命令
nginx -s stop 或者 pkill nginx
#查看 nginx 的版本信息
nginx -v
#查看完整的 nginx 的配置信息
nginx -V

Nginx WEB 服务器定期更新,如果需要将低版本升级或者将高版本降级,升级或者降 级方法如下,分为四个步骤,包括软件下载、预编译、编译、配置,具体方法如下:

wget http://www.nginx.org/download/nginx-1.4.2.tar.gz 获取旧版本 nginx 的 configure 选项 /usr/local/nginx/sbin/nginx -V
编译新版本的 Nginx

tar -xvf nginx-1.4.2.tar.gz
cd nginx-1.4.2
./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_stub_status_module --with-http_ssl_module

make
备份旧版本的 nginx 可执行文件,复制新版本的 nginx 这行文件
mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old
cp objs/nginx /usr/local/nginx/sbin/
测试新版本 nginx 是否正常
/usr/local/nginx/sbin/nginx -t
平滑重启升级 nginx
kill –QUIT cat /usr/local/nginx/log/nginx.oldbin ##关闭旧版 nginx 验证 nginx 是否升级成功
/usr/local/nginx/sbin/nginx -V 显示最新编译的版本信息即可。

14.5 Nginx 配置文件优化一

学习 Nginx 服务的难点在于对配置文件的理解和优化,熟练掌握 Nginx 配置文件参 数的含义可以更快的掌握 Nginx,如下为 Nginx.conf 配置文件常用参数详解:

#定义 Nginx 运行的用户和用户组
user www www;
#启动进程,通常设置成和 cpu 的数量相等
worker_processes 8;
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;

#为每个进程分配 cpu,上例中将 8 个进程分配到 8 个 cpu,当然可以写多个,或者将一 个进程分配到多个 cpu。
worker_rlimit_nofile 102400;
#该指令是当一个 nginx 进程打开的最多文件描述符数目,理论值应该是最多打开文件 数(ulimit -n)与 nginx 进程数相除,但是 nginx 分配请求并不是那么均匀,所以最好与 ulimit -n 的值保持一致。

#全局错误日志及 PID 文件
error_log /usr/local/nginx/logs/error.log;
#错误日志定义等级,[ debug | info | notice | warn | error | crit ]
pid /usr/local/nginx/nginx.pid;
#工作模式及连接数上限
events {
use epoll;
#epoll 是多路复用 IO(I/O Multiplexing)中的一种方式,但是仅用于 linux2.6 以上内 核,可以大大提高 nginx 的性能.
worker_connections 102400;
#单个后台 worker process 进程的最大并发链接数 (最大连接数=连接数*进程数) multi_accept on;
#尽可能多的接受请求.
}
#设定 http 服务器,利用它的反向代理功能提供负载均衡支持
http {
#设定 mime 类型,类型由 mime.type 文件定义
include mime.types;
default_type application/octet-stream;
#设定日志格式
access_log /usr/local/nginx/log/nginx/access.log;
sendfile on;
#sendfile 指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件, 对于普通应用必须设为 on
#如果用来进行下载等应用磁盘 IO 重负载应用,可设置为 off,以平衡磁盘与网络 I/O处理速度,降低系统的 uptime。
#autoindex on; #开启目录列表访问,合适下载服务器,默认关闭。 tcp_nopush on;

#防止网络阻塞
keepalive_timeout 60;
#keepalive 超时时间,客户端到服务器端的连接持续有效时间,当出现对服务器的后继 请求时,keepalive-timeout 功能可避免建立或重新建立连接。
tcp_nodelay on;
#提高数据的实时响应性
#开启 gzip 压缩
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.1;
gzip_comp_level 2;
#压缩级别大小,最大为 9,值越小,压缩后比例越小,CPU 处理更快。
#值越大,消耗 CPU 比较高。
gzip_types text/plain application/x-javascript text/css application/xml;
gzip_vary on;
client_max_body_size 10m;
#允许客户端请求的最大单文件字节数
client_body_buffer_size 128k;
#缓冲区代理缓冲用户端请求的最大字节数.
proxy_connect_timeout 90;

#nginx 跟后端服务器连接超时时间(代理连接超时) proxy_send_timeout 90; #后端服务器数据回传时间(代理发送超时) proxy_read_timeout 90; #连接成功后,后端服务器响应时间(代理接收超时) proxy_buffer_size 4k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小 proxy_buffers 4 32k;

#proxy_buffers 缓冲区,网页平均在 32k 以下的话,这样设置 proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2)
#设定请求缓冲

large_client_header_buffers 4 4k;
client_header_buffer_size 4k; #客户端请求头部的缓冲区大小,这个可以根据你的系统分页大小来设置,一般一个请 求的头部大小不会超过 1k
#不过由于一般系统分页都要大于 1k,所以这里设置为分页大小。分页大小可以用命令 getconf PAGESIZE 取得。
open_file_cache max=102400 inactive=20s; #这个将为打开文件指定缓存,默认是没有启用的,max 指定缓存数量,建议和打开文件 数一致,inactive 是指经过多长时间文件没被请求后删除缓存。 open_file_cache_valid 30s;
#这个是指多长时间检查一次缓存的有效信息。
open_file_cache_min_uses 1;
#open_file_cache 指令中的 inactive 参数时间内文件的最少使用次数,如果超过这个 数字,文件描述符一直是在缓存中打开的,如上例,如果有一个文件在 inactive

包含其它配置文件,如自定义的虚拟主机

include vhosts.conf;

14.6 Nginx 配置文件优化二

Nginx WEB 默认发布静态页面,也可以均衡后端动态网站,用户发起 HTTP 请求,如 果请求静态页面,Nginx 直接处理并返回,如果请求的是动态页面,Nginx 收到请求之后 会进行判断,转到后端服务器去处理。

Nginx 实现负载均衡需要基于 upstream 模块,同时需要设置 location proxy_pass 转发指令实现。

如下为 Ningx 应用负载均衡集群配置,根据后端实际情况修改即可,jfedu_www 为负 载均衡模块的名称,可以任意指定,但必须跟 vhosts.conf、Nginx.conf 虚拟主机的 proxy_pass 段保持一致,否则不能将请求转发至后端的服务器,weight 表示配置权重, 在 fail_timeout 内检查 max_fails 次数,失败则剔除均衡。

upstream jfedu_www {
server 127.0.0.1:8080 weight=1 max_fails=2 fail_timeout=30s; server 127.0.0.1:8081 weight=1 max_fails=2 fail_timeout=30s;

} #虚拟主机配置

server {
#侦听 80 端口

listen 80;
#定义使用 www.jfedu.net 访问 server_name www.jfedu.net; #设定本虚拟主机的访问日志

access_log logs/access.log main;
root /data/webapps/www; #定义服务器的默认网站根目录位置

index index.php index.html index.htm; #定义首页索引文件的名称 #默认请求
location ~ /{

root /data/webapps/www; #定义服务器的默认网站根目录位置 index index.php index.html index.htm; #定义首页索引文件的名称 #以下是一些反向代理的配置.
proxy_next_upstream http_502 http_504 error timeout invalid_header;

如果后端的服务器返回 502、504、执行超时等错误,自动将请求转发到

upstream 负载均衡池中的另一台服务器,实现故障转移。 proxy_redirect off;

#后端的 Web 服务器可以通过 X-Forwarded-For 获取用户真实 IP proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_pass http://jfedu_www; #请求转向后端定义的均衡模块 }

# 定义错误提示页面
error_page 500 502 503 504 /50x.html; location = /50x.html {
root html;

}
#配置 Nginx 动静分离,定义的静态页面直接从 Nginx 发布目录读取。 location ~ .*.(html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css)$ {

root /data/webapps/www;

#expires 定义用户浏览器缓存的时间为 3 天,如果静态页面不常更新,可 以设置更长,这样可以节省带宽和缓解服务器的压力,在浏览器保存该类型文件的天数。

expires 3d; }

#PHP 脚本请求全部转发到 FastCGI 处理. 使用 FastCGI 默认配置.

location ~ .php$ {

​ root /root;
FastCGI_pass 127.0.0.1:9000;

FastCGI_index index.php; FastCGI_param

/data/webapps/www$FastCGI_script_name;

include FastCGI_params;

}
#设定查看 Nginx 状态的地址 location /NginxStatus {

stub_status on; }

} }

SCRIPT_FILENAME

通过 Expires 参数设置,可以使浏览器缓存过期时间,减少与服务器之间的请求和 流量。具体 Expires 定义是给一个资源设定一个过期时间,也就是说无需去服务端验证, 直接通过浏览器自身确认是否过期即可,所以不会产生额外的流量。

如果静态文件不常更新,Expires 可以设置为 30d,表示在这 30 天之内再次访问该 静态文件,浏览器会发送一个 HTTP 请求,会比对服务器该文件最后更新时间是否有变化, 如果没有变化,则不会从服务器抓取,返回 HTTP 状态码 304,如果有修改,则直接从服务器重新下载,返回 HTTP 状态码 200。

14.7 Nginx 虚拟主机实战

原文地址:https://www.cnblogs.com/gerenboke/p/12727983.html