swoft微服务实战十:ip_hash算法

3. ip_hash算法:

①. 公式:
   hashcode(客户端Ip) % size
②. 类似nginx负载均衡配置:
   upstream lb {
     server xxxxxx1;
     server xxxxxx2;
     ip_hash;
   }

(1). 算法公共类:
app\Consul\ServiceSelector.php:

namespace App\Consul;
class ServiceSelector {
    ...
    public static function selectByIPHash(string $ip, array $serviceList) : array
    {
        $index = crc32($ip) % count($serviceList);
        $key = array_keys($serviceList)[$index];
        return $serviceList[$key];
    }
}:. crc32算法(循环冗余校验):只要内容是一致的,获取的校验码就是一致的.

(2). 调用方法:
app\Http\MyClient.php:

use App\Consul\ServiceSelector;
...
/**
  * @RequestMapping(router="getOneService", method={RequestMethod::GET})
  */
public function getOneService(): array
{
    // 静态方法调用
    return ServiceSelector::selectByIPHash(ip(), $this->getHealthService());
}

(3). 全局函数:
app\Helper\Functions.php:

function request()  {
    return Swoft\Context\Context::get()->getRequest();
}
function ip(){
    $req=request();
    if ($req->server('http_x_forwarded_for')) {
        return $req->server('http_x_forwarded_for');
    } elseif ($req->server('http_client_ip')) {
        return $req->server('http_client_ip');
    } else {
        return $req->server('remote_addr');
    }
}

(4). 总结:

①. 只要是这个IP,就永远返回这个服务.可以解决保持session一致的问题.
②. 但是服务列表的总数发生变化呢?

4. 简单的轮训算法:

一个一个轮着来,最简单做法,是弄个变量保存到bean中(有权重就不一样了).
(1). 追加方式轮训:

namespace App\Consul;
use Swoft\Bean\Annotation\Mapping\Bean;
/**
 * @Bean()
 */
class ServiceSelector {
    ...
    private static $nodeIndex = 0;
    public static function selectByRoundRobin(array $serviceList) {
        if(self::$nodeIndex>=count($serviceList)){
            self::$nodeIndex = 0;
        }
        $getKey=array_keys($serviceList)[self::$nodeIndex];
        self::$nodeIndex++;
        return $serviceList[$getKey];
    }
}

(2). 取余方式轮训:

namespace App\Consul;
use Swoft\Bean\Annotation\Mapping\Bean;
/**
 * @Bean()
 */
class ServiceSelector {
    ...
    private static $nodeIndex = 0;
    public static function selectByRoundRobin(array $serviceList) {
        $getKey=array_keys($serviceList)[self::$nodeIndex];
        self::$nodeIndex = (self::$nodeIndex + 1) % count($serviceList);
        return $serviceList[$getKey];
    }
}
  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值