本文目录导读:

在Laravel中进行降级响应(Degraded Response)通常有以下几种实现方式:
使用中间件进行降级处理
// app/Http/Middleware/DegradeResponse.php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class DegradeResponse
{
public function handle(Request $request, Closure $next)
{
$response = $next($request);
// 检查是否需要降级
if ($this->shouldDegrade()) {
// 返回降级后的响应
return response()->json([
'status' => 'degraded',
'message' => '服务暂时降级,请稍后重试',
'data' => null
], 200); // 保持200状态码
}
return $response;
}
protected function shouldDegrade(): bool
{
// 判断逻辑:系统负载、服务可用性等
return cache()->get('degraded_mode', false);
}
}
在控制器中返回降级响应
// app/Http/Controllers/ApiController.php
namespace App\Http\Controllers;
use Illuminate\Http\JsonResponse;
class ApiController extends Controller
{
public function getUserData($id): JsonResponse
{
// 检测是否需要降级
if ($this->isSystemDegraded()) {
return $this->degradedResponse('用户服务暂时不可用');
}
try {
$user = User::findOrFail($id);
return response()->json([
'status' => 'success',
'data' => $user
]);
} catch (\Exception $e) {
return $this->degradedResponse('查询用户信息失败');
}
}
protected function degradedResponse(string $message): JsonResponse
{
return response()->json([
'status' => 'degraded',
'message' => $message,
'timestamp' => now()->timestamp
], 200);
}
protected function isSystemDegraded(): bool
{
// 检查系统负载、第三方服务状态等
return system_load_average() > 0.8 ||
app('redis')->exists('system_degraded');
}
}
使用异常处理进行全局降级
// app/Exceptions/Handler.php
namespace App\Exceptions;
use Throwable;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
class Handler extends ExceptionHandler
{
public function render($request, Throwable $e)
{
// 如果是API请求且系统处于降级模式
if ($request->expectsJson() && $this->isDegradedMode()) {
return response()->json([
'status' => 'degraded',
'message' => '系统正在降级运行',
'error' => $e->getMessage()
], 200);
}
return parent::render($request, $e);
}
protected function isDegradedMode(): bool
{
return config('app.degraded_mode', false) ||
app()->runningInConsole() === false;
}
}
使用门面或辅助函数
创建一个全局辅助函数:
// app/helpers.php (记得在composer.json中autoload)
if (!function_exists('degraded_response')) {
function degraded_response($message = '服务降级', $data = null, $status = 200)
{
return response()->json([
'status' => 'degraded',
'message' => $message,
'data' => $data,
'timestamp' => now()->toIso8601String()
], $status);
}
}
使用:
// 在任何控制器或路由中
return degraded_response('数据库连接超时');
降级响应格式化器
// app/Services/DegradedResponse.php
namespace App\Services;
use Illuminate\Http\JsonResponse;
class DegradedResponse
{
protected array $config;
public function __construct()
{
$this->config = config('degraded');
}
public function respond(string $reason = '', array $data = []): JsonResponse
{
$response = [
'status' => 'degraded',
'code' => $this->config['code'] ?? 200,
'message' => $reason ?: ($this->config['message'] ?? 'Service temporarily unavailable'),
'timestamp' => now()->timestamp,
'data' => $data
];
return response()->json($response, $this->config['http_status'] ?? 200);
}
}
注册为服务:
// app/Providers/AppServiceProvider.php
public function register()
{
$this->app->singleton('degraded', function ($app) {
return new \App\Services\DegradedResponse();
});
}
结合缓存和配置管理
// config/degraded.php
return [
'enabled' => env('DEGRADED_MODE', false),
'message' => '系统正在降级运行,部分功能可能不可用',
'http_status' => 200,
'code' => 200,
];
// 在服务提供者中动态控制
use Illuminate\Support\Facades\Cache;
public function boot()
{
// 监听配置变更
Cache::macro('degradedMode', function () {
return Cache::remember('degraded_mode', 60, function () {
return config('degraded.enabled');
});
});
}
完整的降级响应示例
// app/Http/Controllers/ProductController.php
namespace App\Http\Controllers;
use App\Services\DegradedResponse;
use Illuminate\Http\JsonResponse;
class ProductController extends Controller
{
public function __construct(
protected DegradedResponse $degradedResponse
) {}
public function index(): JsonResponse
{
// 检查数据库连接
if (!app('db')->connection()->getPdo()) {
return $this->degradedResponse->respond('数据库连接异常');
}
// 检查Redis缓存
if (!app('redis')->ping()) {
return $this->degradedResponse->respond('缓存服务异常');
}
// 正常业务逻辑
try {
$products = Product::paginate(20);
return response()->json([
'status' => 'success',
'data' => $products
]);
} catch (\Exception $e) {
// 数据库降级:从备份或缓存返回数据
$products = Cache::get('products_cache', []);
return $this->degradedResponse->respond('使用备用数据', $products);
}
}
}
路由级别的降级控制
// routes/api.php
use Illuminate\Support\Facades\Route;
Route::middleware(['degraded'])->group(function () {
Route::get('/users', 'UserController@index');
Route::get('/products', 'ProductController@index');
});
// 或者在全局中间件中
Route::middleware(['api', 'degraded'])->group(function () {
require base_path('routes/api.php');
});
降级响应最佳实践:
- 保持HTTP状态码200:降级不代表错误,保持客户端正常接收
- 明确的状态标识:让客户端知道这是降级响应
- 合理的时间戳:帮助调试和监控
- 详细的原因说明:提供降级原因供开发者定位问题
- 备用数据:尽可能提供备用的缓存数据