1

我遇到了一个奇怪的问题:
eventlet.green.urllib2.urlopen() raise HTTP Error 408: Request Timeout。
但如果打开“# eventlet.green.time.sleep(0.1)”成功
,有人知道为什么吗?多谢!

测试.py:

import eventlet
import eventlet.green.urllib2

pool = eventlet.GreenPool()
status = "idling"

url_list = [
   "http://192.168.1.218:1995/api/v1/srs_conf", # valid url
   "http://192.168.1.163:1995/api/v1/srs_conf", # valid url
   "http://safsawegdffsd:1995/api/v1/srs_conf", # invalid urls followed
   "http://sddsadfggdfsd:1995/api/v1/srs_conf",
   "http://safsadffddfsd:1995/api/v1/srs_conf",
   "http://safsssadffdsd:1995/api/v1/srs_conf",
   "http://sarsadfggdfsd:1995/api/v1/srs_conf",
   "http://werweer3fsfgv:1995/api/v1/srs_conf"
]

def do_get(url):
    conn = None
    try:
        conn = eventlet.green.urllib2.urlopen(url)
        res = conn.read()
        print res
    except Exception, ex:
        print url, ex
    finally:
        if conn:
            conn.close()

def start():
    for i in range(len(url_list)):
        pool.spawn_n(do_get, url_list[i])
        # eventlet.green.time.sleep(0.1)

while True:
    if status == "idling":
        status = "running"
        start()
    eventlet.green.time.sleep(1)

结果:

http://safsadffddfsd:1995/api/v1/srs_conf <urlopen error [Errno 11004] getaddrinfo failed>
http://sddsadfggdfsd:1995/api/v1/srs_conf <urlopen error [Errno 11004] getaddrinfo failed>
http://safsssadffdsd:1995/api/v1/srs_conf <urlopen error [Errno 11004] getaddrinfo failed>
http://safsawegdffsd:1995/api/v1/srs_conf <urlopen error [Errno 11004] getaddrinfo failed>
http://sarsadfggdfsd:1995/api/v1/srs_conf <urlopen error [Errno 11004] getaddrinfo failed>
http://werweer3fsfgv:1995/api/v1/srs_conf <urlopen error [Errno 11004] getaddrinfo failed>
http://192.168.1.218:1995/api/v1/srs_conf <urlopen error [Errno 10061] WSAECONNREFUSED>
http://192.168.1.163:1995/api/v1/srs_conf HTTP Error 408: Request Timeout
4

1 回答 1

0

TL;博士

while True:
  if status == "idling":
    status = "running"
    start()
  eventlet.sleep(0)  # or pool.waitall()

为什么

这是发生的事情:

1: while True:               # True, next
2:   if status == "idling":  # True, execute if branch
3:     status = "running"    # set, next
4:     start()               # pool.spawn() N times
                             # go to 1, True, next
2:   if status == "idling":  # False, skip if branch
                             # go to 1, True, next
2:   if status == "idling":  # and again ...

Python 解释器无法进入 Eventlet 集线器并切换到绿色线程来进行网络 IO。

Eventlet 提供协作多线程。这意味着您需要让出控制权才能让协程有机会运行。eventlet.sleep()要让出控制权,请使用GreenPool.waitall()或等待任何 IO,例如 urlopen conn.read

合适的方式

去掉while True循环,Eventlet 已经为你隐藏了一个。删除status.

def start():
  # ...

start()
pool.waitall()
于 2015-05-27T09:44:50.687 回答