Python: архитектура для URL-опроса и публикации - PullRequest
0 голосов
/ 16 ноября 2009

У меня простая проблема. Я должен получить URL (примерно раз в минуту), проверить, есть ли новый контент, и, если есть, опубликовать его на другой URL.

У меня есть рабочая система с 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 минуту, и у меня останется миллион из них, выполняющих перезапись друг друга.

Итак, как мне это переписать?

Некоторые проблемы:

  • Я не хочу слишком сильно бить по API, если они меня блокируют. Поэтому я хотел бы иметь максимум 5 открытых соединений с любым API в любое время.
  • Пользователи продолжают регистрироваться в системе, пока это выполняется, поэтому мне нужно как-то добавить их
  • Я бы хотел, чтобы это масштабировалось как можно лучше
  • Я бы хотел использовать как можно больше существующего кода

Итак, некоторые мысли у меня были:

  • Создать поток для каждого link
  • Использовать Python-Twisted - Оставить один запущенный процесс, который cronjob просто гарантирует, что работает.
  • Использовать без стеков - Не особо много знаю об этом.
  • Ask StackOverflow:)

Как бы вы это сделали?

1 Ответ

2 голосов
/ 16 ноября 2009

Самый простой: использовать длительный процесс с sched (в своем собственном потоке) для управления расписанием - отправляя запросы в Очередь ; иметь пул потоков фиксированного размера (вы можете найти готовый пул потоков здесь , но его легко настроить или свернуть самостоятельно), принимая запросы из очереди (и возвращая результаты через отдельную очередь ). При необходимости регистрация и другие системные функции могут выполняться несколькими выделенными потоками.

Потоки не так уж и плохи, если (а) вам никогда не придется беспокоиться о синхронизации между ними (просто попросите их обмениваться данными с помощью поточно-ориентированных экземпляров очереди, никогда не будет делиться доступом к любой структуре или подсистема, которая не только для чтения), и (b) у вас их никогда не бывает слишком много (используйте несколько выделенных потоков для специализированных функций, включая планирование, и небольшой пул потоков для общей работы - никогда порождает поток за запрос или что-то в этом роде, которое взорвется).

Twisted может быть более масштабируемым (с низкими затратами на оборудование), но если вы используете архитектуру threading (и Queues), у вас есть встроенный способ расширения системы (путем покупки большего количества оборудования) вместо этого использовать очень похожий многопроцессорный модуль ... практически замену и потенциальное увеличение на несколько порядков! -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...