├── src ├── Constant.php ├── Contracts │ ├── Apollo.php │ └── Operate.php ├── Facades │ └── Apollo.php ├── ApolloManager.php ├── RedisOperate.php ├── InputVar.php ├── Console │ └── WorkCommand.php ├── ApolloLaravelServiceProvider.php ├── ApolloVariable.php ├── ApolloServiceProvider.php └── ApolloService.php ├── composer.json ├── config └── apollo.php └── README.md /src/Constant.php: -------------------------------------------------------------------------------- 1 | app = $app; 22 | } 23 | 24 | public function resetConfig() 25 | { 26 | $input = new InputVar($this->app['apollo.cache']); 27 | $input->input(); 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sunaloe/apollo-laravel", 3 | "license": "MIT", 4 | "authors": [ 5 | { 6 | "name": "lkboy", 7 | "email": "lk88boy@gmail.com" 8 | } 9 | ], 10 | "require": { 11 | "php": "^7.1.3", 12 | "multilinguals/apollo-client": "~0.1.2", 13 | "illuminate/support": "~5.7|~6", 14 | "illuminate/redis": "~5.7|~6", 15 | "illuminate/cache": "~5.7|~6", 16 | "predis/predis": "~1.1", 17 | "illuminate/console": "~5.7|~6" 18 | }, 19 | "autoload": { 20 | "psr-4": { 21 | "Sunaloe\\ApolloLaravel\\":"src/" 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/RedisOperate.php: -------------------------------------------------------------------------------- 1 | redis = $redis; 18 | } 19 | 20 | /** 21 | * @param $key 22 | * @return mixed|string 23 | */ 24 | public function get($key) 25 | { 26 | $result = $this->connection()->get($key); 27 | 28 | return $result; 29 | } 30 | 31 | /** 32 | * @param $key 33 | * @param $value 34 | * @return mixed 35 | */ 36 | public function set($key, $value) 37 | { 38 | return $this->connection()->set($key, $value); 39 | } 40 | 41 | public function connection() 42 | { 43 | return $this->redis->connection('apollo'); 44 | } 45 | } -------------------------------------------------------------------------------- /src/InputVar.php: -------------------------------------------------------------------------------- 1 | cache = $cache; 15 | } 16 | 17 | /** 18 | * @return array|mixed 19 | */ 20 | private function getData() 21 | { 22 | $ret = []; 23 | $redisKey = config('apollo.data_redis_key'); 24 | $data = $this->cache->get($redisKey); 25 | $arr = \json_decode($data, true); 26 | if (!empty($arr)) { 27 | $ret = $arr; 28 | } 29 | return $ret; 30 | } 31 | 32 | public function input() 33 | { 34 | $ret = $this->getData(); 35 | $prefix = config("apollo.prefix"); 36 | $varObj = app('apollo.variable'); 37 | foreach ($ret as $key => $val) { 38 | $key = sprintf("%s%s", $prefix, $key); 39 | $varObj->setEnvironmentVariable($key, $val); 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /config/apollo.php: -------------------------------------------------------------------------------- 1 | 'http://127.0.0.1:8081', 8 | 9 | /** 10 | * 11 | */ 12 | 'save_dir' => './', 13 | 14 | /** 15 | * apollo 配置appid 16 | */ 17 | 'appid' => 'demo', 18 | 19 | /** 20 | * 读取的namespace 21 | */ 22 | 'namespaces' => ['application'], 23 | 24 | /** 25 | * 数据存储的 redis key 26 | */ 27 | 'data_redis_key' => 'apollo_data', 28 | 29 | /** 30 | * 数据 key 前缀 31 | */ 32 | 'prefix' => 'apollo:', 33 | 34 | /** 35 | * redis 使用的默认连接 36 | */ 37 | 'redis_use' => 'default', 38 | 39 | /** 40 | * 配置缓存 41 | */ 42 | 'cache' => [ 43 | 'default' => 'file', 44 | 45 | 'stores' => [ 46 | 47 | 'file' => [ 48 | 'driver' => 'file', 49 | 'path' => storage_path('framework/cache/data'), 50 | ], 51 | 52 | 53 | 'redis' => [ 54 | 'driver' => 'redis', 55 | 'connection' => 'apollo', 56 | ], 57 | ], 58 | ], 59 | 60 | ]; 61 | -------------------------------------------------------------------------------- /src/Console/WorkCommand.php: -------------------------------------------------------------------------------- 1 | getServer(); 39 | 40 | $pid = getmypid(); 41 | echo "start [$pid]\n"; 42 | $err = ''; 43 | try { 44 | $err = $client->start(function () use ($apollo, &$err) { 45 | $err = $apollo->startCallback(); 46 | }); 47 | } catch (\Exception $e) { 48 | $err = $e->getMessage(); 49 | } 50 | 51 | echo $err . "\n"; 52 | } 53 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # laravel 接入携程 [Apollo](https://github.com/ctripcorp/apollo) 2 | 3 | 4 | ## 概述 5 | 6 | Apollo(阿波罗)是携程框架部门研发的分布式配置中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景。 7 | 此插件让 laravel 框架方便的接入 apollo 8 | 9 | ## 运行环境 10 | - PHP 7.0 11 | - laravel 5.7 12 | - lumen 5.7 13 | 14 | 15 | ## 安装方法 16 | 17 | composer require sunaloe/apollo-laravel 18 | 19 | ### laravel 20 | 21 | - 配置引入 22 | 把 /apollo-laravel/config/apollo.php 拷贝放到配置目录 23 | 24 | - 服务提供者引入 25 | 26 | ```php 27 | 'providers' => [ 28 | \Sunaloe\ApolloLaravel\ApolloLaravelServiceProvider::class, 29 | ], 30 | ``` 31 | 32 | ### lumen 33 | 34 | - 配置引入 35 | 把 /apollo-laravel/config/apollo.php 拷贝放到配置目录 36 | 37 | ```php 38 | $app->configure('apollo'); 39 | ``` 40 | 41 | - 服务提供者引入 42 | 43 | 44 | ```php 45 | $app->register(\Illuminate\Redis\RedisServiceProvider::class); 46 | $app->register(\Sunaloe\ApolloLaravel\ApolloServiceProvider::class); 47 | ``` 48 | 49 | 50 | ## 使用 51 | 52 | - apollo 配置监控 53 | 54 | #### 配置work的常驻进程 55 | ```php 56 | php artisan apollo:work 57 | ``` 58 | 59 | #### 使用配置 60 | ```php 61 | env('apollo:配置名') 62 | ``` 63 | 64 | ### 重新更新env变量 65 | ```php 66 | \Sunaloe\ApolloLaravel\Facades\Apollo::resetConfig(); 67 | ``` 68 | 69 | ## License 70 | 71 | - MIT 72 | 73 | 74 | -------------------------------------------------------------------------------- /src/ApolloLaravelServiceProvider.php: -------------------------------------------------------------------------------- 1 | app['apollo.cache']); 15 | $input->input(); 16 | } 17 | 18 | 19 | public function register() 20 | { 21 | $this->configure(); 22 | $this->registerServices(); 23 | $this->registerCommands(); 24 | } 25 | 26 | protected function registerServices() 27 | { 28 | 29 | $this->app->singleton('apollo.cache', function ($app) { 30 | $app['config']->set('cache', config('apollo.cache')); 31 | $obj = new CacheManager($app); 32 | return $obj; 33 | }); 34 | 35 | $this->app->singleton('apollo.service', function ($app) { 36 | return new ApolloService($app['apollo.cache']); 37 | }); 38 | 39 | 40 | $this->app->singleton('apollo.variable', function () { 41 | return new ApolloVariable(); 42 | }); 43 | } 44 | 45 | protected function configure() 46 | { 47 | $this->mergeConfigFrom( 48 | __DIR__ . '/../config/apollo.php', 'apollo' 49 | ); 50 | ApolloService::useConfig(config('apollo.redis_use')); 51 | } 52 | 53 | protected function registerCommands() 54 | { 55 | if ($this->app->runningInConsole()) { 56 | $this->commands([Console\WorkCommand::class]); 57 | return; 58 | } 59 | } 60 | } -------------------------------------------------------------------------------- /src/ApolloVariable.php: -------------------------------------------------------------------------------- 1 | immutable = $immutable; 14 | } 15 | 16 | /** 17 | * @param $name 18 | * @return array|false|null|string 19 | */ 20 | public function getEnvironmentVariable($name) 21 | { 22 | switch (true) { 23 | case array_key_exists($name, $_ENV): 24 | return $_ENV[$name]; 25 | case array_key_exists($name, $_SERVER): 26 | return $_SERVER[$name]; 27 | default: 28 | $value = getenv($name); 29 | return $value === false ? null : $value; // switch getenv default to null 30 | } 31 | } 32 | 33 | /** 34 | * @param $name 35 | * @param null $value 36 | */ 37 | public function setEnvironmentVariable($name, $value = null) 38 | { 39 | if ($this->immutable && $this->getEnvironmentVariable($name) !== null) { 40 | return; 41 | } 42 | 43 | if (function_exists('apache_getenv') && function_exists('apache_setenv') && apache_getenv($name) !== false) { 44 | apache_setenv($name, $value); 45 | } 46 | 47 | if (function_exists('putenv')) { 48 | putenv("$name=$value"); 49 | } 50 | 51 | $_ENV[$name] = $value; 52 | $_SERVER[$name] = $value; 53 | } 54 | 55 | public function clearEnvironmentVariable($name) 56 | { 57 | if ($this->immutable) { 58 | return; 59 | } 60 | 61 | if (function_exists('putenv')) { 62 | putenv($name); 63 | } 64 | 65 | unset($_ENV[$name], $_SERVER[$name]); 66 | } 67 | } -------------------------------------------------------------------------------- /src/ApolloServiceProvider.php: -------------------------------------------------------------------------------- 1 | app['apollo.cache']); 16 | $input->input(); 17 | } 18 | 19 | 20 | public function register() 21 | { 22 | $this->configure(); 23 | $this->registerServices(); 24 | $this->registerCommands(); 25 | } 26 | 27 | protected function registerServices() 28 | { 29 | 30 | $this->app->singleton('apollo.cache', function ($app) { 31 | $app['config']->set('cache', config('apollo.cache')); 32 | $obj = new CacheManager($app); 33 | return $obj; 34 | }); 35 | 36 | $this->app->singleton('apollo.service', function ($app) { 37 | return new ApolloService($app['apollo.cache']); 38 | }); 39 | 40 | 41 | $this->app->singleton('apollo.variable', function () { 42 | return new ApolloVariable(); 43 | }); 44 | 45 | $this->app->singleton('apollo', function ($app) { 46 | return new ApolloManager($app); 47 | }); 48 | } 49 | 50 | protected function configure() 51 | { 52 | $this->app->configure('apollo'); 53 | $this->mergeConfigFrom( 54 | __DIR__ . '/../config/apollo.php', 'apollo' 55 | ); 56 | 57 | ApolloService::useConfig(config('apollo.redis_use')); 58 | } 59 | 60 | protected function registerCommands() 61 | { 62 | if ($this->app->runningInConsole()) { 63 | $this->commands([Console\WorkCommand::class]); 64 | return; 65 | } 66 | } 67 | 68 | 69 | } -------------------------------------------------------------------------------- /src/ApolloService.php: -------------------------------------------------------------------------------- 1 | cache = $cache; 18 | } 19 | 20 | /** 21 | * @param $fileList 22 | * @throws \Exception 23 | */ 24 | private function updateConfig($fileList) 25 | { 26 | $newConfig = []; 27 | foreach ($fileList as $file) { 28 | if (!is_file($file)) { 29 | throw new \Exception('config file no exists'); 30 | } 31 | $c = require $file; 32 | if (is_array($c) && isset($c['configurations'])) { 33 | $newConfig = array_merge($newConfig, $c['configurations']); 34 | } 35 | } 36 | 37 | if (empty($newConfig)) { 38 | echo "No configuration data\n"; 39 | return; 40 | } 41 | 42 | 43 | $redisKey = config('apollo.data_redis_key'); 44 | $this->cache->forever($redisKey, json_encode($newConfig)); 45 | 46 | echo date('c') . ":update success\n"; 47 | } 48 | 49 | /** 50 | * @return ApolloClient 51 | */ 52 | public function getServer() 53 | { 54 | $server = new ApolloClient( 55 | config('apollo.server'), config('apollo.appid'), config('apollo.namespaces')); 56 | $server->save_dir = config('apollo.save_dir'); 57 | return $server; 58 | } 59 | 60 | /** 61 | * @throws \Exception 62 | */ 63 | public function startCallback() 64 | { 65 | $list = glob(config('apollo.save_dir') . DIRECTORY_SEPARATOR . 'apolloConfig.*'); 66 | $this->updateConfig($list); 67 | } 68 | 69 | /** 70 | * @param $connection 71 | * @throws \Exception 72 | */ 73 | public static function useConfig($connection) 74 | { 75 | if (is_null($config = config("database.redis.{$connection}"))) { 76 | throw new \Exception("Redis connection [{$connection}] has not been configured."); 77 | } 78 | 79 | config(['database.redis.apollo' => array_merge($config, [ 80 | 'options' => ['prefix' => config('apollo.prefix') ?: 'apollo:'], 81 | ])]); 82 | } 83 | 84 | } --------------------------------------------------------------------------------