baseConsumer.php 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. <?php
  2. namespace common\components\rabbitmq;
  3. use mikemadisonweb\rabbitmq\components\ConsumerInterface;
  4. use common\components\noticeUtil;
  5. use Yii;
  6. abstract class baseConsumer implements ConsumerInterface
  7. {
  8. /**
  9. * 在长驻进程中保证 db 连接可用
  10. */
  11. protected function ensureDbConnection()
  12. {
  13. $db = Yii::$app->db;
  14. try {
  15. if (!$db->isActive) {
  16. $db->open();
  17. return;
  18. }
  19. $db->createCommand('SELECT 1')->queryScalar();
  20. } catch (\Throwable $e) {
  21. // 连接失效时主动重建
  22. $db->close();
  23. $db->open();
  24. }
  25. }
  26. /**
  27. * 遇到 MySQL 断连时自动重连并重试一次
  28. *
  29. * @param callable $callback
  30. * @return mixed
  31. * @throws \Throwable
  32. */
  33. protected function runWithDbReconnect(callable $callback)
  34. {
  35. try {
  36. return $callback();
  37. } catch (\Throwable $e) {
  38. if (!$this->isMysqlConnectionLost($e)) {
  39. throw $e;
  40. }
  41. Yii::warning('检测到 MySQL 连接断开,尝试重连并重试一次: ' . $e->getMessage(), __METHOD__);
  42. noticeUtil::push('检测到 MySQL 连接断开,尝试重连并重试一次: ' . $e->getMessage(), __METHOD__);
  43. Yii::$app->db->close();
  44. Yii::$app->db->open();
  45. return $callback();
  46. }
  47. }
  48. /**
  49. * 判断是否属于 MySQL 连接丢失错误
  50. *
  51. * @param \Throwable $e
  52. * @return bool
  53. */
  54. protected function isMysqlConnectionLost(\Throwable $e)
  55. {
  56. $message = $e->getMessage();
  57. if (stripos($message, 'server has gone away') !== false) {
  58. return true;
  59. }
  60. if (stripos($message, 'Lost connection to MySQL server') !== false) {
  61. return true;
  62. }
  63. if (stripos($message, 'SQLSTATE[HY000] [2006]') !== false) {
  64. return true;
  65. }
  66. if (stripos($message, 'SQLSTATE[HY000] [2013]') !== false) {
  67. return true;
  68. }
  69. return false;
  70. }
  71. }