注意事项

  • 单例问题

    • 传统FPM下,单例模式的对象的生命周期仅在每次请求中,请求开始=>实例化单例=>请求结束后=>单例对象资源回收。

    • Swoole Server下,所有单例对象会常驻于内存,这个时候单例对象的生命周期与FPM不同,请求开始=>实例化单例=>请求结束=>单例对象依旧保留,需要开发者自己维护单例的状态。

    • 常见的解决方案:

      1. 写一个XxxCleaner清理器类来清理单例对象状态,此类需实现接口Hhxsv5\LaravelS\Illuminate\Cleaners\CleanerInterface,然后注册到laravels.phpcleaners中。

      2. 用一个中间件重置单例对象的状态。

      3. 如果是以ServiceProvider注册的单例对象,可添加该ServiceProviderlaravels.phpregister_providers中,这样每次请求会重新注册该ServiceProvider,重新实例化单例对象,参考

    • LaravelS 已经内置了一些清理器

  • 常见问题:一揽子的已知问题和解决方案。

  • 调试方式:记录日志、Laravel Dump Server(Laravel 5.7已默认集成)

  • 应通过Illuminate\Http\Request对象来获取请求信息,$_ENV是可读取的,$_SERVER是部分可读的,不能使用$_GET、$_POST、$_FILES、$_COOKIE、$_REQUEST、$_SESSION、$GLOBALS。

    1. public function form(\Illuminate\Http\Request $request)
    2. {
    3. $name = $request->input('name');
    4. $all = $request->all();
    5. $sessionId = $request->cookie('sessionId');
    6. $photo = $request->file('photo');
    7. // 调用getContent()来获取原始的POST body,而不能用file_get_contents('php://input')
    8. $rawContent = $request->getContent();
    9. //...
    10. }
  • 推荐通过返回Illuminate\Http\Response对象来响应请求,兼容echo、vardump()、print_r(),不能使用函数 dd()、exit()、die()、header()、setcookie()、http_response_code()。

    1. public function json()
    2. {
    3. return response()->json(['time' => time()])->header('header1', 'value1')->withCookie('c1', 'v1');
    4. }
  • 各种单例的连接将被常驻内存,建议开启持久连接

  1. 数据库连接,连接断开后会自动重连

    1. // config/database.php
    2. 'connections' => [
    3. 'my_conn' => [
    4. 'driver' => 'mysql',
    5. 'host' => env('DB_MY_CONN_HOST', 'localhost'),
    6. 'port' => env('DB_MY_CONN_PORT', 3306),
    7. 'database' => env('DB_MY_CONN_DATABASE', 'forge'),
    8. 'username' => env('DB_MY_CONN_USERNAME', 'forge'),
    9. 'password' => env('DB_MY_CONN_PASSWORD', ''),
    10. 'charset' => 'utf8mb4',
    11. 'collation' => 'utf8mb4_unicode_ci',
    12. 'prefix' => '',
    13. 'strict' => false,
    14. 'options' => [
    15. // 开启持久连接
    16. \PDO::ATTR_PERSISTENT => true,
    17. ],
    18. ],
    19. //...
    20. ],
    21. //...
  2. Redis连接,连接断开后不会立即自动重连,会抛出一个关于连接断开的异常,下次会自动重连。需确保每次操作Redis前正确的SELECT DB

    1. // config/database.php
    2. 'redis' => [
    3. 'client' => env('REDIS_CLIENT', 'phpredis'), // 推荐使用phpredis,以获得更好的性能
    4. 'default' => [
    5. 'host' => env('REDIS_HOST', 'localhost'),
    6. 'password' => env('REDIS_PASSWORD', null),
    7. 'port' => env('REDIS_PORT', 6379),
    8. 'database' => 0,
    9. 'persistent' => true, // 开启持久连接
    10. ],
    11. ],
    12. //...
  • 你声明的全局、静态变量必须手动清理或重置。

  • 无限追加元素到静态或全局变量中,将导致内存溢出。

    1. class Test
    2. {
    3. public static $array = [];
    4. public static $string = '';
    5. }
    6. // 某控制器
    7. public function test(Request $req)
    8. {
    9. // 内存溢出
    10. Test::$array[] = $req->input('param1');
    11. Test::$string .= $req->input('param2');
    12. }
  • Linux内核参数调整

  • 压力测试