Nginx Web服务器
- 主要内容:Nginx高性能Web服务器、Nginx工作原理、安装配置及升级、Nginx配置文件深入剖析、Nginx虚拟主机、location案例演示、Nginx rewrite实战、HTTPS安全Web服务器及Nginx高性能集群实战
Nginx Web简介
- Nginx(engine x)是一个高性能HTTP、反向代理、IMAP、POP3、SMTP服务器.其源码以类BSD许可证的形式发布,因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名
- Nginx的特点是占有内存少,并发能力强
- Nginx相对于Apache优点:
- 高并发响应性能非常好,官方Nginx处理静态文件并发5w/s
- 负载均衡及反向代理性能非常强
- 系统内存和CPU占用率低
- 可对后端服务进行健康检查
- 支持PHP CGI和FastCGI方式
- 可以作为缓存服务器、邮件代理服务器
- 配置代码简洁且容易上手
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这个连接之后,就开始读取请求,解析请求、处理请求,产生数据后,再返回给客户端,最后才断开连接,形成一个完整的请求流程
Nginx安装配置
- Nginx Web安装时可以指定很多的模块,默认需要安装rewrite模块,需要系统有PCRE库,安装PCRE支持rewrite功能.注意Nginx整合PCRE库,需要指定PCRE源码目录,而不是PCRE编译完成之后的路径,否则会报错
# 安装PCRE库支持
yum install pcre-devel pcre -y
# 下载Nginx源码包
wget http://nginx.org/download/nginx-1.12.0.tar.gz
cd /usr/src
mv ~/nginx-1.12.0.tar.gz ./
# 解压Nginx源码包
tar -xf nginx-1.12.0.tar.gz
# 进入解压目录,修改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
# 安装完毕
- 测试Nginx服务安装是否正确,同时启动Nginx Web服务
/usr/local/nginx/sbin/nginx -t
/usr/local/nginx/sbin/nginx # 按Enter键启动
ps -ef|grep nginx
Nginx管理及升级
- Nginx Web服务器安装完毕后,可以执行以下命令对其进行管理和维护
# 查看Nginx进程
ps -ef|grep nginx
# 平滑启动,进程文件路径在配置文件nginx.conf中可以找到
nginx -s reload 或者 kill -HUP 'cat /var/run/nginx.pid'
# 平滑启动的意思是在不停止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
# 停止Nginx
nginx -s stop
# 或者
pkill nginx
# 查看Nginx版本信息
nginx -v
# 查看完整的Nginx的配置信息
nginx -V
- Nginx Web软件定期更新,以下为将低版本升级或者将高版本降级的方法,一般分为4个步骤:软件下载、预编译、编译、配置
wget http://nginx.org/download/nginx-1.4.2.tar.gz
# 获取旧版本Nginx的configure选项
/usr/local/nginx/sbin/nginx -V
# 编译新版本的Nginx,千万不能make install
tar xf nginx-1.4.2.tar.gz
cd nginx-1.4.2/
./configure --user=www --group=www --prefix=/usr/local/nginx --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
make upgrade # 执行升级
# 验证Nginx是否升级成功,发现版本已经升级为1.4.2
/usr/local/nginx/sbin/nginx -V
[root@mango nginx-1.4.2]# ls /usr/local/nginx/sbin/
nginx nginx.old
Nginx配置文件优化一
# 定义Nginx运行的用户和用户组
user www www
# 启动进程,通常设置为和CPU的数量相等
worker_process 1
# 为每个进程分配CPU,将8个进程分配到8个CPU,也可以写多个,或者将一个进程分配到多个CPU
worker_cpu_affinity 00000001 ... 1000000
# 该指令是当一个Nginx进程打开的最多文件描述数目
worker_rlimit_nofile 102400
# 全局错误日志
error_log /usr/local/nginx/logs/error.log
# 错误日志定义等级,[debug|info|notice|warning|error|crit]
# PID文件
pid logs/nginx.pid
# 工作模式及连接数上限
events {
use epoll; # epoll是多路复用I/O中的一种方式,仅用于Linux2.6以上内核,可以大大提高Nginx性能
worker_connections 1024 # 单个后台worker process进程的最大并发连接数(最大连接数=连接数*进程数)
multi_accept on # 尽可能多地接受请求
}
# 设定HTTP服务器,利用它的反向代理功能提供负载均衡
http {
include mime.types # 设定MIME类型,类型由mime.type文件定义
default_type application/octet-stream
log_format # 设定日志格式
access_log /usr/local/nginx/logs/access.log
sendfile on # sendfile指令指定Nginx是否调用sendfile函数(zero copy方式)来输出文件,对于普通应用必须设为on,如果用来进行下载等应用磁盘I/O重负载应用,可设置为off,以平衡磁盘与网络I/O处理速度,降低系统的uptime
autoindex on # 开启目录列表访问,适合下载服务器,默认关闭
tcp_nopush on # 防止网络阻塞
keepalive_timeout 60 # keepalive超时时间,客户端到服务器端的连接持续有效时间,当出现对服务器的后继请求时,keepalive_timeout功能可避免建立或重新建立连接
tcp_nodelay on # 提高数据的实时响应性
gzip on # 开启gzip压缩
gzip_min_length 1KB
gzip_buffers 4 16KB
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 10MB # 允许客户端请求的最大单文件字节数
client_body_buffer_size 128KB # 缓冲区代理缓冲用户端请求的最大字节数
proxy_connect_timeout 90 # Nginx跟后端服务器连接超时时间(代理超时时间)
proxy_send_timeout 90 # 后端服务器数据回传时间(代理发送超时)
proxy_read_timeout 90 # 连接成功后,后端服务器响应时间(代理接收超时)
proxy_buffer_size 4KB # 设置代理服务器(Nginx)保存用户头信息的缓冲区大小
proxy_buffers 4 32KB # proxy_buffers缓冲区,网页平均在32KB以下的话这样设置
proxy_busy_buffers_size 64KB # 高负荷下缓冲大小(proxy_buffers * 2)
# 设定请求缓冲
large_client_header_buffers 4 4KB
client_header_buffer_size 4KB # 客户端请求头部的缓冲区大小,根据系统分页大小来设置,一般一个请求的头部大小不会超过1KB,不过由于一般系统分页都要大于1KB,所以这里设置为分页大小.分页大小可以用命令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指令中的inactice参数时间内文件的最少使用次数,如果超过这个数据,文件描述符一直是在缓存中打开的
# 包含其他配置文件,如自定义的虚拟主机
include vhosts.conf
Nginx配置文件优化二
- Nginx Web默认发布静态页面,也可以均衡后端动态页面.用户发起HTTP请求,如果请求为静态页面,Nginx直接处理并返回,如果请求的是动态页面,Nginx收到请求后之后会进行判断,转到后端服务器去处理
- Nginx实现负载均衡需要基于upstream模块,同时需要设置location proxy_pass转发指令实现
- 以下为Nginx应用负载均衡集群配置.负载均衡模块的名称可以任意指定但必须和vhosts.conf、nginx.conf虚拟主机的proxy_pass段保持一致,否则不能将请求转发至后端的服务器,weight表示配置权重,在fail_timeout内建成max_fails次数,失败则剔除均衡
upstream test { # test为负载均衡名称
server 10.0.0.204 weight=1 max_fails=2 fail_timeout=30s;
server 10.0.0.205 weight=1 max_fails=2 fail_timeout=30s;
}
# 虚拟主机配置
server {
# 监听80端口
listen 80;
# 定义网址访问
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
# 定义服务器的默认网站根目录
# root html;
# 定义首页索引文件名称
# index index.html index.htm;
# 反向代理的配置
# 如果后端服务器返回502、504、执行超时等错误,自动将请求转发到upstream负载均衡池的另一台服务器,实现故障转移
proxy_next_upstream http_502 http_504 error timeout invalid_header;
# 后端的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://test;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
# 定义错误提示页面
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# 配置Nginx动静分离,定义的静态页面直接从Nginx发布目录读取
location ~.*\.(html|htm|gif|jpg|bmp|png|ico|txt|js|css)$
{
# root /data/webapps/www;
# expires定义用户浏览器缓存的时间为3天,如果静态页面不常更新,可以设置更长,可以节省带宽和缓解服务器的压力
# expires 3d;
}
# 查看Nginx状态的地址
location /NginxStatus {
stub_status on;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
# 将PHP脚本全部转发到FastCGI处理,使用FastCGI默认配置
location ~ \.php$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# fastcgi_param SCRIPT_FILENAME /data/webapps/www$fastcgi_script_name;
include fastcgi_params;
}
- 通过expires参数设置,可以在浏览器缓存静态文件,从而减少用户与服务器之间的请求和流量.具体expires定义是给一个资源设定一个过期时间,浏览器无须去服务器端下载资源,直接通过浏览器自身确认是否过期即可,所以不会产生额外的流量
- 如果静态文件不常更新,expires可以设置为30d,表示在这30天之内在此访问该静态文件,浏览器会发送一个HTTP请求,会比对服务器该文件最后更新时间是否有变化,如果没有变化,则不会从服务器抓取,返回状态码304,如果有修改,则直接从服务器重新下载,返回HTTP状态码200