论坛首页 综合技术论坛

lighty的lb问题

浏览 3520 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2008-03-23  
看了galaxystar的帖子之后对lighty有了初步的了解,而且从google的trends上也可以看出lighty确实是一个web server中迅速崛起的新星,势头非常之强劲,所以趁这个周末我也来学习一把

1,下载安装,我使用的是ubuntu7.10,所以下载lighttpd非常简单,只要执行
sudo apt-get install lighttpd 命令就可以下载并安装lighttpd了,我下载的好像是1.4的版本。
安装结束之后,它就自动启动了,这时候在流览器里输入http://localhost就可以看到lighttpd的页面了。

2,下载tomcat6.10,拷贝一份出来,修改conf目录下的server.xml,将connector中的8080改成18080。启动两个tomcat实例。这时候在浏览器里输入http://localhost:8080/index.jsp和http://localhost:18080/index.jsp,分别出现两个tomcat的页面,接下来在这两个index.jsp(webapps/root()目录下)分别加入以下代码<%out.println("-aaaaaa-");%>和<%out.println("-bbbbbb-");%>

3,接下来修改lighttpd.conf文件,在server.modules 数组中加入一个新的元素,如下:
server.modules              = (

            "mod_access",

            "mod_alias",

            "mod_accesslog",

            "mod_compress",

#           "mod_rewrite",

#           "mod_redirect",

#           "mod_status",

#           "mod_evhost",

#           "mod_usertrack",

#           "mod_rrdtool",

#           "mod_webdav",

#           "mod_expire",

#           "mod_flv_streaming",

            "mod_proxy", #主要是增加这个节点,代表lighty将会使用proxy模块

#           "mod_evasive"

)

接着在下面加上如下配置:
$HTTP["host"] == "localhost" {



$HTTP["url"] =~ ".jsp|.go|.do|action" {

proxy.balance = "fair"

proxy.server = ( "" => ( ( "host" => "127.0.0.1", "port" => 8080 ),("host" => "127.0.0.1", "port" => 18080) ))

}

}

上面这段配置浅显易懂,只有一个proxy.balance节点的熟悉比较奇怪。
lighttpd的配置要比apache简单的多了,而且更容易理解。这也是apache需要学习的地方。

4,重启lighttpd,看看有什么效果:./lighttpd restart

在浏览器中输入http://localhost/index.jsp
出现的页面上有-aaaaaa-这个字符串,这代表请求被转发到1号tomcat了,再多次请求,发现返回的页面上一直有a的字符串,而没有出现b的字符串,貌似lb没有产生效果。


ok,让我们来看看proxy.loadblance的几个值:
hash:表示相同的request uri会被发送到同一个proxyhandler,比如说现在我们有两个node,那么a.jsp的hashcode为1,b.jsp的hashcode为2,那么a.jsp的请求只会被发到node1(2),而b.jsp的请求只会被发到node2(1)。

fair:表示使用普通的基于负载的消极的均衡,什么意思呢,我的理解就是,当node1负载过高时,才把请求发给node2,所以就出现了上面的那种情况,不管你怎么刷,都是出现-aaaaaa-,而不会出现-bbbbbb-了。只有当node1压力过高时才会出现b。该策略是lighttpd默认的lb策略。

round-robin:表示不管怎么样都是轮发。也就是说通过这种方式我们不能通过设置factor来控制node的处理数量,这个是一个个小小的缺憾。更大的问题是据说lighttpd的round-robin不是很稳定,这个是最麻烦的(最大的麻烦是我没有试出来,一使用round-robin,lighttpd就跟我说:no proxy-handler found for: /,文档上写道:Check if you have used an IP address for the proxy address. Hostnames are not allowed there!   但是我没有用hostname也不行,有点郁闷了。
)。所以综合看来hash策略应该是最佳选择了。

题外话,lighttpd好像也不支持stickly-session吧,所以我觉得使用lighttpd来做lb不是很合适。在这个功能上它和apache还有较大差距,今天试用的是lighttpd1.4的版本,不知道1.5版本的lighttpd在这方面会不会好一点。有空我来试用一下lighttpd1.5的round-robin,看能否让它正常跑起来。
   发表时间:2008-03-23  
lighttpd 1.4的mod_proxy的lb功能的确是不够完善的。

1、fair算法的问题

正如你所说,fair算法只有当A节点负载超过一定程度以后才会分流到B节点。关于这一点我做过详细的测试,你需要多加一些并发负载上去,才能观测到balance的效果。

2、fail-over的问题

1.4的fail-over是有点问题的,如果A节点挂掉,当前请求就会503错误返回,下一个请求才会转到B节点。这一点不像apache2.2的mod_proxy_balance,不会出现一个503错误请求。

3、sticky-session的问题

apache2.2的mod_proxy_balance支持sticky-session,但是这种基于HTTP Header里面携带的cookie信息解析来决定如何转发的方式,其性能开销是非常大的,但凡需要balance的情况都是访问量非常高的场景,在这种情况下apache的的sticky-session策略就会成为一个严重的前端瓶颈。

lighttpd 1.4和1.5都不支持sticky-session,未来计划实现基于IP地址的sticky-session,这也是LVS的实现方法,从软件层面来讲,是最高效的方式了。

BTW: 需要lb的情况,应用软件应该设计成为SNA架构,彻底抛弃HttpSession,改为cookie+分布式缓存的方式来存储Session信息。

4、lighttpd 1.5的mod_proxy_core

1.5的mod_proxy_core整个重写了一遍,和1.4已经完全不同了,支持SQF,CARF等分发方式。可以参考:

http://trac.lighttpd.net/trac/wiki/Docs%3AModProxyCore

编译1.5需要glib库,安装起来稍微有点麻烦。
0 请登录后投票
   发表时间:2008-03-23  
robbin 写道
lighttpd 1.4的mod_proxy的lb功能的确是不够完善的。


3、sticky-session的问题

apache2.2的mod_proxy_balance支持sticky-session,但是这种基于HTTP Header里面携带的cookie信息解析来决定如何转发的方式,其性能开销是非常大的,但凡需要balance的情况都是访问量非常高的场景,在这种情况下apache的的sticky-session策略就会成为一个严重的前端瓶颈。
原来我以为apache的sticky-session是根据ip来判定转发的node的,原来是在header里携带cookie信息的呀,明白了。虽然我知道他有这个功能,但是我没有用过,之前一个项目我是通过filter把session中的数据放到了memcached中去了,所以apache只配置了分发的功能,没有使用stickly-session。

不过这种方式jetty并不支持,jetty用了自己的一个session类,我proxy了httpsession之后,在jetty上跑它就抛类型不匹配的异常。



0 请登录后投票
   发表时间:2008-03-24  
127.0.0.1 - - [28/Dec/2007:19:25:21 +0800] "GET /service/js/demo2do-utils.js HTTP/1.1" 200 1850
127.0.0.1 - - [28/Dec/2007:19:25:21 +0800] "GET /service/js/glassprotector.js HTTP/1.1" 200 1972
127.0.0.1 - - [28/Dec/2007:19:25:21 +0800] "GET /service/js/validator.js HTTP/1.1" 200 32281
127.0.0.1 - - [28/Dec/2007:19:25:21 +0800] "GET /service/js/behaviour.js HTTP/1.1" 200 8149
127.0.0.1 - - [28/Dec/2007:19:25:21 +0800] "GET /service/js/alternationcolor.js HTTP/1.1" 200 1537


从apahce的日志文件上可以看到所有的请求的ip地址都是记录下来的,而apache的stickly-session没有根据ip来分发我猜是不是这个原因:
如果使用ip来分发,那么所有访问过的ip和对应的节点号都必须记录下来,这样会消耗更多的内存。所以apache选择把请求
第一次访问的机器的节点号放在cookie里,下次这个用户再过来就可以迅速的获知它应该访问的机器。如果说lighty也要根据ip来分发的话,估计应该也会占用一部分内容用以记录ip和节点号。请求量越大,这个内存占用就越大.

0 请登录后投票
   发表时间:2008-03-24  
内存当中维护一个IP对应表的开销很小,可以忽略不计,你一个apache进程少说也要占据10MB内存的,一个IP对应表撑死了也不会到1MB内存。

0 请登录后投票
   发表时间:2008-03-24  
我做了一个小测试,在java里做的:
@Test
public void testIpMemo() {
long begin = Runtime.getRuntime().freeMemory();
System.out.println(begin);

Map<String, String> map = new HashMap<String, String>();
for (int k = 0; k < 1000; k++) {
String ip = new String("974127103");//每循环一次代表一个新的ip地址
String node = "tomcat1";
map.put(ip, node);
}


System.out.println(begin - Runtime.getRuntime().freeMemory());

System.out.println();
}


我的目的是想得到1000个独立ip地址所消耗的内存,结果如下:
8928(内存使用了 8kb(修改))

不过这个java的测试,希望有人做一下python的测试(apache是python写的吧)。

现在的问题是我这个测试代码写得是否正确。

换一个思路,一个ip是长度为9的string,那就是说有有9个char,也就是说有9个byte,那么1000个独立ip就是9000个byte,和8928这个值非常接近。
0 请登录后投票
   发表时间:2008-03-24  
你这个算法太天真了,切不说带GC的语言你无法准确统计内存占用,就说你这个测试程序前后都不GC一把,那结果能不离谱吗?再说你在Java里面构造1000个String对象,和C的data struct那能是一码事吗?apache可是标准的用C写的程序。

IPv4的地址只需要8位16进制存储,也就是一个IP地址只需要4字节存储,1024个IP地址仅仅需要4KB,而一百万个IP地址仅仅需要4MB。顺便说一句,貌似CSDN网站号称每日独立IP也不过50万而已,而他是30多台服务器。你会在乎这多出来的4MB吗?
0 请登录后投票
   发表时间:2008-03-24  
robbin 写道
你这个算法太天真了,切不说带GC的语言你无法准确统计内存占用,就说你这个测试程序前后都不GC一把,那结果能不离谱吗?再说你在Java里面构造1000个String对象,和C的data struct那能是一码事吗?apache可是标准的用C写的程序。

我之前一直以为apache是用python写的,想不到是c写的。

robbin 写道

IPv4的地址只需要8位16进制存储,也就是一个IP地址只需要4字节存储,1024个IP地址仅仅需要4KB,而一百万个IP地址仅仅需要4MB。顺便说一句,貌似CSDN网站号称每日独立IP也不过50万而已,而他是30多台服务器。你会在乎这多出来的4MB吗?

上面我算错了(晕了),9000bytes大概也就是8kb不是8m。既然1000个独立ip只消耗这么一点内存,那为什么apache不这样做呢,这是想不通了。它往cookie里写标识我想应该没有直接用ip快吧


题外话:csdn用apache分发吗,一直以为象csdn这种网站怎么也得lvs,或者买硬件呢

ps,在我调用gc之后,确实1000个地址的内存使用量变成了4kb左右
0 请登录后投票
   发表时间:2008-03-24  
CSDN是IIS+ asp.net,我只是拿csdn打个比方。

apache为啥还没有提供基于IP的分发方式,这个原因我也不清楚,但是我想熟悉apache的人写一个这样的module,好像也不太难,也许有第三方这样的module也说不定,只是我没有去找过。
0 请登录后投票
论坛首页 综合技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics