介绍
Memcached是一个分布式对象缓存系统,该系统在内存中存储信息,而不是在磁盘上,以便更快访问。PHP的Memcache模块可以用来处理会话,否则会存储在文件系统上。
如果没有这种 Memcached 设置,如果您的应用程序在多个服务器上负载均衡,则需要在负载均衡器上配置会话粘度,从而保持用户体验并防止他们突然退出。
前提条件
本教程假定您熟悉 Ubuntu 中的 LAMP 服务器设置。 此设置将使用 3 个 Droplets 与 Ubuntu 14.04 图像。
水滴1
- 名称:光灯01
- 公共IP: 1.1.1.1
- 私人IP: 10.1.1.1
2
- 名称:光灯02 公共IP:2.2.2 私人IP:10.2.2
3
- 名称:光灯03
- 公共IP: 3.3.3.3
- 私人IP: 10.3.3
在创建 Droplets 时,请确保在 私人网络检查框中标记。
在三个服务器上安装LAMP。
首先,更新存储库并安装Apache。
1apt-get update
2apt-get install apache2
安装 PHP 和 Apache 的 mod_php 扩展。
1apt-get install php5 libapache2-mod-php5 php5-mcrypt
若要了解更多信息,请参阅 此文章。
步骤一 - 安装 Memcache 包
在 lamp01上,安装Memcached DAEMON和PHP的Memcache模块。
1apt-get install php5-memcache memcached
PHP有两种包:php5-memcache和php5-memcached(在结尾注明d
)。我们将使用第一种包(memcache),因为它更轻,没有任何依赖性。
Memcached 服务只在 localhost 上收听(127.0.0.1)。
1nano /etc/memcached.conf
找下面的线条:
1-l 127.0.0.1
更改它以倾听该服务器的私人IP地址。
1-l 10.1.1.1
重新启动memcached
服务。
1service memcached restart
在其他两个服务器上重复这些步骤,用相应的私人IP地址取代127.0.0.1
。
灯光2
1-l 10.2.2.2
灯光03
1-l 10.3.3.3
在第二两个服务器上重新启动memcached
服务。
步骤二:将 Memcache 设置为 PHP 会话处理器
在 lamp01上,打开php.ini
文件进行编辑。
1nano /etc/php5/apache2/php.ini
此檔案位於 PHP-FPM 安裝中的 `/etc/php5/fpm/php.ini。
查找以下配置指令:
1session.save_handler =
2session.save_path =
修改它们以如下方式使用 Memcache. 在session.save_path
中使用所有三个私人 IP 地址。
1session.save_handler = memcache
2session.save_path = 'tcp://10.1.1.1:11211,tcp://10.2.2.2:11211,tcp://10.3.3.3:11211'
您可能需要删除session.save_path
的评论,请记住在每个 IP 地址后输入端口号 11211,因为 Memcached 在这个端口上收听。
在其他两个服务器上添加完全相同的设置。
On lamp02:
1session.save_handler = memcache
2session.save_path = 'tcp://10.1.1.1:11211,tcp://10.2.2.2:11211,tcp://10.3.3.3:11211'
点击3
点击:
1session.save_handler = memcache
2session.save_path = 'tcp://10.1.1.1:11211,tcp://10.2.2.2:11211,tcp://10.3.3.3:11211'
此配置必须在所有会话共享的 Droplets 上完全相同,以便正常工作。
步骤三 - 配置 Memcache for Session Redundancy
在 lamp01上,编辑memcache.ini
文件。
1nano /etc/php5/mods-available/memcache.ini
将以下配置指令添加到本文件的末尾。
1memcache.allow_failover=1
2memcache.session_redundancy=4
memcache.session_redundancy
指令必须等于 memcached 服务器数量 + 1 以便将会话信息复制到所有服务器。
这些指令允许会话失败和冗余,因此PHP将会话信息写入到session.save_path
中指定的所有服务器上;类似于RAID-1设置。
重启 Web 服务器或 PHP FPM Daemon 取决于正在使用的内容。
1service apache2 reload
重复这些步骤在 lamp02和 lamp03上。
第四步 - 测试会议解雇
要测试此设置,在所有 Droplets 上创建以下PHP脚本。
/var/www/html/session.php 网站
1<?php
2 header('Content-Type: text/plain');
3 session_start();
4 if(!isset($_SESSION['visit']))
5 {
6 echo "This is the first time you're visiting this server\n";
7 $_SESSION['visit'] = 0;
8 }
9 else
10 echo "Your number of visits: ".$_SESSION['visit'] . "\n";
11
12 $_SESSION['visit']++;
13
14 echo "Server IP: ".$_SERVER['SERVER_ADDR'] . "\n";
15 echo "Client IP: ".$_SERVER['REMOTE_ADDR'] . "\n";
16 print_r($_COOKIE);
17?>
此脚本仅供测试,可在设置 Droplets 后删除。
在使用 curl 的第一个 Droplet 上访问此文件并提取 Cookie 信息。
1curl -v -s http://1.1.1.1/session.php 2>&1 | grep 'Set-Cookie:'
这将返回类似于以下的输出。
1< Set-Cookie: PHPSESSID=8lebte2dnqegtp1q3v9pau08k4; path=/
复制PHPSESSID
Cookie 并将请求发送到其他 Droplets 使用此 Cookie. 如果没有请求在 1440 秒内,PHP 将删除此会话,所以请确保在这个时间框架内完成测试。
1curl --cookie "PHPSESSID=8lebte2dnqegtp1q3v9pau08k4" http://1.1.1.1/session.php http://2.2.2.2/session.php http://3.3.3.3/session.php
您将发现,该会话正在通过所有Dropplets进行。
1Your number of visits: 1
2Server IP: 1.1.1.1
3Client IP: 117.193.121.130
4Array
5(
6 [PHPSESSID] => 8lebte2dnqegtp1q3v9pau08k4
7)
8Your number of visits: 2
9Server IP: 2.2.2.2
10Client IP: 117.193.121.130
11Array
12(
13 [PHPSESSID] => 8lebte2dnqegtp1q3v9pau08k4
14)
15Your number of visits: 3
16Server IP: 3.3.3.3
17Client IP: 117.193.121.130
18Array
19(
20 [PHPSESSID] => 8lebte2dnqegtp1q3v9pau08k4
21)
要测试故障,请停止memcached
服务并访问此文件。
1service memcached stop
Droplet 透明地使用存储在其他两个服务器上的会话信息。
1curl --cookie "PHPSESSID=8lebte2dnqegtp1q3v9pau08k4" http://1.1.1.1/session.php
输出:
1Your number of visits: 4
2Server IP: 1.1.1.1
3Client IP: 117.193.121.130
4Array
5(
6 [PHPSESSID] => 8lebte2dnqegtp1q3v9pau08k4
7)
现在可以配置负载平衡器以均匀地分配请求,而无需配置会话粘度。
在你完成测试后,重新开始memcached
:
1service memcached start
步骤五 - 使用 IPTables 保护 Memcached
即使 Memcached 使用私人网络,同一数据中心的其他 DigitalOcean 用户也可以连接到您的 Droplet,如果他们知道您的私人 IP。
经过测试,我们正在执行此步骤,以便更容易解决如果不正确的规则被应用时可能出现的问题。
在 lamp01上创建防火墙规则,使用 lamp02和 lamp03的私人 IP 地址。
1iptables -A INPUT -s 10.2.2.2 -i eth1 -p tcp -m state --state NEW -m tcp --dport 11211 -j ACCEPT
2iptables -A INPUT -s 10.3.3.3 -i eth1 -p tcp -m state --state NEW -m tcp --dport 11211 -j ACCEPT
在典型的LAMP服务器上,以下将是完整的规则集:
1iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
2iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
3iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
4iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
5iptables -A INPUT -s 10.2.2.2 -i eth1 -p tcp -m state --state NEW -m tcp --dport 11211 -j ACCEPT
6iptables -A INPUT -s 10.3.3.3 -i eth1 -p tcp -m state --state NEW -m tcp --dport 11211 -j ACCEPT
7iptables -A INPUT -i lo -j ACCEPT
8iptables -A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
9iptables -P INPUT DROP
在 lamp02上输入防火墙规则,使用 lamp01和 lamp03的私人IP地址。
1iptables -A INPUT -s 10.1.1.1 -i eth1 -p tcp -m state --state NEW -m tcp --dport 11211 -j ACCEPT
2iptables -A INPUT -s 10.3.3.3 -i eth1 -p tcp -m state --state NEW -m tcp --dport 11211 -j ACCEPT
在 lamp03上,使用 lamp01和 lamp02的私人 IP 地址做同样的事情。
1iptables -A INPUT -s 10.1.1.1 -i eth1 -p tcp -m state --state NEW -m tcp --dport 11211 -j ACCEPT
2iptables -A INPUT -s 10.2.2.2 -i eth1 -p tcp -m state --state NEW -m tcp --dport 11211 -j ACCEPT
在步骤 4 中重复测试以确认防火墙不会阻止我们的流量。