背景
互联网的广泛应用,使分布式系统越来越流行,但也同时引入了两个问题:
- 每个层次各个服务节点的负载均衡问题
- 服务节点的临时故障问题(容灾)
什么是服务发现
简单的说,在soa架构体系中,通常地,服务作为一个功能模块,只对外开放一个服务名,使用方只需要拿着这个服务名,就可以找到一个可以提供正常服务的机器。这种根据服务名发现服务的功能,就叫做服务发现。
服务发现的好处
在soa架构体系下,可以方便地进行水平伸缩。
传统方式下,每增加一个服务实例,就需要更新一下客户端的应用配置。
但是到了微服务时代,这种处理方式显得太过于低效。引入了服务发现,可以让这种伸缩不对客户端造成影响,只在中间做一层转换,使服务的变化都在这个系统中登记,外部只需要在调用时去获取实例的网络位置(IP地址和端口),不需要频繁修改自己的配置。
什么是lvs
lvs是Linux虚拟服务器,将内网的机器组成机器群提供网络服务,外部的请求打在负载均衡器上,负载均衡器再将请求分发到其中一台服务器上去。
服务发现与lvs的差异
共同点
服务发现与lvs都是为了实现负载均衡;
不同点
- 服务发现只是提供服务查询,服务发现挂了,客户端仍可以通过缓存的查询结果,继续与服务端简历连接;
- lvs则是网络中的一个关键节点,lvs挂了,将直接导致整个网络服务对外不可用;
负载均衡算法
比较常见的有权重随机算法(RandomLoadBalance),权重轮询算法(RobinRoundLoadBalance),一致性哈希算法(ConsistenHashLoadBalance),最少活跃度算法(LeastActiviteLoadBalance)。
权重随机算法
这种算法最简单,权重为几个随机对象的命中比例,权重设置越高越容易命中。
<?php
/**
* file: random.php
*/
$config = [
'apple' => 5,
'banana' => 3,
'orange' => 3,
'pear' => 4
];
$choices = [];
foreach ($config as $choice => $weight) {
while ($weight >= 0) {
$choices[] = $choice;
$weight--;
}
}
if (count($choices) <= 0) {
throw new Exception("weight config invalid");
}
for ($i = 0; $i < 30; $i++) {
$choosedKey = array_rand($choices);
var_dump($choices[$choosedKey]);
}
<?php
/**
* 权重随机算法改进版
* file: random_v2.php
*/
$config = [
'apple' => 5,
'banana' => 3,
'orange' => 3,
'pear' => 4
];
function random_choose($config)
{
$weightSum = array_sum($config);
if ($weightSum <= 0) {
throw new Exception("config valid");
}
$randNum = rand(1, $weightSum);
foreach ($config as $choice => $weight) {
if ($randNum <= $weight) {
return $choice;
}
$randNum -= $weight;
}
}
for ($i = 0; $i < 30; $i++) {
$choosed = random_choose($config);
var_dump($choosed);
}
权重轮询算法
轮流使用共享资源的基础上,加上权重分配,相对公平地使用各个资源。
一致性哈希算法
通过对请求做hash处理,映射到hash环上,来分配到对应的资源。