冤枉urllib3了,望文生义不可取

in #python6 years ago

一般情况写一些技术相关的内容时,我都会做足够的测试,来支持我的每一点结论。所以涉及到技术问题时,我一般都附带代码以及执行结果,没有什么比执行结果更有说服力了。

比如今天的《Requests 与 HTTP Keep-Alive》,无论从代码的执行时间还是从调试信息上来看,都证明Requests的会话(Session)中可以自动实现持久链接(Keep-Alive)。


(图源:https://pixabay.com

有时候明明看着很简单的东西,为了用代码去证明,然后耗费了很长时间,甚至会遇到一些坑,比如之前介绍Click中遇到的docstring 与help冲突的问题。尽管遇到一些坑,尽管去解决这个坑可能花费了好多时间,但是遇坑填坑的过程就是学习的过程,对此我挺欢喜的。

但是有时候也难免会因为太过于自信,不去测试,就下结论,而犯一些错误。今天要说的就是,我冤枉urllib3了。

SO_KEEPALIVE 不等于HTTP Keep-Alive

在之前介绍urllib3时,我已经介绍过了Requests,并且知道了Requests的会话(Session)中可以自动实现持久链接(Keep-Alive)等高级特性。然后我就想,既然Requests一直强调这是高级特性,而Request使用的是urllib3,那么这些高级功能在urllib3上实现起来,总应该略复杂才对。然后我在其它程序中看到如下代码:

from urllib3.connection import HTTPConnection
socket_options = HTTPConnection.default_socket_options + \
[(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1), ]
http = urllib3.poolmanager.PoolManager(socket_options=socket_options)

就想当然认为urllib3实现HTTP Keep-Alive要加入上述代码,于是直接在文章中加入了这个结论。

但是今天抽时间测试了一下这个功能,发现加不加上述代码,连接都是Keep-Alive的,那么就说明我之前得出的结论完全错误,另外又产生一个疑问加上述代码有什么意义呢?

通过一番调查,并祭出了我的宝典(200页),又找了好多网页,大致明白了SO_KEEPALIVE相当于在TCP层实现了以个心跳机制,具体是啥我也没太看懂啦(没研究懂之前,我不敢妄下结论啦),总之,和我们要实现HTTP Keep-Alive是两码事,可以看作是HTTP Keep-Alive设置的特性之一。

urllib3 HTTP Keep-Alive的实现

那么urllib3的HTTP Keep-Alive又如何实现的呢?答案是自动实现的。(好像是废话?) 因为HTTP 1.1中默认启用Keep-Alive,所以无需指定诸如:headers={'connection': 'Keep-Alive'}的HTTP头。

那么如何不让它 Keep-Alive呢?(咦,好变态的需求),答案有两个:

  • 设置Header,比如headers={'connection': 'close'}

  • 每次清理PoolManager

对比一下,Keep-Alive的输出

结论

不要在没有做充分调研的时候就妄下结论,否则自己弄错了到无所谓,再误导了别人就不好啦。😳

把这个糗事记录下来,与诸君共勉吧。

Sort:  

我写了一篇关于steem的思考,其中有好多疑问,有时间的话是否可以给我们这些一知半解的小白写一篇这方面的科普帖。感谢先!

额,你文中提到的问题,我连一知半解都没有,用一头雾水形容比较贴切😭

你太谦虚了。可能是我的一知半解对问题描述不清。感谢阅读!

wow,nice post,thanks for sharing

为严谨点赞 :-)

没有调研,就没有话语权。。

Nice post..

I think you did a good work with this article. You always share great info

Nice Post thanks you for this attractive information @oflyhigh

:-:-👍👍👍

Very Good post.

自动实现的,很有趣

Coin Marketplace

STEEM 0.20
TRX 0.13
JST 0.029
BTC 62871.45
ETH 3479.64
USDT 1.00
SBD 2.53