如何在 Ubuntu 14.04 上共享多个 Memcached 服务器上的 PHP 会话

介绍

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

重复这些步骤在 lamp02lamp03上。

第四步 - 测试会议解雇

要测试此设置,在所有 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上创建防火墙规则,使用 lamp02lamp03的私人 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上输入防火墙规则,使用 lamp01lamp03的私人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上,使用 lamp01lamp02的私人 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 中重复测试以确认防火墙不会阻止我们的流量。

额外阅读

Published At
Categories with 技术
comments powered by Disqus