Python Boto3 не получает сообщений, но SQS отображается в полете

#python #amazon-web-services #boto3 #amazon-sqs

Вопрос:

У меня есть докер, который получает сообщения из стандартного SQS. Но в большинстве случаев код показывает, что он получил ноль сообщений и завершает работу. В то время как консоль SQS отображает сообщения в разделе «Сообщения в полете», значит, сообщения были получены каким-то потребителем.

Это моя точка входа в докер

 ENV PYTHONPATH="$PYTHONPATH:/app"

ENTRYPOINT [ "python3" ]
CMD ["multi.py"]
 

Это multi.py код

 import multiprocessing as mp
import subprocess

def s():
    subprocess.call(['python3', 'script.py'])

n_process = min(mp.cpu_count(), 8)
process = []

for i in range(n_process):
    p = mp.Process(target=s)
    process.append(p)
    p.start()

for p in process:
    p.join()
 

Это script.py часть кода, которая вызывает receive_messages

 sqs = boto3.resource('sqs', region_name=REGION, aws_access_key_id=ACCESS_KEY, aws_secret_access_key=SECRET_KEY)
queue = sqs.get_queue_by_name(QueueName=QUEUE_NAME)

def main():
    while True:
        m = queue.receive_messages()
        for message in m:
            process_message(message)
            message.delete()
 

Кроме того, докер работает примерно в 60% случаев. Но я пытаюсь понять, почему это не удается.

PS: Решено, это из документов boto3

Короткий опрос-это поведение по умолчанию, при котором при вызове ReceiveMessage отбирается взвешенный случайный набор машин. Таким образом, возвращаются только сообщения на выбранных машинах. Если количество сообщений в очереди крайне мало, вы можете не получить никаких сообщений в конкретном ответе ReceiveMessage. Если это произойдет, повторите запрос.

Комментарии:

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

2. Я пробовал регистрировать данные, подпроцесс запускает сценарий, а длина «m» равна нулю, процесс завершается. Но затем я проверяю SQS, который показывает, что сообщения были израсходованы.

3. Если queue.receive_messages() что-то вернет, то он извлечет одно сообщение из списка сообщений, а затем позвонит process_message() (которое вы нам не показали). Что вы подразумеваете под «длина» m «равна нулю» — единственное место, где вы показали нам m переменную, находится непосредственно перед вызовом process_message() . Возможно, вам нужно показать нам дополнительный код и результаты вашей отладки?

4. очередь. функция receive_messages() возвращает список сообщений, либо много, если указано, либо только одно. Он возвращает мне пустой список, даже если в очереди есть сообщения. Но благодаря тебе я разобрался в этом вопросе.

5. Если ваше решение будет полезно другим людям, не стесняйтесь добавлять его в качестве ответа на свой собственный вопрос. Или, если вы думаете, что это не поможет людям (из-за того, что это вызвано ошибкой в другом месте), не стесняйтесь удалять этот вопрос.

Ответ №1:

m = queue.receive_messages(WaitTimeSeconds=5)

Это решит проблему, потому что в тех случаях, когда в SQS очень мало сообщений, опрос сообщений, скорее всего, завершится неудачей.

Вы можете прочитать о коротком опросе в документах boto3 здесь. https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sqs.html#SQS.Queue.получение_сообщения

Комментарии:

1. Параметр определяет, сколько времени должен ждать запрос, прежде чем возвращать пустой результат (максимальное значение 20 секунд). Это не должно было вызвать проблему с вашим приложением, так как оно в любом случае часто получало бы нулевые сообщения. Итак, я рад, что вам удалось это исправить, но я не понимаю, как это стало причиной проблемы.