我有一个简单的问题。我必须获取一个网址(大约每分钟一次),检查是否有新内容,如果有,请将其发布到另一个网址。
我每分钟都有一个带有cronjob的工作系统,基本上是:
for link in models.Link.objects.filter(enabled=True).select_related():
# do it in two phases in case there is cross pollination
# get posts
twitter_posts, meme_posts = [], []
if link.direction == "t2m" or link.direction == "both":
twitter_posts = utils.get_twitter_posts(link)
if link.direction == "m2t" or link.direction == "both":
meme_posts = utils.get_meme_posts(link)
# process them
if len(twitter_posts) > 0:
post_count += views.twitter_link(link, twitter_posts)
if len(meme_posts) > 0:
post_count += views.meme_link(link, meme_posts)
count += 1
msg = "%s links crawled and %s posts updated" % (count, post_count)
这对我现在拥有的150个用户来说非常有用,但它的同步性让我感到害怕。我有内置的url超时,但在某些时候我的cronjob将采取> 1分钟,我将留下一百万人在另外一起覆盖。
那么,我应该如何重写呢?
一些问题:
所以,我有过一些想法:
link
你会怎么做?
答案 0 :(得分:2)
最简单:使用sched(在其自己的线程上)长时间运行的进程来处理调度 - 通过将请求发布到Queue;有一个固定大小的线程池(你可以找到一个预先制作的线程池here,但很容易调整它或自己动摇)从队列中获取请求(并通过一个单独的队列返回结果)。如果需要,可以通过一些专用线程来处理注册和其他系统功能。
线程并不是那么糟糕,只要(a)你永远不必担心它们之间的同步(只是让它们通过本质上线程安全的队列实例进行通信,永远不会共享对任何线程的访问权限不严格只读的结构或子系统,以及(b)你从来没有太多(使用一些专用线程用于专门的功能,包括调度,以及用于一般工作的小线程池 - never 每个请求或类似的东西产生一个线程,它会爆炸)。
Twisted可以更具可扩展性(以较低的硬件成本),但是如果您在threading(和队列)上铰接架构,则可以通过内置方式来扩展系统(通过购买更多硬件)来使用非常相似的multiprocessing模块而不是......几乎是一个简单的替代品,可能会扩大数量级! - )