У меня есть сценарий PHP, который быстро отправляет кучу запросов в Apple API ( APNs ). Иногда 10k запросов отправляются полностью нормально (только для записи, это занимает ~ 30se c). Однако когда API возвращает не-200 кодов, установление новых подключений к этому API выдает следующую ошибку:
curl: (35) OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to api.push.apple.com:443
При включенном режиме отладки я получаю странные результаты:
Когда все в порядке:
* Found bundle for host api.push.apple.com: 0x55eba8b11660 [serially]
* Found bundle for host api.push.apple.com: 0x55eba8b11660 [serially]
* Trying 17.188.140.151...
* TCP_NODELAY set
* Hostname 'api.push.apple.com' was found in DNS cache
* Trying 17.188.140.151...
...
...
(полный вывод здесь ).
После возникновения проблемы:
* Found bundle for host api.push.apple.com: 0x561d83bb1f00 [serially]
* Server doesn't support multiplex (yet)
* Connection #0 is still name resolving, can't reuse
* Found bundle for host api.push.apple.com: 0x561d83bb1f00 [serially]
* Server doesn't support multiplex (yet)
* Connection #0 is still name resolving, can't reuse
* Connection #1 is still name resolving, can't reuse
* Trying 17.188.156.30:443...
* TCP_NODELAY set
* Hostname 'api.push.apple.com' was found in DNS cache
* Trying 17.188.156.30:443...
...
...
(полный вывод здесь ).
Итак, IP-адрес изменен и что-то связано с мультиплексированием.
После этого отправка запросов в этот API с помощью cli curl
также перестает работать:
$ curl -v -I https://api.push.apple.com
* Trying 17.188.156.30:443...
* TCP_NODELAY set
* Connected to api.push.apple.com (17.188.156.30) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: none
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to api.push.apple.com:443
* Closing connection 0
curl: (35) OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to api.push.apple.com:443
(полный вывод здесь ).
Ошибка может исчезнуть через несколько минут, а может и нет. Код выполняется в контейнере docker (php: 7.3-cli-alpine), перезапуск контейнера обычно сбрасывает проблему до тех пор, пока некоторые будущие запросы не получат коды не-200. Выполнение перезапусков не вариант.
Предположительно, curl каким-то образом хранит открытые соединения и пытается их повторно использовать, но по какой-то причине внутри curl что-то не работает, и это не позволяет корректно перезапускать curl. используйте соединения.
Пока curl перестает работать, openssl работает нормально:
$ openssl s_client -connect api.push.apple.com:443
CONNECTED(00000003)
write:errno=0
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 320 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---
Версии программного обеспечения:
$ curl --version
curl 7.67.0 (x86_64-alpine-linux-musl) libcurl/7.67.0 OpenSSL/1.1.1d zlib/1.2.11 nghttp2/1.40.0
Release-Date: 2019-11-06
Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp
Features: AsynchDNS HTTP2 HTTPS-proxy IPv6 Largefile libz NTLM NTLM_WB SSL TLS-SRP UnixSockets
$ openssl version
OpenSSL 1.1.1d 10 Sep 2019
Похоже, проблема с curl, но как ее исправить это?
Любая помощь будет оценена