diff --git a/.env.example b/.env.example index 862a20f..518c037 100644 --- a/.env.example +++ b/.env.example @@ -39,5 +39,10 @@ ALIPAY_APP_ID= FORUM_BASEURL=https://forum.laecloud.com +# 实例类型,如果是备用节点,需要设置为 backup。否则设置为 primary +INSTANCE_TYPE=primary + +# 实例地址,留空会自动获取 IP。 +INSTANCE_ADDRESS= SOKETI_DEBUG=0 diff --git a/app/Console/Commands/Check.php b/app/Console/Commands/Check.php new file mode 100644 index 0000000..442ab4a --- /dev/null +++ b/app/Console/Commands/Check.php @@ -0,0 +1,129 @@ +warn('检查服务可用性'); + + // 检查是否可以连接到数据库 + try { + DB::connection()->getPdo(); + $this->info('数据库连接正常'); + } catch (\Exception $e) { + $this->error($e->getMessage()); + } + + // 检测是否可以连接到 Redis + try { + $redis = app('redis'); + $redis->ping(); + $this->info('Redis 连接正常'); + } catch (\Exception $e) { + $this->error($e->getMessage()); + } + + if (config('app.instance_address')) { + $addr = $this->info('当前实例地址: ' . config('app.instance_address')); + } else { + $this->info('正在获取公网 IP'); + // get public ip + $addr = file_get_contents('https://ifconfig.me/ip'); + $this->warn('公网 IP: ' . $addr); + } + $port = config('laravels.listen_port'); + $type = config('app.instance_type'); + + + $this->info('正在准备节点'); + $instance_id = config('app.instance_id'); + + // 检测其他 莱云 计算节点 + $nodes = Cache::get('nodes', collect([])); + + // 检测节点是否在集合里 + $node = $nodes->where('instance_id', $instance_id)->first(); + + if ($node == null) { + $this->warn('节点未注册'); + $this->info('正在注册节点'); + + // add to collect + $nodes->push([ + 'instance_id' => $instance_id, + 'ip' => $addr, + 'port' => $port, + 'type' => $type, + ]); + + $this->info('节点注册成功'); + } else { + $this->info('节点已注册'); + + // 如果 IP 不同,则更新 IP + if ($node['ip'] != $addr) { + $this->info('正在更新节点 IP'); + $node['ip'] = $addr; + $this->info('节点 IP 更新成功'); + } + + $node['port'] = $port; + } + + // save cache + Cache::forever('nodes', $nodes); + + + + // 检测模块是否正常 + // Module::chunk(100, function ($modules) { + // foreach ($modules as $module) { + // $this->info('检测模块 ' . $module->name); + // if($module->check()) { + // $this->warn('模块 ' . $module->name . ' 正常'); + // } else { + // $this->error('模块 ' . $module->name . ' 异常'); + // } + // } + // }); + } +} diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 9a10571..0d7452c 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -4,6 +4,7 @@ use App\Console\Commands\BanUser; use App\Console\Commands\CalcModule; +use App\Console\Commands\Check; use App\Console\Commands\Count; use App\Console\Commands\GetUser; use App\Console\Commands\ReduceBalance; @@ -39,6 +40,7 @@ class Kernel extends ConsoleKernel ReduceBalance::class, Count::class, Status::class, + Check::class, Commands\System\Down::class, Commands\System\Up::class, ]; diff --git a/app/Helpers.php b/app/Helpers.php index 06af366..2483603 100644 --- a/app/Helpers.php +++ b/app/Helpers.php @@ -7,3 +7,16 @@ function now($timezone = null) { return Carbon::now($timezone); } + + +// function nodes() +// { +// return Cache::remember('nodes', 60, function () { + +// $collection = collect(['taylor', 'abigail', null])->map(function ($name) { +// return strtoupper($name); +// })->reject(function ($name) { +// return empty($name); +// }); +// }); +// } diff --git a/app/Models/Module/Module.php b/app/Models/Module/Module.php index 81c686d..e8f3d52 100644 --- a/app/Models/Module/Module.php +++ b/app/Models/Module/Module.php @@ -3,11 +3,13 @@ namespace App\Models\Module; use Illuminate\Support\Str; +use Illuminate\Support\Facades\Log; use Illuminate\Auth\Authenticatable; use Illuminate\Support\Facades\Http; use Laravel\Lumen\Auth\Authorizable; use Illuminate\Support\Facades\Cache; use Illuminate\Database\Eloquent\Model; +use GuzzleHttp\Exception\ConnectException; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract; use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract; @@ -130,6 +132,29 @@ public function remotePost($path = '', $data = []) return [$json, $status]; } + public function check($module_id = null) + { + if ($module_id) { + $module = Module::find($module_id); + } else { + $module = $this; + } + + try { + $http = Http::remote($module->api_token, $module->url); + // dd($module->url); + $response = $http->get('remote'); + } catch (ConnectException $e) { + Log::error($e->getMessage()); + } + + if ($response->status() == 200) { + return true; + } else { + return false; + } + } + // get cached modules public static function cached_modules() diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index d5001a0..6ba472d 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -2,12 +2,14 @@ namespace App\Providers; -use Illuminate\Support\ServiceProvider; -use Alipay\EasySDK\Kernel\Config as AlipayConfig; -use Alipay\EasySDK\Kernel\Factory as AlipayFactory; +use Dotenv\Dotenv; +use Illuminate\Support\Facades\App; use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Storage; +use Illuminate\Support\ServiceProvider; use EasyWeChat\Pay\Application as WePay; +use Alipay\EasySDK\Kernel\Config as AlipayConfig; +use Alipay\EasySDK\Kernel\Factory as AlipayFactory; class AppServiceProvider extends ServiceProvider { @@ -25,6 +27,7 @@ public function register() public function boot() { + $this->generateInstanceId(); // // header('server: Cluster Ready!'); @@ -112,4 +115,23 @@ private function alipayOptions() return $options; } + + + public function generateInstanceId() + { + if (config('app.instance_id') == null) { + $instance_id = md5(uniqid()); + + // 获取 .env 目录 + $env_path = dirname(__DIR__) . '/../.env'; + + // 追加到 .env 文件 + file_put_contents($env_path, PHP_EOL . "INSTANCE_ID={$instance_id}", FILE_APPEND); + + // $env = file_get_contents(app()->environmentFilePath()); + // $env = preg_replace('/INSTANCE_ID=(.*)/', 'INSTANCE_ID=' . $instance_id, $env); + // file_put_contents(app()->environmentFilePath(), $env); + + } + } } diff --git a/config/app.php b/config/app.php index 7436101..a504b5d 100644 --- a/config/app.php +++ b/config/app.php @@ -108,4 +108,10 @@ 'cipher' => 'AES-256-CBC', + 'instance_id' => env('INSTANCE_ID', null), + + 'instance_type' => env('INSTANCE_TYPE', 'primary'), + + 'instance_address' => env('INSTANCE_address', null), + ];