nacos
什么是nacos
英文全称Dynamic Naming and Configuration Service,Na为naming/nameServer即注册中心,co为configuration即注册中心,service是指该注册/配置中心都是以服务为核心。服务在nacos是一等公民
nacos工作原理
Nacos注册中心分为server与client,server采用Java编写,为client提供注册发现服务与配置服务。而client可以用多语言实现,client与微服务嵌套在一起,nacos提供sdk和openApi,如果没有sdk也可以根据openApi手动写服务注册与发现和配置拉取的逻辑
Nacos服务领域模型主要分为命名空间、集群、服务。在下图的分级存储模型可以看到,在服务级别,保存了健康检查开关、元数据、路由机制、保护阈值等设置,而集群保存了健康检查模式、元数据、同步机制等数据,实例保存了该实例的ip、端口、权重、健康检查状态、下线状态、元数据、响应时间。
注册中心原理
服务注册的策略的是每5秒向nacos server发送一次心跳,心跳带上了服务名,服务ip,服务端口等信息。同时 nacos server也会向client 主动发起健康检查,支持tcp/http检查。如果15秒内无心跳且健康检查失败则认为实例不健康,如果30秒内健康检查失败则剔除实例。
配置中心原理
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) . ';';
}
}