我有一个Laravel Spark项目,该项目使用Horizon来管理Redis的作业队列。
在本地(在Mac OS上的Homestead盒子上),一切正常,但是在我们新的Digital Ocean(已配置Forge的Droplet)上,它是内存优化的256GB,32vCPU,10TB和1x 800GB VPS,我不断收到错误消息:
PDOException: Packets out of order. Expected 0 received 1. Packet size=23
或该错误的某种变体,其中数据包大小信息可能有所不同。在经过数小时/天的调试和研究之后,我在StackOverflow和其他地方遇到了很多帖子,这似乎表明可以通过做一些事情来解决此问题,如下所示:
PDO::ATTR_EMULATE_PREPARES
设置为true。这对问题绝对没有影响,实际上引入了另一个问题,即整数被转换为字符串。DB_HOST
设置为127.0.0.1
而不是localhost
,以便它使用TCP而不是UNIX套接字。同样,这没有效果。DB_SOCKET
将show variables like '%socket%';
设置为MySQL中列出的套接字路径,该命令将套接字路径列出为/run/mysqld/mysqld.sock
。我还将DB_HOST
设置为localhost
。这也不起作用。我注意到的一件事是pdo_mysql.default_socket
变量设置为/var/run/mysqld/mysqld.sock
,我不确定这是否是问题的一部分?/etc/mysql/mariadb.conf.d/50-server.cnf
中找到的MySQL配置设置大量增加到以下内容:key_buffer_size = 2048M
max_allowed_packet = 2048M
max_connections = 1000
thread_concurrency = 100
query_cache_size = 256M
我必须承认,更改这些设置是在使用吸管类型的情况下的不得已而为之。但是,这确实在某种程度上减轻了该问题,但是并不能完全解决该问题,因为MySQL仍然有99%的时间失败,尽管是在后期。
就队列而言,我总共将
1,136 workers
划分为6个主管/队列,并全部通过Laravel Horizon(作为守护程序运行)进行处理。我还再次使用Laravel Websockets PHP软件包进行广播,该软件包也作为守护程序运行。
我当前的环境配置如下(忽略敏感信息)。
APP_NAME="App Name"
APP_ENV=production
APP_DEBUG=false
APP_KEY=thekey
APP_URL=https://appurl.com
LOG_CHANNEL=single
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=databse
DB_USERNAME=username
DB_PASSWORD=password
BROADCAST_DRIVER=pusher
CACHE_DRIVER=file
QUEUE_CONNECTION=redis
SESSION_DRIVER=file
SESSION_LIFETIME=120
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_MAILER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=name@email.com
MAIL_PASSWORD=password
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=name@email.com
MAIL_FROM_NAME="${APP_NAME}"
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION="us-east-1"
AWS_BUCKET=
PUSHER_APP_ID=appid
PUSHER_APP_KEY=appkey
PUSHER_APP_SECRET=appsecret
PUSHER_APP_CLUSTER=mt1
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
AUTHY_SECRET=
CASHIER_CURRENCY=usd
CASHIER_CURRENCY_LOCALE=en
CASHIER_MODEL=App\Models\User
STRIPE_KEY=stripekey
STRIPE_SECRET=stripesecret
# ECHO SERVER
LARAVEL_WEBSOCKETS_PORT=port
服务器设置如下:我已经检查了MySQL服务器崩溃/消失时的所有日志(请参阅下文),并且MySQL日志中根本没有任何内容。没有任何错误。我也看不到任何东西:
/var/log/nginx/error.log
/var/log/nginx/access.log
/var/log/php7.4-fpm.log
我目前仍在深入研究和调试,但是现在,我很困惑。这是我第一次遇到此错误。
难道是因为击中数据库(读/写)的速度太快了吗?
有关队列如何工作的一些信息。
所有这些都根据运行的监听器/作业及其触发的事件顺序工作。
我还实时监视了
laravel.log
,当发生崩溃时,什么都没有记录。虽然,无论MySQL是否崩溃,我偶尔都会得到production.ERROR: Failed to connect to Pusher.
,所以我认为这与该问题无关。我什至注意到Laravel API速率限制已达到,所以我确保将其从60急剧增加到500。仍然没有喜悦。
最后,运行哪个Event,Job或Listener似乎无关紧要,因为错误发生在随机事件上。因此,尽管可能确实如此,但不确定它是否特定于代码。
希望我已经提供了足够的背景信息和详细的信息来对此有所帮助,但是,如果我错过了任何事情,请告诉我,并将其添加到问题中。谢谢。
最佳答案
我们收到了类似的关于数据包乱序的PHP警告。
为我们解决的是在MySQL my.cnf中增加 max_connections 。
您当前的max_connections可能是1024。我们将我们的max_connections增加到4096,警告消失了。
在MySQL中,您可以使用以下命令查看当前的max_connections:
SHOW VARIABLES LIKE "%max_connections%";
or
mysqladmin variables | grep max_connections
关于php - PDOException : Packets out of order.预期收到0。1.数据包大小= 23,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63301495/