负载均衡
之前将Node server的服务改成 Master-Worker模式,不过它是在一个主机上fork多个进程。不过它毕竟是在一个主机上。而微服务是需要负载均衡的,将请求根据负载规则分配到具体主机上。常用的有Ixia、BigIP、Node的cluster模块、Nginx等。
我们产品现在用的是BigIP,使用F5 编写iRules 来定义分发规则。不过一般情况下,用的更多的是Nginx。
Nginx
Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器。使用C进行编写,移植性和性能都比较好。
安装
Windows安装
Nginx 安装起来很容易,官网下载后,解压即可。然后双击该目录下的nginx.exe,即可启动nginx服务器。
bin\nginx.conf 里默认配置的是端口80,即HTTP 协议默认端口80。因此,输入http://localhost即可验证是否成功。
关闭时,执行以下命令即可。
nginx -s stop
Ubuntu安装
下执行以下命令即可:
sudo apt-get install nginx
切换到/usr/sbin/目录下启动。如果需要修改配置,切换到/etc/nginx 下更改即可。
算法
Nginx支持多种负载均衡调度算法:
weight轮询(默认)
ip_hash
fair
url_hash
轮询
所谓轮询就是从upstream 定义的待选服务器列表中从上到下依次选择一个使用。默认情况下:weight=1
upstream tomcat {
server localhost:8080;
server localhost:8180;
}
ip_hash
同一客户端两次访问的要是同一个server,这样可以解决session的问题。注意:ip_hash时,不要加权重。
upstream mypro {
ip_hash;
server localhost:8080;
server localhost:8090;
}
另外,网上说ip_hash 只根据IP地址前三位来进行hash,如192.168.1.10 计算时只用到 192.168.1。因此并不是十分地均衡。我查看了源码,之前版本源码如下:
for (i = 0; i < 3; i++) {
hash = (hash * 113 + iphp->addr[i]) % 6271; //iphp->addr[i]为ip的点分十进制法的第i段
}
for循环里确实只用到了前三位。而
最新代码如下(我用的是1.14.0)
for (i = 0; i < (ngx_uint_t) iphp->addrlen; i++) {
hash = (hash * 113 + iphp->addr[i]) % 6271;
}
w = hash % iphp->rrp.peers->total_weight;
peer = iphp->rrp.peers->peer;
p = 0;
while (w >= peer->weight) {
w -= peer->weight;
peer = peer->next;
p++;
}
这里用到了所有ip,而且weight也对计算产生了影响。有了解的欢迎指教。
fair
fair属于第三方模块。按后端服务器的响应时间来分配请求,响应时间短的优先分配。
upstream mypro {
fair;
server localhost:8080;
server localhost:8090;
}
注意:使用fair时,要先安装第三方的负载均衡模块nginx-upstream-fair
url_hash
也是第三方的,按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。
upstream mypro {
fair;
server localhost:8080;
server localhost:8090;
hash $request_uri;
hash_method crc32;
}
配置
这里演示一个例子,Nginx代理两个Server的情况。现在本机上安装两个Tomcat,端口分别是8080、8180。为了更好的演示,最好使用不同版本的Tomcat。
安装Nginx后,修改配置如下:
upstream tomcat {
#ip_hash;
server localhost:8080 weight=1 max_fails=5 fail_timeout=5s;
server localhost:8180 weight=1 max_fails=5 fail_timeout=5s;
}
server {
listen 10002;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location /tomcat {
proxy_redirect off;
proxy_pass http://tomcat/;
}
}
配置好,启动Nginx。访问http://localhost:10002/tomcat,即可发现每次访问的页面version不一样。
upstream
upstream模块用于定义待选服务器列表。列表中的服务器提供相同的服务。
upstream myserver {
server localhost:8888 down;
server localhost:8080 weight=2 max_fails=5 fail_timeout=5s;
server localhost:8180 weight=1 max_fails=5 fail_timeout=5s;
server localhost:8888 backup;
}
server {
listen 10000;
proxy_next_upstream error timeout invalid_header http_500 http_503 http_404;
#... other
location / {
proxy_pass http://myserver
}
}
down 表示该server暂时不参与负载
weight 表示当前server的负载权重,越大表示被选中的概率越大。默认为1.
backup 表示为备选server(类似主备模式),暂不参与负载。当所有非backup的server忙或者down时,才启用。
max_fails 允许最大失败次数,超过这个次数时,使用proxy_next_upstream 定义的异常。
fail_timeout 当失败max_fails次后,暂停的时间。
整个过程可以通过以下命令测试你的配置:
sudo nginx -t -c <path-t nginx.conf>