问题解决方案

在上一篇问题解决中:python OSError: [Errno 24] Too many open files | HTTPConnectionPool(host=‘‘, port=80): Max retries e
有提到修改本地进程最大文件数来避免Max retries exceeded with url 报错,也谈到如果请求api端有请求数量限制,仍然是拉取不到结果的。这时我们就要限制我们请求的频率了。
下面有三个常见的方法:
1、增加重试连接次数:
requests.DEFAULT_RETRIES = 5
2、关闭多余的链接:
默认的http connection是keep-alive的,在post请求中,header中有这样一个字段:Connection,我们将其置为’close’

monitor_header = {
    "Content-type":"application/json",
    "Accept":"*/*",
    "Connection":"close",
    "X-API-Version":"v1",
    "projectname": "wemeet",
    "appname": "media_proxy",
    "token": "2e962d4104a2c28477ab7f38883b79bb"
}

http是一个无状态的面向连接的协议。
http无状态:无状态协议是指http协议本身对于事务处理没有记忆功能,服务器不知道浏览器的状态。通俗的即使你登录了,去访问同一个网站的不同网页,服务器都不会知道你是谁,如果需要记录登录用户的信息,用户操作,用户行为等数据需要使用cookie或session来存储。

keep-alive:从HTTP/1.1起,浏览器默认都开启了Keep-Alive,保持连接特性,客户端和服务器都能选择随时关闭连接,则请求头中为connection:close。简单地说,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的TCP连接。但是Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。

误解:无状态不代表HTTP不能保持TCP连接,更不能代表HTTP使用的是UDP协议(无连接)。即使http在无状态下,只要客户端和服务器的头部信息connection:keep-alive,则在有效期内他们使用同一条TCP连接。
3、请求时增加缓冲延时
由于我这里是多线程进行post请求,总共有2744个线程。这里进行分批次的发请求,发完一次sleep一段时间:

def get_machine_quality(mapping):
    threads = []
    list_machine_obj = []
    now_time = time.time()
    for value in mapping.values():
        for v in value:
            machine_obj = quality_data(v, 0, now_time)
            list_machine_obj.append(machine_obj)
    index = 0
    for value in mapping.values():
        for v in value:
            # 创建新线程
            thread_tmp = my_thread(v, threadfunc_get_machine_quality, list_machine_obj[index])
            # 添加线程到线程列表
            threads.append(thread_tmp)
            index += 1
    # 开启新线程
    length = len(threads)
    part = 4
    for i in range(0,part):
        start = int(i / part * length)
        end = int((i + 1) / part * length)
        for i in range(start, end):
            threads[i].start()
        for i in range(start, end):
            threads[i].join()
        time.sleep(40)
        print(str(start) + "to" + str(end))
        logging.critical(str(start) + "to" + str(end))
    # print ("退出主线程")
    return list_machine_obj  

keep alive 与close使用场景

1、当你的Server内存充足时,KeepAlive =On还是Off对系统性能影响不大。
2、当你的Server上静态网页(Html、图片、Css、Js)居多时,建议打开KeepAlive 。
3、当你的Server多为动态请求(因为连接数据库,对文件系统访问较多),KeepAlive 关掉,会节省一定的内存,节省的内存正好可以作为文件系统的Cache(vmstat命令中cache一列),降低I/O压力。
PS:当KeepAlive =On时,KeepAliveTimeOut的设置其实也是一个问题,设置的过短,会导致Apache 频繁建立连接,给Cpu造成压力,设置的过长,系统中就会堆积无用的Http连接,消耗掉大量内存,具体设置多少,可以进行不断的调节,因你的网站浏览和服务器配置 而异。

参考:
解决Max retries exceeded with url的问题
转:Connection: close和Connection: keep-alive有什么区别?

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐