leyton / laravel-circuit-breaker
Laravel 实现断路器模式
1.0
2024-05-17 08:58 UTC
Requires
- php: ^8.0
- illuminate/support: ~8|~9|~10
README
断路器模式对于确保软件的健壮性至关重要。它阻止故障扩散,即使在服务遇到问题时也能保持操作稳定性。通过提供视觉反馈和改进用户体验,它使应用程序运行顺畅。此外,它简化了维护和故障排除,使问题解决更快。总的来说,集成断路器模式对于提高可靠性和用户满意度至关重要。
您可以在以下链接中找到更多关于此模式的详细信息 断路器模式
安装
composer require leyton/laravel-circuit-breaker
安装后,请确保发布资源
php artisan vendor:publish --provider="Leyton\LaravelCircuitBreaker\LaravelCircuitBreakerServiceProvider"
您将在 config/circuit-breaker.php
文件中找到所有需要的配置。
<?php return [ 'threshold' => 10, // number of trials to pass from half-open to closed/open and from closed to half-open 'available_after_seconds' => 10, // the seconds it takes while in the open status 'driver' => 'redis', // the cache store driver ];
使用
该包为您提供了一个简单的 API 来使用。
<?php use Leyton\LaravelCircuitBreaker\Circuit; use Leyton\LaravelCircuitBreaker\Exceptions\RequestFailedException; function goToGoogle(){ try{ $response = Http::get("https://gooogle.com"); if($response->status() === 500){ throw new RequestFailedException(); } return "all is good"; }catch(\Exception $exception){ throw new RequestFailedException(); } } // The Circuit is resolved out of the service container $circuit = app()->make(Circuit::class); //The run method expects the service name and the function that wraps the service //It should throw the RequestFailedException when the service is not responding as expected $packet = $circuit->run("go-to-google", fn() => goToGoogle());
包对象持有回调的结果和服务的状态
Leyton\LaravelCircuitBreaker\Transporters\Packet {#2939 +result: "all is good", +status: Leyton\LaravelCircuitBreaker\CircuitStatus {#2943 +name: "CLOSED", +value: "closed", }, +success: true, }
此模式的一个优点是防止系统在存在多个事务时执行不必要的操作。以下是使用示例
<?php namespace App\Http\Controllers; use Leyton\LaravelCircuitBreaker\Circuit; use App\Services\LocationServiceClient; use App\Services\PaymentGatewayClient; use Illuminate\Http\Request; use Exception; class MakeOrderController extends Controller { public function __construct( protected LocationServiceClient $locationServiceClient, protected PaymentGatewayClient $paymentGatewayClient, protected Circuit $Circuit, ) { } public function __invoke(Request $request) { $location = $request->get('location'); $paymentDetails = $request->get('payment_details'); $client = $request->get('client'); if(!$this->circuit->available(['location-service', 'payment-service'])){ return response()->json([ 'message' => 'Services are un-available, please retry later' ]); } $withdrawalPoint = $this->circuit->run("location-service", fn() => $this->locationServiceClient->getNearWithdrawalPoint($location)); $payment = $this->circuit->run( "payment-service", fn() => $this->paymentGatewayClient->processPayment($client, $order, $withdrawalPoint->result) ); // ... return response()->json($data); } }