Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calling RunCommandRequest every 60 seconds got 104 error (Connection aborted) #542

Open
tthnu opened this issue Feb 8, 2025 · 2 comments

Comments

@tthnu
Copy link

tthnu commented Feb 8, 2025

Python version: 3.10.12
SDK-Version:2.16.0

I need to monitor the task process which run on ECS. So I called RunCommandRequest every 60 seconds to get the process info. But got 104 error:
HttpError occurred. Host:ecs-cn-hangzhou.aliyuncs.com SDK-Version:2.16.0 ClientException:SDK.HttpError ('Connection aborted.', ConnectionResetError(104, 'Connection reset by peer'))

Is there any limit to the frequency of RunCommandRequest calling?

@yndu13
Copy link
Contributor

yndu13 commented Feb 17, 2025

Hi,

Could you please let us know how many requests per second you are making to the API? Additionally, could you provide us with a usage example? This information will help us better understand the issue you are experiencing.

In the meantime, we recommend using a single global instance of AcsClient. When initializing AcsClient, you can configure the connection pool size to better suit your needs. For example:

acs_client = AcsClient(pool_size=128)
The pool_size value should be adjusted based on your specific use case and business requirements.

Please let us know if you need further assistance.

@tthnu
Copy link
Author

tthnu commented Feb 17, 2025

Hi,

Could you please let us know how many requests per second you are making to the API? Additionally, could you provide us with a usage example? This information will help us better understand the issue you are experiencing.

In the meantime, we recommend using a single global instance of AcsClient. When initializing AcsClient, you can configure the connection pool size to better suit your needs. For example:

acs_client = AcsClient(pool_size=128) The pool_size value should be adjusted based on your specific use case and business requirements.

Please let us know if you need further assistance.

Thanks for your reply!

I call RunCommandRequest for ONE time every 60 seconds as I say in title. Below is my example code. It's almost a total copy of the code in interface user guide.

#### get client for one time ONLY at the begin of program 
client = AcsClient(args.ali_key, args.ali_secret, args.ali_ecs_region)


def run_command_async(client, cmdcontent, instance_id, timeout=60):
    try:
        request = RunCommandRequest()
        request.set_accept_format('json')

        request.set_Type("RunShellScript")
        request.set_CommandContent(cmdcontent)
        request.set_InstanceIds([instance_id])
        # 执行命令的超时时间,单位s,默认是60s,请根据执行的实际命令来设置
        request.set_Timeout(timeout)
        response = client.do_action_with_exception(request)
        # invoke_id = json.loads(response).get("InvokeId")
        # return invoke_id
        return json.loads(response)
    except Exception as e:
        return {
            'error': f'Running command error occurred: {str(e)}',
            'http_code': -1,
        }

def get_command_output(client, command_id, instance_id):
    """
    获取阿里云 ECS 命令执行的输出结果
    
    Args:
        command_id (str): 命令 ID
        instance_id (str): 实例 ID
    
    Returns:
        dict: 包含命令执行输出的字典
    """
    try:
        # 创建请求对象
        request = DescribeInvocationResultsRequest()
        request.set_accept_format('json')
        
        # 设置请求参数
        request.set_CommandId(command_id)
        request.set_InstanceId(instance_id)
        
        # 发送请求
        response = client.do_action_with_exception(request)
        result = json.loads(response)
        
        # 解析结果
        if result['Invocation']['InvocationResults']['InvocationResult']:
            invocation_result = result['Invocation']['InvocationResults']['InvocationResult'][0]
            
            # 输出是 Base64 编码的,需要解码
            if invocation_result['Output']:
                output = base64.b64decode(invocation_result['Output']).decode('utf-8')
            else:
                output = "No output available"
                
            return {
                'CommandId': command_id,
                'InstanceId': instance_id,
                'Status': invocation_result['InvocationStatus'],
                'Output': output,
                'ExitCode': invocation_result.get('ExitCode'),
                'ErrorInfo': invocation_result.get('ErrorInfo', '')
            }
        else:
            return {
                'error': 'No results found for the specified command and instance'
            }
            
    except Exception as e:
        return {
            'error': f'Running command error occurred: {str(e)}',
            'http_code': -1,
        }

### call RunCommandRequest and DescribeInvocationResultsRequest
res = run_command_async(client, main_cmd, instance_id)
output = get_command_output(client, command_id, instance_id)

time.sleep(60)

I think this frequency will not encounter any TPS limit.

BTW It's OK after using V2 SDK instead of V1 . I can do more test If you need more information to work it out.

from alibabacloud_ecs20140526.client import Client as EcsClient
from alibabacloud_ecs20140526 import models as ecs_models


    def run_command(
        client: EcsClient,
        content: str,
        instance_id: str,
        region_id: str,
    ) -> str:
        """
        RunCommand  执行脚本
        """
        req = ecs_models.RunCommandRequest()
        # ECS实例ID列表
        req.instance_id = [
            instance_id
        ]
        # 可用区ID
        req.region_id = region_id
        # 脚本的明文内容或者Base64编码后的内容
        req.command_content = content
        # 运维脚本的语言类型
        req.type = 'RunShellScript'
        resp = client.run_command(req)
        # ConsoleClient.log('--------------------执行脚本--------------------')
        # ConsoleClient.log(f'脚本ID {resp.body.command_id} 请求ID {resp.body.request_id}')
        return resp.body.command_id

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants