Python Asyncio 如何 itertools.cycle 同时处理超过 1 个请求

Python Asyncio How To itertools.cycle with more than 1 Request At The Same Time

我正在使用 Sanic,我们正在使用代理来建立外部连接以进行网络抓取。

我想创建一个 python 字典,并在 python 字典中放置一个代理列表。在此字典中,我们将存储 01 等值。 1 = 代理连接失败。

我希望均匀地访问一个列表,因此我们的代理在一段时间内的使用方式有一些可预测的模式。而不是随机选择它们可能会大量使用 1 个代理而不是其他代理。

但是,由于Sanic有很多工人。我正在想办法解决这个问题。

在视觉上我的想法是,它就像一排代理,每次请求时,上面的代理执行下一步,一旦被调用,它就会再次到线的后面。

类似 https://docs.python.org/2/library/itertools.html#itertools.cycle 似乎是个不错的选择。

但是,我的问题是......这怎么会发生异步和非阻塞。作为工作者或请求可以同时发生。如果同时发生 2-50 个请求,如何解决这个问题。

您最好的选择可能是查看类似 aredis 的内容。 Worker 本质上是子流程,因此共享字典不起作用。

如果您查看使用 worker 设置的源代码,请在名为 serve_multiple

的方法中进一步查看
   def serve_multiple(server_settings, workers):
"""Start multiple server processes simultaneously.  Stop on interrupt
and terminate signals, and drain connections when complete.

:param server_settings: kw arguments to be passed to the serve function
:param workers: number of workers to launch
:param stop_event: if provided, is used as a stop signal
:return:
"""
server_settings['reuse_port'] = True

# Handling when custom socket is not provided.
if server_settings.get('sock') is None:
    sock = socket()
    sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
    sock.bind((server_settings['host'], server_settings['port']))
    sock.set_inheritable(True)
    server_settings['sock'] = sock
    server_settings['host'] = None
    server_settings['port'] = None

def sig_handler(signal, frame):
    logger.info("Received signal %s. Shutting down.", Signals(signal).name)
    for process in processes:
        os.kill(process.pid, SIGINT)

signal_func(SIGINT, lambda s, f: sig_handler(s, f))
signal_func(SIGTERM, lambda s, f: sig_handler(s, f))

processes = []
for _ in range(workers):
    process = Process(target=serve, kwargs=server_settings)
    process.daemon = True
    process.start()
    processes.append(process)

for process in processes:
    process.join()

# the above processes will block this until they're stopped
for process in processes:
    process.terminate()
server_settings.get('sock').close()

Redis 有一个队列,因此您可以从队列中取出一些东西,然后在需要时替换它。

我想你可以用 nginx 实现代理?