时间:2021-05-22
前文:
最近在搞全网的CDN刷新系统,在性能调优时遇到了requests长连接的一个问题,以前关注过长连接太多造成浪费的问题,但因为系统都是分布式扩展的,针对这种各别问题就懒得改动了。 现在开发的缓存刷新系统,对于性能还是有些敏感的,我后面会给出最优的http长连接池构建方式。
老生常谈:
python下的httpclient库哪个最好用? 我想大多数人还是会选择requests库的。原因么?也就是简单,易用!
如何蛋疼的构建reqeusts的短连接请求:
python requests库默认就是长连接的 (http 1.1, Connection: keep alive),如果单纯在requests头部去掉Connection是不靠谱的,还需要借助httplib来配合.
s = requests.Session()
del s.headers['Connection']
正确发起 http 1.0的请求姿势是:
#xiaorui.ccimport httplibimport requestshttplib.HTTPConnection._http_vsn = 10httplib.HTTPConnection._http_vsn_str = 'HTTP/1.0'r = requests.get('http://127.0.0.1:8888/')服务端接收的http包体内容:
GET / HTTP/1.0Accept-Encoding: gzip, deflateAccept: */*User-Agent: python-requests/2.5.1 CPython/2.7.10 Darwin/15.4.0所谓短连接就是发送 HTTP 1.0 协议,这样web服务端当然会在send完数据后,触发close(),也就是传递 \0 字符串,达到关闭连接 ! 这里还是要吐槽一下,好多人天天说系统优化,连个基本的网络io都不优化,你还想干嘛。。。下面我们依次聊requests长连接的各种问题及性能优化。
那么requests长连接如何实现?
requests给我们提供了一个Session的长连接类,他不仅仅能实现最基本的长连接保持,还会附带服务端返回的cookie数据。 在底层是如何实现的?
把HTTP 1.0 改成 HTTP 1.1 就可以了, 如果你标明了是HTTP 1.1 ,那么有没有 Connection: keep-alive 都无所谓的。 如果 HTTP 1.0加上Connection: keep-alive ,那么server会认为你是长连接。 就这么简单 !
poll([{fd=5, events=POLLIN}], 1, 0) = 0 (Timeout)sendto(5, "GET / HTTP/1.1\r\nHost: ', port=80, path=None, ...) >>> parse_url('/foo?bar') Url(scheme=None, host=None, port=None, path='/foo', query='bar', ...) return Url(scheme, auth, host, port, path, query, fragment)# 获取匹配的长连接def connection_from_url(self, url, pool_kwargs=None): u = parse_url(url) return self.connection_from_host(u.host, port=u.port, scheme=u.scheme, pool_kwargs=pool_kwargs)# 获取匹配host的长连接def connection_from_host(self, host, port=None, scheme='http', pool_kwargs=None): if scheme == "https": return super(ProxyManager, self).connection_from_host( host, port, scheme, pool_kwargs=pool_kwargs) return super(ProxyManager, self).connection_from_host( self.proxy.host, self.proxy.port, self.proxy.scheme, pool_kwargs=pool_kwargs)# 根据url的三个指标获取连接def connection_from_pool_key(self, pool_key, request_context=None): with self.pools.lock: pool = self.pools.get(pool_key) if pool: return pool scheme = request_context['scheme'] host = request_context['host'] port = request_context['port'] pool = self._new_pool(scheme, host, port, request_context=request_context) self.pools[pool_key] = pool return pool# 获取长连接的主入口def urlopen(self, method, url, redirect=True, **kw): u = parse_url(url) conn = self.connection_from_host(u.host, port=u.port, scheme=u.scheme)这里为止,Python requests关于session连接类实现,说的算明白了。 但就requests和urllib3的连接池实现来说,还是有一些提升空间的。 但问题来了,单单靠着域名和端口会造成一些问题,至于造成什么样子的问题,我在上面已经有详细的描述了。
那么如何解决?
我们可以用 scheme + 主domain + host_ip + port 来实现长连接池的管理。
其实大多数的场景是无需这么细致的实现连接池的,但根据我们的测试的结果来看,在服务初期性能提升还是不小的。
这样既解决了域名ip轮询带来的连接重置问题,也解决了多级域名下不能共用连接的问题。
以上这篇构建高效的python requests长连接池详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
使用springboot开发时,默认使用内置的tomcat数据库连接池,经常碰到这种情况:运行时间一长,数据库连接中断了。所以使用c3p0连接池吧。引入的mav
Druid是Java语言中最好的数据库连接池。Druid相比于其他的数据库连接池,有两大特性:监控数据库,有利于分析线上数据库问题更容易扩展,同时也很高效。今天
在开发中中我们经常会使用到数据库连接池,比如dbcp数据库连接池,本章将讲解java连接dbcp数据库库连接池的简单使用。开发工具myeclipse20141、
首先要了解为什么用连接池,连接池能为你解决什么问题连接池主要的作用:1、减少与数据服务器建立TCP连接三次握手及连接关闭四次挥手的开销,从而降低客户端和mysq
代码如下所示:这个标签的class就已经配置了连接池了这里使用的是现在比较流行的阿里巴巴得druid连接池,其实就是使用连接池的类而已以上所述是小编给大家介绍的