123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- import os
- import sys
- import logging
- import asyncio
- from typing import List
- from concurrent.futures import ThreadPoolExecutor
- from alibabacloud_ecs20140526.client import Client as Ecs20140526Client
- from alibabacloud_alb20200616.client import Client as Alb20200616Client
- from alibabacloud_tea_openapi import models as open_api_models
- from alibabacloud_ecs20140526 import models as ecs_20140526_models
- from alibabacloud_alb20200616 import models as alb_20200616_models
- from alibabacloud_tea_util import models as util_models
- from alibabacloud_tea_util.client import Client as UtilClient
- import config
- import utils
- class Sample:
- def __init__(self):
- pass
- @staticmethod
- def create_ecs_client() -> Ecs20140526Client:
- config = open_api_models.Config( # 创建Config对象,用于配置访问凭证
- access_key_id=config.ALIBABA_CLOUD_ACCESS_KEY_ID, # 从config中获取ALIBABA_CLOUD_ACCESS_KEY_ID参数
- access_key_secret=config.ALIBABA_CLOUD_ACCESS_KEY_SECRET # 从config中获取ALIBABA_CLOUD_ACCESS_KEY_SECRET参数
- )
- config.endpoint = 'ecs-cn-hangzhou.aliyuncs.com' # 设置ECS服务的访问地址
- return Ecs20140526Client(config) # 返回配置好的ECS客户端对象
- @staticmethod
- def create_alb_client() -> Alb20200616Client:
- config = open_api_models.Config( # 创建Config对象,用于配置访问凭证
- access_key_id=config.ALIBABA_CLOUD_ACCESS_KEY_ID, # 从config中获取ALIBABA_CLOUD_ACCESS_KEY_ID参数
- access_key_secret=config.ALIBABA_CLOUD_ACCESS_KEY_SECRET # 从config中获取ALIBABA_CLOUD_ACCESS_KEY_SECRET参数
- )
- config.endpoint = 'alb.cn-hangzhou.aliyuncs.com' # 设置ALB服务的访问地址
- return Alb20200616Client(config) # 返回配置好的ALB客户端对象
- @staticmethod
- def create_ecs_instance(ecs_client: Ecs20140526Client, amount: int) -> List[str]:
- instance_ids = []
- for i in range(amount):
- request = ecs_20140526_models.CreateInstanceRequest( # 创建ECS实例请求
- size=config.instance_config['size'], # 实例大小
- category=config.instance_config['category'], # 实例类型
- region_id=config.instance_config['region_id'], # 地域ID
- image_id=config.instance_config['image_id'], # 镜像ID
- instance_type=config.instance_config['instance_type'], # 实例类型
- security_group_id=config.instance_config['security_group_id'], # 安全组ID
- v_switch_id=config.instance_config['v_switch_id'], # 虚拟交换机ID
- instance_name=f"{config.instance_config['instance_name']}-{i+1}", # 实例名称
- unique_suffix=config.instance_config['unique_suffix'], # 是否使用唯一后缀
- password_inherit=config.instance_config['password_inherit'], # 是否继承密码
- zone_id=config.instance_config['zone_id'], # 可用区ID
- key_pair_name=config.instance_config['key_pair_name'] # 密钥对名称
- )
- response = ecs_client.create_instance(request) # 调用ECS客户端的创建实例方法
- instance_id = response.body.instance_id # 获取创建的实例ID
- instance_ids.append(instance_id) # 将实例ID添加到列表中
- logging.info(f"Created ECS instance with ID: {instance_id}") # 记录日志
- return instance_ids # 返回实例ID列表
- @staticmethod
- async def start_services_and_health_check(create_client: Ecs20140526Client, slb_client: Alb20200616Client, ess_instance_ids: List[str]):
- try:
- await utils.send_file_to_ecs(client=create_client, instance_id_list=ess_instance_ids, **config.start_sh) # 发送启动脚本到机器上
- logging.info(f"send start shell file finished, instances: {ess_instance_ids}")
- start_sh_param = "latest"
- server_start_sh = os.path.join(config.start_sh['target_dir'], config.start_sh['name'])
- server_start_commend = f"sh {server_start_sh} {start_sh_param}"
- await utils.run_command(client=create_client, instance_ids=ess_instance_ids, command=server_start_commend) # 启动服务
- global health_instances
- health_instances = []
- max_wait_time = 180
- loop = asyncio.get_running_loop()
- max_workers = 10 # 设置最大线程数
- executor = ThreadPoolExecutor(max_workers=max_workers)
- tasks = [
- loop.run_in_executor(executor, utils.health_check, *args) for args in
- [(slb_client, instance_id, max_wait_time) for instance_id in ess_instance_ids]
- ]
- await asyncio.wait(tasks) # 异步探活
- logging.info(f"health instances count: {len(health_instances)}, {health_instances}")
- if len(health_instances) > 0: # 如果有机器探活成功
- time.sleep(20)
- Sample.mount_alb_to_instance(slb_client, ess_instance_ids) # 将机器挂载到ALB服务器组中
- except Exception as e:
- logging.error(f"An error occurred: {e}")
- sys.exit(1) # 退出程序并返回错误状态码
- @staticmethod
- def mount_alb_to_instance(client: Alb20200616Client, instance_ids: List[str]) -> None:
- try:
- servers = [alb_20200616_models.AddServersToServerGroupRequestServers( # 创建要添加的服务器列表
- server_id=instance_id,
- server_type=config.alb_config['server_type'],
- weight=config.alb_config['weight']
- ) for instance_id in instance_ids]
- add_servers_to_server_group_request = alb_20200616_models.AddServersToServerGroupRequest( # 创建添加服务器到服务器组的请求
- server_group_id=config.alb_config['server_group_id'], # 服务器组ID
- servers=servers # 服务器列表
- )
- runtime = util_models.RuntimeOptions() # 创建运行时选项
- client.add_servers_to_server_group_with_options(add_servers_to_server_group_request, runtime) # 将机器挂载到ALB服务器组中
- except Exception as e:
- logging.error(f"An error occurred: {e}")
- sys.exit(1) # 退出程序并返回错误状态码
- @staticmethod
- def main(args: List[str]) -> None:
- try:
- ecs_client = Sample.create_ecs_client() # 创建ECS客户端
- alb_client = Sample.create_alb_client() # 创建ALB客户端
- amount = int(args[0]) if len(args) > 0 else 1 # 从命令行参数获取amount值,如果没有传入则默认为1
- instance_ids = Sample.create_ecs_instance(ecs_client, amount) # 创建ECS实例并获取实例ID列表
- asyncio.run(Sample.start_services_and_health_check(ecs_client, alb_client, instance_ids)) # 使用asyncio运行启动服务和异步探活
- except Exception as e:
- logging.error(f"An error occurred: {e}")
- sys.exit(1) # 退出程序并返回错误状态码
- if __name__ == '__main__':
- Sample.main(sys.argv[1:]) # 调用main方法,传递命令行参数
|