一、性能优化体系
1. OPcache深度配置
; php.ini 生产环境优化配置
[opcache]
opcache.enable=1
opcache.enable_cli=1
opcache.memory_consumption=512
opcache.interned_strings_buffer=32
opcache.max_accelerated_files=20000
opcache.revalidate_freq=0
opcache.validate_timestamps=0 ; 生产环境关闭
opcache.consistency_checks=0
opcache.huge_code_pages=1
opcache.save_comments=0
opcache.file_cache="/tmp/opcache"
opcache.file_cache_only=0
opcache.file_cache_consistency_checks=1
; Swoole OPcache增强
opcache.preload=/var/www/weiai/app/preload.php
opcache.preload_user=www-data
; 监控配置
opcache.error_log=/var/log/php/opcache.log
opcache.opt_debug_level=0
2. Composer自动加载优化
// composer.json 优化配置
{
"config": {
"optimize-autoloader": true,
"classmap-authoritative": true,
"apcu-autoloader": true,
"platform": {
"php": "8.2",
"ext-redis": "*",
"ext-swoole": "*"
},
"sort-packages": true
},
"scripts": {
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"@php artisan package:discover --ansi"
],
"post-install-cmd": [
"@php artisan optimize:clear",
"@php artisan config:cache",
"@php artisan route:cache",
"@php artisan view:cache",
"@php artisan event:cache",
"chmod -R 755 storage bootstrap/cache"
],
"post-update-cmd": [
"@php artisan vendor:publish --tag=laravel-assets --ansi --force"
]
},
"require": {
"php": "^8.2",
"laravel/framework": "^10.0",
"laravel/sanctum": "^3.2",
"laravel/telescope": "^4.0",
"laravel/octane": "^2.0",
"swoole/ide-helper": "@dev",
"ext-swoole": "*",
"ext-redis": "*",
"ext-opcache": "*"
},
"autoload": {
"psr-4": {
"App\\": "app/",
"Database\\Factories\\": "database/factories/",
"Database\\Seeders\\": "database/seeders/"
},
"classmap": [
"app/Helpers",
"app/Services"
],
"exclude-from-classmap": [
"**/tests/",
"**/node_modules/"
]
}
}
3. Laravel Octane + Swoole配置
// config/octane.php
return [
'server' => 'swoole',
'swoole' => [
'options' => [
// 监狱通信高并发优化
'worker_num' => swoole_cpu_num() * 2,
'task_worker_num' => swoole_cpu_num(),
'max_request' => 1000,
'dispatch_mode' => 2,
'enable_coroutine' => true,
'max_coroutine' => 30000,
// 内存优化
'buffer_output_size' => 32 * 1024 * 1024,
'socket_buffer_size' => 128 * 1024 * 1024,
'package_max_length' => 20 * 1024 * 1024,
// 连接池
'max_conn' => 10000,
'heartbeat_check_interval' => 60,
'heartbeat_idle_time' => 600,
// 安全配置
'open_http2_protocol' => true,
'ssl_cert_file' => env('SSL_CERT_PATH'),
'ssl_key_file' => env('SSL_KEY_PATH'),
'open_http_protocol' => true,
],
'listeners' => [
[
'host' => '0.0.0.0',
'port' => 8000,
'type' => \Laravel\Octane\Swoole\Server::LISTENER_HTTP,
'socket' => \Laravel\Octane\Swoole\Server::SOCKET_TCP,
'settings' => [
'open_websocket_protocol' => true,
],
],
],
'warm' => [
'app',
'config',
'views',
'files',
],
'tables' => [
'sessions:10000' => [
'size' => 10000,
'columns' => [
['name' => 'value', 'type' => \Swoole\Table::TYPE_STRING, 'size' => 2048],
['name' => 'timestamp', 'type' => \Swoole\Table::TYPE_INT, 'size' => 8],
],
],
'prison_cache:50000' => [
'size' => 50000,
'columns' => [
['name' => 'value', 'type' => \Swoole\Table::TYPE_STRING, 'size' => 65535],
['name' => 'expire', 'type' => \Swoole\Table::TYPE_INT, 'size' => 8],
],
],
],
],
'cache' => [
'rows' => 1000,
'gc' => 86400,
],
'watch' => [
'app',
'bootstrap',
'config',
'database',
'public',
'resources',
'routes',
'storage',
],
];
// 预加载脚本
// bootstrap/preload.php
<?php
$preload = [
__DIR__.'/../vendor/autoload.php',
__DIR__.'/../app/Providers/AppServiceProvider.php',
__DIR__.'/../app/Providers/RouteServiceProvider.php',
__DIR__.'/../app/Http/Kernel.php',
];
foreach ($preload as $file) {
if (file_exists($file)) {
require_once $file;
}
}
// 预热服务容器
$app = require_once __DIR__.'/../bootstrap/app.php';
$app->make(\Illuminate\Contracts\Console\Kernel::class)->bootstrap();
// 预热常用类
$classesToWarm = [
\Illuminate\Support\Facades\Cache::class,
\Illuminate\Support\Facades\DB::class,
\Illuminate\Support\Facades\Redis::class,
\Illuminate\Support\Facades\Log::class,
];
foreach ($classesToWarm as $class) {
class_exists($class);
}
二、数据库优化
1. Laravel数据库连接池
// app/Providers/AppServiceProvider.php
public function register()
{
// 数据库连接池
$this->app->singleton('db.connection.mysql', function ($app) {
$factory = new \Illuminate\Database\Connectors\ConnectionFactory($app);
$config = $app['config']['database.connections.mysql'];
// 连接池配置
$config['options'] = [
\PDO::ATTR_PERSISTENT => true,
\PDO::ATTR_TIMEOUT => 5,
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
\PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8mb4' COLLATE 'utf8mb4_unicode_ci'",
\PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true,
\PDO::MYSQL_ATTR_COMPRESS => true,
\PDO::MYSQL_ATTR_LOCAL_INFILE => true,
\PDO::MYSQL_ATTR_FOUND_ROWS => true,
];
// 启用连接池
if (extension_loaded('swoole')) {
$config['pool'] = [
'min_connections' => 10,
'max_connections' => 100,
'connect_timeout' => 3.0,
'wait_timeout' => 5.0,
'heartbeat' => -1,
'max_idle_time' => 60.0,
];
}
return $factory->make($config, 'mysql');
});
// 查询监听器
DB::listen(function ($query) {
if ($query->time > 100) { // 超过100ms的慢查询
Log::channel('slow-query')->warning('Slow query detected', [
'sql' => $query->sql,
'bindings' => $query->bindings,
'time' => $query->time,
'connection' => $query->connectionName,
]);
}
});
}
// config/database.php 优化配置
'mysql' => [
'driver' => 'mysql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
'engine' => 'InnoDB',
'options' => extension_loaded('pdo_mysql') ? array_filter([
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
PDO::MYSQL_ATTR_INIT_COMMAND => "SET SESSION sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'",
PDO::ATTR_PERSISTENT => false, // Swoole连接池时设为false
PDO::ATTR_TIMEOUT => 5,
PDO::ATTR_EMULATE_PREPARES => false, // 禁用模拟预处理
PDO::ATTR_STRINGIFY_FETCHES => false,
]) : [],
// 读写分离配置
'read' => [
'host' => [
env('DB_READ_HOST', '127.0.0.1'),
],
'port' => env('DB_READ_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
],
'write' => [
'host' => [
env('DB_WRITE_HOST', '127.0.0.1'),
],
'port' => env('DB_WRITE_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
],
'sticky' => true, // 写后读主库
// 连接池配置(使用Swoole时)
'pool' => [
'min_connections' => 10,
'max_connections' => 100,
'connect_timeout' => 3.0,
'wait_timeout' => 5.0,
'heartbeat' => -1,
'max_idle_time' => 60.0,
],
],
2. 查询优化服务
php
// app/Services/QueryOptimizer.php
class QueryOptimizer
{
private $cache;
private $queryLogger;
public function __construct()
{
$this->cache = app('cache.store');
$this->queryLogger = new QueryLogger();
}
/**
* 智能查询构建器
*/
public function buildOptimizedQuery($model, array $params)
{
$query = $model::query();
// 1. 字段选择优化
$this->selectOnlyNeeded($query, $params['fields'] ?? []);
// 2. 关联预加载优化
$this->optimizeWith($query, $params['with'] ?? []);
// 3. 条件优化
$this->optimizeConditions($query, $params['where'] ?? []);
// 4. 分页优化
if (isset($params['page'])) {
$this->optimizePagination($query, $params['page'], $params['per_page'] ?? 15);
}
// 5. 缓存策略
return $this->applyCacheStrategy($query, $params['cache'] ?? false);
}
private function selectOnlyNeeded($query, $fields)
{
if (!empty($fields)) {
$query->select($fields);
} else {
// 默认排除大字段
$model = $query->getModel();
if (method_exists($model, 'getExcludedFields')) {
$excluded = $model->getExcludedFields();
$allFields = \Schema::getColumnListing($model->getTable());
$selected = array_diff($allFields, $excluded);
$query->select($selected);
}
}
}
private function optimizeWith($query, $relations)
{
foreach ($relations as $relation => $callback) {
if (is_callable($callback)) {
// 嵌套预加载优化
$query->with([
$relation => function ($q) use ($callback) {
$callback($q);
$this->selectOnlyNeeded($q, []);
}
]);
} else {
$query->with($relation);
}
}
}
private function optimizeConditions($query, $conditions)
{
foreach ($conditions as $field => $value) {
if (str_contains($field, '.')) {
// 关联条件优化
$this->addRelationCondition($query, $field, $value);
} else {
// 索引优化检查
$this->checkIndexUsage($query, $field, $value);
}
}
}
private function optimizePagination($query, $page, $perPage)
{
// 使用更快的分页方法
if ($page == 1) {
// 第一页使用简单分页
return $query->simplePaginate($perPage);
}
// 使用游标分页优化大表
if ($this->shouldUseCursorPagination($query)) {
return $query->cursorPaginate($perPage);
}
return $query->paginate($perPage);
}
private function applyCacheStrategy($query, $cacheConfig)
{
if (!$cacheConfig) {
return $query;
}
$cacheKey = $this->generateCacheKey($query);
$ttl = $cacheConfig['ttl'] ?? 300;
// 使用记忆化缓存
return Cache::remember($cacheKey, $ttl, function () use ($query) {
return $query->get();
});
}
/**
* 批量插入优化(监狱信件批量处理)
*/
public function batchInsert($table, array $data, $chunkSize = 1000)
{
// 使用事务
DB::beginTransaction();
try {
$chunks = array_chunk($data, $chunkSize);
foreach ($chunks as $chunk) {
// 使用原生插入优化速度
$sql = $this->buildBatchInsertSql($table, $chunk);
DB::insert($sql);
// 每批提交后释放内存
if (memory_get_usage() > 100 * 1024 * 1024) { // 100MB
DB::commit();
DB::beginTransaction();
}
}
DB::commit();
} catch (\Exception $e) {
DB::rollBack();
throw $e;
}
}
private function buildBatchInsertSql($table, $data)
{
if (empty($data)) {
return '';
}
$columns = array_keys($data[0]);
$values = [];
foreach ($data as $row) {
$escapedValues = array_map(function ($value) {
return DB::connection()->getPdo()->quote($value);
}, array_values($row));
$values[] = '(' . implode(', ', $escapedValues) . ')';
}
$columnsStr = '`' . implode('`, `', $columns) . '`';
$valuesStr = implode(', ', $values);
return "INSERT INTO `{$table}` ({$columnsStr}) VALUES {$valuesStr}";
}
}
三、缓存策略优化
1. Redis多级缓存
php
// config/cache.php
return [
'default' => env('CACHE_DRIVER', 'redis'),
'stores' => [
'redis' => [
'driver' => 'redis',
'connection' => 'cache',
'lock_connection' => 'default',
'client' => env('REDIS_CLIENT', 'phpredis'),
'options' => [
'cluster' => env('REDIS_CLUSTER', 'redis'),
'prefix' => env('REDIS_PREFIX', 'weiai_cache:'),
'persistent' => true,
'serializer' => \Redis::SERIALIZER_IGBINARY,
'compression' => \Redis::COMPRESSION_LZF,
'read_timeout' => 2,
'connect_timeout' => 2,
],
],
// 监狱数据专用缓存
'prison_data' => [
'driver' => 'redis',
'connection' => 'prison',
'prefix' => 'prison:',
'ttl' => 3600, // 1小时
],
// 用户会话缓存
'user_sessions' => [
'driver' => 'redis',
'connection' => 'sessions',
'prefix' => 'session:',
'ttl' => 86400, // 24小时
],
// 信件内容缓存(大内容优化)
'letter_content' => [
'driver' => 'redis',
'connection' => 'letters',
'prefix' => 'letter:',
'serializer' => \Redis::SERIALIZER_IGBINARY,
'compression' => \Redis::COMPRESSION_LZ4,
'ttl' => 1800, // 30分钟
],
],
'prefix' => env('CACHE_PREFIX', 'weiai_'),
// 缓存预热配置
'preheat' => [
'enabled' => true,
'patterns' => [
'config:*',
'routes:*',
'views:*',
'prison:list:*',
],
],
];
// app/Services/CacheService.php
class CacheService
{
private $redis;
private $localCache = [];
public function __construct()
{
$this->redis = Redis::connection('cache')->client();
}
/**
* 三级缓存:内存 -> Redis -> 数据库
*/
public function getWithMultiLevel($key, $callback, $ttl = 300)
{
// 1. 检查本地内存缓存(Swoole Table)
if (isset($this->localCache[$key])) {
$data = $this->localCache[$key];
if ($data['expire'] > time()) {
return $data['value'];
}
unset($this->localCache[$key]);
}
// 2. 检查Redis缓存
$cached = $this->redis->get($key);
if ($cached !== false) {
$data = unserialize($cached);
// 存入本地缓存
$this->localCache[$key] = [
'value' => $data,
'expire' => time() + 60, // 本地缓存60秒
];
return $data;
}
// 3. 从数据库获取
$data = $callback();
// 4. 存入缓存
$this->redis->setex($key, $ttl, serialize($data));
// 5. 存入本地缓存
$this->localCache[$key] = [
'value' => $data,
'expire' => time() + 60,
];
return $data;
}
/**
* 批量缓存获取(监狱信件列表优化)
*/
public function mget(array $keys, $callback = null)
{
// 使用pipeline减少网络开销
$pipeline = $this->redis->pipeline();
foreach ($keys as $key) {
$pipeline->get($key);
}
$results = $pipeline->exec();
$missingKeys = [];
$data = [];
foreach ($keys as $index => $key) {
if ($results[$index] !== false) {
$data[$key] = unserialize($results[$index]);
} else {
$missingKeys[] = $key;
}
}
// 如果有缺失,从数据库获取
if (!empty($missingKeys) && $callback) {
$missingData = $callback($missingKeys);
// 批量设置缓存
$pipeline = $this->redis->pipeline();
foreach ($missingData as $key => $value) {
$pipeline->setex($key, 300, serialize($value));
$data[$key] = $value;
}
$pipeline->exec();
}
return $data;
}
/**
* 缓存预热(系统启动时执行)
*/
public function warmUp()
{
$patterns = [
'config:*',
'routes:*',
'views:*',
'prison:metadata:*',
'user:permissions:*',
];
foreach ($patterns as $pattern) {
$keys = $this->redis->keys($pattern);
if (!empty($keys)) {
$this->redis->mget($keys);
}
}
// 预加载监狱列表
$prisons = Prison::select(['id', 'code', 'name', 'province'])->get();
foreach ($prisons as $prison) {
$key = "prison:{$prison->id}:basic";
$this->redis->setex($key, 3600, serialize($prison));
}
}
/**
* 缓存雪崩防护
*/
public function getWithMutex($key, $callback, $ttl = 300)
{
$lockKey = "lock:{$key}";
// 尝试获取缓存
$data = $this->redis->get($key);
if ($data !== false) {
return unserialize($data);
}
// 尝试获取分布式锁
$lock = $this->redis->set($lockKey, 1, ['NX', 'EX' => 5]);
if ($lock) {
// 获取到锁,执行回调
$data = $callback();
$this->redis->setex($key, $ttl, serialize($data));
$this->redis->del($lockKey);
} else {
// 等待其他进程生成缓存
usleep(100000); // 100ms
// 最多重试3次
for ($i = 0; $i < 3; $i++) {
$data = $this->redis->get($key);
if ($data !== false) {
return unserialize($data);
}
usleep(50000); // 50ms
}
// 最终降级:直接执行回调
$data = $callback();
}
return $data;
}
}
四、安全加固优化
1. 请求验证优化
php
// app/Http/Middleware/SecurityHeaders.php
class SecurityHeaders
{
public function handle($request, Closure $next)
{
$response = $next($request);
// 安全头部
$headers = [
'X-Frame-Options' => 'DENY',
'X-Content-Type-Options' => 'nosniff',
'X-XSS-Protection' => '1; mode=block',
'Referrer-Policy' => 'strict-origin-when-cross-origin',
'Content-Security-Policy' => $this->buildCSP(),
'Permissions-Policy' => 'geolocation=(), microphone=(), camera=()',
'Strict-Transport-Security' => 'max-age=31536000; includeSubDomains',
'X-Permitted-Cross-Domain-Policies' => 'none',
'Cache-Control' => 'no-store, no-cache, must-revalidate',
];
foreach ($headers as $key => $value) {
$response->header($key, $value);
}
// 监狱通信特定安全头
if ($request->is('api/prison/*')) {
$response->header('X-Judicial-Security', 'level-3');
$response->header('X-Content-Encryption', 'AES-256-GCM');
}
return $response;
}
private function buildCSP()
{
return implode('; ', [
"default-src 'self'",
"script-src 'self' 'unsafe-inline' https://static.weiai.tech",
"style-src 'self' 'unsafe-inline'",
"img-src 'self' data: https://img.weiai.tech",
"font-src 'self'",
"connect-src 'self' https://api.postal.gov",
"frame-src 'none'",
"object-src 'none'",
"media-src 'self'",
"worker-src 'self'",
]);
}
}
// app/Http/Middleware/RateLimit.php
class RateLimit
{
public function handle($request, Closure $next)
{
$key = 'rate_limit:' . $request->ip() . ':' . $request->path();
// 使用Redis滑动窗口限流
$current = Redis::connection('rate_limit')->zcount($key, time() - 60, time());
if ($current > $this->getLimit($request)) {
return response()->json([
'error' => '请求过于频繁',
'retry_after' => Redis::connection('rate_limit')->zmin($key) + 60 - time()
], 429);
}
// 记录请求
Redis::connection('rate_limit')->zadd($key, time(), microtime(true));
// 清理过期记录
Redis::connection('rate_limit')->zremrangebyscore($key, 0, time() - 60);
return $next($request);
}
private function getLimit($request)
{
// 监狱接口特殊限流
if ($request->is('api/prison/*')) {
return 30; // 30次/分钟
}
// 信件上传接口
if ($request->is('api/letter/upload')) {
return 10; // 10次/分钟
}
return 60; // 默认60次/分钟
}
}
2. SQL注入防护增强
php
// app/Providers/AppServiceProvider.php
public function boot()
{
// 全局SQL监控
DB::listen(function ($query) {
$this->detectSqlInjection($query);
});
}
private function detectSqlInjection($query)
{
$sql = strtolower($query->sql);
$bindings = $query->bindings;
$dangerousPatterns = [
'/union.*select/i',
'/sleep\s*\(/i',
'/benchmark\s*\(/i',
'/load_file\s*\(/i',
'/into\s+outfile/i',
'/into\s+dumpfile/i',
];
foreach ($dangerousPatterns as $pattern) {
if (preg_match($pattern, $sql)) {
$this->logSecurityEvent('sql_injection_attempt', [
'sql' => $sql,
'bindings' => $bindings,
'ip' => request()->ip(),
'user_agent' => request()->userAgent(),
]);
throw new SecurityException('检测到可疑SQL语句');
}
}
// 检查绑定参数中的可疑内容
foreach ($bindings as $binding) {
if (is_string($binding)) {
if (preg_match('/[\x00-\x1f\x7f]/', $binding)) {
$this->logSecurityEvent('suspicious_parameter', [
'parameter' => $binding,
'context' => 'sql_binding',
]);
}
}
}
}
五、监控与调试优化
1. Telescope监控配置
php
// config/telescope.php
return [
'enabled' => env('TELESCOPE_ENABLED', true),
'storage' => [
'database' => [
'connection' => env('DB_TELESCOPE_CONNECTION', 'mysql'),
'chunk' => 1000,
],
],
// 监狱通信特殊监控
'monitoring' => [
'prison_requests' => [
'enabled' => true,
'sample_rate' => 1.0, // 100%采样
],
'letter_processing' => [
'enabled' => true,
'sample_rate' => 1.0,
],
],
'watchers' => [
Watchers\CacheWatcher::class => env('TELESCOPE_CACHE_WATCHER', true),
Watchers\CommandWatcher::class => env('TELESCOPE_COMMAND_WATCHER', true),
Watchers\DumpWatcher::class => env('TELESCOPE_DUMP_WATCHER', true),
Watchers\EventWatcher::class => env('TELESCOPE_EVENT_WATCHER', true),
Watchers\ExceptionWatcher::class => env('TELESCOPE_EXCEPTION_WATCHER', true),
Watchers\JobWatcher::class => env('TELESCOPE_JOB_WATCHER', true),
Watchers\LogWatcher::class => env('TELESCOPE_LOG_WATCHER', true),
Watchers\MailWatcher::class => env('TELESCOPE_MAIL_WATCHER', true),
Watchers\ModelWatcher::class => env('TELESCOPE_MODEL_WATCHER', true),
Watchers\NotificationWatcher::class => env('TELESCOPE_NOTIFICATION_WATCHER', true),
Watchers\QueryWatcher::class => [
'enabled' => env('TELESCOPE_QUERY_WATCHER', true),
'slow' => 100, // 100ms以上视为慢查询
],
Watchers\RedisWatcher::class => env('TELESCOPE_REDIS_WATCHER', true),
Watchers\RequestWatcher::class => env('TELESCOPE_REQUEST_WATCHER', true),
Watchers\ScheduleWatcher::class => env('TELESCOPE_SCHEDULE_WATCHER', true),
Watchers\GateWatcher::class => env('TELESCOPE_GATE_WATCHER', true),
],
];
// 自定义监控器
namespace App\Telescope\Watchers;
use Laravel\Telescope\Telescope;
use Laravel\Telescope\IncomingEntry;
use Laravel\Telescope\Watchers\Watcher;
class PrisonRequestWatcher extends Watcher
{
public function register($app)
{
$app['events']->listen(RequestHandled::class, [$this, 'recordRequest']);
}
public function recordRequest(RequestHandled $event)
{
if (!Telescope::isRecording()) {
return;
}
// 只监控监狱相关请求
if (str_contains($event->request->path(), 'prison')) {
Telescope::recordRequest(IncomingEntry::make([
'uri' => $event->request->path(),
'method' => $event->request->method(),
'headers' => $this->headers($event->request->headers->all()),
'payload' => $this->payload($this->input($event->request)),
'session' => $this->payload($this->sessionVariables($event->request)),
'response_status' => $event->response->getStatusCode(),
'response_time' => defined('LARAVEL_START') ? floor((microtime(true) - LARAVEL_START) * 1000) : null,
'memory_usage' => memory_get_peak_usage(true),
'prison_id' => $event->request->input('prison_id'),
'inmate_id' => $event->request->input('inmate_id'),
]));
}
}
}
2. 性能监控
php
// app/Helpers/PerformanceMonitor.php
class PerformanceMonitor
{
private static $timers = [];
private static $memoryPeak = 0;
public static function start($name)
{
self::$timers[$name] = [
'start' => microtime(true),
'memory' => memory_get_usage(),
];
}
public static function end($name)
{
if (!isset(self::$timers[$name])) {
return null;
}
$timer = self::$timers[$name];
$end = microtime(true);
$metrics = [
'duration' => round(($end - $timer['start']) * 1000, 2), // ms
'memory_used' => memory_get_usage() - $timer['memory'],
'memory_peak' => memory_get_peak_usage(true),
];
// 记录到日志
if ($metrics['duration'] > 100) { // 超过100ms
Log::channel('performance')->warning('Slow operation', [
'operation' => $name,
'metrics' => $metrics,
'timestamp' => now(),
]);
}
// 记录到监控系统
if (extension_loaded('statsd')) {
$statsd = new \Domnikl\Statsd\Connection\UdpSocket('localhost', 8125);
$client = new \Domnikl\Statsd\Client($statsd, 'weiai.performance');
$client->timing("operation.{$name}.duration", $metrics['duration']);
$client->gauge("operation.{$name}.memory", $metrics['memory_used']);
}
unset(self::$timers[$name]);
return $metrics;
}
public static function monitorQuery($query)
{
return DB::table(DB::raw("/*+ MONITOR */ {$query}"));
}
public static function getReport()
{
$report = [
'php_version' => PHP_VERSION,
'laravel_version' => app()->version(),
'memory_limit' => ini_get('memory_limit'),
'max_execution_time' => ini_get('max_execution_time'),
'opcache_enabled' => ini_get('opcache.enable'),
'opcache_memory_used' => opcache_get_status()['memory_usage']['used_memory'] ?? 0,
'opcache_memory_free' => opcache_get_status()['memory_usage']['free_memory'] ?? 0,
'database_connections' => DB::getConnections(),
'redis_connections' => Redis::connection()->info(),
'queue_status' => Queue::size(),
'cache_hit_rate' => self::calculateCacheHitRate(),
];
return $report;
}
private static function calculateCacheHitRate()
{
$hits = Cache::store('redis')->get('cache:hits', 0);
$misses = Cache::store('redis')->get('cache:misses', 0);
$total = $hits + $misses;
return $total > 0 ? round($hits / $total * 100, 2) : 0;
}
技术价值
这些优化不是单纯的技术升级,而是对特殊群体通信责任的技术承诺。每一毫秒的性能提升,都是为了让高墙内外的连接更顺畅;每一个安全加固,都是为了守护每一份信任。
代码有温度,优化见真心
在技术极限处,我们守护人间最珍贵的连接。
微爱帮技术委员会 · 架构优化组