php PDO例外:数据包的顺序不对,预期为0,但收到了1,数据包大小=23

chhkpiq4  于 2023-01-04  发布在  PHP
关注(0)|答案(5)|浏览(135)

我有一个Laravel Spark项目,使用Horizon来管理Redis的作业队列。
在本地,(在我的宅基地机器上,Mac OS)一切都按预期运行,但在我们新的Digital Ocean(Forge提供)Droplet上,它是一个内存优化的256 GB、32 vCPU、10 TB和1x 800 GB VPS,我一直收到错误:

PDOException: Packets out of order. Expected 0 received 1. Packet size=23

或者错误某种变化,其中分组大小信息可以不同。
经过几个小时/几天的调试和研究,我在StackOverflow和其他地方看到了许多帖子,它们似乎表明可以通过做以下几件事来修复这个问题:
1.在database.php配置中将PDO::ATTR_EMULATE_PREPARES设置为true,这对问题完全没有影响,实际上引入了另一个问题,即整数被转换为字符串。
1.将DB_HOST设置为127.0.0.1而不是localhost,这样它就使用TCP而不是UNIX套接字。
1.通过登录MySQL(MariaDB)并运行show variables like '%socket%';,将DB_SOCKET设置为MySQL中列出的套接字路径,show variables like '%socket%';列出的套接字路径为/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%的时间失败,尽管是在稍后阶段。
就队列而言,我有6个管理器/队列,总共1,136 workers,这都是通过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

服务器设置如下所示:

*最大文件上载大小:1024
*最长执行时间:300
*PHP版本:7.4
*MariaDB版本:10.3.22

我已经检查了MySQL服务器崩溃/消失时的所有日志(见下文),MySQL日志中没有任何内容。没有任何错误。我也没有看到任何内容:

  • /var/log/nginx/error.log
  • /var/log/nginx/access.log
  • x1米20英寸1x

我目前还在挖掘和调试,但现在,我被难倒了。这是我第一次遇到这个错误。
这可能是因为访问数据库(读/写)太快了吗?
关于队列如何工作的一些信息。
1.我有一个初始控制器,它将一个作业分派到队列中。
1.此作业完成后,它将触发一个事件,然后该事件将启动依次运行其他几个侦听器/事件的过程,所有这些都取决于在触发新事件和新侦听器/作业接管工作之前完成的先前作业。
1.总共有30个事件被广播。
1.总共有30名听众。
1.总共有5个职位。
这些都是基于运行的侦听器/作业及其触发的事件按顺序工作的。
我还实时监控了laravel.log,当崩溃发生时,什么都没有记录,尽管我偶尔会得到production.ERROR: Failed to connect to Pusher.,无论MySQL是否崩溃,所以我不认为这与这个问题有任何关系。
我甚至注意到Laravel的API速率限制正在受到冲击,所以我确保将其从60大幅提高到500。仍然没有喜悦。
最后,由于错误发生在随机的事件、作业或侦听器上,因此似乎与运行哪个事件、作业或侦听器无关。因此,不确定它是特定于代码的,尽管它很可能是。
希望我已经提供了足够的背景和详细的信息来获得一些帮助,但如果我错过了什么,请告诉我,我会把它添加到问题中。谢谢。

6rqinv9w

6rqinv9w1#

对我来说,修复它的是增加最大数据包大小。
my.cnf中,我添加了:

max_allowed_packet=200M

然后是service mysql stopservice mysql start,它起作用了:)

knpiaxh1

knpiaxh12#

我们收到了一个类似的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
gblwokeq

gblwokeq3#

我遇到了一个类似的问题,这是一个可重现的编程错误:
我使用了一个无缓冲的数据库游标,并且在触发其他DB操作之前没有关闭游标。

c9qzyr3d

c9qzyr3d4#

我会检查您是否使用了持久连接,并且没有一次又一次地连接到服务器。有时候,连接过程,特别是有许多并发工作者的情况下,会导致大量的网络开销,从而可能导致这样的问题。
然而,有时候,在一个生产的、高事务量的服务器中,会发生奇怪的网络问题,数据包到达的顺序会混乱,在您的情况下,甚至在环回接口上也会出现这种情况。
在任何情况下,最好编写代码,使其能够优雅地处理错误并重试。通常,您可以将SQL查询 Package 在try..catch中,以便在错误发生时捕获该错误并重试。

tag5nh1u

tag5nh1u5#

MySQL 8 -在mysql.cnf中,禁用所有这些-〉

# For error - ( MySQL server has gone away )
#wait_timeout=90
#net_read_timeout=90
#net_write_timeout=90
#interactive_timeout=300

看起来像是帮我。

相关问题