tcp会偶尔3秒timeout的分析以及如何用php规避这个问题
2年前做一个cache中间件调用的时候,发现很多通过php的curl调用一个的服务会出现偶尔的connect_time超时, 表现为get_curlinfo的connect_time在3秒左右, 本来没怎么注意, 因为客户端的curl_timeout设置的就是3秒, 某天, 我把这个timeout改到了5秒后, 发现了一
2年前做一个cache中间件调用的时候,发现很多通过php的curl调用一个的服务会出现偶尔的connect_time超时, 表现为get_curlinfo的connect_time在3秒左右, 本来没怎么注意, 因为客户端的curl_timeout设置的就是3秒, 某天, 我把这个timeout改到了5秒后, 发现了一个奇怪的现象, 很多慢请求依旧表现为connect_time在3秒左右..看来这个3秒并不是因为客户端设置的timeout引起的.于是开始查找这个原因.
首先, 凭借经验调整了linux内核关于tcp的几个参数
<code>net.core.netdev_max_backlog = 862144 net.core.somaxconn = 262144 </code>
经过观察发现依旧会有3秒超时, 而且数量并没有减少.
第二步, 排除是大并发导致的问题, 在一台空闲机器上也部署同样的服务, 仅让线上一台机器跑空闲机器的服务, 结果发现依旧会有报错.排除并发导致的问题.
最后, 通过查了大量的资料才发现并不是我们才遇到过这个问题, 而且这个问题并不是curl的问题, 它影响到所有tcp的调用, 网上各种说法, 但结论都指向linux内核对于tcp的实现.(某些版本会出现这些问题), 有兴趣的可以看下下面这两个资料.
资料1
资料2
一看深入到linux内核..不管怎样修改的成本一定很大..于是乎, 发挥我们手中的php来规避这个问题的时间到了.
原本的代码, 简单实现,常规curl调用:
<code>function curl_call($p1, $p2 ...) { $ch = curl_init(); curl_setopt($ch, CURLOPT_TIMEOUT, 5); curl_setopt($ch, CURLOPT_URL, 'http://demon.at'); $res = curl_exec($ch); if (false === $res) { //失败..抛异常.. } return $res; } </code>
可以看出, 如果用上面的代码, 无法避免3秒connect_time的问题..这种实现对curl版本会有要求(CURLOPT_CONNECTTIMEOUT_MS),主要的思路是,通过对链接时间进行毫秒级的控制(因为超时往往发生在connect的时候),加上失败重试机制,来最大限度保证调用的正确性。所以,下面的代码就诞生了:
<code>function curl_call($p1, $p2, $times = 1) { $ch = curl_init(); curl_setopt($ch, CURLOPT_TIMEOUT, 5); curl_setopt($ch, CURLOPT_URL, 'http://demon.at'); $curl_version = curl_version(); if ($curl_version['version_number'] >= 462850) { curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, 20); curl_setopt($ch, CURLOPT_NOSIGNAL, 1); } else { throw new Exception('this curl version is too low, version_num : ' . $curl_version['version']); } $res = curl_exec($ch); curl_close($ch); if (false === $res) { if (curl_errno($ch) == CURLE_OPERATION_TIMEOUTED and $times != 最大重试阀值 ) { $times += 1; return curl_call($p1, $p2, $times); } } return $res; } </code>
上面这段代码只是一个规避的简单实例, 一些小细节并没有可以完善..比如抛出异常常以后curl资源的手动释放等等..这里不做讨论..当然还漏了一点要说的是,对重试次数最好加上限制 :)
说明一下上面几个数字值的含义:
<code>462850 //因为php的CURLOPT_CONNECTTIMEOUT_MS需要 curl_version 7.16.2,这个值就是这个版本的数字版本号,还需要注意的是, php版本要大于5.2.3 20 //连接超时的时间, 单位:ms </code>
这样这个问题就这样通过php的代码来规避开了.
如果有对这个问题有更好的解决方法,欢迎指教.
- 作者:蘑菇街蚩尤/Demon,江湖人称「门神」
- 作者简介:蘑菇街移动团队后端工程师,php 技术专家
擅长领域:php 性能调优、 yaf 框架,在 php 领域有多年技术经验 - 个人博客:http://demon.at/
原文地址:tcp会偶尔3秒timeout的分析以及如何用php规避这个问题, 感谢原作者分享。

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Sujets chauds

Dans ce chapitre, nous comprendrons les variables d'environnement, la configuration générale, la configuration de la base de données et la configuration de la messagerie dans CakePHP.

PHP 8.4 apporte plusieurs nouvelles fonctionnalités, améliorations de sécurité et de performances avec une bonne quantité de dépréciations et de suppressions de fonctionnalités. Ce guide explique comment installer PHP 8.4 ou mettre à niveau vers PHP 8.4 sur Ubuntu, Debian ou leurs dérivés. Bien qu'il soit possible de compiler PHP à partir des sources, son installation à partir d'un référentiel APT comme expliqué ci-dessous est souvent plus rapide et plus sécurisée car ces référentiels fourniront les dernières corrections de bogues et mises à jour de sécurité à l'avenir.

Pour travailler avec la date et l'heure dans cakephp4, nous allons utiliser la classe FrozenTime disponible.

Pour travailler sur le téléchargement de fichiers, nous allons utiliser l'assistant de formulaire. Voici un exemple de téléchargement de fichiers.

Dans ce chapitre, nous allons apprendre les sujets suivants liés au routage ?

CakePHP est un framework open source pour PHP. Il vise à faciliter grandement le développement, le déploiement et la maintenance d'applications. CakePHP est basé sur une architecture de type MVC à la fois puissante et facile à appréhender. Modèles, vues et contrôleurs gu

Travailler avec la base de données dans CakePHP est très simple. Nous comprendrons les opérations CRUD (Créer, Lire, Mettre à jour, Supprimer) dans ce chapitre.

Le validateur peut être créé en ajoutant les deux lignes suivantes dans le contrôleur.
