-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Alpine + Swoole + PgSQL on the host = could not send SSL negotiation packet: Resource temporarily unavailable
#5313
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
could not send SSL negotiation packet: Resource temporarily unavailable
It seems that I need to synchronize the code for php8.3 pdo_pgsql. |
Swoole unfortunately doesn't work with PHP 8.3 on Alpine because the most recent published version is the one with the bug 5.1.1. Alpine maintains only the most recent version and it's related to the PECL problem. Ref #5242 |
I encountered the same problem on Debian, and the issue persists after attempting to upgrade PHP to 8.3. $ uname -a
Linux 2a9a37e4e7c4 6.7.11-orbstack-00143-ge6b82e26cd22 #1 SMP Sat Mar 30 12:20:36 UTC 2024 aarch64 GNU/Linux
$ lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux 12 (bookworm)
Release: 12
Codename: bookworm
$ php -v
PHP 8.3.6 (cli) (built: Apr 24 2024 19:23:57) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.3.6, Copyright (c) Zend Technologies
with Zend OPcache v8.3.6, Copyright (c), by Zend Technologies
$ php --ri swoole
Swoole => enabled
Author => Swoole Team <[email protected]>
Version => 5.1.2
Built => May 14 2024 03:45:52
coroutine => enabled with boost asm context
epoll => enabled
eventfd => enabled
signalfd => enabled
cpu_affinity => enabled
spinlock => enabled
rwlock => enabled
sockets => enabled
openssl => OpenSSL 3.0.11 19 Sep 2023
dtls => enabled
http2 => enabled
json => enabled
curl-native => enabled
pcre => enabled
c-ares => 1.18.1
zlib => 1.2.13
mutex_timedlock => enabled
pthread_barrier => enabled
futex => enabled
async_redis => enabled
coroutine_pgsql => enabled
Directive => Local Value => Master Value
swoole.enable_coroutine => On => On
swoole.enable_library => On => On
swoole.enable_fiber_mock => Off => Off
swoole.enable_preemptive_scheduler => Off => Off
swoole.display_errors => On => On
swoole.use_shortname => On => On
swoole.unixsock_buffer_size => 8388608 => 8388608 |
Same here on alpine with the new version. The thing that sucks is that alpine only has the latest versions which now makes everyone stuck with the broken one. I tried switching to FrankenPHP but Swoole outperforms it by 30x in my humble benchmarks. So it's also hard to say no. |
@myxingkong Can you provide a script for reproduction? |
@flexchar Do you have coroutines enabled? |
@NathanFreeman If this is the fair way to judge, then it seems so. (Note this is the output from the working version) laravel@:/var/www $ php --ri swoole
swoole
Swoole => enabled
Author => Swoole Team <[email protected]>
Version => 5.0.3
Built => May 11 2023 21:36:59
coroutine => enabled with boost asm context
epoll => enabled
eventfd => enabled
signalfd => enabled
spinlock => enabled
rwlock => enabled
sockets => enabled
openssl => OpenSSL 3.1.0 14 Mar 2023
dtls => enabled
http2 => enabled
json => enabled
curl-native => enabled
c-ares => 1.19.1
zlib => 1.2.13
brotli => E16777225/D16777225
mutex_timedlock => enabled
pthread_barrier => enabled
mysqlnd => enabled
async_redis => enabled
Directive => Local Value => Master Value
swoole.enable_coroutine => On => On
swoole.enable_library => On => On
swoole.enable_preemptive_scheduler => Off => Off
swoole.display_errors => On => On
swoole.use_shortname => On => On
swoole.unixsock_buffer_size => 8388608 => 8388608 I tried setting them off using the following but the issue remains the same. [swoole]
swoole.enable_coroutine = 0 |
If coroutines are not used, connecting to external servers will not work properly. However, there is no problem connecting to the internal Docker server. $dsn = 'pgsql:dbname=postgres host=192.168.199.201 port=5432';
try {
$db = new PDO($dsn, 'postgres', '123456');
echo "Connected successfully";
} catch (PDOException $e) {
echo "Connection failed: " . $e->getMessage();
} Output:
Moving the above code into a coroutine, it can work normally. use function Swoole\Coroutine\run;
run(function () {
$dsn = 'pgsql:dbname=postgres host=192.168.199.201 port=5432';
try {
$db = new PDO($dsn, 'postgres', '123456');
echo "Connected successfully";
} catch (PDOException $e) {
echo "Connection failed: " . $e->getMessage();
}
}); Output:
After attempting to disable coroutines, the problem still exists. Only when I completely disable the Swoole extension, can the problem be solved. |
Hi, |
I have tried many methods,
None of which can be reproduced. |
Or execute |
@NathanFreeman, Did you try the 2nd using the docker image I provided? I used Postrgres.App on mac as the database on the host and in this scenario it will cause the error. |
@NathanFreeman , |
If I run Swoole v5.1.2 and PostgreSQL v15.2 on the same network via docker compose, then everything works fine. But if I assign swoole the network "net1", and postgresql the network "net2", then I get an error "could not send SSL negotiation packet". |
@NathanFreeman I understand you cannot reproduce the issue, because it only happens sometimes. The bug doesn't always occur on every environment and I have absolutely no idea why. I've spend the good part of the day trying to debug this issue, because we run into this issue on 2 of our 4 DTAP environments. In our environments, everything is running great up until the acceptance and production environments, where the 'SSL negotiation packet' error is thrown. Each environment is rolled out using the same IaC codebase. I have confirmed they are all using the same software, tools, versions and OS's. The same image - based on your Dockerfile - is being used on all environments during my tests. I've also tested it with a Debian based image, which gives the exact same results. Connecting from within the image to the Postgres database using the Disabling the SSL mode - for testing only obviously - results in a All things together; it looks like the PHP process just can't seem to connect with the Postgres database, even though TCP packets are send to and from the database when these errors occur. I'm currently out of ideas how to debug this issue and provide you with the information you need. If there is anything that I missed here or anything I can do to help you out, let me know. |
Not sure if this is of help, otherwise just another +1 here. We have the same with a Laravel application which we try to migrate from OpenSwoole to Swoole. Our phpinfo output looks similar to the mentions above. Our image is built On start a PostgreSQL db migration on an AWS RDS instance via
We hunt this problem for 3 months now and cannot find anything, so we're stuck with OpenSwoole currently. Maybe you have an idea how we can debug this further from here in our app and provide you with infos? |
After some debugging, I found the problem. Swoole sets the PostgreSQL connection to non-blocking mode and does not use functions like select to listen for the connection status in non-coroutine mode. This causes the PQconnectPoll function to return immediately. It is not possible to reproduce this problem between containers because the latency between them is small. When the PQconnectPoll function returns, the socket has been sent. This problem only occurs when trying to connect to an external server with a delay of >2ms. Try to rebuild Swoole using the following patches, and the problem is temporarily resolved. diff --git a/ext-src/swoole_pgsql.cc b/ext-src/swoole_pgsql.cc
index 7c8ee1649..fade6827f 100644
--- a/ext-src/swoole_pgsql.cc
+++ b/ext-src/swoole_pgsql.cc
@@ -86,7 +86,28 @@ PGconn *swoole_pgsql_connectdb(const char *conninfo) {
PQsetnonblocking(conn, 1);
+ fd_set readfds, writefds;
+ timeval timeout = {0, 10000};
+ int retval = 0;
+ if (swoole_pgsql_blocking) {
+ FD_ZERO(&readfds);
+ FD_ZERO(&writefds);
+ FD_SET(fd, &readfds);
+ FD_SET(fd, &writefds);
+ }
+
SW_LOOP {
+ if (swoole_pgsql_blocking) {
+ retval = select(fd + 1, &readfds, &writefds, nullptr, &timeout);
+ if (retval == -1) {
+ if (errno == EINTR) {
+ continue;
+ }
+ return nullptr;
+ } else if (retval == 0) {
+ continue;
+ }
+ }
int r = PQconnectPoll(conn);
if (r == PGRES_POLLING_OK || r == PGRES_POLLING_FAILED) {
break; |
Wow, you're the hero @myxingkong! I rooting this is enough for @NathanFreeman to pin a new version and unblocks as all to upgrade to PHP 8.3 :)) |
I think we have the same issue since we rebuild our image for production yesterday. Is there a way to prevent this issue from happening until a fix is released? Does this only happen if I connect to the database with SSL? Can I set the ssl mode to |
For anyone running into this problem with a Laravel Forge provisioned server, here are the steps I took to disable Swoole. Forge, by default, installs the Swoole extension so users can easily run Laravel Octane, but its there whether or not you decide to use it.
Then comment out the extension line like this
Restart PHP
Obviously if not using 8.3, update the command to the particular version, but this fixed the |
@flexchar @myxingkong Here, it should be necessary to distinguish between coroutine and non-coroutine situations. Let me make the modification. |
@andreinocenti The latest release https://github.com/swoole/swoole-src/releases/tag/v5.1.3 is from June 6th, but #5397 has been merged July 5th into You could build from |
@7oku Thank you. I just found a "solution". I lowered my php version to 8.2.19 and the swoole to 5.0.3. Now it is working using these old versions. |
Thank you @therobfonz this worked for me, with the small change of the file being a symlink so the actual file I needed to edit was |
Hello @NathanFreeman |
For alpine users. Waiting for Andy Postnikov @andypost to release on Alpine: https://pkgs.alpinelinux.org/packages?name=php83-*swoole*&branch=v3.20 If anyone knows how to let him know of the new version, it'd be greatly appreciated! |
Send to build alpinelinux/aports@ee4d00d alpinelinux/aports@d89ba00 |
@matyhtf @NathanFreeman Hi! We have been getting this same error in our production environment after upgrading to Chart: Number of occurrences of Last sunday we upgraded from Swoole The number of occurrences of this error went down from 22,000 per day to "only" 200 per day. But still, 200 lost connections to our database is a lot and we are losing important customer data so I am still worried. We are using an Ubuntu server hosted on AWS, Laravel Forge for deployment and nginx. Any idea what can it be the cause? Edit reason: I mistyped the version numbers. The correct version numbers are good now. Edit2: Swoole is installed from PECL. |
@jhm-ciberman You can try disabling |
@jhm-ciberman I'm very sorry; I missed fixing one more thing in the previous update. I will likely submit a new PR tonight or tomorrow. |
@NathanFreeman Thanks for your answer. Sorry my ignorance, how should I tackle this?
I am new to the world of installing PECL extensions so I want to minimize the downtime of our application. Thank you for your help 😁 |
@jhm-ciberman If your project does not use coroutines, then it doesn't matter if you disable |
@NathanFreeman Mh... Nope, I don't think I am using Coroutines. I am using Laravel + Laravel Octane with the Swoole driver to serve my application. I use Nginx as reverse proxy. I just checked Laravel Octane source code and I don't think it's making use of Swoole coroutines in any way. I could be wrong. I will try to recompile with |
@NathanFreeman Sorry to bother. But as far as I understand, my version of Swoole in my production server is compiled without
I compiled swoole in my staging server with and without pgsql support and the difference is that Am I missing something? |
@jhm-ciberman Yes, according to the configuration above, |
If you previously had |
@NathanFreeman Hey, thanks for your quick answer!
Mh. I am not sure how to check that
Yes! I just checked my
I just re restarted everything again just to be sure. I also I will wait a few hours and keep you updated just in case that second restart somehow solves the problem. |
@jhm-ciberman I could totally recommend hosting on your own server, with docker & cloudflare tunnels. Not that I have anything against Forge but this setup lets you roll out your own docker image with your own packages. Even though I opened this issue because I used to connect to the host during development, thanks to this deployment my production never had an issue. :) That being said, if you're feeling lucky, you could also try Swoole 6.0.0. beta. Don't run it if you risk loosing revenue but do try. I tried and found no issues whatsoever, even though it is a beta version. Also, where is your database hosted at? |
@jhm-ciberman It may be that the PHP pgsql extension is dependent on an older version of the PostgreSQL library. If the PostgreSQL library version is <= 16.1 and SSL connections are enabled, there may be issues. |
@NathanFreeman Is this the version of PostgreSQL that I should look for? $ php -i | grep PostgreSQL
PDO Driver for PostgreSQL => enabled
PostgreSQL(libpq) Version => 14.13
PostgreSQL Support => enabled
PostgreSQL (libpq) Version => 14.13 $ apt-cache policy php8.3-pgsql
php8.3-pgsql:
Installed: 8.3.3-1+ubuntu22.04.1+deb.sury.org+1
Candidate: 8.3.11-1+ubuntu22.04.1+deb.sury.org+1
Version table:
8.3.11-1+ubuntu22.04.1+deb.sury.org+1 500
500 https://ppa.launchpadcontent.net/ondrej/php/ubuntu jammy/main arm64 Packages
*** 8.3.3-1+ubuntu22.04.1+deb.sury.org+1 100
100 /var/lib/dpkg/status
``` |
@flexchar I am more of a VPS server guy. I like docker, but I prefer the simplicity of working with our own machine. Maybe in a future I change my mind, so thanks for the suggestion.
Definitely no. Our server handles 1700 requests per minute. We cannot afford losing (more) customer data.
Server is a AWS EC2 instance. Database is a AWS Postgres RDS instance. |
@jhm-ciberman Can you show me your octane.php configuration? |
@NathanFreeman You are not gonna believe me. Yesterday we upgraded our server from The disk image was exactly the same, so it wasn't something related to software. Maybe the server was under a heavy load and that caused the bug? I am not sure. I will be keeping you up to date in case the bug appears again. But thank you a lot for your help, and thanks for making Swoole. Thanks to Swoole our app runs super fast. Thanks! |
Since the issue is so mysterious, I was able to and made a reproducible. Please try it yourself.
https://github.com/flexchar/pdo-pgsql-issue
Please answer these questions before submitting your issue.
I attempt to connect to the pgsql running on my host mac machine from inside docker container running Laravel. It would fail with
SQLSTATE[08006] [7] could not send SSL negotiation packet: Resource temporarily unavailable
error.It does work if I would connect using
psql
cli terminal. It also works if I usedpg_connect
insteadphp-pdo
.I cannot test with php83 since the latest swoole pecl upstream has been broken for months now. I am not sure what's going on.
What did you expect to see?
It should connect.
What did you see instead?
SQLSTATE[08006] [7] could not send SSL negotiation packet: Resource temporarily unavailable
What version of Swoole are you using (show your
php --ri swoole
)?as installed from https://pkgs.alpinelinux.org/packages?name=php82-pecl-swoole&branch=v3.19&repo=community&arch=x86_64&maintainer=
uname -a
&php -v
&gcc -v
) ?$ uname -a Linux 031104a4b74c 6.6.22-linuxkit #1 SMP Fri Mar 29 12:21:27 UTC 2024 aarch64 Linux $ php -v PHP 8.2.18 (cli) (built: Apr 11 2024 14:41:12) (NTS) Copyright (c) The PHP Group Zend Engine v4.2.18, Copyright (c) Zend Technologies $ gcc -v ash: gcc: not found
It may also be that pdo-pgsql is broken but I am not sure where to report it. I would appreciate the guidance. Thank you. :)
The text was updated successfully, but these errors were encountered: