Почему я иногда получаю Key Error, используя SQS клиент - PullRequest
0 голосов
/ 06 октября 2018

Я использую клиент boto3 SQS для получения сообщений из очереди AWS SQS FIFO.

def consume_msgs():
    sqs = None
    try:
        sqs = boto3.client('sqs',
                       region_name=S3_BUCKET_REGION,
                       aws_access_key_id=AWS_ACCESS_KEY_ID,
                       aws_secret_access_key=AWS_SECRET_ACCESS_KEY)
    except Exception:
        logger.warning('SQS client error {}'.format(sys.exc_info()[0]))
        logger.error(traceback.format_exc())

  ### more code to process message

Приложение настроено в качестве службы на EC2 с использованием upstart.Работает нормально большую часть времени.Но иногда, когда я перезапускаю службу после изменения кода, приложение завершает работу со следующей ошибкой

2018-10-06 01:29:38,654 WARNING SQS client error <class 'KeyError'>
2018-10-06 01:29:38,658 WARNING SQS client error <class 'KeyError'>
2018-10-06 01:29:38,663 ERROR Traceback (most recent call last):
  File "/home/ec2-user/aae_client/app/run.py", line 194, in consume_msgs
    aws_secret_access_key=AWS_SECRET_ACCESS_KEY)
  File "/home/ec2-user/aae_client/env/lib64/python3.6/dist-packages/boto3/__init__.py", line 83, in client
    return _get_default_session().client(*args, **kwargs)
  File "/home/ec2-user/aae_client/env/lib64/python3.6/dist-packages/boto3/session.py", line 263, in client
    aws_session_token=aws_session_token, config=config)
  File "/home/ec2-user/aae_client/env/lib64/python3.6/dist-packages/botocore/session.py", line 851, in create_client
    endpoint_resolver = self.get_component('endpoint_resolver')
  File "/home/ec2-user/aae_client/env/lib64/python3.6/dist-packages/botocore/session.py", line 726, in get_component
    return self._components.get_component(name)
  File "/home/ec2-user/aae_client/env/lib64/python3.6/dist-packages/botocore/session.py", line 926, in get_component
    del self._deferred[name]
KeyError: 'endpoint_resolver'

Перезапуск службы обычно исправляет это.Это не происходит каждый раз, когда я перезапускаю службу.Что сбивает с толку, так это предупреждение KeyError, ведущее фактическую трассировку ошибки.К чему конкретно относится KeyError?Это не может быть AWS_SECRET_ACCESS_KEY, так как этот ключ никогда не изменяется, и в большинстве случаев он работает просто отлично.Проблема возникает совершенно случайно и приходит и уходит.Поэтому сложно отлаживать.И я не понимаю, как эта ошибка вырвалась из блока try..except

EDIT

Судя по комментариям, это связано с многопоточностью.consume_msg действительно выполняется несколькими потоками def process_msgs ():

for i in range(NUM_WORKERS):
    t = threading.Thread(target=consume_msgs, name='worker-%s' % i)
    t.setDaemon(True)
    t.start()
while True:
    time.sleep(MAIN_PROCESS_SLEEP_INTERVAL)

Ответы [ 2 ]

0 голосов
/ 13 июня 2019

Я получил эту ошибку при создании клиента для S3, но AFAIK это та же проблема.Существует не поточно-безопасный код, который используется в процессе создания клиента:

        if name in self._deferred:
            factory = self._deferred[name]
            self._components[name] = factory()
            # Only delete the component from the deferred dict after
            # successfully creating the object from the factory as well as
            # injecting the instantiated value into the _components dict.
            del self._deferred[name]

(из botocore / session.py в методе get_component - это код, который вызывает KeyError при попыткеудалить ключ, который был удален другим потоком)

Блокировка создания клиента решила его для меня (как предложено в https://github.com/boto/boto3/pull/806)

0 голосов
/ 06 октября 2018

Эта проблема github предполагает, что вы должны установить клиента sqs на верхнем уровне один раз (а не в функции):

sqs = boto3.client('sqs',
                   region_name=S3_BUCKET_REGION,
                   aws_access_key_id=AWS_ACCESS_KEY_ID,
                   aws_secret_access_key=AWS_SECRET_ACCESS_KEY)


def consume_msgs():
    # code to process message
...