• 技术文章 >php框架 >Laravel

    关于Nacos解决laravel多环境下配置切换

    藏色散人藏色散人2021-02-19 17:03:34转载116

    下面由Laravel教程栏目给大家介绍Nacos 解决 laravel 多环境下配置切换的方法 ,希望对需要的朋友有所帮助!

    前言

    对于应用程序运行的环境来说,不同的环境有不同的配置通常是很有用的。例如,你可能希望在本地使用的缓存驱动不同于生产服务器所使用的缓存驱动。

    痛点

    Nacos 简介

    Nacos 是阿里巴巴最新开源的项目,核心定位是 “一个更易于帮助构建云原生应用的动态服务发现、配置和服务管理平台”,项目地址:nacos.io/zh-cn/

    应用

    这里主要使用了 Nacos 的配置管理,并没有使用到动态服务等功能。原理也很简单,通过接口直接修改 .env 文件。Nacos 服务可以直接使用使用阿里云提供的 应用配置管理,无须安装。链接如下: 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('请检查配置参数');
    
                return;
            }
    
            $this->client = new Client(['verify' => false]);
    
            $this->info('Nacos 配置工具');
    
            $actions = [
                '获取配置',
                '发布配置',
                '删除配置',
            ];
    
            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 '发布配置':
                    if ($this->publishConfig()) {
                        $this->info('发布配置成功');
                    } else {
                        $this->error('发布配置失败');
                    }
    
                    break;
    
                case '删除配置':
                    if ($this->removeConfig()) {
                        $this->info('删除配置成功');
                    } else {
                        $this->error('删除配置失败');
                    }
    
                    break;
            }
        }
    
        /**
         * 验证配置参数
         *
         * 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' => '请填写`.env`配置 NACOS_ACCESS_KEY',
                'secretKey.required' => '请填写`.env`配置 NACOS_SECRET_KEY',
                'endpoint.required'  => '请填写`.env`配置 NACOS_ENDPOINT',
                'namespace.required' => '请填写`.env`配置 NACOS_NAMESPACE',
                'dataId.required'    => '请填写`.env`配置 NACOS_DATA_ID',
                'group.required'     => '请填写`.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;
            }
        }
    
        /**
         * 发布配置
         *
         * 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';
        }
    
        /**
         * 获取配置服务器地址
         *
         * 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. 注册账号,开通服务这些就不说了
    2. .env 添加配置项 NACOS_ACCESS_KEY NACOS_SECRET_KEY
    3. php artisan nacos 0 获取配置
    4. php artisan nacos 1 发布配置
    5. php artisan nacos 2 删除配置

    配置项说明

    NACOS_ENDPOINT= #nacos节点 如使用阿里云服务 即:acm.aliyun.comNACOS_DATA_ID= #项目ID 可以填项目名NACOS_GROUP= #分组ID 这里可以用于区分环境 建议 local production test 等值NACOS_NAMESPACE= # 命名空间 建议用来区分服务器 server-A server-BNACOS_ACCESS_KEY= #阿里云access_key 建议使用子账号access_keyNACOS_SECRET_KEY= #阿里云secret_key 建议使用子账号secret_key

    总结

    使用 nacos 后,再也不用担心 .env.example 忘记加配置项,共享配置也不是件麻烦事了,自动部署也不需要频繁的改动配置了。

    以上就是关于Nacos解决laravel多环境下配置切换的详细内容,更多请关注php中文网其它相关文章!

    本文转载于:learnku,如有侵犯,请联系a@php.cn删除
    专题推荐:laravel nacos
    上一篇:详解Laravel之路由请求方式、路由传参 下一篇:关于 Laravel 项目 伪静态分页处理
    第15期线上培训班

    相关文章推荐

    • 解决laravel上传图片之后目录有图片,但访问不到(404)的问题• 详解Laravel项目中实现Ajax上传用户头像的方法• 关于laravel自定义模板指令-tojs• 分享个人推荐的laravel或其它框架的编程规范• 详解Laravel之路由请求方式、路由传参

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网