X.d 笔记

小Web,大世界

0%

使Apache服务器Rewrite+Proxy实现ABTest

公司的产品作到一定规模后,应该考虑一下灰度发布,又称 ABTest

ABTest 并不是一种技术,只是一种产品发布模型,只要你的发布流程满足其中一项条件,就可以称为已经运用了 ABTest.

  1. 在产品上,提供了 体验新版,或 回到旧版 之类的切换功能。
  2. 如果有新版需要发布,可以技术手段让一小部分用户切换到新版,大部分用户还在旧版。
  3. 不局限于两个版本,更多的版本也是可以的,通过技术手段可以自由控制。
  4. (个人见过最变态,但没有测试目的,不能称为ABTEST :scream:),针对个领导专门做个版本,只要是领导的帐号,就直通 领导版,服务器什么的都是独享.

有了ABTest后,可以通过用户在不同版本之间的行为,进行分析产品,得到更好的改进决策。

ABTest的实现方法可以多种多样,各有优缺点,这里提供一个 Apache 的,跑了半年了,还没出现过太大问题。

自己实现的方案

我这里使用的是 Apache + ajp + Tomcat

由于业务原因,本人实现的是以用户区分的方案,如果想进行一轮灰度测试,首先会在数据库里面标记一些用户为灰度用户,用户登录后,会将标记存放在 cookie 里。

第一步,Copy…

这个是年烦人的事,也就是把对应环境的代码放到对应环境的Tomcat里面去,运行起来。

我这刚好有两台空机器,每个机器都COPY一套程序,分别作为环境一,环境二。

没有空的机器的话,可以用一台机多装点Tomcat,只要端口不冲突就行了。多装的话,注意内存配置什么的~。

第二步,代理

在生产环境的Apache上,开启proxy模块。作用是代理请求再转发,参考说明

那就开工代理了,先配置好proxy,假设我的网站是http://xxx.com/

加入

ProxyPass / http://{testip:port}/ timeout=15
#由于域名都一样,反向代理可以不配置。
ProxyPassReverse / http://xxx.com/

这样所有发到xxx.com的请求都由正式服务器代码到testip:port了,testip:port是先前第一步已经部署好的,也由测试服务器响应,这样的配置当然是没意义的,只是测试一小下。

第三步,路由

现在是解决问题的时候了,该怎么样才能让用户对应到它对应的环境呢,需要两个模块配合实现:

模块 功能 说明
mod_proxy 代理,上面已经说过,将一个符合URI规则的代理到另一个服务器去。 只能基于URI的规则进行代理
mod_rewrite URI重写,PHP玩的多的朋友都知道它是伪静态不可少的 可以根据多种规则重写URI

结论出来了:

  1. 先通过mod_rewrite将uri重写为匹配mod_proxy的规则
  2. mod_proxy将请求代理到对应的服务器上去。

刚说了mod_rewrite可以根据多种规则重写URI,我这里用到了Cookie.

首先,在用户登录的时候,伪代码可能是这个样子的

if(isTestUser1){
  addCookie("roteServer","proxy1");
}else if(isTestUser2){
  addCookie("roteServer","proxy2");
}

然后,根据Cookie重写URI

RewriteCond %{HTTP_COOKIE} ^.*\roteServer=proxy1.*
RewriteRule ^/(.*) /proxy1/$1 [PT,L]
RewriteCond %{HTTP_COOKIE} ^.*\roteServer=proxy2.*
RewriteRule ^/(.*) /proxy2/$1 [PT,L]

这状代码的作用就是重写URI,很多人用伪静态时都用过,比如将/act/2换成?act=2这样的。我这里依据的是Cookie里面的值,登录后就可以得到,如果得不到,说明是正式用户,就不会重写,也不会路由到体验服务器了。

最后,根据URI进行PROXY

ProxyPass /proxy1 http://{testip1:port}/ timeout=15
ProxyPassReverse /proxy1 http://xxx.com/
ProxyPass /proxy2 http://{testip2:port}/ timeout=15
ProxyPassReverse /proxy2 http://xxx.com/

这样一个简单的ABTest就这样了,只要你在登录里面去配置用户和它对应的环境,也就OK了。

说明

这个只是一个相当简单的思路性架构,依赖场景太多,实际操作中会有各种问题,HTTPS(需要配置HOST什么什么的,不然不通),AJP等等。

另外也不是太灵活,如果对环境经常会变化的用这种方案会感觉很痛苦。

好吧,方案就是这么挫了,仅作记录,供思路学习~~