#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 секунд). Это не должно было вызвать проблему с вашим приложением, так как оно в любом случае часто получало бы нулевые сообщения. Итак, я рад, что вам удалось это исправить, но я не понимаю, как это стало причиной проблемы.