本文为您介绍使用SDK时,可能遇到的问题。

使用SDK时遇到报错ErrCode:SDK.ServerUnreachable怎么办?

问题现象

当您使用SDK时,遇到以下报错信息(请求超时或服务器不可达):

ErrCode:ServerUnreachable
ErrMsg:SocketTimeoutException has occurred on a socket read or accept.
解决方案
  1. 在请求中设置ClientToken参数避免多次重试带来重复操作的问题。

    Python示例代码如下:

    #!/usr/bin/env python
    # coding=utf-8
    import time
    import uuid
    
    from aliyunsdkcore.client import AcsClient
    from aliyunsdkcore.acs_exception.exceptions import ClientException, ServerException
    from aliyunsdkros.request.v20190910.CreateStackRequest import CreateStackRequest
    
    ACCESS_KEY_ID = ''
    ACCESS_KEY_SECRET = ''
    REGION_ID = 'cn-beijing'
    
    
    def generate_client_token(prefix, add_uuid, *suffix_list):
        if prefix:
            t = [prefix]
        else:
            t = []
        if add_uuid:
            t.append(str(uuid.uuid1())[:-13])
        t.extend(suffix_list)
        r = '_'.join(t)
        if len(r) > 64:
            r = r[:64]
        return r
    
    
    def retry_with_client_token(retry_interval=10, retry_time_out=300):
        def wrapper(fun):
            def retry_func(*args, **kwargs):
                retry_timeout = retry_time_out
                elapsed_time = 0
                # 保证请求的幂等性。该值由客户端生成,并且必须是全局唯一的。
                kwargs['ClientToken'] = generate_client_token(None, True)
                while True:
                    try:
                        retry_timeout -= elapsed_time
                        return fun(*args, **kwargs)
                    except Exception as e:
                        if isinstance(e, ClientException):
                            if e.error_code != 'SDK.HttpError':
                                raise
                        elif isinstance(e, ServerException):
                            if e.error_code not in ('LastTokenProcessing', 'ServiceUnavailable'):
                                raise
                        else:
                            raise
    
                        time.sleep(retry_interval)
                        elapsed_time += retry_interval
                        if elapsed_time >= retry_timeout:
                            raise
    
            return retry_func
    
        return wrapper
    
    
    class RosClient(object):
        def __init__(self):
            self.client = AcsClient(ACCESS_KEY_ID, ACCESS_KEY_SECRET, REGION_ID)
    
        def _send_request(self, request, params, **kwargs):
            request.set_accept_format('json')
            request.set_connect_timeout(10000)
            request.set_read_timeout(0.01)
            params.update(kwargs)
            for name, value in params.items():
                set_func = getattr(request, 'set_{}'.format(name))
                set_func(value)
            return self.client.do_action_with_exception(request)
    
        @retry_with_client_token(retry_interval=10, retry_time_out=300)
        def create_stack(self, params, **kwargs):
            request = CreateStackRequest()
            return self._send_request(request, params, **kwargs)
    
    
    if __name__ == '__main__':
        ros_client = RosClient()
        result = ros_client.create_stack(dict(
            StackName='test',
            TemplateBody="{\"ROSTemplateFormatVersion\": \"2015-09-01\"}"
        ))
        print('stack_id:', result)                  
  2. 如果问题依然存在,请提交工单获取支持。