基于Nginx反向代理及负载均衡

基于Nginx反向代理及负载均衡

参考:http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass

只要没有被启用,默认就是开启的,因为proxy属于nginx内置标准模块,通常实现代理的时候,最核心模块是proxy_pass,用于将用户请求的rui递交至上游服务器的某个URI但这个模块大部分用于location当中,因此要实现将某一URI的访问代理某个上游服务器大致的格式为:

location /name/ {

proxy_pass http://127.0.0.1/remote/;

}

参数解释:

location /name/ 指定当前服务器server的某一访问路径,本来这个location中定义的是root或其他相关参数,从此这个 location不在本地提供任何服务,而是通过proxy_pass模块传至远程其他主机http://127.0.0.1/remote/上去

其中/name/ 和 /remote/ 可以是不相匹配的, nginx可以自动处理这种映射关系。

但需要注意的是,当定义location的时候,其必须有一个转换关系,意为我们当前主机的路径uri要转换另外服务器的uri,这是其对应关系,事实上目标主机的uri可以省略掉,但是一旦省略掉就表示不将其转换

示例:

location/some/path/ {

proxy_pass http://127.0.0.1;#这里只有ip地址,后面没有任何uri

}

例:

如图所示当我们请求nginx某个uri的时候,nginx自动的代理至web服务器中,它并不真正提供用户请求的内容而仅仅的将用户的请求接进来,并且代理用户去web服务器上去取数据

通常web服务器会记录日志的,那么这时访问日志中远程ip则是nginx的ip地址

对于一个web服务器来讲记录的所有的ip地址都是代理服务器的,那么我们在某些分析的层面来讲是没有意义的,所以通常在这类场景下通常需要在nginx服务上做一些简单修改,并且在后端服务器上也做一些修改用于记录真实的客户端IP地址

将请求在nginx转发至后端主机的时候在头部加入header信息

参考:http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass_header

实现反向代理


IP地址


服务器角色


10.0.10.61


Nginx 实现反向代理


10.0.10.83


Apache上游服务器


10.0.10.82


Apache上游服务器

启动后端apache 服务

[[email protected] local]#/usr/local/apache/bin/apachectl start

[[email protected] test]# echo‘<h1>10.0.10.83</h1>‘ > index.html

[[email protected]_test]# curl localhost
<h1>10.0.10.83</h1>

我们期望用户访问某个路径的时候,来源的路径是后端服务器的:

我们只要建一个新的location就可以了,如下所示

新建立location,明确说明使用proxy_pass模块代理后端主机10.0.10.83

location /test {
            proxy_pass http://10.0.10.83/; #注意一旦带有斜线就表示有url的如果没有url一定不能带斜线,这就表示访问的test没错,但是将test映射至后端主机,但后端并没有test目录
        }

检查语法是否正确并重新加载配置文件

[[email protected] nginx]#/usr/local/nginx/sbin/nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

[[email protected] nginx]#/etc/init.d/nginx reload

使用curl访问测试http://10.0.10.61/test

[[email protected] nginx]#curl http://10.0.10.61/test/

<h1>10.0.10.83</h1>

我们再来查看后端apache的访问日志

[[email protected]_php]# tail access_w_20140508.log

10.0.10.61 - -[08/May/2014:11:04:38 +0800] "GET / HTTP/1.0" 304 - "-""Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, likeGecko) Chrome/34.0.1847.131 Safari/537.36"

10.0.10.61 - - [08/May/2014:11:04:38+0800] "GET / HTTP/1.0" 304 - "-" "Mozilla/5.0(Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko)Chrome/34.0.1847.131 Safari/537.36"

可以看到来源地址都是nginx服务器的地址,对于我们之后分析日志没有任何意义所在,所以那这个时候我们想换成客户端地址必须借助于proxy_set_header模块

实现显示真实客户端IP

proxy_set_header模块使用示例

location /test {
            proxy_passhttp://10.0.10.83/;
proxy_set_header X-Real-IP $remote_addr;
        }

proxy_set_header表示将发送至upsream server的报文的某首部进行重写;

X-Real-IP 表示 hader的名称为X-Real-IP

传递给X-Real-IP的地址是$remote_addr

再来查看后端日志的访问ip,无论怎么刷新它的记录ip依旧还是nginx

因为后端的服务器只记录了client值,并没有记录我们定义的header的值,所以我们还需要对apache的日志参数做修改

编辑httpd.conf,定义日志格式

[[email protected] conf]#vim httpd.conf

将其注释并复制

#LogFormat "%h%l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\""combined

将%h改为"%{X-Real-ip}i

LogFormat "%{X-Real-IP}i %l %u %t \"%r\"%>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined

%h是表示远端客户的ip地址,这里我们将其改成某个特定首部的值也就是刚才我定义的X-Real-IP,而引用特定首部的值的格式是%{xxx}i这样就表示引用这个首部的值

保存退出并重新加载apache

[[email protected] conf]#/usr/local/apache/bin/apachectl graceful

再次访问并查看日志

已看到目前已记录客户端的真实IP地址

[[email protected]_php]# tail -1 access_w_20140508.log

10.0.10.1- - [08/May/2014:12:44:40 +0800] "GET / HTTP/1.0" 304 -"-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/34.0.1847.131 Safari/537.36"

使用模式匹配

示例:

location ~/test {
   proxy_pass http://10.0.10.83/hello;
    proxy_set_header X-real-ip $remote_addr;
  }

只要客户端访问的uri中只要包含test的路径则进行跳转至于10.0.10.83的/test的物理路径;

一旦使用了模式匹配,那么后面跟上test之后里面代理的时候,后面一定不能带有路径hello,一定什么路径都不要加,它会将test的内容填充至于后面

测试:

location ~/test {
   proxy_pass http://10.0.10.83/hello;#一定不能带有任何字符
    proxy_set_header X-real-ip $remote_addr;
  }

保存退出并检查语法

[[email protected] nginx]#nginx -t

nginx:[emerg] "proxy_pass" cannot have URI part in location given byregular expression, or inside named location, or inside "if"statement, or inside "limit_except" block in /etc/nginx/nginx.conf:49

nginx:configuration file /etc/nginx/nginx.conf test failed

首先语法检测根本不通过,提示路径中不能加入uri,所以如果出现此类配置方式是连服务都不能启动的

将后面的uri去掉再测试:

location   /test {
          proxy_passhttp://10.0.10.83;          #注意没有斜线
          proxy_set_headerX-real-ip $remote_addr;
        }

总结:使用匹配模式,一定不能加uri,只是将其前端的参数传递过来

重新加载并访问测试:

[[email protected] test_php]#curl http://10.0.10.61/test
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>

加入斜线

location  /test {
            proxy_passhttp://10.0.10.83/;
            proxy_set_headerX-real-ip $remote_addr;
        }

访问测试:

[[email protected]_php]# curl http://10.0.10.61/test
<h1>10.0.10.83</h1>

如果location 给了uri 而proxy_pass没有跟任何uri 意味着将location的uri附加至proxy_pass 当做请求的路径,哪怕加一个斜线也表示对应的uri,所以请求的test路径相对于http://10.0.10.83/目录下的文件

基于匹配规则实现动静分离

新建location,内容如下

location  ~* \.(jpg|bng|html|css|png|gif|ico|)${
   proxy_pass http://10.0.10.83;
proxy_set_header X-real-ip $remote_addr;
  }

如果访问的内容是不区分大小写的方式:

如果访问的uri后缀是以静态内容或图片格式结尾的,那么直接将请求转向10.0.10.83

检查语法并重启

[[email protected] nginx]#!ngin

[[email protected] nginx]# !ser

然后在服务10.0.10.83服务器创建目录及文件

上传某张图片或创建某路径文件并访问测试

[[email protected] if]# pwd
/var/html/php_test/if

[[email protected] if]#echo "test 10.0.10.83" > 1.html

[[email protected] if]#curl http://10.0.10.61/if/1.html
1

先来测试一下访问静态内容

[[email protected] nginx]#curl http://10.0.10.61/if/1.html#指定其uri

test 10.0.10.83#可以看到,已经成功跳转至10.0.10.83

所以就算前端没有这样的路径但能映射到后端服务器相关路径都能访问的到

那么假如说有另外服务器可以访问动态内容的话,则可以将所有的动态请求直接转发至动态内容服务器

如下所示

我们本机已经存在fastcgi,所以将nginx的fastcgi功能开启,由于9000端口在本地监听,所以这里默认即可

location ~ \.php$ {#已经默认帮我们定义了location匹配规则,如果后缀是php的uri,那么全部转发至这个主机

root/web/htdocs;#指定其php目录

fastcgi_pass127.0.0.1:9000;#fastcgi在我们本机已监听

fastcgi_indexindex.php;

fastcgi_paramSCRIPT_FILENAME/scripts$fastcgi_script_name;

includefastcgi_params;

}

定义在本机,

那么直接访问测试:

可以发现,现在我们将2个请求分开了

如果请求的是静态内容则到10.0.10.83上去,如果请求的是动态内容则到本机,而如果动态请求在另外服务器上部署的也完全可以实现分割

基于匹配规则实现上传转发功能

随着我们业务量的越来越大,需求将上传服务器也对其进行分离,在站点上搭建一个专门的服务器用来接收上传

有时候web服务器可以实现上传,web也支持上传,但是需要将DAV功能打开

新建虚机10.0.10.62并开启apache上传功能

[[email protected]]# ./bin/apachectl  -M  | grep -i ‘dav‘
dav_module (static)
dav_fs_module (static)

这时只需要在DocumentRoot上对应的访问权限上启动对应的DAV即可

加入参数:

Dav on

Options Indexes FollowSymLinks

将网页目录给予写权限

[[email protected]]# setfacl -m u:apache:rwx /var/www/html/

编辑nginx配置文件,加入if判断语句并引用$request_method模块,判断如果用户操作是put,那么将其转发至10.0.10.62

location / {

root/web/htdocs/;

indexindex.php index.html index.htm;

if ($request_method ~*"PUT"){

proxy_pass http://10.0.10.62;

break;

}

}

保存退出检查语法并重新加载配置

[[email protected] nginx]#nginx -t

nginx: theconfiguration file /etc/nginx/nginx.conf syntax is ok

nginx:configuration file /etc/nginx/nginx.conf test is successful

[[email protected] nginx]#!ser

这时我们可以使用curl -T 上传文件

[[email protected] nginx]#curl -T koi-utf http://10.0.10.62/

查看文件是否存在

[[email protected] conf]#ll /var/www/html/

total 16

-rw-r--r--. 1rootroot11 May6 18:31 index.html

-rw-r--r--. 1rootroot6 Apr 28 21:15 index.html.bak

-rw-r--r--. 1apache apache 2837 May6 00:08 koi-utf

如上,说明支持put的方法,已经可以上传

假设我们现在代理如果用户请求的内容是上传操作则专至62这台服务器,这样就一个静态动态 一个负责上传的角色,完全将服务角色分割开来

由此可见,我们的服务扮演了三种角色,将上传、动态、静态内容分别分发至不同的服务器

nginx实现负载均衡

nginx实现负载均衡有单独一模块来实现需求,叫做upstream

参考:http://nginx.org/en/docs/http/ngx_http_upstream_module.html

示例:

#首先在全局配置中定义upstream name

upstream backend {

server backend1.example.comweight=5;

server backend2.example.com:8080;

server unix:/tmp/backend3;

server backup1.example.com:8080backup;

server backup2.example.com:8080backup;

}

#定义完成后再从location中引用

server {

location / {

proxy_pass http://backend;

}

}

一旦启动了此模块,将引入一个新的上下文(只要加大括号就表示新引入一个新的上下文)因此upstream也引入了一个新的上下文

每个server后面跟了一个主机名或ip 可以加端口,但注意的是前面一定不能加http://

而upstream为一个关键字,后面的backend为名称,说明这是一组服务器可以被轮流访问的

之后在location定义反向代理的时候,定义的再也不是某个指定服务器了而是upstream,因此用户的请求发往这个upstream以后,这个upstream模块会自动从定义的规则中每一次选择一个server 进行分发

为了演示效果,我们将后端的apache服务器分别创建不同的页面,步骤略

配置nginx 先将其备份,方便之后恢复

[[email protected] nginx]#cp nginx.conf nginx.conf.bak
[[email protected] nginx]# vim nginx.conf

将之前定义的location全都删掉,步骤略

在httpd{}上下文中定义upstream

upstream webservers {

server 10.0.10.62;

server 10.0.10.83;

}

定义upstream名为webservers,其组内定义2个web主机 分别是10.0.10.62和10.0.10.83 注意的是ip前面不能加http://

定义location,如下所示

location / {

#root/web/htdocs/;

#indexindex.php index.html index.htm;

proxy_pass http://webservers;#webservers为定义的upstream的名称

}

假如用户访问的location的根目录,当访问的是根的时候直接使用proxy_pass直接映射至upstream组内的主机

保存退出检测语法并重启nginx

[[email protected] nginx]#!nginx

[[email protected] nginx]#!ser

访问如下

[[email protected] nginx]#curl http://10.0.10.61

10.0.10.62

[[email protected] nginx]#curl http://10.0.10.61

<h1>10.0.10.83</h1>

实现后端realserver健康状态检查

使其一旦出现故障不再将其加进来

定义upstream,如下所示

upstream webservers {

#server 10.0.10.62 ;

server 10.0.10.61 max_fails=3fail_timeout=1s backup;

server 10.0.10.83 weight=1max_fails=3 fail_timeout=2s;

}

weight=1 设置其权重;

max_fails=3最大允许3次失败;

fail_timeout=2s如果超过2秒则超时;

在第三行可以看到,我们在本机也启动一个web服务器,但是这个服务器不是专门提供工作的,一旦后端服务器出现故障,那么则转至backup服务器,使其服务器专门为用户提供错误页面

backup表示其主机始终不会生效除非组内所有主机全部故障

至此,实验结束,感谢各位。

时间: 2024-12-22 19:32:29

基于Nginx反向代理及负载均衡的相关文章

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

大纲 一.前言 二.环境准备 三.安装与配置Nginx 四.Nginx之反向代理 五.Nginx之负载均衡 六.Nginx之页面缓存 七.Nginx之URL重写 八.Nginx之读写分离 注,操作系统为 CentOS 6.4 x86_64 , Nginx 是版本是最新版的1.4.2,所以实验用到的软件请点击这里下载:http://yunpan.cn/QXIgqMmVmuZrm 一.前言 在前面的几篇博文中我们主要讲解了Nginx作为Web服务器知识点,主要的知识点有nginx的理论详解.ngin

Nginx反向代理,负载均衡,redis session共享,keepalived高可用

相关知识自行搜索,直接上干货... 使用的资源: nginx主服务器一台,nginx备服务器一台,使用keepalived进行宕机切换. tomcat服务器两台,由nginx进行反向代理和负载均衡,此处可搭建服务器集群. redis服务器一台,用于session的分离共享. nginx主服务器:192.168.50.133 nginx备服务器:192.168.50.135 tomcat项目服务器1:192.168.50.137 tomcat项目服务器2:192.168.50.139 redis服

Web服务之Nginx反向代理与负载均衡

一.代理 正向代理: 正向代理是一个位于客户端和目标服务器之间的服务器,为了从目标服务器取得内容,客户端向代理发送一个请求并指定目标服务器,然后代理向目标服务器转交请求并将获得的内容返回给客户端.客户端必须要进行一些特别的设置才能使用正向代理. 作用: 访问无法访问的服务器(翻墙,懂得) 加速访问目标服务器(链路加速) Cache缓存(访问加速) 实现客户端访问授权 隐藏访问者 反向代理: 反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转

Nginx反向代理、负载均衡, keepalived高可用

Nginx反向代理.负载均衡,  keepalived高可用 Nginx反向代理.负载均衡,  keepalived高可用 一.Nginx反向代理.负载均衡 1.什么是反向代理.负载均衡 严格的说,Nginx仅仅是作为Nginx Proxv反向代理使用的,因为这个反向代理功能表现的效果是负载均衡集群的效果,所以本文称之为Nginx负载均衡.那么,反向代理和负载均衡有什么区别呢? 普通负载均衡软件,例如大名鼎鼎的LVS,其实现的功能只是对请求数据包的转发(也可能会改写数据包).传递,其中DR模式明

[转]Nginx反向代理和负载均衡部署指南

Nginx反向代理和负载均衡部署指南 1.        安装 1)         从Nginx官网下载页面(http://nginx.org/en/download.html)下载Nginx最新版本(目前是1.5.13版本)安装包: 2)         解压后复制到部署目录. 2.        启动和停止Nginx Nginx目前只支持命令行操作,操作前先进入Dos命令环境,并进入Nginx部署目录. 1)         启动Nginx:start nginx 2)         停

马哥学习笔记二十八——nginx反向代理,负载均衡,缓存,URL重写及读写分离

Nginx反向代理 Nginx通过proxy模块实现反向代理功能.在作为web反向代理服务器时,nginx负责接收客户请求,并能够根据URI.客户端参数或其它的处理逻辑将用户请求调度至上游服务器上(upstream server).nginx在实现反向代理功能时的最重要指令为proxy_pass,它能够将location定义的某URI代理至指定的上游服务器(组)上.如下面的示例中,location的/uri将被替换为上游服务器上的/newuri. location /uri { proxy_pa

Nginx系列-11.配置Nginx反向代理和负载均衡

Nginx系列-11.配置Nginx反向代理和负载均衡 目录 - Nginx系列 Nginx系列-1.Linux下安装Nginx Nginx系列-2.配置LNMP(Linux.Nginx.MySQL.PHP)架构 Nginx系列-3.配置Nginx虚拟主机 Nginx系列-4.Nginx日志配置及日志切割 Nginx系列-5.配置Nginx的防盗链 Nginx系列-6.配置Nginx的HTTPS Nginx系列-7.配置Nginx使用uwsgi支持web.py框架 Nginx系列-8.配置Ngi

nginx学习3:实现nginx反向代理和负载均衡

nginx学习3:实现nginx反向代理和负载均衡 正向代理和反向代理的区别(这里不赘述什么是正向代理和反向代理) 一句话概括:正向代理隐藏真实客户端,反向代理隐藏真实服务端:即正向代理服务器不知道客户端是谁,反向代理客户端不知道服务器是谁: 反向代理实例1 需求描述:输入nginx监听IP:8081,可以访问真实的IP:8088 tomcat服务 准备tomcat服务 1-准备tomcat服务(8088端口) 2-开放防火墙8088端口 ##添加8088端口[[email protected]

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

大纲 一.前言 二.环境准备 三.安装与配置Nginx 四.Nginx之反向代理 五.Nginx之负载均衡 六.Nginx之页面缓存 七.Nginx之URL重写 八.Nginx之读写分离 注,操作系统为 CentOS 6.4 x86_64 , Nginx 是版本是最新版的1.4.2,所以实验用到的软件请点击这里下载:http://yunpan.cn/QXIgqMmVmuZrm 一.前言 在前面的几篇博文中我们主要讲解了Nginx作为Web服务器知识点,主要的知识点有nginx的理论详解.ngin