溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Nacos解決laravel多環(huán)境下配置切換的案例

發(fā)布時(shí)間:2021-02-20 09:18:19 來源:億速云 閱讀:283 作者:小新 欄目:編程語言

這篇文章主要介紹了Nacos解決laravel多環(huán)境下配置切換的案例,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

前言

對于應(yīng)用程序運(yùn)行的環(huán)境來說,不同的環(huán)境有不同的配置通常是很有用的。例如,你可能希望在本地使用的緩存驅(qū)動(dòng)不同于生產(chǎn)服務(wù)器所使用的緩存驅(qū)動(dòng)。

痛點(diǎn)

  • .env 配置不能區(qū)分多環(huán)境(開發(fā),測試,生產(chǎn))

  • .env 配置共享太麻煩(團(tuán)隊(duì)局域網(wǎng)環(huán)境)

  • 配置不能實(shí)時(shí)管理,增刪改配置

  • 自動(dòng)化部署配置 .env 文件過于繁瑣

Nacos 簡介

Nacos 是阿里巴巴最新開源的項(xiàng)目,核心定位是 “一個(gè)更易于幫助構(gòu)建云原生應(yīng)用的動(dòng)態(tài)服務(wù)發(fā)現(xiàn)、配置和服務(wù)管理平臺(tái)”,項(xiàng)目地址:nacos.io/zh-cn/

應(yīng)用

這里主要使用了 Nacos 的配置管理,并沒有使用到動(dòng)態(tài)服務(wù)等功能。原理也很簡單,通過接口直接修改 .env 文件。Nacos 服務(wù)可以直接使用使用阿里云提供的 應(yīng)用配置管理,無須安裝。鏈接如下: acmnext.console.aliyun.com/

代碼

<?php

namespace App\Console\Commands;use GuzzleHttp\Client;use Illuminate\Console\Command;use Illuminate\Support\Facades\Artisan;use Illuminate\Support\Facades\Validator;class NacosTools extends Command{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'nacos {action?}';

    private $accessKey;
    private $secretKey;
    private $endpoint = 'acm.aliyun.com';
    private $namespace;
    private $dataId;
    private $group;
    private $port = 8080;
    private $client;

    private $serverUrl;

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Nacos 管理工具';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     * @throws \Exception
     */
    public function handle()
    {
        $this->accessKey = env('NACOS_ACCESS_KEY');
        $this->secretKey = env('NACOS_SECRET_KEY');
        $this->endpoint = env('NACOS_ENDPOINT');
        $this->namespace = env('NACOS_NAMESPACE');
        $this->port = env('NACOS_PORT', $this->port);
        $this->dataId = env('NACOS_DATA_ID');
        $this->group = env('NACOS_GROUP');

        if (!$this->validate()) {
            $this->error('請檢查配置參數(shù)');

            return;
        }

        $this->client = new Client(['verify' => false]);

        $this->info('Nacos 配置工具');

        $actions = [
            '獲取配置',
            '發(fā)布配置',
            '刪除配置',
        ];

        if (is_null($this->argument('action'))) {
            $action = $this->choice('請選擇操作',
                $actions,
                $actions[0]);
        } else {
            if (in_array($this->argument('action'), array_keys($actions))) {
                $action = $actions[$this->argument('action')];
            } else {
                $action = $this->choice('請選擇操作',
                    $actions,
                    $actions[0]);
            }
        }

        $this->do($action);
    }

    public function do($action = '獲取配置')
    {
        switch ($action) {
            default:
            case '獲取配置':
                $config = $this->getConfig();

                if ($config) {
                    file_put_contents('.env', $config);
                    $this->info('獲取配置成功');
                } else {
                    $this->error('獲取配置失敗');
                }

                break;
            case '發(fā)布配置':
                if ($this->publishConfig()) {
                    $this->info('發(fā)布配置成功');
                } else {
                    $this->error('發(fā)布配置失敗');
                }

                break;

            case '刪除配置':
                if ($this->removeConfig()) {
                    $this->info('刪除配置成功');
                } else {
                    $this->error('刪除配置失敗');
                }

                break;
        }
    }

    /**
     * 驗(yàn)證配置參數(shù)
     *
     * Date: 2020/6/10
     * @return bool
     */
    private function validate()
    {
        $data = [
            'accessKey' => $this->accessKey,
            'secretKey' => $this->secretKey,
            'endpoint'  => $this->endpoint,
            'namespace' => $this->namespace,
            'dataId'    => $this->dataId,
            'group'     => $this->group,
        ];

        $rules = [
            'accessKey' => 'required',
            'secretKey' => 'required',
            'endpoint'  => 'required',
            'namespace' => 'required',
            'dataId'    => 'required',
            'group'     => 'required',
        ];

        $messages = [
            'accessKey.required' => '請?zhí)顚慲.env`配置 NACOS_ACCESS_KEY',
            'secretKey.required' => '請?zhí)顚慲.env`配置 NACOS_SECRET_KEY',
            'endpoint.required'  => '請?zhí)顚慲.env`配置 NACOS_ENDPOINT',
            'namespace.required' => '請?zhí)顚慲.env`配置 NACOS_NAMESPACE',
            'dataId.required'    => '請?zhí)顚慲.env`配置 NACOS_DATA_ID',
            'group.required'     => '請?zhí)顚慲.env`配置 NACOS_GROUP',
        ];

        $validator = Validator::make($data, $rules, $messages);

        if ($validator->fails()) {
            foreach ($validator->getMessageBag()->toArray() as $item) {
                foreach ($item as $value) {
                    $this->error($value);
                }
            }

            return false;
        }

        return true;
    }

    /**
     * 獲取配置
     *
     * Date: 2020/6/10
     * @return bool
     */
    private function getConfig()
    {
        $acmHost = str_replace(['host', 'port'], [$this->getServer(), $this->port],
            'http://host:port/diamond-server/config.co');

        $query = [
            'dataId' => urlencode($this->dataId),
            'group'  => urlencode($this->group),
            'tenant' => urlencode($this->namespace),
        ];

        $headers = $this->getHeaders();

        $response = $this->client->get($acmHost, [
            'headers' => $headers,
            'query'   => $query,
        ]);

        if ($response->getReasonPhrase() == 'OK') {
            return $response->getBody()->getContents();
        } else {
            return false;
        }
    }

    /**
     * 發(fā)布配置
     *
     * Date: 2020/6/10
     * @return bool
     */
    public function publishConfig()
    {
        $acmHost = str_replace(
            ['host', 'port'],
            [$this->getServer(), $this->port],
            'http://host:port/diamond-server/basestone.do?method=syncUpdateAll');

        $headers = $this->getHeaders();

        $formParams = [
            'dataId'  => urlencode($this->dataId),
            'group'   => urlencode($this->group),
            'tenant'  => urlencode($this->namespace),
            'content' => file_get_contents('.env'),
        ];

        $response = $this->client->post($acmHost, [
            'headers'     => $headers,
            'form_params' => $formParams,
        ]);

        $result = json_decode($response->getBody()->getContents(), 1);

        return $result['message'] == 'OK';
    }

    public function removeConfig()
    {
        $acmHost = str_replace(['host', 'port'], [$this->getServer(), $this->port],
            'http://host:port/diamond-server//datum.do?method=deleteAllDatums');

        $headers = $this->getHeaders();

        $formParams = [
            'dataId' => urlencode($this->dataId),
            'group'  => urlencode($this->group),
            'tenant' => urlencode($this->namespace),
        ];

        $response = $this->client->post($acmHost, [
            'headers'     => $headers,
            'form_params' => $formParams,
        ]);

        $result = json_decode($response->getBody()->getContents(), 1);

        return $result['message'] == 'OK';
    }

    /**
     * 獲取配置服務(wù)器地址
     *
     * Date: 2020/6/10
     * @return string
     */
    private function getServer()
    {
        if ($this->serverUrl) {
            return $this->serverUrl;
        }

        $serverHost = str_replace(
            ['host', 'port'],
            [$this->endpoint, $this->port],
            'http://host:port/diamond-server/diamond');

        $response = $this->client->get($serverHost);

        return $this->serverUrl = rtrim($response->getBody()->getContents(), PHP_EOL);
    }

    /**
     * 獲取請求頭
     *
     * Date: 2020/6/10
     * @return array
     */
    private function getHeaders()
    {
        $headers = [
            'Diamond-Client-AppName' => 'ACM-SDK-PHP',
            'Client-Version'         => '0.0.1',
            'Content-Type'           => 'application/x-www-form-urlencoded; charset=utf-8',
            'exConfigInfo'           => 'true',
            'Spas-AccessKey'         => $this->accessKey,
            'timeStamp'              => round(microtime(true) * 1000),
        ];

        $headers['Spas-Signature'] = $this->getSign($headers['timeStamp']);

        return $headers;
    }

    /**
     * 獲取簽名
     *
     * @param $timeStamp
     * Date: 2020/6/10
     * @return string
     */
    private function getSign($timeStamp)
    {
        $signStr = $this->namespace.'+';

        if (is_string($this->group)) {
            $signStr .= $this->group."+";
        }

        $signStr = $signStr.$timeStamp;

        return base64_encode(hash_hmac(
            'sha1',
            $signStr,
            $this->secretKey,
            true
        ));
    }}

使用示例

  1. 注冊賬號(hào),開通服務(wù)這些就不說了

  2. .env 添加配置項(xiàng) NACOS_ACCESS_KEY NACOS_SECRET_KEY

  3. php artisan nacos 0 獲取配置

  4. php artisan nacos 1 發(fā)布配置

  5. php artisan nacos 2 刪除配置

配置項(xiàng)說明

NACOS_ENDPOINT= #nacos節(jié)點(diǎn) 如使用阿里云服務(wù) 即:acm.aliyun.comNACOS_DATA_ID= #項(xiàng)目ID 可以填項(xiàng)目名NACOS_GROUP= #分組ID 這里可以用于區(qū)分環(huán)境 建議 local production test 等值NACOS_NAMESPACE= # 命名空間 建議用來區(qū)分服務(wù)器 server-A server-BNACOS_ACCESS_KEY= #阿里云access_key 建議使用子賬號(hào)access_keyNACOS_SECRET_KEY= #阿里云secret_key 建議使用子賬號(hào)secret_key

感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“Nacos解決laravel多環(huán)境下配置切換的案例”這篇文章對大家有幫助,同時(shí)也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI