http重定向
所谓http重定向,就是通过修改http响应头中的location标识为新的url,然后返回给客户端,让客户端重新根据这个location标识的url去做新的请求。
这是一种最简单、也是最轻量级的负载均衡实现方案,使用.net,我们可以这样来实现,比如在主站中,我们在默认主页如下编码:

static string[] servers = 
        {
            “”,
            “”
        };
protected void page_load(object sender, eventargs e)
{
    response.redirect(servers[datetime.now.millisecond % 2]);
}
在上面的代码中,response.redirect实际为http头返回状态码302,这是为了告诉,请到location中去拿url,并且去到这个新的url去做请求。当然,我们也可以采用最原始的方法来代替redirect方法:

response.status = “302 found”;
response.statuscode = 302;
response.addheader(“location”, servers[datetime.now.millisecond % 2]);
使用httpwatch监视,我们对请求,得到:
 

可以清晰的看到第一次请求返回的302,然后转发到新的地址,得到状态码200。
以上方法是在客户端的重定向,即浏览器请求了两次,一次是到主服务器,第二次是到location中指定的服务器上去请求。
http重定向的方式非常依赖于主站的处理能力,它的性能瓶颈也是来自于iis对于接受请求->asp.net处理首页动态程序->返回带有特定头请求,是的,它不能突破自身的性能瓶颈,比如,在我的破测试机上,我得到的吞吐率为:
 

好在iis自身已经支持重定向(查阅http://technet.microsoft.com/zh-cn/library/cc732969(ws.10).aspx),这更进一步省略了我们自己写代码实现重定向,省略运行asp.net代码带来的性能损耗。
2:varnish实现的反向代理负载均衡
另外一种思路是使用反向代理服务器的负载均衡功能,上篇当中介绍的varnish就支持这样的功能,查看配置文件:

backend web1 {
     .host = “192.168.0.77”;
     .port = “8081”;     
}
backend web2 {
     .host = “192.168.0.77”;
     .port = “8082”;
}
director lb round-robin {
    {
        .backend = web1;
    }
    {
        .backend = web2;
    }
}
 sub l_recv {
     set req.backend = lb;
     return (pass);
 }
在该配置文件中,我们部署了两台web服务器,当然,为了简单期间,我这里是使用了同一台服务器的两个端口。在vcl_recv函数中,varnish定义了负载均衡。
运行varnish之,我们会发现请求被转发到后台服务器了。
3:其它方案
1:dns负载均衡,通过增加域名a记录来让dns服务器实现负载均衡。好处是几乎不会碰到性能问题。缺点:要求每个web服务器必须有外网地址。一旦某台服务器崩溃,不能及时让dns修改生效。不能定义自己的转发策略;
2:ip负载均衡,有lvs-nat,采用iptables,对linux内核操作,性能相对于反向代理服务器并没有质的飞跃;ip负载均衡仍旧需要转发请求给实际服务器,同时需要转发实际服务器的响应给用户,所以,它的性能瓶颈来自于nat服务器的性能及网络带宽;
3:直接路由,有lvs-dr,工作在数据链路层(第二层),要求所有web服务器接入外网;负载均衡器负责转发请求给实际服务器,但是它通过修改数据包中的mac地址,能够做到让实际服务器的响应直接返回给用户,而不用通过负载均衡器,这当然进一步提升了负载均衡的效率;
4:ip隧道,有lvs-tun,用于不同机房(即不同wan网段)的负载均衡,原理同lvs-dr;

 

作者 luminji