您的位置:首页 > 运维架构 > 反向代理

Nginx 反向代理、负载均衡、页面缓存、URL重写及读写分离详解

2016-09-23 19:14 1011 查看

一、关于Nginx

nginx在启动后,在unix系统中会以daemon的方式在后台运行,后台进程包含一个master进程和多个worker进程。

master进程主要用来管理worker进程,包含:接收来自外界的信号,向各worker进程发送信号,监控worker进程的运行状态,当worker进程退出后(异常情况下),会自动重新启动新的worker进程。

而基本的网络事件,则是放在worker进程中来处理了。

多个worker进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的。

关于nginx,主要由3大模块,内核模块,事件模块,http核心模块。

nginx模块一般被分成三大类:handler、filter和upstream。

handler源码分析,可以去看 tengine的介绍 http://tengine.taobao.org/book/chapter_03.html

filter源码分析,可以去看 tengine的介绍 http://tengine.taobao.org/book/chapter_04.html

upstream源码分析,可以去看 tengine的介绍 http://tengine.taobao.org/book/chapter_05.html

Nginx开发从入门到精通

二、安装Nginx

1、安装yum源

rpm -ivh http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6[/code] 
2、安装nginx

① gzip 模块需要 zlib 库 ( 下载: http://www.zlib.net/zlib-1.2.8.tar.gz )

② rewrite 模块需要 pcre 库 ( 下载: http://www.pcre.org/ 下载: ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.37.tar.gz)

③ ssl 功能需要 openssl 库 ( 下载: http://www.openssl.org/source/openssl-fips-2.0.12.tar.gz )

④ Nginx包下载: http://nginx.org/download/nginx-1.9.13.tar.gz

依赖包安装顺序依次为:openssl、zlib、pcre, 然后安装Nginx包.

[root@nginx ~]# yum install -y pcre-devel openssl-devel zlib-devel
[root@nginx ~]# wget http://nginx.org/download/nginx-1.9.13.tar.gz [root@nginx ~]# tar -xvf nginx-1.9.13.tar.gz
[root@nginx ~]#./configure --with-pcre=../pcre-8.21 --with-zlib=../zlib-1.2.7 --with-openssl=../openssl-fips-2.0.2
[root@nginx ~]#make && make install


3、为nginx提供SysV init脚本

cat /etc/init.d/nginx

#!/bin/sh
#
# nginx - this script starts and stops the nginx daemon
#
# chkconfig:   - 85 15
# description:  Nginx is an HTTP(S) server, HTTP(S) reverse \
#               proxy and IMAP/POP3 proxy server
# processname: nginx
# config:      /etc/nginx/nginx.conf
# config:      /etc/sysconfig/nginx
# pidfile:     /var/run/nginx.pid
# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0
nginx="/usr/sbin/nginx"
prog=$(basename $nginx)
NGINX_CONF_FILE="/etc/nginx/nginx.conf"
[ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx
lockfile=/var/lock/subsys/nginx
make_dirs() {
# make required directories
user=`nginx -V 2>&1 | grep "configure arguments:" | sed 's/[^*]*--user=\([^ ]*\).*/\1/g' -`
options=`$nginx -V 2>&1 | grep 'configure arguments:'`
for opt in $options; do
if [ `echo $opt | grep '.*-temp-path'` ]; then
value=`echo $opt | cut -d "=" -f 2`
if [ ! -d "$value" ]; then
# echo "creating" $value
mkdir -p $value && chown -R $user $value
fi
fi
done
}
start() {
[ -x $nginx ] || exit 5
[ -f $NGINX_CONF_FILE ] || exit 6
make_dirs
echo -n $"Starting $prog: "
daemon $nginx -c $NGINX_CONF_FILE
retval=$?
echo
[ $retval -eq 0 ] && touch $lockfile
return $retval
}
stop() {
echo -n $"Stopping $prog: "
killproc $prog -QUIT
retval=$?
echo
[ $retval -eq 0 ] && rm -f $lockfile
return $retval
}
restart() {
configtest || return $?
stop
sleep 1
start
}
reload() {
configtest || return $?
echo -n $"Reloading $prog: "
killproc $nginx -HUP
RETVAL=$?
echo
}
force_reload() {
restart
}
configtest() {
$nginx -t -c $NGINX_CONF_FILE
}
rh_status() {
status $prog
}
rh_status_q() {
rh_status >/dev/null 2>&1
}
case "$1" in
start)
rh_status_q && exit 0
$1
;;
stop)
rh_status_q || exit 0
$1
;;
restart|configtest)
$1
;;
reload)
rh_status_q || exit 7
$1
;;
force-reload)
force_reload
;;
status)
rh_status
;;
condrestart|try-restart)
rh_status_q || exit 0
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"
exit 2
esac


4、为此脚本赋予执行权限,添加至服务管理列表,并让其开机自动启动

[root@nginx ~]# chmod +x /etc/init.d/nginx

[root@nginx ~]# chkconfig --add nginx
[root@nginx ~]# chkconfig nginx on


5、启动nginx,并用浏览器访问 htpp://192.168.1.22, 即主机ip, 如果有欢迎进入nginx则说明nginx配置安装成功, 否则可能需要关闭防火墙。

[root@nginx ~]# service nginx start


6、关闭防火墙

[root@nginx ~]# service iptables stop
[root@nginx ~]# chkconfig iptables off
[root@nginx ~]# getenforce


三、nginx.conf 配置文件

Nginx 配置文件主要分成四部分:main(全局设置)、http(HTTP 的通用设置)、server(虚拟主机设置)、location(匹配 URL 路径)。还有一些其他的配置段,如 event,upstream 等。

通用设置说明

user nginx #指定运行 nginx workre 进程的用户和组

worker_rlimit_nofile #指定所有 worker 进程能够打开的最大文件数

worker_cpu_affinity #设置 worker 进程的 CPU 粘性,以避免进程在 CPU 间切换带来的性能消耗.如 worker_cpu_affinity 0001 0010 0100 1000;(四核)

worker_processes 4 #worker 工作进程的个数,这个值可以设置为与 CPU 数量相同,如果开启了 SSL 和 Gzip,那么可以适当增加此数值

worker_connections 1000 #单个 worker 进程能接受的最大并发连接数,放在 event 段中

error_log logs/error.log info #错误日志的存放路径和记录级别

use epoll #使用 epoll 事件模型,放在 event 段中

server 配置示例

# server {}: 定义一个虚拟主机
server {
# 定义监听的地址和端口,默认监听在本机所有地址上
listen  80;
# 定义虚拟主机名,可以使用多个名称,还可以使用正则表达式或通配符。
server_name www.example.com;
# 开启 sendfile 调用来快速的响应客户端
sendfile on
# 长连接超时时间,单位是秒。
keepalive_timeout 65
# 指定响应客户端的超时时间
send_timeout
# 允许客户端请求的实体最大大小
client_max_body_size 10m
# 设置请求 URL 所对应资源所在文件系统上的根目录
root /web/htdocs;

# location [ = | ~ | ~* | ^~ ] URI { ... }
# 设置一个 URI 匹配路径
# =:精确匹配
# ~:正则表达式匹配,区分字符大小写
# ~*:正则表达式匹配,不区分字符大小写
# ^~:URI 的前半部分匹配,且不实用正则表达式
# 优先级:= > location 完整路径 > ^~ > ~ > ~* > location 起始路径 > location /
location / {
index index.html index.htm;
}

location /status {
stub_status on;
# 基于 IP 访问控制: allow 和 deny, 允许10.0.0.0网段客户进行访问
allow 10.0.0.0/8;
# 拒绝其他所有网段进行访问
deny all;
# 访问日志是否开启
access_log off;
# 重定向: rewrite <REGEX> <REPL> <FLAG>
# 可用的 flag:
# - last:重写完成后,继续匹配其他 rewrite 规则
# - break:重写完成后不再继续匹配
# - redirect:返回 302 重定向(临时重定向),客户端对重定向的 URL 发起新的请求
# - permanent:返回 301 重定向(永久重定向),客户端对重定向的 URL 发起新的请求
rewrite  ^(/status/.*)/media/(.*)\..*$  $1/mp3/$2.mp3  last;
}


四、nginx配置ssl

server {
listen 443;
server_name example.com;

root /apps/www;
index index.html index.htm;

ssl on;
# ssl_certificate 表示 CA 文件
ssl_certificate /etc/nginx/ssl/nginx.crt;
# 表示密钥文件
ssl_certificate_key /etc/nginx/ssl/nginx.key;

#  ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
#  ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
#  ssl_prefer_server_ciphers on;

}


五、nginx防盗图配置

防盗图主要是针对定向的路径,当用户访问该路径,检测域名,如果域名不对,重定向。

location ~ \/public\/(css|js|img)\/.*\.(js|css|gif|jpg|jpeg|png|bmp|swf) {
valid_referers none blocked *.homeway.me;
if ($invalid_referer) {
rewrite ^/  http://xiaocao.u.qiniudn.com/blog%2Fpiratesp.png; }
}


六、Nginx之反向代理

关于反向代理和正向代理的说明请阅读:http://blog.csdn.net/xlxxcc/article/details/52640432

在配置nginx反向代理之间我们得先准备两台测试服务器,Web1与Web2。

注意:每次修改配置,需要重新加载配置或者重新启动。

# 重启apache
service httpd restart
# 重新加载nginx配置
service nginx reload


1、安装httpd

[root@web1 ~]# yum install -y httpd
[root@web2 ~]# yum install -y httpd


2、提供测试页面

[root@web1 ~]# echo "<h1>web1.test.com</h1>" > /var/www/html/index.html
[root@web2 ~]# echo "<h1>web2.test.com</h1>" > /var/www/html/index.html


3、启动httpd服

[root@web1 ~]# service httpd start
[root@web2 ~]# service httpd start


4、浏览器访问 http://localhost/, 浏览器显示web1.test.com和web2.test.com说明正常。

5、nginx 代理模块 : proxy_pass ,

注意,当使用http proxy模块(甚至FastCGI),所有的连接请求在发送到后端服务器之前nginx将缓存它们,因此,在测量从后端传送的数据时,它的进度显示可能不正确。

配置http反向代理:

location / {
# 这个指令设置被代理服务器的地址和被映射的URI,地址可以使用主机名或IP加端口号的形式
proxy_pass        http://192.168.1.12; proxy_set_header  X-Real-IP  $remote_addr;
}


6、浏览器访问代理主机,会发现跳转达到192.168.1.12, 显示web1.test.com

7、查看web1的访问日志: tail /var/log/httpd/access_log可以看到我们这里的客户的IP全是,nginx代理服务器的IP,并不是真实客户端的IP。下面我们修改一下,让日志的IP显示真实的客户端的IP。

location / {
proxy_pass      http://192.168.18.201; # 记录访问用户真实ip
proxy_set_header  X-Real-IP  $remote_addr; #加上这一行
}


8、还需要配置被代理的apache配置: vim /etc/httpd/conf/httpd.conf, 才能在apache的访问日志中。


改成:



注,这是修改后的参数,将h%修改为%{X-Real-IP}i,好的下面我们再来测试一下。

好了,到这里Nginx代理后端一台服务器,看到日志里记录的IP地址就是真实的客户端地址了。

七、Nginx之负载均衡

1.upstream 负载均衡模块说明,示例:

upstream test.net{
ip_hash;
server 192.168.10.13:80;
server 192.168.10.14:80  down;
server 192.168.10.15:8009  max_fails=3  fail_timeout=20s;
server 192.168.10.16:8080;
}
server {
location / {
proxy_pass  http://test.net; }
}


2、upstream的几种调度方式和示例,请查阅:http://blog.csdn.net/xlxxcc/article/details/52641063

3、.配置nginx负载均衡, vim /etc/nginx/nginx.conf

upstream webservers {
server 192.168.1.12 weight=1;
server 192.168.1.13 weight=1;
}
server {
listen       80;
server_name  localhost;
#charset koi8-r;
#access_log  logs/host.access.log  main;
location / {
# 此处不可少, 指向上面的均衡负载配置
proxy_pass      http://webservers; proxy_set_header  X-Real-IP  $remote_addr;
}
}


4、重新加载nginx配置

service nginx reload


5、浏览器访问代理主机,会发现浏览器偶尔显示web1.test.com, 偶尔显示web2.test.com。两者交替出现,说明达到了负载均衡的效果。

6、配置nginx进行健康状态检查

upstream webservers {
#max_fails,允许请求失败的次数,默认为1。当超过最大次数时,返回proxy_next_upstream 模块定义的错误。
server 192.168.18.201 weight=1 max_fails=2 fail_timeout=2;
# fail_timeout,在经历了max_fails次失败后,暂停服务的时间。max_fails可以和fail_timeout一起使用,进行健康状态检查。
server 192.168.18.202 weight=1 max_fails=2 fail_timeout=2;
}


7、配置backup服务器, 应对所有服务器都不能提供服务

[root@nginx ~]# vim /etc/nginx/nginx.conf
upstream webservers {
server 192.168.18.201 weight=1 max_fails=2 fail_timeout=2;
server 192.168.18.202 weight=1 max_fails=2 fail_timeout=2;
server 127.0.0.1:8080 backup;
}
[root@nginx ~]# mkdir -pv /data/www/errorpage
[root@nginx errorpage]# cat index.html
<h1>Sorry......</h1>


8、关闭web1和web2,浏览器访问服务器,会发现浏览器显示 Sorry……

八、Nginx之页面缓存

1、页面缓存指令说明,请查阅:http://blog.csdn.net/xlxxcc/article/details/52641496

2、定义一个简单nginx缓存服务器,

[root@nginx ~]# vim /etc/nginx/nginx.conf
proxy_cache_path /data/nginx/cache/webserver levels=1:2 keys_zone=webserver:20m max_size=1g;
server {
listen       80;
server_name  localhost;
#charset koi8-r;
#access_log  logs/host.access.log  main;
location / {
proxy_pass      http://webservers; proxy_set_header  X-Real-IP  $remote_addr;
proxy_cache webserver;
proxy_cache_valid 200 10m;
}
}


3、新建缓存目录, 并重新加载配置文件

[root@nginx ~]# mkdir -pv /data/nginx/cache/webserver


4、配置$server_addr和$upstream_cache_status缓存变量

$server_addr: 服务器地址,在完成一次系统调用后可以确定这个值,如果要绕开系统调用,则必须在listen中指定地址并且使用bind参数。

$upstream_cache_status: 其值可能为:

MISS 未命中

EXPIRED - expired。请求被传送到后端。

UPDATING - expired。由于proxy/fastcgi_cache_use_stale正在更新,将使用旧的应答。

STALE - expired。由于proxy/fastcgi_cache_use_stale,后端将得到过期的应答。

HIT 命中

[root@nginx ~]# vim /etc/nginx/nginx.conf
proxy_cache_path /data/nginx/cache/webserver levels=1:2 keys_zone=webserver:20m max_size=1g;
server {
listen       80;
server_name  localhost;
#charset koi8-r;
#access_log  logs/host.access.log  main;
#增加两头部
add_header X-Via $server_addr;
add_header X-Cache $upstream_cache_status;
location / {
proxy_pass      http://webservers; proxy_set_header  X-Real-IP  $remote_addr;
proxy_cache webserver;
proxy_cache_valid 200 10m;
}
}


5、重新加载配置文件

[root@nginx ~]# service nginx reload


6、谷歌浏览器访问服务,点击F12 -> Network, 查看Response Headers, 我们可以看到X-Cache: HIT, 说明访问的服务器是缓存命中。

7、查看缓存目录

[root@nginx ~]# cd /data/nginx/cache/webserver/f/63/
[root@nginx 63]# ls
681ad4c77694b65d61c9985553a2763f


注,缓存目录里确实有缓存文件。好了,nginx缓存配置就到这边了,更多配置请根据需要看配置文档。

九、Nginx之URL重写

1、Nginx Rewrite 指令说明,请查阅:http://blog.csdn.net/xlxxcc/article/details/52641293

2、简单案例

注,由于配置文件内容较多,为了让大家看着方便,我们备份一下配置文件,打开一个新的配置文件。

[root@nginx ~]# cd /etc/nginx/
[root@nginx nginx]# mv nginx.conf nginx.conf.proxy
[root@nginx nginx]# cp nginx.conf.bak nginx.conf
[root@nginx nginx]# vim /etc/nginx/nginx.conf
server {
listen       80;
server_name  localhost;
#charset koi8-r;
#access_log  logs/host.access.log  main;
location / {
root   html;
index  index.html index.htm;
rewrite ^/bbs/(.*)$ http://192.168.1.12/forum/$1; }
}


[root@nginx ]# service nginx reload

web1 准备forum目录与测试文件

[root@web1 ~]# cd /var/www/html/
[root@web1 html]# ls
index.html
[root@web1 html]# mkdir forum
[root@web1 html]# cd forum/
[root@web1 forum]# vim index.html
<h1>forum page!</h1>


3、浏览测试一下, 显示 forum page! 谷歌浏览器打开F12 -> Network -> Headers,可以看到status code 302指的是临时重定向,那就说明我们rewrite重写配置成功。大家知道302是临时重定向而301是永久重定向,那么怎么实现永久重定向呢。一般服务器与服务器之间是临时重定向,服务器内部是永久重定向。下面我们来演示一下永久重定向。

4、配置永久重定向

[root@nginx nginx]# vim /etc/nginx/nginx.conf
server {
listen       80;
server_name  localhost;
#charset koi8-r;
#access_log  logs/host.access.log  main;
location / {
root   html;
index  index.html index.htm;
rewrite ^/bbs/(.*)$ /forum/$1;
}
}


准备forum目录与测试文件

[root@nginx ~]# cd /usr/html/
[root@nginx html]# ls
50x.html  index.html
[root@nginx html]# mkdir forum
[root@nginx html]# cd forum/
[root@nginx forum]# vim index.html
<h1>192.168.18.208 forum page</h1>


5.重新加载一下配置文件

[root@nginx ~]# service nginx reload


6、测试一下,谷歌浏览器打开F12 -> Network -> Headers,我们访问bbs/是直接帮我们跳转到forum/下,这种本机的跳转就是永久重定向也叫隐式重定向。好了,rewrite重定向我们就说到这里了,想要查询更多关于重定向的指令请参考官方文档。

十、Nginx之URL重写

1、实验拓扑

需求分析,前端一台nginx做负载均衡反向代理,后面两台httpd服务器。整个架构是提供BBS(论坛)服务,有一需求得实现读写分离,就是上传附件的功能,我们上传的附件只能上传到Web1,然后在Web1上利用rsync+inotify实现附件同步,大家都知道rsync+inotify只能是主向从同步,不能双向同步。所以Web1可进行写操作,而Web2只能进行读操作,这就带来读写分离的需求,下面我们就来说一下,读写分离怎么实现。

2、WebDAV功能说明

WebDAV (Web-based Distributed Authoring and Versioning) 一种基于 HTTP 1.1协议的通信协议。它扩展了HTTP 1.1,在GET、POST、HEAD等几个HTTP标准方法以外添加了一些新的方法,使应用程序可直接对Web Server直接读写,并支持写文件锁定(Locking)及解锁(Unlock),还可以支持文件的版本控制。这样我们就能配置读写分离功能了,下面我们来具体配置一下。

3、修改配置文件

[root@nginx nginx]# vim /etc/nginx/nginx.conf
server {
listen       80;
server_name  localhost;
#charset koi8-r;
#access_log  logs/host.access.log  main;
location / {
proxy_pass http://192.168.18.202; if ($request_method = "PUT"){
proxy_pass http://192.168.18.201; }
}
}


4、重新加载一下配置文件

[root@nginx ~]# service nginx reload


5、配置httpd的WebDAV功能

[root@web1 ~]# vim /etc/httpd/conf/httpd.conf
<Directory "/var/www/html">
Dav on
....
</Directory>


6、重新启动一下httpd

[root@web1 ~]# service httpd restart


7、测试一下

[root@nginx ~]# curl http://192.168.18.201 <h1>web1.test.com</h1>
[root@nginx ~]# curl http://192.168.18.202 <h1>web2.test.com</h1>


注,web1与web2访问都没问题。

[root@nginx ~]# curl -T /etc/issue  http://192.168.18.202 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>405 Method Not Allowed</title>
</head><body>
<h1>Method Not Allowed</h1>
The requested method PUT is not allowed for the URL /issue.
<hr>
<address>Apache/2.2.15 (CentOS) Server at 192.168.18.202 Port 80</address>
</body></html>


注,我们上传文件到,web2上时,因为web2只人读功能,所以没有开户WebDAV功能,所以显示是405 Method Not Allowed。

[root@nginx ~]# curl -T /etc/issue  http://192.168.18.201 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
You don't have permission to access /issue
on this server.
<hr>
<address>Apache/2.2


注,我们在Web1开启了WebDAV功能,但我们目录是root目录是不允许apache用户上传的,所以显示的是403 Forbidden。下面我们给apache授权,允许上传。

[root@web1 ~]# setfacl -m u:apache:rwx /var/www/html/


下面我们再来测试一下,

[root@nginx ~]# curl -T /etc/issue  http://192.168.18.201 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>201 Created</title>
</head><body>
<h1>Created</h1>
Resource /issue has been created.
<hr />
<address>Apache/2.2.15 (CentOS) Server at 192.168.18.201 Port 80</address>
</body></html>


注,大家可以看到我们成功的上传了文件,说明nginx读写分离功能配置完成。最后,我们来查看一下上传的文件。

[root@web1 ~]# cd /var/www/html/
[root@web1 html]# ll
总用量 12
drwxr-xr-x 2 root   root   4096 9月   4 13:16 forum
-rw-r--r-- 1 root   root     23 9月   3 23:37 index.html
-rw-r--r-- 1 apache apache   47 9月   4 14:06 issue


好了,到这里nginx的反向代理、负载均衡、页面缓存、URL重写及读写分离就全部讲解完成。希望大家有所收获,^_^……

原文出自:陈明乾 的BLOG

原文出处:http://freeloda.blog.51cto.com/2033581/1288553
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐