Nginx介绍
Nginx
Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文:Рамблер)开发的,第一个公开版本0.1.0发布于2004年10月4日。
其将源代码以类BSD许可证的形式发布,因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。2011年6月1日,nginx 1.0.4发布。
Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。
Nginx特性:
轻量级、高性能HTTP服务器
高性能的reverse proxy反向代理服务器
代理http、mail
基于模块化设计
基于事件驱动模型
重新加载配置及在线升级时,不需要中断正在处理的请求(nginx热部署)
带缓存的日志写操作
重写(rewrite)模块
支持验证HTTP referer,实现反倒链机制
支持sendfile,将数据在内核中直接封装响应客户端,不需要将数据复制到进程地址空间
10000个非活跃的HTTP KEEPALIVE连接仅占用2.5M内存
支持缓存功能
WEB服务器响应客户端请求的方式:
多进程方式
服务器每接收一个客户端请求,由服务器主进程生成一个子进程响应,响应结束后,子进程结束
稳定
多线程方式
服务器每接收一个客户端请求,由服务器主进程生成一个线程响应
节点系统开销
异步方式
同步机制和异步机制
用于描述网络中的主机通信的模式
同步机制
发送方发送请求后,需要等待接收方回应,才会继续发送下一个请求
异步机制
发送方发送请求后,不等待接收文回应,继续发送下一个请求
阻塞和非阻塞
用于描述进程处理调用的方式
阻塞机制
调用结果返回前,进程会从运行状态切换到挂起状态,待调用结果返回后,进程再次进入就绪状态,获取CPU后继续执行
非阻塞机制
调用结果如果不能及时返回,进程也不会进入挂起状态,而是开始处理下一个请求,待调用结果返回时,进程暂停运行该任务,开始继续处理上一个任务
同步阻塞
同步非阻塞
异步阻塞
异步非阻塞
Nginx服务器处理请求的机制
由主进程(master process)事先生成多个空闲的工作进程(worker process),每个工作进程等待客户端的访问请求
每个工作进程响应请求时,使用的是异步非阻塞方式
Nginx的事件处理机制
在非阻塞模型下,进程无法及时获取IO结果时,可以进行其他的操作;
IO操作返回结果时,进程如何知道?
方法1: 进程每隔一段时间轮询一次
方法2: IO操作完成后,主动通知进程
系统中的select, poll, epoll, kqueue4种系统调用机制就是实现第二种方法的应用,此4种模型也称为事件驱动机制;
事件驱动机制可以使得进程可以同时处理多个请求
Nginx的事件驱动模型
Nginx服务器接收和处理客户端请求时,就是基于事件驱动机制的
SELECT
Linux, windows平台支持的事件驱动模型
首先,创建所关注事件的描述符集合。对于每一个描述符,需要关注其上面的读事件,写事件,异常事件;所以要创建三类事件描述符集合
调用底层以的select()函数,等待事件发生
轮询所有事件描述符,检查是否有事件发生,如果有,就进行处理
POLL
Linux平台支持的事件驱动模型,2.1.23版本内核中引入
和select一样,需要创建 一个关注事件的描述符集合,等待事件发生,轮询描述符集合,检测有没有事件发生,如果有,就执行
不一样的是,select需要创建三类描述符集合,而poll只需要创建一类集合,在每个描述符下分别创建读、写、异常事件,最后轮询时,可同时轮询
EPOLL(事件驱动模型)
Linux 2.5.44内核后引入
把描述符列表的管理交由内核负责,一旦有某种事件发生,内核把发生事件的描述符列表通知给进程,避免轮询减少系统开销
(详解事件驱动模型)
kqueue
支持BSD系列平台的高效事件驱动模型
/dev/poll
支持UNIX衍生平台的高效事件驱动模型
eventport
支持Solaris 10及以上版本平台的高效事件驱动模型
Nginx服务器架构 :
Nginx启动时会启动一个主进程master及多个子进程worker;配置缓存时还会启动cache load和cache manager进程。所有进程以"共享内存"机制完成进程间通信;master进程以特权用户运行,其他进程以非特权用户运行
master主进程主要完成如下工作:
1、读取并验证配置文件
2、创建、绑定、及关闭套接字
3、启动、终止及维护worker进程的个数
4、无须中止服务而重新配置工作特性
5、控制非中断式程序升级,启用新的二进制程序并在需要时回滚至老版本
6、重新打开日志文件
7、编译嵌入式perl脚本
worker进程主要完成如下工作:
1、接收、传入并处理客户端的连接
2、提供反向代理及过滤功能
3、IO调用,获取响应数据
4、与后端服务器通信,接收后端服务器处理结果
5、数据缓存、访问缓存索引、查询和调用缓存数据
6、发送请求结果,响应客户端请求
7、接收主程序指令,比如重启、退出、升级等
cache load进程主要完成的工作:
1、检查缓存存储中的缓存对象
2、使用缓存元数据建立内存数据库
cache manager进程的主要工作:
1、缓存的失效及过期检验
Nginx配置是分段的:
main,http,server,upstream(反向代理),location(类似于documentroot),mail
Nginx安装
useradd nginx
yum install -y pcre-devel openssl-devel
tar zxf nginx-1.4.7.tar.gz
cd nginx-1.4.7
./configure \
--prefix=/usr/local/nginx
--error-log-path=/var/log/nginx/error.log
--http-log-path=/var/log/nginx/access.log
--pid-path=/var/run/nginx/nginx.pid
--lock-path=/var/lock/nginx.lock
--user=nginx
--group=nginx
--with-http_ssl_module
--with-http_flv_module
--with-http_stub_status_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
--http-uwsgi-temp-path=/var/tmp/nginx/uwsgi
--http-scgi-temp-path=/var/tmp/nginx/scgi
--with-pcre
--with-file-aio
--with-http_ssl_module
--with-http_secure_link_module
--with-http_perl_module \
make && make install
http://pan.baidu.com/share/link?shared=402894734&uk=3340480807
nginx服务启动脚本:
!/bin/bash
chkconfig: 2345 86 14
Descirption: Nginx Script File
prog="/usr/local/nginx/sbin/nginx"
pfile="/var/run/nginx/nginx.pid"
if [ $# -ne 1 ];then
echo "Usage:basename $0
{ start | stop | restart | reload | configtest }"
exit 9
fi
case $1 in
start)
$prog
if [ $? -eq 0 ];then
echo "Starting nginx service ..... [ok]"
# create lock file
touch /var/lock/subsys/nginx
fi
;;
stop)
kill cat $pfile
if [ $? -eq 0 ];then
echo "Stopping nginx.... [ok]"
fi
;;
restart)
kill cat $pfile
echo "Stopping nginx...."
$prog
if [ $? -eq 0 ];then
echo "Starting nginx service ..... [ok]"
# create lock file
touch /var/lock/subsys/nginx
fi
;;
reload)
kill -s HUP cat $pfile
;;
configtest)
$prog -t &> /dev/null
if [ $? -eq 0 ];then
echo "Syntax is ok!!!"
else
$prog -t
fi
;;
*)
echo "Usage:basename $0
{ start | stop | restart | reload | configtest }"
;;
esac
mime:多用途互联网邮件扩展
用于识别非文本文档
Nginx配置---/etc/nginx/nginx.conf
启动worker进程的数量;如果是CPU密集型,如SSL及压缩应用,worker数量与CPU个数一致;如果是IO密集型,如响应大量给客户端 ,worker进程个数为CPU个数的1.5或者2倍
worker_processes 1;
每个worker进程支持的连接数
events {
worker_connections 1024;
}
启用sendfile机制
sendfile on;
启用长连接并设置超时时间
keepalive_timeout 65;
是否对发送给客户端的内容进行压缩
gzip on;
每个server定义一个虚拟主机 server { }
location / {
root html;
index index.html index.htm;
}
location /URI路径 {
root "/web/htdocs" 定义URI路径所对应的网页文件存放的路径
}
URI路径
http://www.bj.com/URI路径
如果错误代码为500,502,503,504,则返回URI路径下50x.html页面内容
error_page 500 502 503 504 /50x.html;
location [ = | ~ | ~* | ^~ ] URI路径 {...}
location URI路径 {}:
对当前路径及子路径下的所有资源都生效
location = URI路径 {}:
精确匹配指定路径,不包括子路径,因此只对当前资源生效
location ~ URI路径 {}:区分大小写
locaiton ~* URI路径 {}:不区分大小写
模式匹配URI路径,此处的URI可使用正则表达式
location ^~ URI路径 {}
不使用正则表达式
匹配优先级:
=匹配优先级最高
^~匹配优先级次之
~ ~*
示例1:客户端通过http://10.1.1.1访问/web/htdocs下的网页
location / {
root /web/htdocs;
index index.html index.htm;
}
示例2:客户端通过http://10.1.1.1/bbs,访问/web/bbs下的网页
location /bbs {
root /web;
index index.html index.htm;
}
基于客户端IP地址进行访问控制
location / {
....
allow 10.1.1.100;
deny 10.1.1.0/24;
}
默认规则是允许访问。如果想要明确禁止某个客户端访问可直接写deny 10.1.1.1;
如果想要明确只允许某个客户端访问,要这样写
allow 10.1.1.100
deny all
基于用户名/密码认证访问
location / {
auth_basic "please input user:";
auth_basic_user_file /etc/nginx/.user;
}
使用htpasswd命令创建用户名、密码
配置显示nginx连接数
location /status {
stub_status on;
access_log off;
allow 10.1.1.100;
deny all;
}
Active connections: 4 打开的所有连接数
server accepts handled requests
10 10 36 已经接受的连接数 已经处理的连接数 已经处理的请求数
Reading: 0 Writing: 1 Waiting: 3
Reading:nginx正在读取其报文首部的连接数
Writing:nginx正在读取其报文主体的连接数、或者正在处理请求的请求个数以及正在响应客户端的连接个数
Waiting:长连接中保持活动连接的连接个数(Reading+Writing)
配置基于SSL的HTTP
HTTPS server
server {
listen 443 ssl;
server_name localhost;
ssl_certificate /usr/local/nginx/ssl/nginx.crt;
ssl_certificate_key /usr/local/nginx/ssl/nginx.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
root /web/ssl;
index index.html index.htm;
}
}
生成自签证书:
cd /etc/pki/CA
生成证书服务器私钥
(umask 077; openssl genrsa 2048 > private/cakey.pem)
Generating RSA private key, 2048 bit long modulus
.........................+++
..............+++
e is 65537 (0x10001)
生成自签证书
openssl req -new -x509 -key private/cakey.pem -out cacert.pem
touch index.txt
echo 01>serial
生成WEB服务器的密钥
mkdir /usr/local/nginx/ssl
cd /usr/local/nginx/ssl
(umask 077;openssl genrsa 1024 > nginx.key)
Generating RSA private key, 1024 bit long modulus
..............................++++++
.............++++++
e is 65537 (0x10001)
创建证书申请
openssl req -new -key /usr/local/nginx/ssl/nginx.key -out /usr/local/nginx/ssl/nginx.csr
签署证书
cd /usr/local/nginx/ssl/
openssl ca -in nginx.csr -out nginx.crt -days 3650
配置基于域名的虚拟主机
server {
listen 80;
server_name www.a.com;
location / {
root /web/a;
index index.html;
access_log /var/log/nginx/bj/access_log main;
error_log /var/log/nginx/bj/error_log;
}
}
nginx添加第三方模块支持
http://labs.frickle.com/nginx_ngx_cache_purge/下载最新版本模块
1、查看nginx当前编译的模块
[root@www nginx-1.11.4]# /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.11.4
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-11) (GCC)
built with OpenSSL 1.0.1e-fips 11 Feb 2013
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-threads --with-file-aio --with-ipv6 --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_auth_request_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_stub_status_module --with-http_slice_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/fastcgi --http-uwsgi-temp-path=/var/tmp/nginx/uwsgi --http-scgi-temp-path=/var/tmp/nginx/scgi --with-pcre
2、解压缩下载的模块,重新编译nginx添加新模块支持
[root@www nginx-1.11.4]# tar zxf ngx_cache_purge-2.3.tar.gz
[root@www ~]# cd nginx-1.11.4
[root@www nginx-1.11.4]# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-threads --with-file-aio --with-ipv6 --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_auth_request_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_stub_status_module --with-http_slice_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/fastcgi --http-uwsgi-temp-path=/var/tmp/nginx/uwsgi --http-scgi-temp-path=/var/tmp/nginx/scgi --with-pcre --add-module=/root/ngx_cache_purge-2.3
[root@www nginx-1.11.4]# make
注意不要make install,否则会覆盖安装
3、 替换nginx可执行命令即可
[root@www ~]# /usr/local/nginx/sbin/nginx -s stop
[root@www ~]# cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak
[root@www ~]# cd nginx-1.11.4
[root@www nginx-1.11.4]# cp objs/nginx /usr/local/nginx/sbin/nginx
LEMP/LNMP:
PHP+MySQL
仅支持以FastCGI方式工作的PHP
编译安装cmake
tar zxf cmake-2.8.6.tar.gz
cd cmake-2.8.6
./configure
make && make install
安装MySQL
groupadd mysql
useradd -g mysql -s /sbin/nologin mysql
mkdir /mydata/data -p
chown -R mysql.mysql /mydata/data/
tar zxf mysql-5.5.28.tar.gz
cd mysql-5.5.28
cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
-DMYSQL_DATADIR=/mydata/data
-DSYSCONFDIR=/etc
-DWITH_INNOBASE_STORAGE_ENGINE=1
-DWITH_ARCHIVE_STORAGE_ENGINE=1
-DWITH_BLACKHOLE_STORAGE_ENGINE=1
-DWITH_SSL=system
-DWITH_ZLIB=system
-DWITH_LIBWRAP=0
-DMYSQL_UNIX_ADDR=/tmp/sql.sock
-DDEFAULT_CHARSET=utf8
-DDEFAULT_COLLATION=utf8_general_ci
make && make install
chgrp -R mysql /usr/local/mysql/
cd /usr/local/mysql
scripts/mysql_install_db --user=mysql --basedir=/usr/local/mysql --datadir=/mydata/data/
cp support-files/my-large.cnf /etc/my.cnf
cp support-files/mysql.server /etc/init.d/mysqld
chmod +x /etc/init.d/mysqld
chkconfig --add mysqld
chkconfig --list mysqld
mysqld 0:off 1:off 2:on 3:on 4:on 5:on 6:off
vim /etc/profile.d/mysql.sh
export PATH=$PATH:/usr/local/mysql/bin
source /etc/profile.d/mysql.sh
vim /etc/ld.so.conf.d/mysql.conf
/usr/local/mysql/lib
ldconfig
ln -s /usr/local/mysql/include/ /usr/include/mysql
安装php-5.3.6
yum localinstall -y --nogpgcheck libmcrypt-2.5.7-1.2.el6.rf.i686.rpm libmcrypt-devel-2.5.7-1.2.el6.rf.i686.rpm mhash-0.9.9-1.el6.rf.i686.rpm mhash-devel-0.9.9-1.el6.rf.i686.rpm mcrypt-2.6.8-10.el6.i686.rpm
tar zxf php-5.3.6.tar.gz
cd php-5.3.6
./configure --prefix=/usr/local/php --with-mysql=/usr/local/mysql --with-openssl --with-mysqli=/usr/local/mysql/bin/mysql_config --enable-mbstring --with-freetype-dir --with-jpeg-dir --with-png-dir --with-zlib --with-libxml-dir=/usr --enable-xml --enable-sockets --enable-fpm --with-mcrypt --with-config-file-path=/etc --with-config-file-scan-dir=/etc/php.d --with-bz2
make && make install
复制php配置文件
cp php.ini-production /etc/php.ini
复制php-fpm配置文件
cp /usr/local/php/etc/php-fpm.conf.default /usr/local/php/etc/php-fpm.conf
复制php-fpm启动脚本
cp sapi/fpm/init.d.php-fpm /etc/rc.d/init.d/php-fpm
chmod +x /etc/rc.d/init.d/php-fpm
chkconfig --add php-fpm
chkconfig --list php-fpm
php-fpm 0:关闭 1:关闭 2:启用 3:启用 4:启用 5:启用 6:关闭
编辑/usr/local/php/etc/php-fpm.conf配置文件
vim /usr/local/php/etc/php-fpm.conf
pm.max_children = 150
pm.start_servers = 8
pm.min_spare_servers = 8
pm.max_spare_servers = 10
pid=pid=/usr/local/php/var/run/php-fpm.pid
user=nginx
group=nginx
/etc/init.d/php-fpm start
Starting php-fpm done
netstat -tnlp | grep php-fpm
tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN 15457/php-fpm
整合nginx和php
编辑nginx配置文件,去掉如下配置的注释:
vim /etc/nginx/nginx.conf
location ~ .php$ {
root /web/htdocs;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
include fastcgi_params;
}
编辑/etc/nginx/fastcgi_params文件,并将内容修改为如下内容,配置fastcgi参数:
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
编辑nginx配置文件,指定php首页
vim /etc/nginx/nginx.conf
location / {
root /web/htdocs;
index index.php index.html index.htm;
}
/etc/init.d/nginx restart
在/web/htdocs目录下创建php页面,测试访问
vim /web/htdocs/index.php
xcache:在同一个PHP服务器,为多个进程缓存同一个opcode
安装xcache-2.0.0,加速php解析
yum install -y m4 autoconf
tar zxf xcache-2.0.0.tar.gz
cd xcache-2.0.0
生成configure配置程序
/usr/local/php/bin/phpize
Configuring for:
PHP Api Version: 20090626
Zend Module Api No: 20090626
Zend Extension Api No: 220090626
./configure --enable-xcache --with-php-config=/usr/local/php/bin/php-config
make && make install
安装完毕后,有如下提示:
Installing shared extensions: /usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/
编辑php.ini,整合php与xcache
将xcache提供的样例配置导入php.ini
mkdir /etc/php.d
cp xcache.ini /etc/php.d/
编辑/etc/php.d/xcache.ini,找到zend_extension开头的行,修改为如下内容:
zend_extension = /usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/xcache.so
重新启动php-fpm
/etc/init.d/php-fpm restart
通过浏览器再次浏览php页面,在页面中可以找到关于xcache特性说明,表明成功
XCache
XCache Support enabled
Version 2.0.0
Modules Built cacher
Readonly Protection N/A
Cache Init Time 2015-12-24 14:04:43
Cache Instance Id 19574
Opcode Cache enabled, 62,914,560 bytes, 1 split(s), with 8192 slots each
Variable Cache enabled, 4,194,304 bytes, 1 split(s), with 8192 slots each
Shared Memory Schemes mmap
location ~* .php$ {
fastcgi_pass 127.0.0.1:9000;
}
Nginx反向代理
server {
listen 80;
server_name www.bj.com;
location / {
后端服务器;
}
}
后端服务器:
proxy_pass
示例:
用户访问http://10.1.2.1/forum时,将以后台服务器10.1.2.2的bbs目录中的页面返回客户端
location /forum {
proxy_pass http://10.1.2.2/bbs;
}
特殊情况:
如果在定义location时,加入了~ ~* ^~这样的模式匹配字符,proxy_pass在写时,只能写到服务器地址
location ~* /forum {
proxy_pass http://10.1.1.2;
}
当用户访问www.bj.com/forum时,将代理到http://10.1.1.2/forum
nginx反向代理示例配置:
10.1.1.1安装nginx作为前端服务器
10.1.1.2安装httpd作为后端服务器
客户端访问http://10.1.1.1/forum时,代理到后端服务器的http://10.1.1.2/bbs
location /forum {
proxy_pass http://10.1.1.2/bbs;
}
使用模式匹配的方式定义location,当客户端访问http://10.1.1.1/forum时,代理到后端服务器http://10.1.1.2/forum上
location ~* ^/forum {
proxy_pass http://10.1.1.2;
}
后端服务器上也要有对应的forum目录
此时,对于后端服务器来说,access_log中记录的日志,客户端IP是nginx的IP
10.1.1.1 - - [24/Dec/2015:16:35:36 +0800] "GET /forum/ HTTP/1.0" 200 35 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 BIDUBrowser/8.1 Safari/537.36"
配置proxy_set_header,实现后端服务器记录真实的客户端IP
编辑/etc/nginx/nginx.conf
vim /etc/nginx/nginx.conf
location ~* ^/forum {
proxy_pass http://10.1.1.2;
proxy_set_header X-Real-IP $remote_addr;
}
proxy_set_header X-Real-IP $remote_addr;
代理在httpd请求报文中加入X-Real-IP段的内容,该内容是变量$remote_addr的值,即真实客户端的IP
编辑后端服务器配置文件/etc/httpd/conf/httpd.conf,修改combined日志格式,将客户端地址%h换成%{X-Real-IP}i,表示记录HTTP请求报文中X-Real-IP的内容
LogFormat "%{X-Real-IP}i %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i"" combined
刷新浏览器,再次查看后端服务器access_log,日志中记录的是真实客户端的IP地址10.1.1.100
10.1.1.100 - - [24/Dec/2015:16:38:54 +0800] "GET /forum/ HTTP/1.0" 200 35 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 BIDUBrowser/8.1 Safari/537.36"
将前端所有请求代理到后端WEB服务器
location / {
root html;
index index.html index.htm;
}
location / {
proxy_pass http://192.168.0.101/;
proxy_set_header x-real-ip $proxy_add_x_forwarded_for;
}
Nginx负载均衡
Nginx负载均衡算法:
roundrobin, rr,轮询,默认算法
ip_hash:根据请求报文中的源IP地址,将相同客户端的请求转发到同一个服务器上
least_conn
nginx负载均衡配置:
定义upstream段,指定后端服务器IP;upstream段要写在server段外面
upstream webserver {
server 10.1.1.2 weight=1 max_fails=2 fail_timeout=2;
server 10.1.1.3 weight=1 max_fails=2 fail_timeout=2;
server 127.0.0.1:8080 backup;
}
server {
....
location / {
proxy_pass http://webserver/;
proxy_set_header X-Real-IP $remote_addr;
}
}
定义虚拟主机,提供错误页面
server {
listen 8080;
server_name localhost;
location / {
root /web/sorry;
index index.html;
}
}
在/web/sorry目录下提供index.html错误页面
经过以上配置后,当客户端访问http://10.1.1.1时,由后端两台服务器10.1.1.2和10.1.1.3负载均衡方式提供页面;当两台后端服务器均down后,跳转到本地8080端口所对应的页面
配置使用ip_hash算法将同一个客户端的请求代理到相同的后端服务器
upstream webserver {
ip_hash;
server 192.168.0.101 weight=1 max_fails=2 fail_timeout=2;
server 192.168.0.111 weight=1 max_fails=2 fail_timeout=2;
#server 127.0.0.1:8080 backup; >>>ip_hash算法不支持backup,因此将其注释
}
Nginx缓存
缓存组成的两部分:
共享内存: 存储键和缓存对象元数据
磁盘空间:存储数据
定义缓存空间
proxy_cache_path: 不能定义在server{}中
proxy_cache_path /nginx/cache/first levels=1:2:3 keys_zone=first:20m max_size=1G
levels=
定义缓存目录子目录的级别,及每个子目录的名称字符个数; 最多只能有3级子目录
levels=1:2:2,3级子目录,第1级目录字符个数为1,第2级目录字符个数为2,第3级目录字符个数为2,字符个数最多只能有2个
keys_zone=name:size
定义存储键的区域(定义共享内存的名称)
max_size=1G
指定/nginx/cache/first中的1G空间用于存储缓存数据
Nginx缓存配置:
定义缓存存放路径为/web/cache/first, 最多使用1G空间; 并定义键值区域名称为first,大小为20m
proxy_cache_path /web/cache/first levels=1:2 keys_zone=first:20m max_size=1g;
在location中开启缓存功能,指定使用键值名称为first的缓存
在httpd响应报文中添加额外项X-cache,用于查看缓存是否命中
add_header X-cache "$upstream_cache_status by $server_addr";
$upstream_cache_status: 用于记录缓存是否命中的状态
location / {
proxy_pass http://webserver/;
proxy_set_header X-Real-IP $remote_addr;
proxy_cache first;
proxy_cache_valid 200 1m;
}
proxy_cache_valid 200 1m;
表示为状态码为200的数据缓存1分钟
查看缓存是否命中,在浏览器中按F12打开开发者模式,查看HTTP响应报文,可以看到X-cache:HIT by 10.1.1.1信息,表示缓存命中
常用的3种缓存:
open_log_cache:日志缓存,将日志先保存到内存,再同步到磁盘,降低磁盘IO
open_file_cache:加快响应速度
fastcgi_cache
rewrite:URL地址重写
1、if指令
if (condition) {......}
{...} 代表条件为真时的nginx操作
condition条件的写法:
-
变量名
如果变量的值为空,或者为以"0"开头的任意字符串,条件为假,其他则为真
if($slow)
-
使用"="或者"!="比较变量的值
if($request_method = POST)
-
使用正则表达式与变量的值进行匹配
变量名与正则表达式间使用~, ~, !~, !~进行连接
在正则表达式中使用()可以对字符进行分组,在{}中可以用$1....$9引用分组
正则表达式写时不需要加双引号,但是如果正则表达式中含有}和;字符,则必须要使用双引号
if ($http_user_agent ~ MSIE)
-
判断请求的文件是否存在
if ( -f $request_filename) {.....}
if (!-f $request_filename)
-
判断请求的目录是否存在 (-d, !-d)
-
判断请求的目录或文件是否存在 (-e, !-e)
-
判断请求的文件是否可执行 (-x, !-x)
2、break指令
该指令用于中断当前相同作用域中的其他 nginx配置
与该指令处于同一个作用域的nginx配置,位于break前的生效,位于break的配置无效
location / {
if ($slow) {
set $id $1
break
limit_rate 10k;
}
}
3、return指令
该指令用于完成对请求的处理,直接向客户端返回响应状态代码。
处于该指令后的所有nginx配置都是无效的
该指令可用于server, location, if段中
语法结构 :
return [ text ]
return code URL;
return URL;
code
为返回客户端的HTTP状态代码。范围是0---999
非标准的444代码可以强制关闭服务器与客户端的连接而不返回任何响应信息给客户端
text
为返回给客户端的响应体内容,支持变量的使用
URL
为返回给客户端的URL地址
当code使用301, 302, 303, 307时,可以使用结构2将新的URL返回给客户端
除上面指定的代码,结构1指定text向客户端发送指定的内容
当返回状态码为302, 307时,可以使用结构3对URL进行配置。返回的URL中应该包括http://, https://或者直接使用变量$scheme指定
4、rewrite指令
该指令通过使用正则表达式的使用来改变URI。
可以同时存在一条或者多条,按顺序依次对URL进行匹配和处理
该指令可用于server, location中
语法结构:
rewrite <REGEX> <REPLACEMENT> [FLAG]
REGEX 用于匹配URI的正则表达式
注意:
1) rewrite接收到的URL地址不包括主机名称部分
2) 不包括URL地址中的请求指令
https://reg.jd.com/reg/person?ReturnUrl=https%3A//sale.jd.com/act/r1z8LpvTcxkDbge.html
REPLACEMENT
匹配成功后用于替换URI中被截取内容的字符串。默认情况下,如果字符串是以http://或者https://开头,则不会继续 向下对URI进行其他处理,而直接将重写后的URI返回给客户端
支持变量的使用
FLAG
1) last
终止继续在本location块中处理接收到的URI,并将此处重写的URI作为一个新的URI,使用各location块进行处理
location / {
rewrite ^(/myweb/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 last;
rewrite ^(/myweb/.*)/audio/(.*)\..*$ $1/mp3/$2.ra last;
}
2) break
将此处重写的URI作为一个新的URI,在本块中继续进行处理。该标志将重写后的地址在当前的location块中执行,不会将新的URI转向到其他location块
location /web/ {
rewrite ^(/myweb/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break;
rewrite ^(/myweb/.*)/audio/(.*)\..*$ $1/mp3/$2.ra break;
}
3) redirect
将重写后的URI返回给客户端,状态代码为302,指明是临时重定向,主要用在replacement不是以http://或者https://开头的情况下
4) permanent
将重写后的URI返回给客户端,状态代码为301,指明是永久重写向
5、rewrite_log指令
该指令配置是否开启URL重写日志的输出功能
rewrite_log {on|off}
如果为on时,URI地址重写的信息会以notice级别记录到error_log中
6、set指令
用于配置一个新的变量
set <variable> <value>
变量名称要以$开头
7、uninitialized_variable_warm指令
用于在使用未初始化的变量时,是否记录警告日志
uninitialized_variable_warm {on|off}
Nginx变量
-
$args
存放URL中的请求指令
https://reg.jd.com/reg/person?ReturnUrl=https%3A//sale.jd.com/act/r1z8LpvTcxkDbge.html
ReturnUrl=https%3A//sale.jd.com/act/r1z8LpvTcxkDbge.html
-
$content_length
存放请求报文中content_length字段内容
-
$content_type
存放请求报文中content_type字段内容
-
$document_root
存放针对当前请求的根路径
-
$document_uri
存放请求报文中的当前URI,并且不包括请求指令
https://reg.jd.com/reg/person?ReturnUrl=https%3A//sale.jd.com/act/r1z8LpvTcxkDbge.html
/reg/person
-
$host
存放请求报文中的主机部分
https://reg.jd.com/reg/person?ReturnUrl=https%3A//sale.jd.com/act/r1z8LpvTcxkDbge.html
reg.jd.com
-
$http_user_agent
存放客户端代理信息
-
$http_cookie
存放客户端的cookie信息
-
$limit_rate
存放nginx服务器对网络连接速率的限制,也就是ngnix配置文件中limit_rate指令的值
-
$remote_addr
存放客户端地址
-
$remote_port
存放客户端端口
-
$remote_user
存放客户端的用户名
-
$request_body_file
存放发给后端服务器的本地文件资源名称
-
$request_method
存放客户端请求资源的方法, GET, POST, PUT
-
$request_filename
存放当前请求的资源文件的路径名
-
$request_uri
存放当前请求的URI,并且带有请求指令
https://reg.jd.com/reg/person?ReturnUrl=https%3A//sale.jd.com/act/r1z8LpvTcxkDbge.html
/reg/person?ReturnUrl=https%3A//sale.jd.com/act/r1z8LpvTcxkDbge.html
-
$query_string
与变量$args含义相同
-
$scheme
存放客户端请求使用的协议,如果http, https
-
$server_protocol
存放客户端请求协议的版本 HTTP/1.0 HTTP/1.1
-
$server_addr
存放服务器地址
-
$server_name
存放了客户端请求到达的服务器的名称
-
$server_port
存放了客户端请求到达的服务器的端口号
-
$uri
与变量$document_uri含义相同
rewrite应用:
示例1:
location / {
root html;
index index.html index.htm;
rewrite "^/forum/(.*)" http://192.168.0.101/bbs/$1;
}
示例2:域名跳转
server {
listen 80;
server_name jump.myweb.name;
rewrite ^/ http://www.myweb.info/;
}
示例3:
server {
listen 80;
server_name jump.myweb.name jump.myweb.info;
if ($host ~ myweb.info$) {
rewrite ^(.*) http://jump.myweb.name$1;
}
}
示例4:
server {
listen 80;
server_name jump1.myweb.name jump.myweb.name;
if ($host ~ ^(.).myweb.name$) {
rewrite ^(.) http://jump.myweb.name$1;
}
WebDAV(Web-based Distributed Authoring and Versioning)
一种基于HTTP 1.1协议的通信协议,它扩展了HTTP 1.1,在GET,POST,HEAD等几个HTTP标准方法以外添加了一些新的方法,使应用程序可直接对Web Server直接读写,并支持写文件锁定(Locking)及解锁(Unlock),还可以支持文件的版本控制。
rpm httpd默认支持DAV功能
通过此协议可以支持在Web Server上传文件
Nginx读写分离
前端:Nginx服务器 10.1.1.1
后端:Apache服务器 10.1.1.2 10.1.1.3(可在此服务器上传文件)
确保10.1.1.3服务器开启DAV功能
确保Apache配置文件加载了DAV相关模块
vim /etc/httpd/conf/httpd.conf
LoadModule dav_module modules/mod_dav.so
LoadModule dav_fs_module modules/mod_dav_fs.so
在相应网页根目录授权段中开启DAV
<Directoy "/var/www/html">
....
dav on
确保运行httpd进程的apache用户对网页根目录拥有写入权限
setfacl -m u:apache:rwx /var/www/html/
测试在客户端可以向10.1.1.3服务器上传文件
curl -T /etc/issue http://10.1.1.3
前端Nginx服务器配置读写分离,读操作代理到10.1.1.2上,写操作代理到10.1.1.3上;
vim /etc/nginx/nginx.conf
location / {
proxy_pass http://10.1.1.2;
if ($request_method = "PUT") {
proxy_pass http://10.1.1.3;
}
}
测试nginx读写分离操作是否成功
读取网页内容时,代理后10.1.1.2服务器上
curl http://10.1.1.1
Apache Page of 10.1.1.2
上传文件时,代理到后端10.1.1.3服务器上
curl -T /etc/fstab http://10.1.1.1
Created
Resource /fstab has been created.
Apache/2.2.15 (Red Hat) Server at 10.1.1.3 Port 80
后端两台服务器通过rsync+inotify进行数据同步,保证上传的数据可以同步到后端所有服务器上
Nginx服务器高级配置
1、针对IPV4内核的配置优化参数
vim /etc/sysctl.conf
net.core.netdev_max_backlog = 20000
net.core.somaxconn = 20000
net.ipv4.tcp_max_orphans = 20000
net.ipv4.tcp_max_syn_backlog = 20000
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_synack_retries = 1
net.ipv4.tcp_syn_retries = 1
参数说明:
-
net.core.netdev_max_backlog
表示当每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许发送到队列的数据包的最大数目。默认为128
-
net.core.somaxconn
用于调节系统同时发起的TCP连接数,一般默认值是128. 在存在高并发时,可将该值调大
-
net.ipv4.tcp_max_orphans
用于设置系统中最多允许存在多少TCP套接字不被关联到任何一个用户文件句柄上。
如果超过这个数字 ,没有与用户文件句柄关联的TCP套接字将立即被复位,同时给出警告信息
在内存比较充足的情况下可调大此值 -
net.ipv4.tcp_max_syn_backlog
用于记录尚未收到客户端确认信息的连接请求的最大值
在内存比较充足的情况下可调大此值 -
net.ipv4.tcp_timestamps
用于设置时间戳,这可以避免序列号的卷绕
默认情况下,TCP协议会让内核接收这种“异常(序列号一致)"的数据包
针对nginx服务器而言,建议将其关闭 -
net.ipv4.tcp_synack_retries
用于设置内核放弃TCP连接前向客户端发送SYN+ACK包的数量
一般赋值为1 -
net.ipv4.tcp_syn_retries
用于设置内核放弃TCP连接前,向客户端发送SYNC包的数量
一般赋值为1
2、针对CPU的配置优化
-
worker_processes
该指定用于设置nginx服务的工作进程数;建议设置为CPU个数的2倍
针对双核CPU,可以设置为2或者4 -
worker_cpu_affinity
用于设置每个进行分配CPU的工作内核
worker_cpu_affinity 0001 0100 1000 0010
以上4组二进制数字分别对应worker_processes指定的4个工作进程 其中0001,代表第1个进程使用CPU的第1个核心进行处理,0100代表使用CPU第3个核心进行处理
3、针对网络连接相关的配置参数
-
keepalive_timeout
用于设置长连接的超时时间
该参数支持两个选项,不同的选项使用空格隔开,例如:
keepalive_timeout 60 50;
该设置表示nginx服务器与客户端的长连接活动时间为60s,60s后服务器与客户端断开连接;使用keep-alive消息头保持与客户端某些浏览器的连接时间为50s,50s后浏览器主动与服务器断开连接 -
send_timeout
该指令用于设置nginx服务器响应客户端的超时时间,这个超时时间仅针对客户端与服务器间建立连接后,某次活动的时间;如果这个时间后客户端没有任何活动,nginx服务器将会关闭连接
send_timeout 10s;
该设置表示nginx服务器与客户端建立连接后,某次会话中服务器等待客户端响应时间为10s,超过该时间,服务器则关闭连接 -
client_header_buffer_size 4k;
该指令用于设置nginx服务器允许的客户端请求头部的缓冲区大小,默认为1KB,此指令可根据系统分布大小来设置
查看系统分页大小的方法:
[root@localhost ~]# getconf PAGESIZE
4096
3、事件驱动模型相关的配置参数
events {
use epoll;
worker_connections 65535;
}
-
use epoll
设置nginx服务器默认使用的事件驱动模型
-
worker_connections 65535;
设置每个工作进程允许的最大连接数
该数字的值的设置如果超过系统允许每个进程打开的文件句柄数,还需要调整该数字查看文件句柄:
[root@localhost ~]# cat /proc/sys/fs/file-max
186531
[root@localhost ~]#
Nginx服务器的压缩功能
在nginx配置文件中可使用gzip压缩功能,对响应数据进行压缩,以节省网络带宽
压缩相关的指令可用于http, server及location段中
nginx服务器通过ngx_http_gzip_module, ngx_http_gzip_static_module和ngx_http_gunzip_module模块对这些指令进行处理
由ngx_http_gzip_module模块处理的指令
gzip on;
gzip_buffers 32 4k;
gzip_comp_level 1;
gzip_disable "MSIE [4-6]\.";
gzip_min_length 1024;
gzip_types text/plain application/x-javascript text/css text/html application/xml;
gzip_vary on;
参数说明:
-
gzip on;
该指令表示开启gzip压缩功能
-
gzip_buffers 32 4k;
该指定用于设置gzip压缩文件时使用缓存空间大小
32表示向系统申请32个缓存空间的个数,4k表示每个缓存空间的大小 -
gzip_comp_level
用于设置压缩比,取值为1--9,1表示压缩比最低
-
gzip_disable
针对不同客户端浏览器类型不同,可选择开启或关闭gzip压缩功能
该指令用于设置对哪些浏览器的访问禁用压缩功能
-
gzip_min_length 1024;
压缩对大数据的处理比较有效果,但是对于一些小文件,可能会出现越压缩文件越大的情况(压缩算法导致)
该指令用于设置响应页面的字节数,超过1024字节再压缩 -
gzip_types
该指令用于设置针对哪些MIME类型进行压缩, 可针对mimes.type文件设置
-
gzip_vary on
该指令用于设置HTTP响应头部中是否带有头部信息,说明压缩
on,在头部中会看到如下信息: Vary:Accept-Encoding
由ngx_http_gzip_static_module模块处理的指令
ngx_http_gzip_static_module模块主要负责搜索和发送经过gzip功能预压缩的数据。这些数据以.gz作为后缀名存储在服务器上。如果客户端请求的数据之前被压缩过,并且客户端浏览器支持gzip压缩,就直接返回压缩后的数据。
参数说明:
-
gzip_static on|off|always;
on 开启该模块的功能
off 关闭该模块的功能
always 一直发送gzip压缩文件,而不检查客户端浏览器是否支持gzip压缩
ngx_http_gunzip_module模块
nginx服务器对数据支持压缩,对于客户端浏览器来说,必须有能力解压。如果客户端浏览器不支持压缩功能,就需要nginx服务器在向其发送数据前先将该数据解析
ngx_http_gunzip_module模块便是用来针对不支持gzip压缩数据处理的客户端浏览器,对压缩数据进行解压处理的。
参数说明:
-
gunzip_statice on|off;
on 开启该模块的功能
off 关闭该模块的功能
Nginx服务器反向代理
1、proxy_pass指令
用于指定后端服务器的主机名或者IP地址
location / {
proxy_pass http://192.168.87.102;
}
location /server {
proxy_pass http://192.168.87.102/;
}
location /server {
proxy_pass http://192.168.87.102;
}
location /server {
proxy_pass http://192.168.87.102/doc;
}
locaiton /server/ {
proxy_pass http://192.168.87.102/doc/;
}
2、proxy_hide_header
该指令用于设置Nginx服务器在发送响应时,隐藏一些头域信息
该指令可用在http, server, location块
proxy_pass_header <field>
默认情况下,nginx服务器在发送响应数据时,报文头中不包含“Date", "Server", "X-Accel"等来自后端服务器的信息
该指令可以设置这些头域信息以被发送
proxy_pass_request_headers {on|off}
该指令用于配置是否将客户端请求的请求体发送给代理服务器
默认为on
3、proxy_set_header
该指令可以更改nginx服务器接收到的客户端请求的请求头信息,然后将新的请求头发送给被代理服务器
4、proxy_set_body
该指令可以更改nginx服务器接收到的客户端请求的请求体信息,然后将新的请求体发送到被代理的服务器
5、proxy_bind
在配置了多个基于名称或者基于IP的虚拟主机时,如果我们希望代理连接由指定的主机处理,就可以使用该指令进行配置
6、proxy_connect_timeout
该指令配置nginx服务器与后端服务器尝试建立连接的超时时间,默认为60s
proxy_connect_timeout <time>
7、proxy_read_timeout
该指令配置nginx服务器向后端被代理服务器发出READ请求后,等待响应的超时时间,默认为60s
8、proxy_send_timeout
该指定配置nginx服务器向后端服务器发出write请求后,等待响应的超时时间,默认为60s
9、proxy_http_version指令
该指令用于设置用于Ngnix服务器提供代理服务的HTTP协议及版本,默认为1.0版本
10、proxy_method
该指令用于设置nginx服务器向后端代理服务器发送请求时使用的方法。一般为POST或者GET,
11、proxy_ignore_client_abort {on|off}
该指令用于设置在客户端中断网络时,nginx服务器是否中断对后端服务器的请求
默认为off,当客户端中断网络请求时,nginx服务器中断对后端服务器的请求
12、proxy_ignore_headers
该指令用于设置一些HTTP响应头的头域,nginx服务器接收到后端服务器的响应数据后,不会处理被设置的头域
13、proxy_redirect
该指令用于修改后端服务器返回的响应头中的Location头域的refresh头域,与proxy_pass指令配合使用
可以把代理服务器返回的地址信息更改为需要的地址信息
proxy_redirect <redirect> <replacement>
假设后端服务器返回的响应头中的Location是"http://localhost:8081/proxy"
proxy_redirect http://localhost:8081/proxy http://myweb/fronted
nginx服务器会将location中的信息修改为如下:
http://myweb/fronted
proxy_redirect <default>
default表示的意思是使用location块中的uri变量作为replacement,并使用Proxy_pass变量作为redirect
location /server/ {
http://proxyserver/src/;
proxy_redirect default;
}
nginx服务器会将location头域的信息修改为http://server
proxy_redirect <off>
off表示当前作用域下所有proxy_redirect指令无效
14、proxy_intercept_errors {on|off}
该指令设置一个状态是开启还是关闭。
在开启该状态时,如果被代理的服务器返回的HTTP 400或者大于400状态码,则Nginx服务器使用自己定义的错误页
如果关闭该状态,Nginx服务器直接将被代理服务器返回的HTTP状态返回客户端
15、proxy_headers_hash_max_size
该指令用于配置存放HTTP报文头的hash表的容量,默认为512个字符
nginx服务器为了能够快速检索HTTP报文头中的各项信息,使用hash表来存储这些信息。nginx服务器在申请存放HTTP报文头的空间时,通常以固定大小 为单位申请,该大小由proxy_headers_hash_bucket_size指令配置
16、proxy_headers_hash_bucket_size
该指令用于配置nginx服务器申请存放HTTP报文头的hash表的容量的单位大小;默认为64个字符
17、proxy_next_upstream
该指令指定在发生哪些异常情况下,将请求顺序交由下一个upstream组内的服务器处理
status:
error:在建立连接、向后端服务器发送请求或者读取响应头时发生连接错误
timeout:在建立连接、向后端服务器发送请求或者读取响应头时发生连接超时
invalid_header:后端服务器返回的响应头为空或者无效
http_500 | http_502 | http_503 | http_504 | http_404
off:无法将请求发送给后端服务器
18、proxy_ssl_session_reuse { on | off }
该指令用于配置是否使用基于SSL的协议连接后端服务器
默认为开启状态;
如果在错误日志中发现"SSL3_GET_FINISHED: digest check failed"的情况下,可以将该指令配置为关闭状态
proxy buffer的配置
工作原理:
proxy buffer启用后,nginx服务器会异步地将被代理服务器的响应数据传递给客户端
Nginx服务器首先尽可能地从被代理服务器那里接收响应的数据,放置在proxy buffer中. 如果在接收过程中,发现buffer中没有足够大的空间来接收一次响应的数据,nginx服务器会将部分接收到的数据临时存放在磁盘的临时文件中。一次响应数据被接收完成或者buffer装满后,nginx服务器开始向客户端传送数据。
每个buffer装满后,在向客户端传送数据的过程中,它都处于BUSY状态,期间对它进行的其他操作都会失败
参数说明:
-
proxy_buffering
该指令用于配置是否启用或者关闭proxy buffer, 默认为开启状态
-
proxy_buffer
该指令用于配置接收一次后端服务器的响应数据的proxy buffer的个数和每个buffer的大小
每个buffer的大小一般设置为内存页的大小
proxy_buffers 8 4k;
-
proxy_buffer_size
该指令用于配置从后端服务器获取的第一部分响应数据的大小 ,该数据中一般包含HTTP响应头
默认设置为4k或者8k
-
proxy_busy_buffers_size
该指令用于设置同时处于BUSY状态的proxy buffer总大小
默认设置为8k或者16k
-
proxy_temp_path
[ level1 level2 level3 ] 该指令用于配置磁盘上的一个文件路径,该文件用于临时存放代理服务器的接收的响应数据
-
proxy_max_temp_file_size
该指令用于配置所有临时文件的总大小 ,这样避免响应数据过大造成磁盘空间不足
默认为1024MB
-
proxy_temp_file_write_size
该指令用于配置同时写入临时文件的数据量的总大小, 合理的设置该值可避免磁盘IO过重导致系统性能下降
根据平台不同,一般设置为内存页的大小
proxy cache的配置
参数说明:
-
proxy_cache
| off; 该指令用于配置一块公用的内存区域的名称,该区域可以存放缓存的索引数据
默认的设置为off
-
proxy_cache_bypass
... 该指令用于配置nginx服务器向客户端发送响应数据时, 不从缓存中获取数据的条件
这些条件会使用nginx的内置变量,例如:
proxy_cache_bypass $cookie_nocache $arg_nocache $arg_comment $http_authorization;
-
proxy_cache_key
该指令用于设置nginx服务器在内存中为缓存数据建立索引时使用的关键字
proxy_cache_key $shceme$proxy_host$uri$is_args$args;
-
proxy_cache_lock
该指令用于设置是否开启缓存的锁功能;默认为关闭状态
在缓存中,某些数据项可以同被多个请求返回的数据使用。开启该功能后,nginx服务器同时只能有一个请求填充缓存的某一个数据项,其他请求如果也想填充该数据项,必须等待该数据项的锁被释放 -
proxy_cache_lock_timeout
该指令用于设置缓存的锁功能开启后的超时时间,默认为5s
-
proxy_cache_min_uses
该指令用于设置客户端请求发送的次数,当客户端向后端服务器发送相同请求的次数超时该数字后,nginx服务器才会对响应数据进行缓存
默认值为1 -
proxy_cache_path
[levels= ] keys_zone= : [max_size= ] [inactive= 该指令用于设置nginx服务器存储缓存数据的路径及缓存索引相关的内容
path,设置缓存数据存放的根路径
levels=用于设置相对于path路径来说,以几级目录的方式存放缓存数据
keys_zone=: 设置存放缓存索引的内存区域的名称和大小
max_size=设置硬盘中缓存数据的大小限制;当缓存数据超过该容量时,会使用最近最少被访问的策略删除相应的缓存数据 inactive=
设置强制更新缓存数据的时间,当硬盘上的缓存数据超过这个时间没有被访问,则删除之;默认为10s loader_files=
设置缓存索引重建进程每次加载的数据元素的数量上限,默认为100
在重建缓存索引的过程中,进程通过一系列的递归遍历读取硬盘上的缓存数据目录及缓存数据文件 ,对每个数据文件中的缓存数据在内存中建立对应的索引,每建立一个索引为加载一个数据元素loader_sleep=
设置缓存索引重建进程在一次遍历结束、下次遍历开始之间的暂停时长。默认为50ms loader_threshold=
设置遍历一次磁盘缓存数据的时间上限。默认为200ms proxy_cache_path /nginx/cache/a levels=1 keys_zone=a:10m;
proxy_cache_path /nginx/cache/b levels=2:2 keys_zone=b:100m;
proxy_cache_path /nginx/cache/c levels=1:1:2 keys_zone=c:100m; -
proxy_cache_use_stale
如果nginx在访问后端服务器的过程中出现不能访问的情况,nginx可以使用历史缓存来响应客户端
该指令用于配置一些状态,设置当出现哪种状态时,以缓存数据响应客户端默认值为off
proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 | http_504 | http_404 | off;
-
proxy_cache_valid [code1 code2]
该指令可针对不同的响应状态码设置不同的缓存时间
proxy_cache_valid 200 302 10m;
proxy_cache_valid 301 1h;
proxy_cache_valid any 1m; -
proxy_no_cache
... 该指令用于设置在什么情况下不使用cache功能
string可以是一个或者多个变量,当string的值不为空或者不为0时,不启用cache功能
提供缓存的另外一种机制:proxy_store
proxy_store机制
它不提供缓存过期更新、内存索引建立等功能,不占用内存空间,对静态数据的效果比较好
proxy_store机制多用在后端服务器发生错误的情况下,用来缓存后端服务器的响应数据
参数说明:
-
proxy_store { on | off |
} on 开启该功能,缓存文件会保存到alias指令或root指令设置本地路径下
默认为offstring 自定义缓存文件的存放路径
-
proxy_store_access
: .... 该指令用于设置用户或者用户组对proxy store缓存的数据的访问权限
users:可以是user, group, all
permission:设置权限
location写法:
location [=||*|^~] URI地址 {
....
....
}
= 精确匹配URI地址
location /bbs {
...
...
}
location = /bbs {
...
...
}
~ 使用正则表达式匹配URI地址, 区分大小写
location ~ /image/ {....}
~* 使用正则表达式匹配URI地址, 不区分大小写
location ~* /image {....} http://10.1.2.1/IMAGES/
location ~* \.jpg$ {.....}
location ~* \.(jpg|gif|png|jpeg)$ {......}
^~ 不使用正则表达式表示URI地址
location ^~ /image {.....}
location /image {.....}
优先级:
= ---> ^~ ----> ~ ------> ~* ------> /
Nginx反向代理
server {
listen 80;
server_name www.bj.com;
location / {
后端服务器;
}
}
后端服务器:
proxy_pass
示例1:客户端通过http://192.168.122.101访问nginx时,以本地页面响应;通过http://192.168.122.101/forum访问时,代理到后端服务器
location / {
root html;
index index.html index.htm;
}
location /forum {
proxy_pass http://192.168.122.102/;
}
注意:
1) 如果location后写自定义的URI地址,在做反向代理时,必须要指定URI地址
示例2:
客户端http://192.168.122.101/discuz访问时,代理到后端服务器192.168.122.102的bbs目录下
location /discuz {
proxy_pass http://192.168.122.102/bbs;
}
特殊情况:
如果在定义location时,加入了~ ~* 这样的模式匹配字符,proxy_pass在写时,只能写到服务器地址
location ~ /discuz {
proxy_pass http://192.168.122.102;
}
注意: 后端服务器要存在相同名称的目录
示例4: 配置nginx不再响应客户端访问请求,所有访问请求全部代理到后端服务器
location / {
proxy_pass http://192.168.122.102;
}
此时,对于后端服务器来说,access_log中记录的日志,客户端IP是nginx的IP
192.168.122.101 - - [05/Jan/2017:21:39:22 +0800] "GET / HTTP/1.0" 403 4954 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"
配置proxy_set_header,实现后端服务器记录真实的客户端IP
location / {
proxy_pass http://192.168.122.102;
proxy_set_header x-real-ip $remote_addr;
}
proxy_set_header x-real-ip $remote_addr;
代理在httpd请求报文中加入x-real-ip段的内容,该内容是变量$remote_addr的值,即真实客户端的IP
编辑后端服务器配置文件/etc/httpd/conf/httpd.conf,修改combined日志格式,将客户端地址%h换成%{x-real-ip}i,表示记录HTTP请求报文中X-Real-IP的内容
LogFormat "%{x-real-ip}i %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i"" combined
刷新浏览器,再次查看后端服务器access_log,日志中记录的是真实客户端的IP地址192.168.122.1
192.168.122.1 - - [05/Jan/2017:21:48:50 +0800] "GET /icons/poweredby.png HTTP/1.0" 304 - "http://192.168.122.101" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"
Nginx负载均衡
算法:
roundrobin, rr, 轮询, 默认; 支持为后端服务器设置权重(weight)
ip_hash 相同IP地址的客户端请求, nginx会代理同一台后端服务器
实现负载均衡:
upstream <组名称> {
[调度算法];
server IP:port [weight=<number>] [max_fails=<number>] [fail_timeout=<number>];
server IP:port [weight=<number>] [max_fails=<number>] [fail_timeout=<number>];
server IP:port [weight=<number>] [max_fails=<number>] [fail_timeout=<number>] [backup];
}
weight=<number> 设置服务器的权重值
max_fails=<number> 检测失败的次数
fail_timeout=<number> 检测的周期,单位为秒
backup 设置为备份服务器
upstream的定义必须在server{..}外定义
location / {
proxy_pass http://<组名称>
}
示例1: 实现负载均衡
upstream websrv {
server 192.168.122.102 weight=1 max_fails=2 fail_timeout=2;
server 192.168.122.103 weight=1 max_fails=2 fail_timeout=2;
}
location / {
proxy_pass http://websrv;
proxy_set_header x-real-ip $remote_addr;
}
提供sorry页面:
upstream websrv {
server 192.168.122.102 weight=1 max_fails=2 fail_timeout=2;
server 192.168.122.103 weight=1 max_fails=2 fail_timeout=2;
server 127.0.0.1:8080 backup;
}
虚拟主机配置:
server {
listen 127.0.0.1:8080;
server_name localhost;
location / {
root /sorry;
index index.html index.htm;
}
}
Nginx反向代理缓存
缓存组成的两部分:
共享内存: 存储键和缓存对象元数据
磁盘空间:存储数据
定义缓存空间
proxy_cache_path: 不能定义在server{}中
proxy_cache_path /nginx/cache/first levels=2:1:2 keys_zone=first:20m max_size=1G
levels=
定义缓存目录子目录的级别,及每个子目录的名称字符个数; 最多只能有3级子目录
levels=1:2:2,3级子目录,第1级目录字符个数为1,第2级目录字符个数为2,第3级目录字符个数为2,字符个数最多只能有2个
keys_zone=name:size
定义存储键的区域(定义共享内存的名称)
max_size=1G
指定/nginx/cache/first中的1G空间用于存储缓存数据
Nginx缓存配置:
定义缓存存放路径为/web/cache, 最多使用1G空间; 并定义键值区域名称为first,大小为20m
proxy_cache_path /web/cache levels=1:2 keys_zone=first:20m max_size=1g;
在location中开启缓存功能,指定使用键值名称为first的缓存
在httpd响应报文中添加额外项X-cache,用于查看缓存是否命中
add_header x-cache "$upstream_cache_status by $server_addr";
$upstream_cache_status: 用于记录缓存是否命中的状态 (HIT, MISS, EXPIRED)
$server_addr 服务器地址
location / {
proxy_pass http://webserver/;
proxy_set_header X-Real-IP $remote_addr;
proxy_cache first; >>>>使用内存first中保存的缓存
proxy_cache_valid 200 1m;
}
proxy_cache_valid 200 1m;
表示为状态码为200的数据缓存1分钟
查看缓存是否命中,在浏览器中按F12打开开发者模式,查看HTTP响应报文,可以看到X-cache:HIT by 10.1.2.1信息,表示缓存命中
URL重写 ----- rewrite
1、if指令
if (条件) {......}
{...} 代表条件为真时的nginx操作
condition条件的写法:
-
变量名
如果变量的值为空,或者为以"0"开头的任意字符串,条件为假,其他则为真
if ($slow)
-
使用"="或者"!="比较变量的值
if ($request_method = POST)
-
使用正则表达式与变量的值进行匹配
变量名与正则表达式间使用~, ~, !~, !~进行连接
在正则表达式中使用()可以对字符进行分组,在{}中可以用$1....$9引用分组
正则表达式写时不需要加双引号,但是如果正则表达式中含有}和;字符,则必须要使用双引号
if ($http_user_agent ~* MSIE)
-
判断请求的文件是否存在
if ( -f $request_filename) {.....}
if (!-f $request_filename)
-
判断请求的目录是否存在 (-d, !-d)
-
判断请求的目录或文件是否存在 (-e, !-e)
-
判断请求的文件是否可执行 (-x, !-x)
WebDAV(Web-based Distributed Authoring and Versioning)
一种基于HTTP 1.1协议的通信协议,它扩展了HTTP 1.1,在GET,POST,HEAD等几个HTTP标准方法以外添加了一些新的方法,使应用程序可直接对Web Server直接读写,并支持写文件锁定(Locking)及解锁(Unlock),还可以支持文件的版本控制。
rpm httpd默认支持DAV功能
通过此协议可以支持在Web Server上传文件
Nginx读写分离
前端:Nginx服务器 192.168.122.101
后端:Apache服务器 192.168.122.102 192.168.122.103(可在此服务器上传文件)
确保192.168.122.103服务器开启DAV功能
确保Apache配置文件加载了DAV相关模块
vim /etc/httpd/conf/httpd.conf
LoadModule dav_module modules/mod_dav.so
LoadModule dav_fs_module modules/mod_dav_fs.so
在相应网页根目录授权段中开启DAV
<Directoy "/var/www/html">
....
dav on
确保运行httpd进程的apache用户对网页根目录拥有写入权限
setfacl -m u:apache:rwx /var/www/html/
测试在客户端可以向192.168.122.103服务器上传文件
curl -T /etc/issue http://192.168.122.103
前端Nginx服务器配置读写分离,读操作代理到192.168.122.102上,写操作代理到192.168.122.103上;
location / {
proxy_pass http://192.168.122.102;
if ($request_method = PUT) {
proxy_pass http://192.168.122.103;
}
}
测试nginx读写分离操作是否成功
测试读操作:
[root@www ~]# curl http://192.168.122.101
web-1 ON Apache
测试写操作:
[root@www ~]# curl -T /etc/fstab http://192.168.122.101
Created
Resource /fstab has been created.
Apache/2.2.15 (CentOS) Server at 192.168.122.103 Port 80
后端两台服务器通过rsync+inotify进行数据同步,保证上传的数据可以同步到后端所有服务器上
2、rewrite指令 --------------- URL重写
该指令通过使用正则表达式的使用来改变URI。
可以同时存在一条或者多条,按顺序依次对URL进行匹配和处理
该指令可用于 server, location, if 中
语法结构:
rewrite <正则表达式> <REPLACEMENT> [FLAG]
REGEX 用于匹配URI的正则表达式
注意:
1) rewrite接收到的URL地址不包括主机名称部分
2) 不包括URL地址中的请求指令
https://reg.jd.com/reg/person?ReturnUrl=https%3A//sale.jd.com/act/r1z8LpvTcxkDbge.html
REPLACEMENT
匹配成功后用于替换URI中被截取内容的字符串。
默认情况下,如果字符串是以http://或者https://开头,则不会继续向下对URI进行其他处理,而直接将重写后的URI返回给客户端
支持变量的使用
FLAG
1) last
终止继续在本location块中处理接收到的URI,并将此处重写的URI作为一个新的URI,使用下一个location块进行处理
location / {
rewrite ^(/myweb/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 last;
rewrite ^(/myweb/.*)/audio/(.*)\..*$ $1/mp3/$2.ra last;
}
2) break
将此处重写的URI作为一个新的URI,在本块中继续进行处理。该标志将重写后的地址在当前的location块中执行,不会将新的URI转向到其他location块
location /web/ {
rewrite ^(/myweb/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break;
rewrite ^(/myweb/.*)/audio/(.*)\..*$ $1/mp3/$2.ra break;
}
3) redirect
将重写后的URI返回给客户端,状态代码为302,指明是临时重定向,主要用在replacement不是以http://或者https://开头的情况下
4) permanent
将重写后的URI返回给客户端,状态代码为301,指明是永久重写向
示例1:
location / {
root /web;
index index.html index.htm;
rewrite ^/mp3 http://192.168.122.101/audio;
}
示例2:
location / {
root /web;
index index.html index.htm;
rewrite ^/mp3/(.*\.html)$ http://192.168.122.101/audio/$1;
}
location / {
root /web;
index index.html index.htm;
rewrite ^/mp3/(.*\.html)$ $scheme://$host/audio/$1;
}
示例3: 域名跳转
location / {
root /web;
index index.html index.htm;
rewrite ^/ http://www.jd.com;
}
示例04:防盗链
server {
listen 80;
server_name www.d.org;
location / {
root /abc;
index index.html;
valid_referers none blocked www.d.org;
if ($invalid_referer) {
return 404;
}
}
}
[root@web01 ~]# cat /var/www/html/index.html
<a href="http://www.d.org/1.html"> httpd hahahaha </a>
Nginx变量
-
$args
存放URL中的请求指令
https://reg.jd.com/reg/person?ReturnUrl=https%3A//sale.jd.com/act/r1z8LpvTcxkDbge.html
ReturnUrl=https%3A//sale.jd.com/act/r1z8LpvTcxkDbge.html
-
$content_length
存放请求报文中content_length字段内容
-
$content_type
存放请求报文中content_type字段内容
-
$document_root
存放针对当前请求的根路径
-
$document_uri
存放请求报文中的当前URI,并且不包括请求指令
https://reg.jd.com/reg/person?ReturnUrl=https%3A//sale.jd.com/act/r1z8LpvTcxkDbge.html
/reg/person
-
$host
存放请求报文中的主机部分
https://reg.jd.com/reg/person?ReturnUrl=https%3A//sale.jd.com/act/r1z8LpvTcxkDbge.html
reg.jd.com
-
$http_user_agent
存放客户端代理信息(浏览器)
-
$http_cookie
存放客户端的cookie信息
-
$limit_rate
存放nginx服务器对网络连接速率的限制,也就是ngnix配置文件中limit_rate指令的值
-
$remote_addr
存放客户端地址
-
$remote_port
存放客户端端口
-
$remote_user
存放客户端的用户名
-
$request_body_file
存放发给后端服务器的本地文件资源名称
-
$request_method
存放客户端请求资源的方法, GET, POST, PUT, DELETE, HEAD
-
$request_filename
存放当前请求的资源文件的路径名
-
$request_uri
存放当前请求的URI,并且带有请求指令
https://reg.jd.com/reg/person?ReturnUrl=https%3A//sale.jd.com/act/r1z8LpvTcxkDbge.html
/reg/person?ReturnUrl=https%3A//sale.jd.com/act/r1z8LpvTcxkDbge.html
-
$query_string
与变量$args含义相同
-
$scheme
存放客户端请求使用的协议,如http, https
-
$server_protocol
存放客户端请求协议的版本 HTTP/1.0 HTTP/1.1
-
$server_addr
存放服务器地址
-
$server_name
存放了客户端请求到达的服务器的名称
-
$server_port
存放了客户端请求到达的服务器的端口号
-
$uri
与变量$document_uri含义相同