重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
通过博文Nginx初步优化就已经了解了Nginx的基础概念,已经可以对Nginx进行初步的优化了,包括:Nginx平滑升级
、更改Nginx版本信息、Nginx虚拟主机配置、nginx配置文件中location选项的作用等等。本篇博文主要针对Nginx进行进一步的优化。
博文大纲:
一、Nginx配置反向代理
二、Nginx的proxy缓存使用
三、优化Nginx服务的压缩功能
配置Nginx作为反向代理和负载均衡,同时利用其缓存功能,将静态页面在Nginx中缓存,以达到降低后端服务器连接数的目的并检查后端web服务器的检查状态。
如图:
环境需求:
一台Nginx服务器(Centos系统)IP地址:192.168.1.1;
两台httpd服务器(Centos系统)IP地址:192.168.1.2 192.168.1.3;
下载Nginx软件包
安装Nginx:
[root@localhost ~]# yum -y install gcc gcc-c++ make libtool zlib zlib-devel pcre pcre-devel openssl openssl-devel
//如果安装系统时,是最小化安装,则需要安装以上依赖包
[root@localhost ~]# yum -y install pcre-devel zlib-devel openssl-devel
//如果系统不是最小安装,则安装以上几个依赖包即可
[root@localhost ~]# unzip nginx-sticky-module.zip -d /usr/src/
//使用 nginx-sticky-module 扩展模块实现 Cookie 会话黏贴(保持会话)
[root@localhost ~]# tar zxf ngx_brotli.tar.gz -C /usr/src/
[root@localhost ~]# tar zxf ngx_cache_purge-2.3.tar.gz -C /usr/src/
//使用 ngx_cache_purge 实现更强大的缓存清除功能
//安装Nginx源码依赖包
[root@localhost ~]# tar zxf nginx-1.14.0.tar.gz -C /usr/src/
[root@localhost ~]# cd /usr/src/nginx-1.14.0/
[root@localhost nginx-1.14.0]# ./configure --prefix=/usr/local/nginx --user=nginx \
--group=nginx --with-http_stub_status_module --with-http_realip_module \
--with-http_ssl_module --with-http_gzip_static_module \
--http-client-body-temp-path=/var/tmp/nginx/client \
--http-proxy-temp-path=/var/tmp/nginx/proxy \
--http-fastcgi-temp-path=/var/tmp/nginx/fcgi --with-pcre \
--add-module=/usr/src/ngx_cache_purge-2.3/ --with-http_flv_module \
--add-module=/usr/src/nginx-sticky-module/ && make && make install
配置选项含义:
- --prefix=/usr/local/nginx:指定Nginx存放路径;
- --with-http_stub_status_module:通过网页方式监控nginx状态;
- --with-http_realip_module:显示客户端真是IP;
- --with-http_ssl_module:开启Nginx的加密传输功能;
- --with-http_gzip_static_module:开启Nginx扩展压缩模块;
- --http-client-body-temp-path=/var/tmp/nginx/client:客户端访问数据临时存放路径;
- --http-proxy-temp-path=/var/tmp/nginx/proxy:同上;
- --http-fastcgi-temp-path=/var/tmp/nginx/fcgi:同上;
- --with-pcre:支持正则匹配表达式;
- --add-module=/usr/src/ngx_cache_purge-2.3: 添加第三方模块,并指定第三方模块路径,支持缓存;
- --with-http_flv_module:支持flv视频流;
- --add-module=/usr/src/nginx-sticky-module: 添加第三方模块,并指定第三方模块路径,添加第三方模块格式:--add-module=源码解压后的路径;
[root@localhost ~]# ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/
//创建符号链接
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
//编写Nginx主配置文件
………… //省略部分内容
http {
include mime.types;
default_type application/octet-stream;
upstream lzj { //定义服务器群组,名称为lzj
sticky; //session会话保持
server 192.168.1.2:80 weight=1 max_fails=2 fail_timeout=10s;
server 192.168.1.3:80 weight=1 max_fails=2 fail_timeout=10s;
}
//定义了后台两台服务器,权重分别为1,大失败次数为2,大超时时间为10S
location / {
proxy_pass http://lzj;
}
//将原本的location规则注释,并重新定义转发到定义的lzj
[root@localhost ~]# nginx -t //检测配置文件
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: [emerg] getpwnam("nginx") failed
nginx: configuration file /usr/local/nginx/conf/nginx.conf test failed
[root@localhost ~]# useradd -s /sbin/nologin -M nginx
//创建Nginx用户,并不允许登录操作系统
[root@localhost ~]# nginx -t //检测配置文件
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: [emerg] mkdir() "/var/tmp/nginx/client" failed (2: No such file or directory)
nginx: configuration file /usr/local/nginx/conf/nginx.conf test failed
[root@localhost ~]# mkdir -p /var/tmp/nginx/client
//创建目录,用于存放客户端访问数据临时存放路径
[root@localhost ~]# 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 //启动Nginx
[root@localhost ~]# nginx -V //可以查看编译时,使用的配置参数
nginx version: nginx/1.14.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module --with-http_realip_module --with-http_ssl_module --with-http_gzip_static_module --http-client-body-temp-path=/var/tmp/nginx/client --http-proxy-temp-path=/var/tmp/nginx/proxy --http-fastcgi-temp-path=/var/tmp/nginx/fcgi --with-pcre --add-module=/usr/src/ngx_cache_purge-2.3/ --with-http_flv_module --add-module=/usr/src/nginx-sticky-module/
测试机操作如下:
第一台:
[root@localhost ~]# yum -y install httpd
[root@localhost ~]# echo "192.168.1.2" > /var/www/html/index.html
[root@localhost ~]# systemctl start httpd
第二台:
[root@localhost ~]# yum -y install httpd
[root@localhost ~]# echo "192.168.1.3" > /var/www/html/index.html
[root@localhost ~]# systemctl start httpd
Nginx测试效果:
[root@localhost ~]# curl 127.0.0.1
192.168.1.2
[root@localhost ~]# curl 127.0.0.1
192.168.1.3
注意:如果需要在已经安装好的Nginx服务器上添加第三方模块,依然需要重新编译,但为了不覆盖原本的配置信息,请不要执行make install,而是直接复制可执行文件即可!
添加Nginx为系统服务脚本:
[root@localhost ~]# vim /etc/init.d/nginx
#!/bin/bash
# chkconfig: 2345 99 20
# description: Nginx Service Control Script
PROG="/usr/local/nginx1.10/sbin/nginx"
PIDF="/usr/local/nginx1.10/logs/nginx.pid"
case "$1" in
start)
netstat -anplt |grep ":80" &> /dev/null && pgrep "nginx" &> /dev/null
if [ $? -eq 0 ]
then
echo "Nginx service already running."
else
$PROG -t &> /dev/null
if [ $? -eq 0 ] ; then
$PROG
echo "Nginx service start success."
else
$PROG -t
fi
fi
;;
stop)
netstat -anplt |grep ":80" &> /dev/null && pgrep "nginx" &> /dev/null
if [ $? -eq 0 ]
then
kill -s QUIT $(cat $PIDF)
echo "Nginx service stop success."
else
echo "Nginx service already stop"
fi
;;
restart)
$0 stop
$0 start
;;
status)
netstat -anplt |grep ":80" &> /dev/null && pgrep "nginx" &> /dev/null
if [ $? -eq 0 ]
then
echo "Nginx service is running."
else
echo "Nginx is stop."
fi
;;
reload)
netstat -anplt |grep ":80" &> /dev/null && pgrep "nginx" &> /dev/null
if [ $? -eq 0 ]
then
$PROG -t &> /dev/null
if [ $? -eq 0 ] ; then
kill -s HUP $(cat $PIDF)
echo "reload Nginx config success."
else
$PROG -t
fi
else
echo "Nginx service is not run."
fi
;;
*)
echo "Usage: $0 {start|stop|restart|reload}"
exit 1
esac
[root@localhost ~]# chmod +x /etc/init.d/nginx
[root@localhost ~]# chkconfig --add nginx
[root@localhost ~]# systemctl restart nginx
缓存也就是将一些静态文件从后端服务器缓存到nginx指定的缓存目录下,既可以减轻后端服务器负担,也可以加快访问速度,但这样缓存及时清理就成了一个头疼的问题。所以需要第三方模块ngx_cache_purge来在过期时间未到之前,手动清理缓存。
proxy模块常用的指令是proxy_pass和proxy_cache
nginx的web缓存功能只要就是由proxy_cache、fastcgi_cache指令集和相关指令集完成:
为了使nginx能够拥有缓存功能,需要修改其配置文件,如下:
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
………… //省略部分内容
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'
'"$upstream_cache_status"'; //记录缓冲命中率,注意这是一个整段,所以只在末尾有一个分号
//以上内容原本已经存在,只需添加最后一行即可!
access_log logs/access.log main;
proxy_buffering on; //代理时,开启缓冲后端服务器的响应
proxy_temp_path /usr/local/nginx/proxy_temp; //定义缓存临时目录
proxy_cache_path /usr/local/nginx/proxy_cache levels=1:2 keys_zone=my-cache:100m inactive=600m max_size=2g;
//定义缓存目录,具体信息已在配置文件外部进行说明
………… //省略部分内容
location ~/purge(/.*) { //定义缓存清除策略
allow 127.0.0.1;
allow 192.168.1.0/24;
deny all;
proxy_cache_purge my-cache $host$1$is_args$args;
}
location / {
proxy_pass http://lzj; //请求转向lzj定义的服务器列表
proxy_redirect off; 指定是否修改被代理服务器返回的响应头中的 location 头域跟 refresh 头域数值
#例如:
# 设置后端服务器“Location”响应头和“Refresh”响应头的替换文本。 假设后端服务器返回的
# 响应头是 “Location: http://localhost:8000/two/some/uri/”,那么指令proxy_redirect
# http://localhost:8000/two/ http://frontend/one/;将把字符串改写为 “Location:
# http://frontend/one/some/uri/”。
proxy_set_header Host $host; //允许重新定义或者添加发往后端服务器的请求头
#Host 的含义是表明请求的主机名,nginx 反向代理服务器会向后端真实服务器发送请求,
#并且请求头中的host字段重写为proxy_pass指令设置的服务器。因为nginx作为反向代理使
#用,而如果后端真实的服务器设置有类似防盗链或者根据 http 请求头中的 host 字段来进行
#路由或判断功能的话,如果反向代理层的nginx不重写请求头中的host字段,将会导致请求失败。
proxy_set_header X-Real-IP $remote_addr;
//web 服务器端获得用户的真实 ip 但是,实际上要获得用户的真实 ip,也可以通过下面的X-Forward-For
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#后端的 Web服务器可以通过 X-Forwarded-For 获取用户真实 IP,X_Forward_For 字段
#表示该条 http 请求是有谁发起的?如果反向代理服务器不重写该请求头的话,那么后端
#真实服务器在处理时会认为所有的请求都来自反向代理服务器,如果后端有防护策略
#的话,那么机器就被封掉了。因此,在配置用作反向代理的 nginx 中一般会增加两条配置,以便修改 http 的请求头部
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
#增加故障转移,如果后端的服务器返回 502、504、执行超时等错误,
#自动将请求转发到upstream 负载均衡池中的另一台服务器,实现故障转移。
proxy_cache my-cache;
add_header Nginx-Cache $upstream_cache_status;
proxy_cache_valid 200 304 301 302 8h;
proxy_cache_valid 404 1m;
proxy_cache_valid any 1d;
proxy_cache_key $host$uri$is_args$args;
expires 30d;
}
[root@localhost ~]# 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 -s reload //重新加载nginx配置文件
配置选项详解:
- levels=1:2 keys_zone=my-cache:100m 表示采用 2 级目录结构,第一层目录只有一个字符,是由 levels=1:2 设置,总共二层目录,子目录名字由二个字符组成。Web 缓存区名称为 my-cache,内存缓存空间大小为 100MB,这个缓冲 zone 可以被多次使用;
- inactive=600 max_size=2g 表示 600 分钟没有被访问的内容自动清除,硬盘大缓存空间为2GB,超过这个大学将清除最近最少使用的数据;
- proxy_cache : 引用前面定义的缓存区 my-cache;
- proxy_cache_key :定义如何生成缓存的键,设置 web 缓存的 key 值,nginx 根据 key 值 md5哈希存储缓存;
- proxy_cache_valid : 为不同的响应状态码设置不同的缓存时间,比如 200、302 等正常结果可以缓存的时间长点,而 404、500 等缓存时间设置短一些,这个时间到了文件就会过期,
而不论是否刚被访问过;- add_header 指令来设置 response header, 语法: add_header name value;
- $upstream_cache_status 这个变量来显示缓存的状态,我们可以在配置中添加一个 http 头来显示这一状态;
$upstream_cache_status 包含以下几种状态:
客户端浏览器访问:
使用F5刷新页面之后,出现如下页面:
清除缓存访问以下路径,如图:
如果访问时访问的URL是:http:192.168.1.1/index.html,那么清除缓存则需要http:192.168.1.1/purge/index.html。
这些从nginx的访问日志中,也可以看出,如图:
注意:测试时,注意清除客户端浏览器的缓存!
优化Nginx服务的压缩功能就需要进行以下操作:
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
……………… //省略部分内容
http {
include mime.types;
default_type application/octet-stream;
upstream lzj {
sticky;
server 192.168.1.2:80 weight=1 max_fails=2 fail_timeout=10s;
server 192.168.1.3:80 weight=1 max_fails=2 fail_timeout=10s;
}
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'
'"$upstream_cache_status"';
access_log logs/access.log main;
brotli on;
brotli_types text/plain text/css text/xml application/xml application/json;
brotli_static off; //是否允许查找预处理好的、以 .br结尾的压缩文件,可选值为on、off、always。
brotli_comp_level 11; //压缩的级别,范围是“1~14”,值越大,压缩比越高
brotli_buffers 16 8k; //读取缓冲区数量和大小
brotli_window 512k; //滑动窗口大小
brotli_min_length 20; //指定压缩数据的最小字节
server_tokens off; //隐藏版本信息
sendfile on; //开启高效文件传输
keepalive_timeout 65; //长连接超时时间,单位是秒
gzip on; //开启 gzip 压缩
gzip_comp_level 6; //压缩的级别,范围是“1~6”,值越大,压缩比越高
gzip_http_version 1.1; //http版本为1.1
gzip_proxied any; // Nginx 作为反向代理的时候启用,根据某些请求和应答来决定是否在对代理请求的应答启用 gzip 压缩,是否压缩取决于请求头中的“Via”字段,指令中可以同时指定多个不同的参数,
常用的参数如下:
off – 关闭所有的代理结果数据的压缩;
expired – 启用压缩,如果 header 头中包含 “Expires” 头信息;
no-cache – 启用压缩,如果 header 头中包含 “Cache-# Control:no-cache” 头信息;
private – 启用压缩,如果 header 头中包含 “Cache-Control:private” 头信息;
no_last_modified – 启用压缩,如果 header 头中不包含 “Last-Modified” 头信息;
no_etag – 启用压缩 ,如果 header 头中不包含 “ETag” 头信息;
auth – 启用压缩 , 如果 header 头中包含 “Authorization” 头信息;
any – 无条件启用压缩;
gzip_min_length 1k;
gzip_buffers 16 8k;
gzip_types text/plain text/css text/xml application/xml application/json;
gzip_vary on;
client_max_body_size 10m;
client_body_buffer_size 128k; //缓冲区代理缓冲用户端请求的大字节数
proxy_connect_timeout 75; //nginx 跟后端服务器连接超时时间(代理连接超时)
proxy_read_timeout 75; //定义从后端服务器读取响应的超时
proxy_buffer_size 4k; //设置缓冲区的大小为 size
proxy_buffers 4 32k; //每块缓冲区的大小
proxy_busy_buffers_size 64k; //高负荷下缓冲大小
proxy_temp_file_write_size 64k; //每次写临时文件的大小
proxy_buffering on;
proxy_temp_path /usr/local/nginx/proxy_temp;
proxy_cache_path /usr/local/nginx/proxy_cache levels=1:2 keys_zone=my-cache:100m inactive=600m max_size=2g;
#sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
#keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name localhost;
charset utf-8;
……………… //省略部分内容,在location规则最后添加
location /nginx_status {
stub_status on;
access_log off;
allow 192.168.1.0/24;
deny all;
}
[root@localhost ~]# nginx -t
nginx: [emerg] unknown directive "brotli" in /usr/local/nginx/conf/nginx.conf:32
nginx: configuration file /usr/local/nginx/conf/nginx.conf test failed
//检查配置文件发现brotli这个工具在编译时忘记安装了(故意的)
接下进行安装原本的模块:
[root@localhost ~]# cd /usr/src/nginx-1.14.0/ //进入源码包路径
[root@localhost nginx-1.14.0]# nginx -V //-V查询编译安装时,使用的那些参数
nginx version: nginx/1.14.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module --with-http_realip_module --with-http_ssl_module --with-http_gzip_static_module --http-client-body-temp-path=/var/tmp/nginx/client --http-proxy-temp-path=/var/tmp/nginx/proxy --http-fastcgi-temp-path=/var/tmp/nginx/fcgi --with-pcre --add-module=/usr/src/ngx_cache_purge-2.3/ --with-http_flv_module --add-module=/usr/src/nginx-sticky-module/
[root@localhost nginx-1.14.0]# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module --with-http_realip_module --with-http_ssl_module --with-http_gzip_static_module --http-client-body-temp-path=/var/tmp/nginx/client --http-proxy-temp-path=/var/tmp/nginx/proxy --http-fastcgi-temp-path=/var/tmp/nginx/fcgi --with-pcre --add-module=/usr/src/ngx_cache_purge-2.3/ --with-http_flv_module --add-module=/usr/src/nginx-sticky-module/ --add-module=/usr/src/ngx_brotli && make && make install
//将上述查到的已加载的模块复制以下,重新编译以下,同时,加上需要添加的模块
//比如我在上面添加了第三方模块“--add-module=/usr/src/ngx_brotli”
[root@localhost ~]# mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak
//将原本的命令进行备份
[root@localhost ~]# cp /usr/src/nginx-1.14.0/objs/nginx /usr/local/nginx/sbin/
//复制新生成的nginx命令到指定的目录中
[root@localhost ~]# ln -sf /usr/local/nginx/sbin/nginx /usr/local/sbin/
//对新命令做一个强制软连接
[root@localhost ~]# nginx -s reload //重新加载nginx配置文件
[root@localhost ~]# 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 -s stop
[root@localhost ~]# nginx
//重新启动nginx服务,注意清除浏览器本地的缓存信息
客户端验证访问:
鉴于复制的问题,最后附上本篇博文有关没有注释的完整的Nginx配置文件:
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
upstream lzj {
sticky;
server 192.168.1.2:80 weight=1 max_fails=2 fail_timeout=10s;
server 192.168.1.3:80 weight=1 max_fails=2 fail_timeout=10s;
}
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'
'"$upstream_cache_status"';
access_log logs/access.log main;
brotli on;
brotli_types text/plain text/css text/xml application/xml application/json;
brotli_static off;
brotli_comp_level 11;
brotli_buffers 16 8k;
brotli_window 512k;
brotli_min_length 20;
server_tokens off;
sendfile on;
keepalive_timeout 65;
gzip on;
gzip_comp_level 6;
gzip_http_version 1.1;
gzip_proxied any;
gzip_min_length 1k;
gzip_buffers 16 8k;
gzip_types text/plain text/css text/xml application/xml application/json;
gzip_vary on;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 75;
proxy_send_timeout 75;
proxy_read_timeout 75;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
proxy_buffering on;
proxy_temp_path /usr/local/nginx/proxy_temp;
proxy_cache_path /usr/local/nginx/proxy_cache levels=1:2 keys_zone=my-cache:100m inactive=600m max_size=2g;
#sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
#keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name localhost;
charset utf-8;
#charset koi8-r;
#access_log logs/host.access.log main;
location ~/purge(/.*) {
allow 127.0.0.1;
allow 192.168.1.0/24;
deny all;
proxy_cache_purge my-cache $host$1$is_args$args;
}
location / {
proxy_pass http://lzj;
proxy_redirect off;
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_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_cache my-cache;
add_header Nginx-Cache $upstream_cache_status;
proxy_cache_valid 200 304 301 302 8h;
proxy_cache_valid 404 1m;
proxy_cache_valid any 1d;
proxy_cache_key $host$uri$is_args$args;
expires 30d;
}
location /nginx_status {
stub_status on;
access_log off;
allow 192.168.1.0/24;
deny all;
}
//以下的内容没有进行修改所以就不复制了
———————— 本文至此结束,感谢阅读 ————————
另外有需要云服务器可以了解下创新互联cdcxhl.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。