亚洲精品成人_精品成人一区_999视频在线播放_免费黄色在线_亚洲成人久久久_久久www免费视频

EasySwoole RPC 自定義注冊中心

EasySwoole 默認(rèn)為通過 UDP 廣播 + 自定義進(jìn)程定時刷新自身節(jié)點(diǎn)信息的方式來實(shí)現(xiàn)無主化/注冊中心的服務(wù)發(fā)現(xiàn)。在服務(wù)正常關(guān)閉的時候,自定義定時進(jìn)程的onShutdown 方法會執(zhí)行 deleteServiceNode 方法來實(shí)現(xiàn)節(jié)點(diǎn)下線。在非正常關(guān)閉的時候,心跳超時也會被節(jié)點(diǎn)管理器踢出。

有些情況,比如服務(wù)都不在一個網(wǎng)段上,由于udp協(xié)議的設(shè)置,將會廣播不到,只能點(diǎn)對點(diǎn)的進(jìn)行廣播數(shù)據(jù),就不是很方便。那么 EasySwoole 支持你自定義一個節(jié)點(diǎn)管理器,來變更服務(wù)注冊及發(fā)現(xiàn)方式。

下面實(shí)現(xiàn)的 Redis 節(jié)點(diǎn)管理器示例是基于 easyswoole/redis-pool 組件 實(shí)現(xiàn),所以請先執(zhí)行 composer require easyswoole/redis-pool 安裝 redis-pool 組件。關(guān)于 easyswoole/redis-pool 組件具體用戶請查看 easyswoole/redis-pool 章節(jié)。

例如使用 Redis 來實(shí)現(xiàn)

<?php

namespace App\RpcServices\NodeManager;

use EasySwoole\Redis\Redis;
use EasySwoole\RedisPool\Pool;
use EasySwoole\RedisPool\RedisPool;
use EasySwoole\Rpc\NodeManager\NodeManagerInterface;
use EasySwoole\Rpc\Server\ServiceNode;

class RedisManager implements NodeManagerInterface
{
    protected $redisKey;

    protected $ttl;

    /**
     * @var Pool $pool
     */
    protected $pool;

    public function __construct(Pool $pool, string $hashKey = 'rpc', int $ttl = 30)
    {
        $this->pool = $pool;
        $this->redisKey = $hashKey;
        $this->ttl = $ttl;
    }

    function getNodes(string $serviceName, ?int $version = null): array
    {
        $fails = [];
        $hits = [];
        $time = time();

        $redisPool = $this->pool;

        /** @var Redis $redis */
        $redis = $redisPool->defer(15);

        try {
            $nodes = $redis->hGetAll("{$this->redisKey}_{$serviceName}");

            $nodes = $nodes ?: [];

            foreach ($nodes as $nodeId => $value) {
                $node = json_decode($value, true);
                if ($time - $node['lastHeartbeat'] > $this->ttl) {
                    $fails[] = $nodeId;
                    continue;
                }
                if ($node['service'] === $serviceName) {
                    if ($version !== null && $version === $node['version']) {
                        $serviceNode = new ServiceNode($node);
                        $serviceNode->setNodeId(strval($nodeId));
                        $hits[$nodeId] = $serviceNode;
                    } else {
                        $serviceNode = new ServiceNode($node);
                        $serviceNode->setNodeId(strval($nodeId));
                        $hits[] = $serviceNode;
                    }
                }
            }
            if (!empty($fails)) {
                foreach ($fails as $failKey) {
                    $this->deleteServiceNode($serviceName, $failKey);
                }
            }
            return $hits;
        } catch (\Throwable $throwable) {
            // 如果該 redis 斷線則銷毀
            $redisPool->unsetObj($redis);
        } finally {
            $redisPool->recycleObj($redis);
        }

        return [];
    }

    function getNode(string $serviceName, ?int $version = null): ?ServiceNode
    {
        $list = $this->getNodes($serviceName, $version);
        if (empty($list)) {
            return null;
        }
        $allWeight = 0;

        $redisPool = $this->pool;;

        /** @var Redis $redis */
        $redis = $redisPool->getObj(15);

        $time = time();

        try {
            foreach ($list as $node) {
                /** @var ServiceNode $nodee */
                $key = $node->getNodeId();
                $nodeConfig = $redis->hGet("{$this->redisKey}_{$serviceName}", $key);
                $nodeConfig = json_decode($nodeConfig, true);
                $lastFailTime = $nodeConfig['lastFailTime'];
                if ($time - $lastFailTime >= 10) {
                    $weight = 10;
                } else {
                    $weight = abs(10 - ($time - $lastFailTime));
                }
                $allWeight += $weight;
                $node->__weight = $weight;
            }
            mt_srand(intval(microtime(true)));
            $allWeight = rand(0, $allWeight - 1);
            foreach ($list as $node) {
                $allWeight = $allWeight - $node->__weight;
                if ($allWeight <= 0) {
                    return $node;
                }
            }
        } catch (\Throwable $throwable) {
            // 如果該 redis 斷線則銷毀
            $redisPool->unsetObj($redis);
        } finally {
            $redisPool->recycleObj($redis);
        }

        return null;
    }

    function failDown(ServiceNode $serviceNode): bool
    {

        $redisPool = $this->pool;;

        /** @var Redis $redis */
        $redis = $redisPool->getObj(15);
        try {
            $serviceName = $serviceNode->getService();
            $nodeId = $serviceNode->getNodeId();
            $hashKey = "{$this->redisKey}_{$serviceName}";
            $nodeConfig = $redis->hGet($hashKey, $nodeId);
            $nodeConfig = json_decode($nodeConfig, true);
            $nodeConfig['lastFailTime'] = time();
            $redis->hSet($hashKey, $nodeId, json_encode($nodeConfig));
            return true;
        } catch (\Throwable $throwable) {
            // 如果該 redis 斷線則銷毀
            $redisPool->unsetObj($redis);
        } finally {
            $redisPool->recycleObj($redis);
        }

        return false;
    }

    function offline(ServiceNode $serviceNode): bool
    {

        $redisPool = $this->pool;;

        /** @var Redis $redis */
        $redis = $redisPool->getObj(15);
        try {
            $serviceName = $serviceNode->getService();
            $nodeId = $serviceNode->getNodeId();
            $hashKey = "{$this->redisKey}_{$serviceName}";
            $redis->hDel($hashKey, $nodeId);
            return true;
        } catch (\Throwable $throwable) {
            // 如果該 redis 斷線則銷毀
            $redisPool->unsetObj($redis);
        } finally {
            $redisPool->recycleObj($redis);
        }

        return false;
    }

    function alive(ServiceNode $serviceNode): bool
    {
        $info = [
            'service' => $serviceNode->getService(),
            'ip' => $serviceNode->getIp(),
            'port' => $serviceNode->getPort(),
            'version' => $serviceNode->getVersion(),
            'lastHeartbeat' => time(),
            'lastFailTime' => 0
        ];

        $redisPool = $this->pool;;

        /** @var Redis $redis */
        $redis = $redisPool->getObj();

        try {
            $serviceName = $serviceNode->getService();
            $nodeId = $serviceNode->getNodeId();
            $hashKey = "{$this->redisKey}_{$serviceName}";
            $redis->hSet($hashKey, $nodeId, json_encode($info));
            return true;
        } catch (\Throwable $throwable) {
            // 如果該 redis 斷線則銷毀
            $redisPool->unsetObj($redis);
        } finally {
            $redisPool->recycleObj($redis);
        }

        return false;
    }

    private function deleteServiceNode($serviceName, $failKey): bool
    {
        $redisPool = $this->pool;;

        /** @var Redis $redis */
        $redis = $redisPool->getObj(15);
        try {
            $redis->hDel("{$this->redisKey}_{$serviceName}", $failKey);
            return true;
        } catch (\Throwable $throwable) {
            $redisPool->unsetObj($redis);
        } finally {
            $redisPool->recycleObj($redis);
        }

        return false;
    }
}
 /** @var \EasySwoole\Rpc\Config $config */
$assistConfig = $config->getAssist();

// 服務(wù)定時自刷新到節(jié)點(diǎn)管理器
$assistConfig->setAliveInterval(5000);

即使關(guān)閉了 UDP 定時廣播,EasySwoole RpcAssistWorker 進(jìn)程依舊會每 5 秒執(zhí)行一次 serviceAlive 用于更新自身的節(jié)點(diǎn)心跳信息。

注冊

<?php

namespace EasySwoole\EasySwoole;

use EasySwoole\EasySwoole\AbstractInterface\Event;
use EasySwoole\EasySwoole\Swoole\EventRegister;use EasySwoole\Redis\Config\RedisConfig;use EasySwoole\RedisPool\Pool;use EasySwoole\RedisPool\RedisPool;

class EasySwooleEvent implements Event
{
    public static function initialize()
    {
        date_default_timezone_set('Asia/Shanghai');
    }

    public static function mainServerCreate(EventRegister $register)
    {
        ###### 注冊 rpc 服務(wù) ######
        /** rpc 服務(wù)端配置 */
        // 采用了redis 節(jié)點(diǎn)管理器 可以關(guān)閉udp 廣播了。
        $redisM = new RedisManager(new Pool(new RedisConfig(['host' => '127.0.0.1'])));
        $config = new \EasySwoole\Rpc\Config($redisM);
        $config->setNodeId('EasySwooleRpcNode1');
        $config->setServerName('EasySwoole'); // 默認(rèn) EasySwoole
        $config->setOnException(function (\Throwable $throwable) {

        });

        $serverConfig = $config->getServer();
        $serverConfig->setServerIp('127.0.0.1');

        // rpc 具體配置請看配置章節(jié)
        $rpc = new \EasySwoole\Rpc\Rpc($config);

        // 創(chuàng)建 Goods 服務(wù)
        $goodsService = new \App\RpcServices\Goods();
        // 添加 GoodsModule 模塊到 Goods 服務(wù)中
        $goodsService->addModule(new \App\RpcServices\GoodsModule());
        // 添加 Goods 服務(wù)到服務(wù)管理器中
        $rpc->serviceManager()->addService($goodsService);

        // 創(chuàng)建 Common 服務(wù)
        $commonService = new \App\RpcServices\Common();
        // 添加 CommonModule 模塊到 Common 服務(wù)中
        $commonService->addModule(new \App\RpcServices\CommonModule());
        // 添加 Common 服務(wù)到服務(wù)管理器中
        $rpc->serviceManager()->addService($commonService);

        // 此刻的rpc實(shí)例需要保存下來 或者采用單例模式繼承整個Rpc類進(jìn)行注冊 或者使用Di

        // 注冊 rpc 服務(wù)
        $rpc->attachServer(ServerManager::getInstance()->getSwooleServer());

    }
}
亚洲精品成人_精品成人一区_999视频在线播放_免费黄色在线_亚洲成人久久久_久久www免费视频
  • <kbd id="eqi2k"><code id="eqi2k"></code></kbd><cite id="eqi2k"><tbody id="eqi2k"></tbody></cite>
    3d蒂法精品啪啪一区二区免费| 亚洲黄色成人| 久久伦理网站| 香蕉久久免费影视| 欧美日韩少妇| 国产精品一级| 精品欧美日韩| 欧美色123| 久久久夜精品| 性欧美.com| 日韩午夜视频在线观看| 国产精品一级久久久| 亚洲欧美日韩精品在线| 一区二区激情| 97久久人人超碰caoprom欧美| 国产伦精品一区二区三区视频黑人 | 波多野结衣一区二区三区在线观看 | 亚洲高清视频一区二区| 亚洲人体大胆视频| 狠狠色噜噜狠狠狠狠色吗综合| 亚洲不卡中文字幕| 国产日韩欧美一区二区| 精品一区二区三区国产| 在线成人www免费观看视频| 精品综合久久久| 一区二区视频在线观看| 久久免费看av| 奶水喷射视频一区| 欧美凹凸一区二区三区视频| 97中文在线观看| 影音先锋亚洲精品| 欧洲一区二区日韩在线视频观看免费| 亚洲毛片视频| 亚洲高清资源综合久久精品| 久久中文字幕一区二区三区| 欧美久久九九| 欧美一区二区在线| 国产精品播放| 亚洲欧美日韩精品久久久 | 国产精品高清一区二区三区| 国产v亚洲v天堂无码| 欧美私人啪啪vps| 欧美成人免费在线| 久久午夜av| 亚洲欧洲一区| 欧美精品成人| 日韩av一级大片| 国产伦精品一区二区三区视频免费| 在线观看成人一级片| 亚洲视频在线二区| 免费毛片一区二区三区久久久| 免费日韩一区二区| 亚洲午夜精品久久久久久app| 日韩中文一区| 美女一区视频| 久久久久久久久一区| 2014国产精品| 久久久精品动漫| 99亚洲一区二区| 狠狠色狠狠色综合人人| 欧美精品导航| 国产伊人精品| 国内精品嫩模av私拍在线观看| 亚洲人成77777| 色综合视频二区偷拍在线| 国产综合av一区二区三区| 99国产超薄丝袜足j在线观看| 亚洲伊人网站| 久久国产精品高清| 久久香蕉精品| av噜噜色噜噜久久| 国产伦精品一区二区| 激情久久av| 欧美一区二区高清在线观看| 久久久久一区二区| 欧美午夜欧美| 一本色道婷婷久久欧美| 亚洲成色www久久网站| 亚洲精品成人自拍| 在线看成人av电影| 伊人久久大香线蕉综合热线| 最新国产拍偷乱拍精品| 亚洲作爱视频| 久久一区免费| 久久婷婷开心| 四虎一区二区| 国产中文一区二区| 国产亚洲欧美一区二区| 97视频资源在线观看| 精品无码久久久久国产| 日韩在线观看电影完整版高清免费| 亚洲一卡二卡三卡四卡无卡网站在线看| 亚洲黄色一区二区三区| 欧美午夜影院| 男人天堂欧美日韩| 久久99精品久久久久久久久久 | 国产精品一区二区三区不卡| 精品视频在线观看| 水蜜桃亚洲一二三四在线| 欧美婷婷久久| 亚洲欧美日韩视频二区| 国产伦精品一区二区三区在线| 欧美高清视频一区| 狠狠色综合网| 91精品国产99久久久久久红楼| 精品久久久久久乱码天堂| 欧美在线视频一区二区三区| 日韩午夜av在线| 国产精品乱码| 一区二区三区四区免费视频| 在线视频亚洲| 久久久影院一区二区三区| 国产精品v亚洲精品v日韩精品| 午夜在线一区| 亚洲精品一区二区三| 亚洲一区精彩视频| 女人一区二区三区| 亚洲精品1区2区| 精品午夜一区二区三区| 激情欧美一区| 久久综合入口| 国产精品日韩欧美一区二区三区 | 中文字幕欧美日韩一区二区| 国产精品久久国产愉拍| 欧美一二三区| 午夜综合激情| 欧美激情偷拍| 国产免费高清一区| 亚洲精品美女| 亚洲图片欧洲图片日韩av| 久久综合福利| 亚洲欧洲精品一区| 亚洲精品一区二区三区四区五区 | 99久久99久久| 黑人中文字幕一区二区三区 | 欧美日韩国产一二| 亚洲在线成人| 永久免费精品视频网站| 久久av一区二区三区亚洲| 亚洲开发第一视频在线播放| 欧美日韩综合精品| 91黄在线观看| 日韩午夜免费| 欧美日韩高清在线一区| 开心色怡人综合网站| 久久综合中文色婷婷| 亚洲国产欧洲综合997久久| 日韩和欧美的一区二区| 国产精品一区二区免费看| 性久久久久久| 国产欧美日韩在线播放| 国产精品国产三级欧美二区 | 老司机精品福利视频| 136国产福利精品导航网址| 一区二区三区四区五区精品 | 国产亚洲在线| 在线观看成人一级片| 欧美在线视频一区二区三区| 日韩高清av电影| 精品综合久久久| 国产一区二区视频在线免费观看| 国产精品一区二区欧美| 日韩视频在线观看国产| 伊人久久婷婷| 亚洲欧洲精品一区二区| 亚洲国产精品123| 亚洲国产欧美日韩| 日韩视频久久| 国产精品午夜av在线| 国产亚洲二区| 久久riav二区三区| **亚洲第一综合导航网站| 激情综合视频| 亚洲黄色三级| 国产九九精品| 久久久精品动漫| 99国产在线| 国产日韩欧美精品| 精品国产福利| 欧美中文娱乐网| 亚洲v国产v| 欧美日韩国产综合网| 合欧美一区二区三区| 99精品99| a级国产乱理论片在线观看99| 国产经典一区二区三区| 蜜桃视频在线观看91| 亚洲欧美丝袜| 在线观看一区欧美| 香蕉久久久久久久av网站| 91精品久久香蕉国产线看观看 | 欧美色一级片| 国产情侣一区| **亚洲第一综合导航网站| 99久久99久久| 日本不卡一区| 91久久精品一区二区别| 91原创国产| 日韩亚洲视频| 亚洲每日在线|