Apache 2.4的反向代理和负载均衡

此生再无相见时 提交于 2020-10-02 10:54:04

文章内容参考自官方文档: http://httpd.apache.org/docs/2.4/howto/reverse_proxy.html

像nginx一样, Apache httpd也提供了反向代理(Reverse Proxy)并能实现负载均衡(Load Balance)。

Apache httpd配置中需要开启以下模块:

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule proxy_http_module modules/mod_proxy_http.so

# 这个也要开启, 否则httpd启动报错
LoadModule slotmem_shm_module modules/mod_slotmem_shm.so

# 以下负载均衡策略按需开启
LoadModule lbmethod_bybusyness_module modules/mod_lbmethod_bybusyness.so
LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.so
LoadModule lbmethod_bytraffic_module modules/mod_lbmethod_bytraffic.so
LoadModule lbmethod_heartbeat_module modules/mod_lbmethod_heartbeat.so

linux下可以开启 mod_proxy_hcheck.so 以检查成员存活状态 (动态健康检查)

mod_lbmethod 模块按需开启, 如果只需按流量则开启mod_lbmethod_bytraffic.so即可

mod_proxy 提供代理功能,mod_proxy_balancer 提供负载均衡功能, mod_proxy_http 让代理服务器能支持HTTP协议。

需要用到的指令: ProxyPass, ProxyPassReverse, BalancerMember

实现简单的反向代理 (Simple reverse proxying)

指令ProxyPass把输入请求映射到后端服务器(或者服务器集群)。先看一个最简单的把所有请求(“/”) 都反向代理到一台服务器的例子:

ProxyPass "/"  "http://www.example.com/"

为了确保从后端服务器生成的“Location”头部被修改以指向反向代理,而不是回到自身(形成死循环),需要添加ProxyPassReverse指令:

ProxyPass "/"  "http://www.example.com/"
ProxyPassReverse "/"  "http://www.example.com/"

如果要设置指定的url被反向代理, 按如下设置:

ProxyPass "/images"  "http://www.example.com/"
ProxyPassReverse "/images"  "http://www.example.com/"

上面的例子, 把所有以"/images"开头的请求代理到指定的后端, 其他请求都被本地处理.

ProxyPass "/"  "http://www.example.com/"

集群和均衡器 (Clusters and Balancers)

通过balancer://来设置一个均衡器, 来把请求反向代理到多个后端服务器。

<Proxy balancer://myset>
    BalancerMember http://www2.example.com:8080
    BalancerMember http://www3.example.com:8080
    ProxySet lbmethod=bytraffic
</Proxy>
ProxyPass "/images/"  "balancer://myset/"
ProxyPassReverse "/images/"  "balancer://myset/"

上面的代码把以“/images/”开头的请求代理到以BalancerMembers定义的2台后端服务器, 用ProxySet来定义负载均衡策略。

均衡器成员(BalancerMembers)有时也被称为节点(workers).

均衡器和成员配置 (Balancer and BalancerMember configuration)

默认是平均分配负载, 如果需要指定, 可以设置负载因子(loadfactor)。

<Proxy balancer://myset>
    BalancerMember http://www2.example.com:8080 loadfactor=8
    BalancerMember http://www3.example.com:8080 loadfactor=2
    ProxySet lbmethod=bytraffic
</Proxy>
ProxyPass "/images/"  "balancer://myset/"
ProxyPassReverse "/images/"  "balancer://myset/"

上面设置了2台服务器,并且把负载分配比例设置为8:2。 如果不设置loadfactor则默认是1。

如果要设置www3的负载是www2的两倍且超时时间1s, 可以如下设置:

<Proxy balancer://myset>
    BalancerMember http://www2.example.com:8080
    BalancerMember http://www3.example.com:8080 loadfactor=3 timeout=1
    ProxySet lbmethod=bytraffic
</Proxy>
ProxyPass "/images"  "balancer://myset/"
ProxyPassReverse "/images"  "balancer://myset/"

故障转移 (Failover)

您还可以微调各种故障转移方案,详细说明在这种情况下应访问哪些节点甚至哪些均衡器。下面的设置实现了三种故障转移情况:

<Proxy balancer://myset>
    BalancerMember http://www2.example.com:8080 loadfactor=7
    BalancerMember http://www3.example.com:8080 loadfactor=3
    BalancerMember http://spare1.example.com:8080 status=+R
    BalancerMember http://spare2.example.com:8080 status=+R
    BalancerMember http://hstandby.example.com:8080 status=+H
    BalancerMember http://bkup1.example.com:8080 lbset=1
    BalancerMember http://bkup2.example.com:8080 lbset=1
    ProxySet lbmethod=byrequests
</Proxy>
ProxyPass "/images/"  "balancer://myset/"
ProxyPassReverse "/images/"  "balancer://myset/"
  1. 当 www3和www2中的一个或者两个都不可用的时候, 会把流量分配给冗余端 spare1和spare2。(一个冗余端会被用来替换本均衡器的一个不可用的成员。)
  2. 当所有的lbset=0的节点(worker)不可用时, 才会把流量分配给 hstandby (热备机)。
  3. 如果所有的lbset=0的节点、冗余和热备都不可用, 当且仅当此时, blset=1的备份机器 bkup1和bkup2 才会进入循环(分配到流量)。

每个均衡器设置可以用一个或多个冗余(hot spares)和热备份(hot standbys)成员。

对于故障转移,冗余(spare)用来替换同一个负载均衡器里面的不可用的节点。 如果节点正在耗尽,停止或处于错误/失败状态,则认为该节点不可用。 如果负载均衡器集中的所有节点和冗余(spare)都不可用,则启用热备用。 始终按从最低到最高的顺序尝试负载均衡器集(及各自的冗余和热备)。

均衡器的管理 (Balancer Manager)

Apache内置的 balancer-manager可以显示当前的配置及工作状态。不但可以显示参数, 还可以动态的,在运行时重新配置大多数参数, 包括添加新的成员到已存在的均衡器中。

在Apache httpd配置文件中添加:

<Location "/balancer-manager">
    SetHandler balancer-manager
    Require host localhost
</Location>

注意: 生产服务器中不可开启, 除非你已经进行了安全设置

重启httpd后访问 http://yourdomain/balancer-manager/

经过测试: balancer-manager只能放在配置文件httpd.conf下才有效, 放在VirtualHost中无效.

动态健康检查 (Dynamic Health Check)

在httpd反向代理向节点发出请求之前,它可以通过使用ProxyPass为该节点设置参数ping来“测试”该节点是否可用。 通常,以动态方式带外(out of band)检查节点的健康状况更有用。 这是通过Apache httpd的mod_proxy_hcheck模块实现的。


实战操作

前面在配置文件 httpd.conf 中设置反向代理, 会影响到整个服务器上的站点。如果一个服务器上有多个站点(域名), 需要指定某些域名才使用反向代理时,把配置转移到 VirtualHost 中即可(同时取消httpd.conf中的balancer设置)。

现在我们在本机的apache服务下直接做负载均衡测试。

在httpd-vhost.conf中添加以下配置:

<VirtualHost *:80>
    ServerAdmin aben_sky@qq.com
    ServerName www.example.com
    ErrorLog "d:/wamp/logs/www.example.com.log"
    CustomLog "d:/wamp/logs/www.example.com.log" combined
	
	#Load Balance===========================
	#关闭正向代理 ProxyRequests
	ProxyRequests Off
    <Proxy balancer://myset>
        BalancerMember http://www2.example.com loadfactor=5
        BalancerMember http://www3.example.com loadfactor=5
        ProxySet lbmethod=bytraffic
    </Proxy>
    ProxyPass "/"  "balancer://myset/"
    ProxyPassReverse "/"  "balancer://myset/"
</VirtualHost>
<VirtualHost *:80>
    DocumentRoot "E:/WWW/example.com/www2/"
    ServerName www2.example.com
    ErrorLog "d:/wamp/logs/www.example.com.log"
    CustomLog "d:/wamp/logs/www.example.com.log" combined

    <Directory "E:/WWW/example.com/www2/">
        Options FollowSymLinks
        AllowOverRide all
        Order Deny,Allow
        Allow from all
        Require all granted
    </Directory>
</VirtualHost>
<VirtualHost *:80>
    DocumentRoot "E:/WWW/example.com/www3/"
    ServerName www3.example.com
    ErrorLog "d:/wamp/logs/www.example.com.log"
    CustomLog "d:/wamp/logs/www.example.com.log" combined

    <Directory "E:/WWW/example.com/www3/">
        Options FollowSymLinks
        AllowOverRide all
        Order Deny,Allow
        Allow from all
        Require all granted
    </Directory>
</VirtualHost>

上面建立了3个站点: www, www2, www3。其中www作为负载均衡的控制端, www2和www3是实际的网站。我们在www2和www3的入口文件夹下建立一个index.php文件, 内容如下:

<?php
session_start();
echo date('Y-m-d H:i:s').'<br/>';
echo $_SERVER['HTTP_HOST'].'<br/>';
var_dump($_SERVER);

然后在本机hosts中添加域名解析, 然后访问 http://www.example.com看看:

这就完成了一个简单的负载均衡服务的搭建。

注意看下$_SERVER中多了HTTP_X_FORWARDED_HOSTHTTP_X_FORWARDED_SERVER

 ["HTTP_X_FORWARDED_HOST"]=>string(15) "www.example.com"
 ["HTTP_X_FORWARDED_SERVER"]=>string(15) "www.example.com"

如果BalancerMember分布在不同的服务器上, 需要进行session的同步, 可以使用文件夹同步、保存到memcache/redis中的方式来实现。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!