Apache提供了 mod_proxy 模块用于提供代理服务,能够支持的包括正向代理、反向代理、透明代理、缓存、负载均衡,HTTP代理、FTP代理、SSL代理等若干强大的功能。
配置代理方法很简单那,首先在 Apache 上启用 mod_proxy 模块,需要注意的是,如果在 Apache-2.2 上,则还需要加载名为 mod_proxy_http 的模块。因为 2.2 系列把代理功能都拆分成N个小模块了。
一般 Apache 的这些功能我们在编译的时候都是以模块的形式加入的,编译时加上相关参数,然后编译安装就可以了。
1
2
|
.
/configure
--prefix=
/usr/local/apache2
--
enable
-so --
enable
-rewrite=shared --
enable
-proxy=shared
make
&&
make
install
|
我这里先是看了我的 Apache 中 有没有这个模块,如果没有 Apache 没有安装 proxy 模块,可以不用重新编译添加模块。
1
2
|
/usr/local/apache2/bin/apxs
-c -i mod_proxy.c proxy_util.c (
ps
必须2个c一起编译,不然会报错)
/usr/local/apache2/bin/apxs
-c -i mod_proxy_http.c proxy_util.c
|
把 proxy 编译成模块,然后再把 proxy 的配置加入配置文件,去掉下面三行记录的#号,如果不存在,添加以下下内容。
1
2
3
|
LoadModule proxy_module modules/mod_proxy.so #必须的模块
LoadModule proxy_connect_module modules/mod_proxy_connect.so #应用软件代理 例如 QQ,MSN
LoadModule proxy_http_module modules/mod_proxy_http.so #http请求代理 访问网页
|
一、正向代理
先说一正向代理(Forward Proxy),通常普通用户使用的比较多的,是正向代理。也就是在浏览器的网络连接属性框中,填写上一个代理服务器的ip和端口,即可通过代理服务器中转,去浏览网页。有时候网站对单个 IP 某些操作进行了次数限制,设置代理 IP 访问,不断的更改代理 IP 来突破网站限制,也是正向代理。
配置这种代理非常简单:
1、打开apache的conf,启用好 proxy 模块后,加入如下几行:(全局配置)
1
2
3
4
5
6
7
8
|
ProxyRequests On
ProxyVia On
Order deny,allow
Deny from all
Allow from 192.16.10.0/24
|
2、当然也可以把在虚拟主机中进行设置,如下:
启用虚拟主机
1
|
NameVirtualHost *:80
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
ServerAdmin [email protected]
DocumentRoot /var/www/test
ServerName www.test.com
ErrorLog logs/dummy-host.example.com-error_log
CustomLog logs/dummy-host.example.com-access_log common
Options FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
ProxyRequests On
ProxyVia On
Order deny,allow
Deny from all
Allow from 192.168.10.0/24
|
然后保存退出,重启加载 Apache 服务,现在即可在浏览器的网络连接属性框中或 QQ 登录配置中,填写上 your_apache_server_ip 的 ip 地址,端口是 80,开始用代理了。
使用 Apache 提供的代理,也可以加身份验证,或者设置 ACL 来限制客户端来源等。这些配置就和普通的 Apache 站点配置一样。
其实关键就是要有 ProxyRequests 开启,功能就已经可以使用了。
二、反向代理
反向代理也是个非常有用的功能。反向代理(Reverse Proxy)方式是指以代理服务器来接受 Internet 上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给 Internet 上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。常用做网站服务器配置,可以提供从防火墙外部代理服务器到防火墙内部安全内容服务器的加密连接,隐藏后端真实服务器,更加安全。如 负载均衡 ,CDN 缓存都是反向代理。配置方法如下:
1、启用好 proxy 模块后,加入下边一内容:(全局配置)
1
2
3
4
5
6
7
8
|
ProxyRequests off
Order deny,allow
Allow from all
ProxyPass /test http://www.reverse.com/proxy
ProxyPassReverse /test http://www.reverse.com/proxy
|
2、在虚拟主机中进行设置,如下:
启用虚拟主机
1
|
NameVirtualHost *:80
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
ServerAdmin [email protected]
ServerName www.test.com
ErrorLog logs/dummy-host.example.com-error_log
CustomLog logs/dummy-host.example.com-access_log common
ProxyRequests Off
Order deny,allow
Allow from all
ProxyPass /test http://www.reverse.com/proxy
ProxyPassReverse /test http://www.reverse.com/proxy
|
ProxyPass /test http://www.reverse.com/proxy : 将 www.test.com/test 域下的所有请求转发给 www.reverse.com/proxy代理,例如www.test.com/test/login.php 会交给 www.reverse.com/proxy/login.php 代理。
ProxyPassReverse /test http://www.reverse.com/proxy :
www.reverse.com/proxy/login.php 中有如下代码:
1
2
3
|
header(
'Location: http://www.reverse.com/proxy/result.php'
);
?>
|
那么在重定向的时候,Apache 会将 HTTP 请求重新设为 http://www.reverse.com/proxy/result.php ,这样的作用稍后讲解
www.reverse.com/proxy/result.php 中有如下代码:
1
2
3
|
echo
'Hello'
;
?>
|
浏览器访问效果,访问:www.test.com/proxy/login.php
HTTP 请求如图:
可以发现其实 Request 中的请求还是 www.test.com 的,但是它确实是由 www.reverse.com 来处理的
reverse.com/proxy/login.php 重定向到 www.reverse.com/proxy/proxy/result.php
HTTP 请求如图:
也可以看到请求依然是 www.test.com/proxy/result.php
这里就是 ProxyPassReverse 发挥作用的地方,如果不加这个项,重定向后 HTTP 请求会如下图:
可以发现请求中的GET是 www.reverse.com 而不是 www.test.com ,这是因为配置了 ProxyPassReverse 后,www.reverse.com/proxy/login.php 在重定向到 www.reverse.com/proxy/result.php 时,Apache会将它调整回 www.test.com/proxy/result.php , 然后Apache再将 www.test.com/proxy/result.php 代理给 www.reverse.com/proxy/result.php,所以说配置了 ProxyPassReverse 后,即使 www.reverse.com/proxy 下的程序有重定向到其他 www.proxypss.com/proxy 的文件的(如 login.php 重定向到 result.php),你也不会在请求中发现 www.reverse.com 的影子。
三、ProxyPass 与 ProxyVia 、ProxyPassReverse 及 ProxyPassMatch 的概述
1、ProxyPass:
语法:ProxyPass [path] !|url
它主要是用作URL前缀匹配,不能有正则表达式,它里面配置的Path实际上是一个虚拟的路径,在反向代理到后端的url后,path是不会带过去的,使用示例:
(1)、ProxyPass /images/ !
这个示例表示,/images/的请求不被转发。
(2)、ProxyPass /site/foo/ http://back.reverse.com/
我们假设当前的服务地址是http://test.com/,如果我们做下面这样的请求:
http://test.com/siter/foo/bar
那将被转成内部请求:
http://back.reverse.com/bar
注:配置的时候,不需要被转发的请求,要配置在需要被转发的请求前面。
2、ProxyVia
语法:ProxyVia [OPTION]
ProxyVia On:控制位于代理服务器链中的代理请求的流向
引用 Apache2.2 官方文档中对 ProxyVia 的解释如下:
如果设置为默认值 Off ,将不会采取特殊的处理。如果一个请求或应答包含 "Via:" 头,将不进行任何修改而直接通过。
如果设置为 O n每个请求和应答都会对应当前主机得到一个 "Via:" 头。
如果设置为 Full ,每个产生的 "Via:" 头中都会额外加入 Apache 服务器的版本,以 "Via:" 注释域出现。
如果设置为 Block ,每个代理请求中的所有 "Via:" 头行都将被删除。且不会产生新的 "Via:" 头。
3、ProxyPassMatch:
语法:ProxyPassMatch [regex] !|url
这个实际上是 url 正则匹配,而不是简单的前缀匹配,匹配上的 regex 部分是会带到后端的 url 的,这个是与 ProxyPass 不同的。使用示例:
(1)ProxyPassMatch ^/images !
这个示例表示对 /images 的请求,都不会被转发。
(2) ProxyPassMatch ^(/.*\.gif)$ http://img.reverse.com$1
这个示例表示对所有 gif 图片的请求,都被会转到后端,如此时请求 http://test.com/foo/bar.gif,那内部将会转换为这样的请求 http://img.reverse.com/foo/bar.gif。
4、ProxyPassReverse
语法:ProxyPassReverse [路径] url
它一般和 ProxyPass 指令配合使用,此指令使 Apache 调整 HTT P重定向应答中 Location, Content-Location, URI 头里的 URL,这样可以避免在 Apache 作为反向代理使用时,后端服务器的 HTTP 重定向造成的绕过反向代理的问题。参看下面的示例:
ProxyPass /example http://www.reverse.com/
ProxyPassReverse /example http://www.reverse.com/
ProxyPassReverse 的作用就是反向代理,如果没有加这样的反向代理设置的情况下,访问 http://www.test.com/example/a,如果 www.reverse.com 对请求进行了 redirect 至 http://www.reverse.com/b,那么,客户端就会绕过反向代理,进而访问 http://www.reverse.com/example/b 。如果设置了反向代理,则会在转交 HTTP 重定向应答到客户端之前调整它为 http://www.test.com/example/a/b,即是在原请求之后追加上了 redirect 的路径。
四、Apache 负载均衡配置
我们同样可以利用 mod_proxy 来做负载均衡,mod_proxy_balancer 是 Apache httpd 自带的负载平衡支持。其优点可以根据实际的运行时机器的环境来决定负载均衡的策略,实现 Session 在 node 上进行共享传递。
1、轮询均衡策略的配置
配置负载均衡时,还要在加上一个模块:
1
|
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
ServerAdmin [email protected]
ServerName www.test.com
ErrorLog logs/dummy-host.example.com-error_log
CustomLog logs/dummy-host.example.com-access_log common
BalancerMember http://192.168.10.121:80/
BalancerMember http://192.168.10.122:80/
BalancerMember http://192.168.10.123:80/
ProxyRequests Off
ProxyPass / balancer://mycluster/
ProxyPassReverse / balancer://mycluster/
|
我们来观察上述的参数“ProxyPass / balancer ://www.test.com/”,其中,“ProxyPass ”是配置虚拟服务器的命令,“/”代表发送 Web 请求的 URL 前缀,如:http://www.test.com/ 或者 http://www.test.com/test,这些URL都将符合上述过滤条件;“balancer ://www.test.com/”表示要配置负载均衡,proxy 代表负载均衡名;Balancer Member 及其后面的 URL 表示要配置的后台服务器,其中 URL 为后台服务器请求时的 URL。以上面的配置为例,实现负载均衡的原理如下:
假设 Apache 接收到 http://localhost/test 请求,由于该请求满足 ProxyPass 条件(其URL前缀为“/”),该请求会被分发到后台某一个 Balancer Member,比如,该请求可能会转发到 http://192.168.10.121:80/test 进行处理。当第二个满足条件的 URL 请求过来时,该请求可能会被分发到另外一台 Balancer Member,转发到 http://192.168.10.122:80/ 或 http://192.168.10.123:80/ 上 。如此循环反复,便实现了负载均衡的机制。
2、按权重分配均衡策略的配置
1
2
3
4
5
6
7
8
9
10
11
12
13
|
BalancerMember http://192.168.10.121:80/ loadfactor=3
BalancerMember http://192.168.10.122:80/ loadfactor=1
BalancerMember http://192.168.10.123:80/ loadfactor=2
ProxyRequests Off
ProxyPass / balancer://mycluster/
ProxyPassReverse / balancer://mycluster/
|
参数”loadfactor”表示后台服务器负载到由 Apache 发送请求的权值,该值默认为 1,可以将该值设置为 1 到 100 之间的任何值。以上面的配置为例,介绍如何实现按权重分配的负载均衡,现假设 Apache 收到 http://www.test.com/test 6 次这样的请求,该请求分别被负载到后台服务器,则有 3 次连续的这样请求被负载到 Balancer Member 为 http://192.168.10.121:80 的服务器,有 1 次这样的请求被负载 Balancer Member 为 http://192.168.10.122:80 后台服务器 。有 2 次这样的请求被负载 Balancer Member 为 http://192.168.10.123:80 后台服务器实现了按照权重连续分配的均衡策略。
3、权重请求响应负载均衡策略的配置
1
|
ProxyPass / balancer://mycluster/ lbmethod=bytraffic
|
或
1
|
|
或
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
BalancerMember http://192.168.10.121:80/ loadfactor=3
BalancerMember http://192.168.10.122:80/ loadfactor=1
BalancerMember http://192.168.10.123:80/ loadfactor=2
ProxyRequests Off
ProxyPass / balancer://mycluster/
ProxyPassReverse / balancer://mycluster/
ProxySet lbmethod=bytraffic
|
在这三的地方配置都可以,Apache 可以识别这三种配置方法。
参数“lbmethod=bytraffic”表示后台服务器负载请求和响应的字节数,处理字节数的多少是以权值的方式来表示的。“loadfactor”表示后台服务器处理负载请求和响应字节数的权值,该值默认为 1,可以将该值设置在 1 到 100 的任何值。根据以上配置是这么进行均衡负载的,假设 Apache 接收到 http://www.test.com/test 请求,将请求转发给后台服务器,如果Balancer Member为 http://192.168.10.121:80 后台服务器负载到这个请求,那么它处理请求和响应的字节数是 Balancer Member 为 http://192.168.10.122:80 服务器的3倍(回想(2)均衡配置,(2)是以请求数作为权重负载均衡的,(3)是以流量为权重负载均衡的,这是最大的区别)。
lbmethod可能的取值有:
lbmethod=byrequests 按照请求次数均衡(默认)
lbmethod=bytraffic 按照流量均衡
lbmethod=bybusyness 按照繁忙程度均衡(总是分配给活跃请求数最少的服务器)
4、管理界面配置
SetHandler balancer-manager
Order Allow,Deny
Allow from all
负载管理模块,一般用来管理集群节点,可以动态设置“权重”,“主机状态”等信息。
5、热备份(Hot Standby)
热备份的实现很简单,只需添加 status=+H 属性,就可以把某台服务器指定为备份服务器:
1
2
3
4
5
6
7
8
9
10
11
12
|
BalancerMember http://192.168.10.121:80/
BalancerMember http://192.168.10.122:80/ status=+H
ProxyRequests Off
ProxyPass / balancer://mycluster/
ProxyPassReverse / balancer://mycluster/
|
从 balancer-manager 界面中可以看到,请求总是流向 192.168.10.121 ,一旦 192.168.10.121 挂掉,Apache 会检测到错误并把请求分流给 192.168.10.122。Apache 会每隔几分钟检测一下 192.168.10.121 的状况,如果 192.168.10.121 恢复,就继续使用 121。
6、http-header 配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
BalancerMember http://192.168.10.121:80/ loadfactor=3 route=1 nofailover=Off
BalancerMember http://192.168.10.122:80/ loadfactor=1 route=2 nofailover=Off
BalancerMember http://192.168.10.123:80/ loadfactor=2 route=3 nofailover=Off
ProxySet stickysession=ROUTEID nofailover=Off
ProxyRequests Off
ProxyPass / balancer://mycluster/
ProxyPassReverse / balancer://mycluster/
|
或加在
1
|
ProxyPass / balancer://mycluster/ nofailover=Off
|
使用 Apache 的 http-header 这个模块,由 Apache来自动生成 cookie。
stickysession session粘连,就是说用户一旦访问了某个 Balancer Member,就给他个 cookie,让他在后面的请求都访问那个 Balancer Member 。
ProxyPass 那行 最后的 stickysession=ROUTEID,表示从 cookie 中读取 ROUTEID,并自动分配到相应的服务上去。如果后端服务器使用不同的cookie名称或者URL编码的ID(像servlet容器),使用|来分开他们。第一个部分针对cookie,第二个针对路径。如:
ProxyPass / balancer://mycluster
stickysession=JSESSIONID|jsessionid
nofailover 是否打开失败转移,默认为‘Off’,如果设为‘On’,当工作单元被禁用或者出错时,如果这样配置,当提供给你服务的服务器发生异常,那么你将一直看着它返回给你503,直到系统恢复正常!
还有其它参数可以添加:
maxattempts 默认值是 1,在放弃之前的故障转移的最大尝试次数。
timeout 默认值是 0,均衡器超时时间,单位为秒。如果设置了,那么就是等待空闲工作单元的最大时间,默认是不等。