IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

本周扑火之 http client 慢连接问题

福林雨-博客 2011-05-25 12:35:46 累计浏览 3,718 次
本机暂存

    短链服务自从上线到现在,已经出了 5 回故障了:

    第一次,某著名的刚过百年的大学,紫荆公寓的一个哥们,写了一个诡异的抓站程序,发出来的 http 请求不合法,导致 jetty 缓冲区出错(微博上的直播)。给 Jetty 提了一个 bug,但开发人员说没法重现。我自己写的程序也没法重现当时的情形。自己写了一个 Utf8StringBuilder,覆盖了 Jetty 的版本,增加了出错重置功能,就算 fix 了。

    第二次,log 把磁盘写满了。运维人员的低级失误。值得一提的,当时情急之下,直接用 iphone 上的 iSSH 登陆到服务器上 debug 。自那以后,用 iphone 登服务器看 log 就成了一种习惯(看这里)。

    第三次,现在看来很可能是 G,F、W 封了国外某个短网址站。而我们的短链里有这样的逻辑:如果是已知的短网址,我们会尝试将其还原成长链接,然后再分配一个我们自己的短网址。当时一堆的 http client 超时,将 http client 线程池占满了,导致其它的 http 请求也发不出去。后来我们拆分了 http client 连接池,将非内网,可能会慢的调用划到一个池子,内网核心调用划到一个池子,其它的调用共用一个池子。这样就能保证互相直接不影响。然后又做了一个开关服务,在紧急情况下,不需要修改代码,甚至不需要修改配置文件重启,直接调用开关接口,就能修改配置项,而且实时生效,将某些受影响的调用跳过。(微博上的直播)

    第四次,一个周五下班后的紧急上线,导致下游依赖我们的服务的另一个功能不能正常使用。不巧的是,我和项目组另外一个成员都不方便立即处理,而我当时慌乱之中居然忘了让运维直接回滚,一直想着怎么修改代码,重新发布。sigh 。最后,看到领导发的邮件,才想起直接回滚二进制版本,解决了问题。

    第五次,就是今天,内网核心调用连接池满了。没办法,只能切流量,重启,通知对方和网络运维一起来 debug 。好在重启之后,调用顺畅了,bug 算是修复了。只是接下来,如何防止类似的情况再次出现,还是一个大问题。几乎所有的 http client 库都采用连接池技术,而连接池中无可用连接的时候,又都采用排队的办法等待连接。怎么设置才能在不修改底层代码的前提下,让 http 调用不排队等候,直接返回错误呢?代码中自己进行连接计数?好像有点太山寨了点。

同分类推荐文章

  1. 等了十年的 Go 链式管道,终于来了:seq 让你像写 Scala 一样写 Go (2026-06-25 18:38:18)
  2. Go 实验特性详解 (2026-06-21 10:05:27)
  3. amd64 微架构级别对 Go 程序性能提升多少? (2026-06-21 09:38:49)

查看更多 后端 文章 →

建议继续学习

  1. 浅析http协议、cookies和session机制、浏览器缓存 (累计阅读 17,446)
  2. 从输入 URL 到页面加载完成的过程中都发生了什么事情? (累计阅读 15,933)
  3. libcurl的使用总结(二) (累计阅读 15,083)
  4. 使用python爬虫抓站的一些技巧总结:进阶篇 (累计阅读 13,301)
  5. HTTP协议Keep-Alive模式详解 (累计阅读 12,104)
  6. 你必须了解的Session的本质 (累计阅读 11,441)
  7. curl 命令使用cookie (累计阅读 10,016)
  8. Hello! 404 (累计阅读 9,384)
  9. 解决 nginx 反向代理网页首尾出现神秘字符的问题 (累计阅读 9,096)
  10. redis在大数据量下的压测表现 (累计阅读 8,292)