问题描述
我正在使用Azure服务总线库供python读取队列中的消息。在x时间段之后 我收到以下错误:
Traceback (most recent call last):
File "/opt/anaconda3/lib/python3.7/site-packages/uamqp/authentication/cbs_auth.py",line 76,in create_authenticator
self._connection.container_id)
File "./src/cbs.pyx",line 73,in uamqp.c_uamqp.CBSTokenAuth.__cinit__
ValueError: Unable to open CBS link.
During handling of the above exception,another exception occurred:
Traceback (most recent call last):
File "/opt/anaconda3/lib/python3.7/site-packages/azure/servicebus/receive_handler.py",line 309,in open
self._handler.open(connection=self.connection)
File "/opt/anaconda3/lib/python3.7/site-packages/uamqp/client.py",line 259,in open
self._build_session()
File "/opt/anaconda3/lib/python3.7/site-packages/uamqp/client.py",line 214,in _build_session
on_attach=self._on_attach)
File "/opt/anaconda3/lib/python3.7/site-packages/uamqp/authentication/cbs_auth.py",line 82,in create_authenticator
"Please confirm target hostname exists: {}".format(connection.container_id,connection.hostname))
uamqp.errors.AMQPConnectionError: Unable to open authentication session on connection b'SBReceiver-00000000-0000-0000-0000-000000000000'.
Please confirm target hostname exists: b'myhostname.servicebus.windows.net'
During handling of the above exception,another exception occurred:
Traceback (most recent call last):
File "/opt/anaconda3/lib/python3.7/runpy.py",line 193,in _run_module_as_main
"__main__",mod_spec)
File "/opt/anaconda3/lib/python3.7/runpy.py",line 85,in _run_code
exec(code,run_globals)
File "/path/to/main.py",line 648,in <module>
main()
File "/path/to/main.py",line 631,in main
run_service_bus()
File "/path/to/main.py",line 482,in run_service_bus
with my_client.get_receiver() as queue_receiver:
File "/opt/anaconda3/lib/python3.7/site-packages/azure/servicebus/base_handler.py",line 57,in __enter__
self.open()
File "/opt/anaconda3/lib/python3.7/site-packages/azure/servicebus/receive_handler.py",line 318,in open
self._handle_exception(e)
File "/opt/anaconda3/lib/python3.7/site-packages/azure/servicebus/base_handler.py",line 131,in _handle_exception
raise ServiceBusConnectionError(message,exception)
azure.servicebus.common.errors.ServiceBusConnectionError: Failed to open handler: Unable to open authentication session on connection b'SBReceiver-00000000-0000-0000-0000-000000000000'.
Please confirm target hostname exists: b'myhostname.servicebus.windows.net'
我认为这里发生的事情是一段时间后我所拥有的令牌过期了。处理此问题的正确方法是什么?
我正在使用的代码如下:
sb_client = ServiceBusClient.from_connection_string("primary_connection_string_here")
my_client = sb_client.get_queue("queue_name_here")
with my_client.get_receiver() as queue_receiver:
messages = queue_receiver.fetch_next(timeout=3)
for message in messages:
message.complete()
解决方法
正如在评论中讨论的那样,这种情况下的问题很可能是由于网络瞬态错误而引起的,这在分布式环境中非常普遍。大多数情况下,瞬时错误可以通过重试来恢复。不幸的是,在 v0.50.x 的旧版python服务总线SDK中,没有开箱即用的重试功能。 latest V7 SDK中已添加了指数退避重试功能(当前处于预览状态,不久将成为GA)。您可以参考migration guide from v0.50 to v7了解更多信息。以下是使用V7 SDK的接收器代码示例(注意:同步版本,还提供了异步支持,您可以在samples的广泛列表中进行检查)。
V7 SDK现在允许您传递客户端的重试参数。尽管默认值通常应该足够。
retry_total
:允许的重试总数。优先于其他计数。默认值为10。
retry_backoff_factor
:在第二次尝试后两次尝试之间应用的退避因素(大多数错误将在第二次尝试后立即解决,而不会造成延迟)。在固定模式下,重试策略将使{backoff factor}处于休眠状态。在“指数”模式下,重试策略将休眠:{backoff factor} *(2 **({total retries}-1))秒。如果backoff_factor为0.1,则重试将在重试之间休眠[0.0s,0.2s,0.4s ...]。默认值为0.8。
retry_backoff_max
:最长退避时间。默认值为120(以秒为单位)。
servicebus_client = ServiceBusClient.from_connection_string(conn_str=CONNECTION_STR,retry_total=10,retry_backoff_factor=1,retry_backoff_max=30)
with servicebus_client:
receiver = servicebus_client.get_queue_receiver(queue_name=QUEUE_NAME)
with receiver:
received_msgs = receiver.receive_messages(max_message_count=10,max_wait_time=5)
for msg in received_msgs:
print(str(msg))
msg.complete()