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

EasySwoole RPC 自定義注冊中心

EasySwoole 默認為通過 UDP 廣播 + 自定義進程定時刷新自身節點信息的方式來實現無主化/注冊中心的服務發現。在服務正常關閉的時候,自定義定時進程的onShutdown 方法會執行 deleteServiceNode 方法來實現節點下線。在非正常關閉的時候,心跳超時也會被節點管理器踢出。

有些情況,比如服務都不在一個網段上,由于udp協議的設置,將會廣播不到,只能點對點的進行廣播數據,就不是很方便。那么 EasySwoole 支持你自定義一個節點管理器,來變更服務注冊及發現方式。

下面實現的 Redis 節點管理器示例是基于 easyswoole/redis-pool 組件 實現,所以請先執行 composer require easyswoole/redis-pool 安裝 redis-pool 組件。關于 easyswoole/redis-pool 組件具體用戶請查看 easyswoole/redis-pool 章節

例如使用 Redis 來實現

<?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();

// 服務定時自刷新到節點管理器
$assistConfig->setAliveInterval(5000);

即使關閉了 UDP 定時廣播,EasySwoole RpcAssistWorker 進程依舊會每 5 秒執行一次 serviceAlive 用于更新自身的節點心跳信息。

注冊

<?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 服務 ######
        /** rpc 服務端配置 */
        // 采用了redis 節點管理器 可以關閉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'); // 默認 EasySwoole
        $config->setOnException(function (\Throwable $throwable) {

        });

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

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

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

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

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

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

    }
}
亚洲精品成人_精品成人一区_999视频在线播放_免费黄色在线_亚洲成人久久久_久久www免费视频
  • <kbd id="eqi2k"><code id="eqi2k"></code></kbd><cite id="eqi2k"><tbody id="eqi2k"></tbody></cite>
    在线天堂一区av电影| 国产精品手机在线| 亚洲一区二区免费视频软件合集 | 亚洲高清乱码| 亚洲一区日韩在线| 亚洲一区三区| 性欧美暴力猛交另类hd| 日本视频精品一区| 91九色在线观看| 亚洲精品一区二区三区av| 蜜桃传媒视频麻豆第一区免费观看| 黄色精品免费| 亚洲一区二区三区在线观看视频| 一区二区三区四区视频在线观看| 欧美日韩视频| 日韩欧美精品一区二区三区经典| av成人午夜| 国产精品精品软件视频| 亚洲一区二区毛片| 亚洲午夜精品久久久中文影院av | 国产亚洲一区二区三区在线播放| 久久99精品久久久久子伦| 久久一二三四| 国内一区在线| 色一情一乱一伦一区二区三区| 国产精品视频久久一区| 一级特黄录像免费播放全99| 国产精品一国产精品最新章节| 欧美一区二区三区在线播放| 伊人久久av导航| 欧美国产一二三区| 狠狠综合久久| 欧美777四色影| 一区二区三区偷拍| 亚洲一区二区三区欧美| 日韩亚洲欧美精品| 日韩激情视频| 亚州欧美一区三区三区在线| 国产一区二区免费在线观看| 欧美日韩国产成人精品| 亚洲国产精品综合| 欧美日韩天天操| 亚洲三区在线观看| 欧美激情91| 蜜桃麻豆91| 久久天堂国产精品| 四虎永久国产精品| 欧美日韩精品一本二本三本| 欧美日韩成人一区二区三区| 韩日欧美一区| 亚洲在线欧美| 黑人一区二区| 91久久极品少妇xxxxⅹ软件| 国内精品视频在线播放| 艳色歌舞团一区二区三区| 一区一区视频| 久久先锋影音| 五月天色一区| 国产欧美丝祙| 国产精品二区在线| 久久高清国产| 亚洲黄色大片| 在线欧美亚洲| 激情欧美日韩| 九九热久久66| 亚洲视频1区| 午夜精品一区二区三区四区| 亚洲精品欧洲精品| 国产一区二区三区色淫影院| 欧美精品v日韩精品v国产精品| 久久久综合香蕉尹人综合网| 亚洲精品一区二区三区蜜桃久| 国产精品入口| 91久久极品少妇xxxxⅹ软件| 国产一区再线| 国产一区二区三区久久| 欧美不卡在线| 亚洲国产精品久久久久久女王| 午夜亚洲伦理| 18成人免费观看视频| 午夜免费电影一区在线观看| 精品欧美日韩| 久久久久综合一区二区三区| 激情欧美一区| 伊人精品视频| 国产日韩在线一区二区三区| 正义之心1992免费观看全集完整版| 国产三区精品| 免费久久久一本精品久久区| 蜜桃视频日韩| 日日夜夜精品网站| 亚洲一区二区三区涩| 亚洲午夜黄色| 亚洲国产日韩欧美一区二区三区| 牛牛国产精品| 亚洲欧洲精品一区| 亚洲一区在线免费| yellow视频在线观看一区二区 | 国产精品一区二区a| 久久福利影视| 久久天天狠狠| 国产一区免费视频| 噜噜噜噜噜久久久久久91| dy888夜精品国产专区| 国产欧美一区二区三区另类精品| 欧美一级片免费观看| 欧美日韩精品免费观看视一区二区| 欧美日韩网址| 51成人做爰www免费看网站| 蜜桃在线一区二区三区精品| 婷婷久久青草热一区二区| 伊人久久大香线蕉av超碰演员| 欧美一级专区| 国产在线欧美| 欧美不卡福利| 国产一区二区三区高清| 日韩成人在线资源| 91传媒免费看| 99re国产精品| 午夜欧美精品| 欧美激情论坛| 成人区精品一区二区| 欧美另类综合| 一区二区在线高清视频| 久久99九九| 久久久久高清| 国产精品播放| 免费不卡亚洲欧美| 国产欧美三级| 激情久久一区| 亚洲午夜av| 亚洲日韩视频| 一区二区亚洲精品| 久久精品中文字幕一区二区三区 | 国产日韩欧美精品| 亚洲精品黄色| 亚洲免费激情| 国产精品区一区| 亚洲免费网址| 91精品国产综合久久久久久丝袜| 亚洲一区国产| 久久尤物视频| 精品一区日韩成人| 亚洲欧洲精品在线观看| 小说区图片区图片区另类灬| 超碰97网站| 欧美大香线蕉线伊人久久| 亚洲国产一区二区三区在线 | 亚洲影院在线| 国产精品视频免费一区| 欧美裸体网站| 一区国产精品| 99精品国产高清一区二区| 精品久久久三级| 精品69视频一区二区三区Q| 国产日韩一区二区三区在线| 精品国产一区二区三区四区精华| 欧美日韩一区在线播放| 一区二区三区我不卡| 3d蒂法精品啪啪一区二区免费| 国模精品娜娜一二三区| 欧美暴力喷水在线| 99c视频在线| 欧美日韩一区二区三| 国产精品一区二| 精品动漫3d一区二区三区免费版 | 伊人成人在线视频| 日韩av电影免费播放| 亚洲免费在线| 亚洲精品九九| 在线国产伦理一区| 久久波多野结衣| 久久综合给合久久狠狠色| 中文字幕人成一区| 亚洲国产日韩综合一区| 国产精品夜夜夜一区二区三区尤| 亚洲国产欧美日韩| 欧美精品成人一区二区在线观看| 九九99玖玖| 久久99九九| 国产欧美韩日| 成人蜜桃视频| 国产精选一区二区| 国产精品果冻传媒潘| 久久成人免费| 久久久人人人| 国产日韩久久| 九九九九精品九九九九| 激情伦成人综合小说| 国产欧美日韩一区二区三区| 国模一区二区三区私拍视频| av在线不卡观看| 久久精品欧美| 色视频一区二区三区| 欧美不卡在线| 国产日韩欧美三区| 国内精品久久国产| 午夜精品亚洲一区二区三区嫩草| 色阁综合av| 在线亚洲免费|