server#
此模块实现了 per Server metadata 的抽象. See Server for more details.
- class acore_server_metadata.server.server.Server(id: str, ec2_inst: Optional[Ec2Instance] = None, rds_inst: Optional[RDSDBInstance] = None)[source]#
“Server” 是一个逻辑对象, 它代表着一个 Realm 背后的 EC2 实例游戏服务器 和 RDS 数据库实例. 这个 “Server” 类是一个状态信息的数据容器, 包含了 EC2 和 RDS 的不可变信息, 例如 instance id, DB identifier. 也包含了一些可变信息, 例如 EC2 status, DB status, IP 地址等. 有了 Server 对象, 开发者就可以对 EC2, RDS 的信息进行访问, 并能刷新动态信息, 还能对它们进行 例如创建, 启动, 关闭, 删除等操作.
一个 “Server” 必须要有一个 id, 这个 id 的命名规则是
{env_name}-{server_name}, 其中env_name是环境名, 例如sbx,tst,prd等. 而server_name则是对人类友好的一些名字, 例如山丘之王,洛萨等. 在 我们的服务器上我们通常用blue,green这一类的名子.按照我们运维魔兽世界服务器的最佳实践, 每一个 Realm 必须要有一个唯一的 id. 例如你的 魔兽世界服务器大区内有 3 个 realm, 而除了有用于生产环境 (prd) 的 3 个服务器外, 你还有用于开发和测试的 (sbx) 3 个服务器. 那么这六台服务器的 id 就应该是: prd-blue, prd-white, prd-yellow, sbx-blue, sbx-white, sbx-yellow. 而根据 Blue Green Deployment 中提到的蓝绿部署, 我们成对的还有 prd-green, prd-black, prd-orange, sbx-green, sbx-black, sbx-orange 六台服务器.
那么我们如何标记哪个 EC2 和 RDS 实例是属于哪个服务器的呢? 按照我们的最佳实践, 我们用 AWS Resources Tag 来标注这些实例是为哪个 Realm 服务的. 例如我们可以用为每个 EC2 和 RDS 创建一个叫
realm的 tag key. 它所属的服务器 id 是什么, 这个 tag value 就是什么.设计这个类的目的是是为了能让这个对象能方便的获取 EC2 和 RDS 的 Metadata, 以及进行 health check. 基于此我们可以实现对整个 Server 集群 (Fleet) 进行管理, 了解集群中的 每台机器的状态, 并对它们进行操作.
Note
这个类是个典型的有状态对象. 里面的属性随着时间会发生变化. 请注意开发时不要将它按照一个 immutable 的数据容器那样设计.
- classmethod get_ec2(ec2_client: EC2Client, id: str) Optional[Ec2Instance][source]#
尝试获取某个 Server 的 EC2 实例信息. 如果 EC2 “不存在” 则返回 None. “不存在” 的含义是这个机器还没有被创建, 或是已经被永久删除了. 如果机器存在而是处于 “启动中”, “停止中” 这一类的情况, 由于这个机器还可以回到 “运行中” 的状态, 所以被视为 “存在”. 而如果我们发现有多台实例都有这个 Tag, 这一定是业务上出现了什么错误, 所以会抛出异常.
- Parameters:
id – server id,
{env_name}-{server_name}
- classmethod get_rds(rds_client: RDSClient, id: str) Optional[RDSDBInstance][source]#
尝试获取某个 Server 的 RDS 实例信息. 如果 RDS “不存在”则返回 None. “不存在” 的含义是这个机器还没有被创建, 或是已经被永久删除了. 如果机器存在而是处于 “启动中”, “停止中” 这一类的情况, 由于这个机器还可以回到 “运行中” 的状态, 所以被视为 “存在”. 而如果我们发现有多台实例都有这个 Tag, 这一定是业务上出现了什么错误, 所以会抛出异常.
- Parameters:
id – server id,
{env_name}-{server_name}
- classmethod from_ec2_inside(ec2_client: Optional[EC2Client] = None, rds_client: Optional[RDSClient] = None) Server[source]#
用 “自省” 的方式, 从 EC2 实例内部通过 metadata API 获得自己的 instance id, 进而获得 Server 的 metadata. 如果这台 EC2 不是一个魔兽世界服务器, 那么将会抛出异常.
- Parameters:
ec2_client – optional EC2 client, if not given, will automatically create on using EC2 IAM role.
rds_client – optional RDS client, if not given, will automatically create on using EC2 IAM role.
- classmethod get_server(id: str, ec2_client: EC2Client, rds_client: RDSClient) Server[source]#
尝试获得某个 Server 的 EC2 和 RDS 信息. 这个方法会同时调用
Server.get_ec2()和Server.get_rds(). 无论 EC2 还是 RDS 存不存在, 它都会返回一个Server对象. 如果 EC2 或 RDS 不存在, 那么.ec2_inst或.rds_inst属性的值可能是 None. 关于 “不存在” 的定义请参考Server.get_ec2()和Server.get_rds().该方法是本模块最常用的方法之一. 用例如下:
>>> server = Server.get_server("prd-1", ec2_client, rds_client) >>> server Server( id='prd-1', ec2_inst=Ec2Instance( id='i-eb5ffe7acc68a252c', status='running', ... tags={'realm': 'prd-1'}, data=... ), rds_inst=RDSDBInstance( id='db-inst-1', status='available', tags={'realm': 'prd-1'}, data=... ), )
这个方法只会返回被调用时的 EC2 和 RDS 状态. 如果你要获得它们的最新状态, 请使用
Server.refresh()方法.
- classmethod batch_get_server(ids: List[str], ec2_client: EC2Client, rds_client: RDSClient) Dict[str, Optional[Server]][source]#
类似于
Server.get_server(), 但是可以批量获取多个 Server 的信息, 减少 API 调用次数.用例:
>>> server_mapper = Server.batch_get_server( ... ids=["prod-1", "prod-2", "dev-1", "dev-2"], ... ec2_client=ec2_client, ... rds_client=rds_client, ... ) >>> server_mapper { "prod-1": <Server id="prod-1">, "prod-2": <Server id="prod-2">, "dev-1": <Server id="dev-1">, "dev-2": <Server id="dev-2">, }
- refresh(ec2_client: EC2Client, rds_client: RDSClient)[source]#
重新获取 EC2 和 RDS 实例的信息. 刷新当前类的
ec2_inst和rds_inst属性.
- ensure_ec2_not_exists()[source]#
Raises an exception if EC2 instance for this server already exists.
- ensure_rds_not_exists()[source]#
Raises an exception if RDS instance for this server already exists.
- ensure_ec2_is_running()[source]#
Raises an exception if EC2 instance for this server is not running.
- ensure_ec2_is_ready_to_start()[source]#
Raises an exception if EC2 instance for this server is not ready to start.
- ensure_ec2_is_ready_to_stop()[source]#
Raises an exception if EC2 instance for this server is not ready to stop.
- ensure_rds_is_running()[source]#
Raises an exception if RDS instance for this server is not running.
- ensure_rds_is_ready_to_start()[source]#
Raises an exception if RDS instance for this server is not ready to start.