Hyperf方案 服务依赖分析与治理

张开发
2026/4/20 22:04:16 15 分钟阅读

分享文章

Hyperf方案 服务依赖分析与治理
Hyperf 服务依赖分析与治理核心工具链 ┌──────────────┬──────────────────────────────────┐ │ 关注点 │ 方案 │ ├──────────────┼──────────────────────────────────┤ │ 依赖图分析 │ hyperf/tracer(Jaeger)自动生成 │ ├──────────────┼──────────────────────────────────┤ │ 静态分析 │ phpstan/phpstandeptrac │ ├──────────────┼──────────────────────────────────┤ │ 运行时治理 │ 熔断超时重试 │ ├──────────────┼──────────────────────────────────┤ │ 循环依赖检测 │ maglnet/composer-require-checker │ └──────────────┴──────────────────────────────────┘---安装 composer require--dev phpstan/phpstan \ qossmic/deptrac \ maglnet/composer-require-checker composer require hyperf/tracer hyperf/circuit-breaker hyperf/retry---1.Deptrac 依赖规则架构守护 deptrac.yaml parameters:paths:-./app layers:-name:Controller collectors:-type:directory value:app/Controller/.*-name:Service collectors:-type:directory value:app/Service/.*-name:Repository collectors:-type:directory value:app/Repository/.*-name:Model collectors:-type:directory value:app/Model/.*-name:Contract collectors:-type:directory value:app/Contract/.*ruleset:Controller:-Service-Contract Service:-Repository-Contract-Model Repository:-Model # Model 不能依赖任何业务层 Model:~执行检测 # 生成依赖图./vendor/bin/deptrac analyse--formattergraphviz-image--outputdeps.png # CI 检测违规./vendor/bin/deptrac analyse--no-progress---2.PHPStan 静态分析 phpstan.neon parameters:level:8paths:-app ignoreErrors:-#Call to an undefined method Hyperf\\.*#checkMissingIterableValueType:false./vendor/bin/phpstan analyse---3.运行时依赖治理超时重试熔断?php namespace App\Governance;use Hyperf\CircuitBreaker\Annotation\CircuitBreaker;use Hyperf\Retry\Annotation\Retry;/** * 统一治理装饰器所有跨服务调用继承此类 */abstract classGovernedService{// 超时控制protectedfunctionwithTimeout(callable $fn,float $seconds3.0):mixed{$resultnull;$exceptionnull;$cid\Swoole\Coroutine::create(function()use($fn,$result,$exception){try{$result$fn();}catch(\Throwable $e){$exception$e;}});\Swoole\Coroutine::join([$cid],$seconds);if($exception)throw$exception;if($resultnull)thrownew\RuntimeException(Service timeout);return$result;}}?php namespace App\Service;use App\Governance\GovernedService;use App\Contract\OrderServiceInterface;use Hyperf\CircuitBreaker\Annotation\CircuitBreaker;use Hyperf\Retry\Annotation\Retry;classOrderDependencyextendsGovernedService{publicfunction__construct(private OrderServiceInterface $client){}#[Retry(maxAttempts:3,base:100)]#[CircuitBreaker(fallback:[self::class,fallback],attemptThreshold:3,recoveryTimeout:10,)]publicfunctionfind(int $orderId):array{return$this-withTimeout(fn()$this-client-find($orderId),seconds:2.0,);}publicfunctionfallback(int $orderId):array{return[id$orderId,statusunknown,degradedtrue];}}---4.依赖健康矩阵?php namespace App\Governance;use Hyperf\HttpServer\Annotation\Controller;use Hyperf\HttpServer\Annotation\GetMapping;#[Controller(prefix:/internal)]classDependencyController{private array $dependencies[order-servicehttp://order-service/health,payment-servicehttp://payment-service/health,user-servicehttp://user-service/health,mysqlnull,redisnull,kafkanull,];#[GetMapping(path:dependencies)]publicfunctionmatrix():array{$results[];foreach($this-dependencies as $name$url){$results[$name]$url?$this-checkHttp($url):$this-checkLocal($name);}$healthy!in_array(DOWN,array_column($results,status));return[serviceconfig(app_name),status$healthy?UP:DEGRADED,dependencies$results,checked_atmicrotime(true),];}privatefunctioncheckHttp(string $url):array{try{$startmicrotime(true);$response\Hyperf\Support\make(\GuzzleHttp\Client::class)-get($url,[timeout2]);return[status$response-getStatusCode()200?UP:DOWN,latencyround((microtime(true)-$start)*1000).ms,];}catch(\Throwable $e){return[statusDOWN,error$e-getMessage()];}}privatefunctioncheckLocal(string $name):array{try{$startmicrotime(true);match($name){mysql\Hyperf\DbConnection\Db::select(SELECT 1),redis\Hyperf\Support\make(\Hyperf\Redis\Redis::class)-ping(),kafka\Hyperf\Support\make(\Hyperf\Kafka\Producer::class),};return[statusUP,latencyround((microtime(true)-$start)*1000).ms,];}catch(\Throwable $e){return[statusDOWN,error$e-getMessage()];}}}---5.依赖调用追踪自动生成拓扑图?php namespace App\Aspect;use Hyperf\Di\Annotation\Aspect;use Hyperf\Di\Aop\AbstractAspect;use Hyperf\Di\Aop\ProceedingJoinPoint;use Hyperf\Tracer\SpanStarter;#[Aspect]classDependencyTraceAspectextendsAbstractAspect{use SpanStarter;// 追踪所有跨服务调用public array $classes[\App\Governance\GovernedService::class,];publicfunctionprocess(ProceedingJoinPoint $joinPoint):mixed{$classget_class($joinPoint-getInstance());$method$joinPoint-methodName;$span$this-startSpan(dep.{$class}::{$method});$span-setTag(dep.class,$class);$span-setTag(dep.method,$method);try{$result$joinPoint-process();$span-setTag(dep.degraded,$result[degraded]??false);return$result;}catch(\Throwable $e){$span-setTag(error,true);$span-log([message$e-getMessage()]);throw$e;}finally{$span-finish();}}}---6.CI 集成.github/workflows/governance.yml name:Dependency Governance on:[push,pull_request]jobs:analyse:runs-on:ubuntu-latest steps:-uses:actions/checkoutv4-name:PHPStan run:./vendor/bin/phpstan analyse--no-progress-name:Deptrac run:./vendor/bin/deptrac analyse--no-progress--fail-on-uncovered-name:Composer unused check run:./vendor/bin/composer-require-checker check---核心要点-deptrac 在 CI 强制架构分层Controller → Service → Repository → Model 单向依赖-GovernedService 基类统一超时/重试/熔断跨服务调用必须继承-/internal/dependencies 健康矩阵暴露给 Prometheus实时监控依赖状态-Jaeger 自动生成服务拓扑图DependencyTraceAspect AOP 零侵入追踪所有调用

更多文章