Python Asyncio如何同时处理1个以上的itertools.cycle

时间:2018-07-12 10:04:29

标签: python python-3.x asynchronous sanic

我正在使用Sanic,我们正在使用代理进行外部连接以进行Web抓取。

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

我希望平均访问列表,因此我们的代理服务器在一段时间内的使用方式上具有一些可预测的模式。而不是随机选择它们,它们可能导致1个代理服务器比其他代理服务器大量使用。

但是,由于Sanic有很多工人。我正在尝试弄清楚该如何处理。

从视觉上看,我的想法就像是一行代理,每次请求顶部的代理进行下一步时,一旦被调用,它将再次返回到该行的末尾。

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

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

1 个答案:

答案 0 :(得分:0)

您最好的选择是看诸如aredis之类的东西。工人本质上是子流程,因此共享字典将无法工作。

如果您在使用了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实现代理吗?