Laravel上集成nacos

1,305 阅读2分钟

nacos

什么是nacos

英文全称Dynamic Naming and Configuration Service,Na为naming/nameServer即注册中心,co为configuration即注册中心,service是指该注册/配置中心都是以服务为核心。服务在nacos是一等公民

nacos工作原理

image.png

Nacos注册中心分为server与client,server采用Java编写,为client提供注册发现服务与配置服务。而client可以用多语言实现,client与微服务嵌套在一起,nacos提供sdk和openApi,如果没有sdk也可以根据openApi手动写服务注册与发现和配置拉取的逻辑 image.png

Nacos服务领域模型主要分为命名空间、集群、服务。在下图的分级存储模型可以看到,在服务级别,保存了健康检查开关、元数据、路由机制、保护阈值等设置,而集群保存了健康检查模式、元数据、同步机制等数据,实例保存了该实例的ip、端口、权重、健康检查状态、下线状态、元数据、响应时间。

注册中心原理

image.png

服务注册的策略的是每5秒向nacos server发送一次心跳,心跳带上了服务名,服务ip,服务端口等信息。同时 nacos server也会向client 主动发起健康检查,支持tcp/http检查。如果15秒内无心跳且健康检查失败则认为实例不健康,如果30秒内健康检查失败则剔除实例。

配置中心原理

image.png

nacos如何在php中使用

配置要求:grpc扩展、php7+

nacos-server安装

git clone https://gitee.com/manic-little-er/nacos-server-1.4.git
unzip nacos-server-1.4
cd bin
单机启动  sh startup.sh -m standalone 
服务注册
`curl -X POST 'http://127.0.0.1:8848/nacos/v1/ns/instance?serviceName=nacos.naming.serviceName&ip=20.18.7.10&port=8080'`
服务发现
`curl -X GET 'http://127.0.0.1:8848/nacos/v1/ns/instance/list?serviceName=nacos.naming.serviceName'`
发布配置
`curl -X POST "http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=nacos.cfg.dataId&group=test&content=HelloWorld"`
获取配置
`curl -X GET "http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=nacos.cfg.dataId&group=test"`

laravel集成nacos

安装扩展 grpc
 pecl install protobuf
 pecl install grpc
 echo "extension=/usr/lib64/php/modules/grpc.so" >> php.ini
composer 安装nacos配置
composer require alibaba/nacos

artisan make:command NacosRefreshConfig

示例代码

<?php

namespace App\Console\Services\Impl;

use alibaba\nacos\listener\Listener;
use alibaba\nacos\Nacos;
use App\Console\Services\NacosSyncService;
use alibaba\nacos\NacosConfig as Config;
use Illuminate\Support\Facades\Log;
use Swoole\Exception;

class NacosSyncServiceImpl implements NacosSyncService
{

    /**
     * @var string
     */
    public $snapshotPath;

    /**
     * @var string
     */
    public $configFilePath;

    const HOST = '127.0.0.1:8848';

    const ENV = 'dev';

    const DATA_ID = 'laravel7';

    const GROUP = 'DEFAULT_GROUP';

    const TENANT = '';

    public function __construct()
    {
        $this->snapshotPath = base_path() . DIRECTORY_SEPARATOR;
        $this->configFilePath =  base_path() . DIRECTORY_SEPARATOR . '.env';
    }

    /**
     * @param bool $isWatch
     */
    public function checkNacosUpdate(bool $isWatch = false): void
    {
        Config::setSnapshotPath($this->snapshotPath);
        Listener::add(function (string $config) {
            $this->updateConfig($config);
        });
        $nacos = Nacos::init(self::HOST, self::ENV, self::DATA_ID, self::GROUP, self::TENANT);
        if ($isWatch) {
            $nacos->listener(58);
        } else {
            $this->updateConfig($nacos->runOnce());
        }
    }

    /**
     * @param string $configJson
     */
    private function updateConfig(string $configJson): void
    {
        try {
            $config = $this->jsonToPhpConfig($configJson);
            if (empty($config)) {
                throw new \Exception('disallow empty config');
            }
            file_put_contents($this->configFilePath, $config);
        } catch (Exception $exception) {
            Log::warning('更新nacos配置失败: ' . $exception->getMessage(), ['exception' => $exception]);
            throw $exception;
        }
    }

    /**
     * @param string $configJson
     * @return string
     * @throws \Exception
     */
    private function jsonToPhpConfig(string $configJson): string
    {
        return $configJson;
        $phpConfig = json_decode($configJson, true);
        if (json_last_error() != JSON_ERROR_NONE) {
            throw new \Exception('配置解析失败');
        } else {

        }
        return "<?php \nreturn " . var_export($phpConfig, true) . ';';
    }
}