0

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

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

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

但是,由于 Sanic 有许多工人。我试图弄清楚如何处理这个问题。

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

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

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

4

1 回答 1

0

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

如果您查看使用工人设置的源代码,请在名为 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 实现的代理?

于 2018-07-24T12:41:47.793 回答