一、选用Nginx的理由
1)支持高并发连接
得益于Nginx使用最新的epoll(Linux 2.6内核)和 kqueue(FreeBSD)网络I/O模型,官方测试Nginx可最高支持5万的并发连接,在实际的生产环境中,可实际支持2~4万的并发连接数。
2)内存消耗低
3)成本低
4)配置简单
5)支持Rewrite重写规则,能够根据域名、URL的不同将http请求分发到不同的后端服务器群组。
6)内置健康检查功能,如果Nginx proxy后端的某台服务器宕机了,不会影响前端访问
7)节省带宽,支持GZIP压缩,可添加浏览器本地缓存的header
8)稳定性高,用于反向代理,宕机概率极低
9)支持热部署,启动容易,几乎可以7x24小时不间断运行,且支持不间断服务的情况下,对软件进行升级。
二、Nginx的启停
运行环境:max os, Nginx通过brew install安装,路径为:/usr/local/Cellar/nginx/1.10.2_1/
1、启动
nginx [-c path]
-c 选项可用来指定配置文件路径, 如 nginx -c /usr/local/etc/nginx.conf
2、停止
一般通过发送系统信号给Nginx主进程的方式来停止。可通过 ps -ef | grep nginx查看进程号
$ ps -ef | grep nginx 501 3709 1 0 3:10下午 ?? 0:00.00 nginx: master process nginx 501 3710 3709 0 3:10下午 ?? 0:00.00 nginx: worker process 501 3711 3709 0 3:10下午 ?? 0:00.01 nginx: worker process 501 3712 3709 0 3:10下午 ?? 0:00.01 nginx: worker process 501 3713 3709 0 3:10下午 ?? 0:00.01 nginx: worker process 501 3724 686 0 3:11下午 ttys001 0:00.00 grep nginx
如上所示,3709为主进程,3710 ~ 3713为工作子进程。nginx.conf配置文件中指定了pid文件的存放路径, 如/usr/local/var/run/nginx.pid, 其中存放了当前Nginx运行的主进程号,可通过该进程号,来平滑停止Nginx服务。
1) 平滑停止
$ kill -QUIT 3709 $ ps -ef | grep nginx 501 3989 686 0 3:49下午 ttys001 0:00.00 grep nginx
# 或者,通过pid文件获取主进程号来停止
$ kill -QUIT `cat /usr/local/var/run/nginx.pid`
2)快速停止
$ kill -TERM 3709 $ ps -ef | grep nginx 501 3989 686 0 3:49下午 ttys001 0:00.00 grep nginx # 或者,通过pid文件获取主进程号来停止 $ kill -TERM `cat /usr/local/var/run/nginx.pid` # 另一种方式 $ kill -INT 3709 $ ps -ef | grep nginx 501 3989 686 0 3:49下午 ttys001 0:00.00 grep nginx # 或者,通过pid文件获取主进程号来停止 $ kill -INT `cat /usr/local/var/run/nginx.pid`
3)强制停止
$ pkill -9 nginx $ ps -ef | grep nginx 501 4081 686 0 3:57下午 ttys001 0:00.00 grep nginx
3、平滑重启
如果修改了配置文件nginx.conf,想重启Nginx,需要发送信号给Nginx主进程来实现。
$ ps -ef | grep nginx 501 4188 1 0 4:13下午 ?? 0:00.00 nginx: master process nginx 501 4189 4188 0 4:13下午 ?? 0:00.00 nginx: worker process 501 4190 4188 0 4:13下午 ?? 0:00.00 nginx: worker process 501 4191 4188 0 4:13下午 ?? 0:00.00 nginx: worker process 501 4192 4188 0 4:13下午 ?? 0:00.00 nginx: worker process 501 4195 686 0 4:13下午 ttys001 0:00.00 grep nginx $ kill -HUP `cat /usr/local/var/run/nginx.pid` $ ps -ef | grep nginx 501 4188 1 0 4:13下午 ?? 0:00.01 nginx: master process nginx 501 4201 4188 0 4:13下午 ?? 0:00.00 nginx: worker process 501 4202 4188 0 4:13下午 ?? 0:00.00 nginx: worker process 501 4203 4188 0 4:13下午 ?? 0:00.00 nginx: worker process 501 4204 4188 0 4:13下午 ?? 0:00.00 nginx: worker process 501 4206 686 0 4:13下午 ttys001 0:00.00 grep nginx
可以看出,重启的只是工作进程,当接收到HUP信号后,当前工作进程会关闭监听套接字,并继续为当前连接的客户端服务,当所有客户端服务完成后,旧的工作进程关闭。
4、其他信号
USR1: 重新打开日志文件,切割日志文件时有用
USR2: 平滑升级可执行程序
WINCTH: 从容关闭工作进程
$ kill -WINCH `cat /usr/local/var/run/nginx.pid` $ ps -ef | grep nginx 501 4188 1 0 4:13下午 ?? 0:00.01 nginx: master process nginx 501 4258 686 0 4:21下午 ttys001 0:00.00 grep nginx
三、Nginx基本配置
1、虚拟主机配置
虚拟主机提供了同一台服务器,同一个Nginx进程上运行多个网站的功能,Nginx支持配置多种类型的虚拟主机: 基于IP的, 基于域名的, 基于端口号的。
在nginx.conf中,一台简化的虚拟主机配置如下:
http { server { listen 8080; server_name localhost; access_log logs/host.access.log main; location / { root html; index index.html index.htm; } } }
基于IP的虚拟主机配置
通过ifconfig和route命令为当前服务器主机添加IP别名,如下:
$ ifconfig eth0:1 192.168.1.102 broadcast 192.168.1.255 netmask 255.255.255.0 up $ route add -host 192.168.1.102 dev eth0:1
接下来分别对192.168.1.101和192.168.1.102配置虚拟主机
http { # 第一个虚拟主机 server { # 监听的IP和端口 listen 192.168.1.101:8080; # 主机名称 server_name 192.168.1.101; # 访问日志文件存放路径 access_log logs/host.access.log main; location / { # html网页文件存放目录 root /data0/htmldoc/server1; # 默认首页文件,从左至右,找不到index.html,就查找index.htm,都查找不到则报错 index index.html index.htm; } } # 第二个虚拟主机 server { listen 192.168.1.102:8080; server_name 192.168.1.102; access_log logs/host.access.log main; location / { root /data0/htmldoc/server2; index index.html index.htm; } } }
基于域名的虚拟主机配置
配置你的DNS服务器,将你的IP映射到不同的域名即可实现,可以有效解决IP地址不足的问题。
http { # 第一个虚拟主机 server { # 监听的IP和端口 listen 8080; # 主机名称 server_name aaa.ssl.com; # 访问日志文件存放路径 access_log logs/host.access.log main; location / { # html网页文件存放目录 root /data0/htmldoc/server1; # 默认首页文件,从左至右,找不到index.html,就查找index.htm,都查找不到则报错 index index.html index.htm; } } # 第二个虚拟主机 server { listen 8080; server_name bbb.ssl.com; access_log logs/host.access.log main; location / { root /data0/htmldoc/server2; index index.html index.htm; } } }
2、日志文件配置与切割
1)配置log_format日志格式 log_format name format [format..]
log_format main '$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"';
name用来指定日志格式的名称,保持唯一性。
$remote_addr用于记录远程客户端IP地址, 还有另外一个变量$http_x_forwarded_for用来记录用户的X-Forwarded-For IP地址。
2)配置日志文件存放路径
access_log path [format [ buffer=size | off ]]
path: 存放路径
format: 日志格式名称,log_format中设置的name
buffer: 内存缓冲区大小
off: 表示关闭日志记录
如: access_log /data0/logs/log1 combined buffer=32k;
3) 日志切割
a) 重命名原日志文件,然后向Nginx主进程发送USR1信号,让Nginx重新生成一个新的日志文件。
mv /data0/logs/access.log /data0/logs/20170716.log
kill -USR1 `cat /usr/local/var/run/nginx.pid`
b)按天定时切割日志文件的方式
# !/bin/bash # 这个脚本须在每天的00:00运行, 保存为cut_nginx.log.sh # Nginx日志文件的存放路径 logs_path="/data0/logs" mkdir -p ${logs_path}$(date -d "yesterday"+"%Y")/$(date -d "yesterday"+"%m")/ mv ${logs_path}access.log ${logs_path}$(date -d "yesterday"+"%Y")/$(date -d "yesterday"+"%m")/access_$(date -d "yesterday"+"%Y%m%d").log kill -USR1 `cat /usr/local/var/nginx/nginx.pid`
配置crontab每天凌晨00:00定时执行该脚本
crontab -e
输入:
00 00 * * * /bin/bash /usr/local/var/nginx/sbin/cut_nginx.log.sh
3、压缩配置
gzip压缩后,页面大小可变为原来的30%甚至更小,这样用户浏览页面时速度会快很多。
4、自动列目录
location / { # html网页文件存放目录 root /Users/qwe/Desktop; # 自动列出目录 autoindex on; }
5、浏览器本地缓存设置
浏览器将用户最近请求过的页面存储到本地磁盘,当用户再次访问时,可以直接从本地磁盘显示文档,加速页面浏览速度,节约网络资源。
浏览器缓存通过expires指令输出header头来实现 。
语法: expires [time | epoch | max | off]
默认值: expires off
作用域:http, server, location
用途: 使用本指令可以控制HTTP应答中的“Expires”和“Cache-Control”
epoch 指定 Expires值为 1 January,1970,00:00:01 GMT
max 指定 Expires值为 31 December,2037 23:59:59 GMT, Cache-Control值为10年
-1 指定"Expires"值为服务器当前时间,即永远过期。
Cache-Control的值由你指定的时间来决定, 负数表示no-cache, 正数或零为你指定时间的秒数。
”off“表示不修改“Expires”和”Cache-Control“的值。
一般对常见格式的图片、Flash文件缓存30天,对js、css文件缓存1小时。如下:
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { expires 30d; } location ~ .*\.(js|css)${ expires 1h; }