微爱帮监狱寄信写信系统后台PHP框架优化实战手册

一、性能优化体系

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;
    }

技术价值

这些优化不是单纯的技术升级,而是对特殊群体通信责任的技术承诺。每一毫秒的性能提升,都是为了让高墙内外的连接更顺畅;每一个安全加固,都是为了守护每一份信任。

代码有温度,优化见真心

在技术极限处,我们守护人间最珍贵的连接。

微爱帮技术委员会 · 架构优化组

相关推荐
历程里程碑2 小时前
滑动窗口秒解LeetCode字母异位词
java·c语言·开发语言·数据结构·c++·算法·leetcode
民乐团扒谱机2 小时前
【微实验】量子光梳技术革命:如何用量子压缩突破时频传递的终极极限?
人工智能·敏感性分析·量子力学·双梳
MARS_AI_2 小时前
AI呼叫中心革命:大模型技术如何重构企业服务体验
人工智能·科技·自然语言处理·信息与通信·agi
思成Codes2 小时前
Go 语言中数组与切片的本质区别
开发语言·后端·golang
白帽子黑客罗哥2 小时前
网络安全防护技术与实战策略:从基础防御到前沿应对
安全·web安全·php
Tandy12356_2 小时前
手写TCP/IP协议栈——TCP结构定义与基本接口实现
c语言·网络·c++·网络协议·tcp/ip·计算机网络
EEPI2 小时前
【论文阅读】Vision Language Models are In-Context Value Learners
论文阅读·人工智能·语言模型
金融Tech趋势派2 小时前
2026企业微信私有化部署新选择:微盛·企微管家如何助力企业数据安全与运营效率提升?
大数据·人工智能·云计算·企业微信
短视频矩阵源码定制2 小时前
专业的矩阵系统哪个公司好
大数据·人工智能·矩阵