xincheng / launcher
There is no license information available for the latest version (v1.0.17) of this package.
v1.0.17
2024-07-16 08:18 UTC
Requires
- ext-json: *
- alibabacloud/mse-20190531: ^6.6
- guzzlehttp/guzzle: ^6.5 || ^7.0
Requires (Dev)
- phpunit/phpunit: ^8.5.29 || ^9.5.23
README
Launcher - 基于http协议的服务调用
目前支持 基于http协议的服务调用和基于nacos注册的服务调用,由于目前项目非常驻内存运行方式,所以无法将现有项目注册到nacos,仅实现通过名称自动路由nacos注册服务。可实现 php、java之前的互相调用以实现架构的灵活扩展
安装
composer require xincheng/launcher
基础配置
项目编写时作者考虑到工程框架的多样性,故没有直接引入Yii Competent方式作为Yii扩展,而是以composer package方式组织,所以需要在项目进行初始化
配置如下:
<?php return [ # 设置代理类,用于初始化launcher 'class' => common\launcher\LauncherDelegate::class, # 配置信息 'properties' => [ # 服务列表 'services' => [ # http 服务示例 [ # 服务名称 'name' => 'xxx', # 目标服务器,可配置多个地址,目前根据随机策略方式进行访问 'target' => ['http://xxx.xxx.xxx.xxx'], # 类型 目前仅支持 http nacos两种类型 'type' => 'http' ], [ 'name' => 'xxx', # nacos 由于自动根据配置路由所以无需填写target,默认空数组即可 'target' => [], 'type' => 'nacos' ] ], # nacos配置信息 'nacos' => [ # nacos host设置 'host' => 'xxx.xxx.xxx.xxx:8848', # nacos 用户名 'username' => 'nacos', # nacos 密码 'password' => 'xxxx', # nacos group 'groupName' => 'DEFAULT_GROUP', #nacos namespace 'namespaceId' => 'xxxx', ], #熔断器配置 只支持redis适配器 需要安装redis拓展 'circuitbreaker'=>[ # 开启 true 关闭 false 'open' => true, # 设置失败率阈值为50%,当请求的失败率超过这个百分比时,熔断器的状态会切换到OPEN 'failureRateThreshold'=> 50, //设置从 OPEN 状态到 HALF_OPEN 状态的转换间隔为5秒。在 HALF_OPEN 状态下,熔断器会允许一定数量的请求尝试通过,以检测服务是否已经恢复正常。 'intervalToHalfOpen'=> 5, #设置最小请求数为10,这是检测失败的最小请求次数。即使失败率超过了阈值,如果请求次数低于这个最小值,熔断器仍然保持 CLOSED 状态 'minimumRequests'=> 10, //设置时间窗口为60秒,这是用来评估失败率阈值的时间间隔 'timeWindow'=> 60 ] ], ];
在Yii中初始化 仅做参考
<?php namespace common\launcher; use Yii; use yii\base\Component; use Xincheng\Launcher\Launcher; use yii\base\InvalidConfigException; /** * LauncherDelegate * * @author: morgan * @slice : 2023-06-20 15:56:27 */ class LauncherDelegate extends Component { /** * @var array 配置属性 */ public array $properties = []; /** * @var Launcher 服务调用实例 */ private Launcher $launcher; /** * 初始化 * * @return void */ public function init() { $launcherCache = new LauncherCache() $this->launcher = new Launcher($this->properties,$launcherCache); $this->launcher->setCache($launcherCache); } /** * 执行调用 * * @throws InvalidConfigException */ public function run($request, array $params = [], array $options = []) { $request = Yii::createObject($request); $request->params = $params; $request->options = $options; return $this->launcher->run($request); } }
缓存配置
通过实现CacheInterface接口实现Launcher缓存
<?php namespace common\launcher; use Xincheng\Launcher\CacheInterface; use Yii; /** * LauncherCache * * @author: morgan * @slice : 2023-06-27 10:44:14 */ class LauncherCache implements CacheInterface { /** * 是否存在key * * @param string $key * @return bool */ public function hasKey(string $key): bool { return Yii::$app->cache->get($key) !== false; } /** * 设置缓存 * * @param string $key key * @param mixed $value 值 * @param int $duration 有效期(秒) * @return void */ public function set(string $key, $value, int $duration) { Yii::$app->cache->set($key, $value, $duration); } /** * 获取缓存 * * @param string $key * @return mixed */ public function get(string $key) { return Yii::$app->cache->get($key); } /** * 删除缓存 * * @param string $key key * @return void */ public function del(string $key) { Yii::$app->cache->delete($key); } /** * 配置redis 服务熔断使用redis适配器 * */ public function getRedis() { $redisConfig = \Yii::$app->components['redis']; $redis = new \Redis(); $redis->connect($redisConfig['hostname'],$redisConfig['port']); $redis->auth($redisConfig['password']); return $redis; } }
编写第一个请求
请求分为web请求和console请求
web请求
只需要继承WebBaseRequest
实现接口方法即可
- server 配置中的服务名称
- router 路由,目标服务的路由从host后面开始 如 https://www.baidu.com/hello/world 这里填写 /hello/world即可
- method 请求类型 http所有请求类型都支持,项目使用guzzle作为请求客户端
- options 可以自定义头信息、post请求body...具体参数查看guzzle文档
- before 可在请求发送前用户自定义设置,可以理解为hook
<?php namespace common\launcher\request; use Xincheng\Launcher\Request\WebBaseRequest; /** * DirectRequest * * @author: morgan * @slice : 2023-06-27 09:42:40 */ class DirectRequest extends WebBaseRequest { public function server(): string { return 'xc_goods'; } public function router(): string { return '/test.php'; } public function method(): string { return 'GET'; } /** * 是否需要服务降级处理 */ public function isCircuitBreakerProcess():bool { return true; } /** * 有降级服务需完成这个方法 */ public function fallback(): \Psr\Http\Message\ResponseInterface { } }
console发起请求
继承 ConsoleBaseRequest
即可,其他和Web一致
控制器基类鉴权控制
如 BaseController
因为后面的所有外部请求经统一网关,所以内部系统之前不必进行鉴权,http头信息中也携带了用户信息
public function init(){ //... code //仅在 x-platform 不存在或 x-platform 等于 web 时进行授权认证 if (!isset($_SERVER['HTTP_X_PLATFORM']) || $_SERVER['HTTP_X_PLATFORM'] === Constants::PLATFORM_WEB) { // 此处的鉴权其实是非必须的,统一网关解析token后会在请求中添加 x-tenant-id、x-user-id、x-request-id、x-platform // 可直接通过请求头获取即可 $login = XcAuth::login(); $login->isLogin(); define('UID', 2); define("UID_NAME", 'dev'); defined('TENANT_ID') or define('TENANT_ID', $login->getTenantId()); defined('USER_ID') or define('USER_ID', $login->getUserId()); } }
调用
$body = Yii::$app->launcher->run(NacosRequest::class); echo $body->getBody();