在物联网架构中,长连接和登录服务器是架构中重要的一部分,而由于牵扯到手机端和物连终端一直在线,而一旦升级长连接服务会导致高并发访问登录服务,进而对整个架构造成压力冲击,甚至造成雪崩现象。
通过近一年的手动部署更新以及日常维护,对更新长连接服务有了一定的认识,也梳理出了“更新八步骤”:
(1)停 nls。使用ucloud控制台,调整到ulb nls machtalk页面,暂停两个后端服务。
(2)关 ncs。使用dcos平台,切换到xcloud-ncs相应节点的目录下,并进行suspend操作。
(3)查 ncs对应的访问地址。
(4)删 删除ncs对应的redis中的server_id_onlines节点。
(5)改 在dcos页面,修改ncs对应的镜像tag。
(6)起 启动ncs节点,等待dcos状态反应正常。
(7)复 恢复一个nls反代节点。
(8)看 观察在线数是否恢复。
其中的关键,在于通过开关登录服务的haproxy代理,实现在长连接服务器重启过程中避免登录服务开启。
以往,以上操作均是手工进行,而随着一次一次的部署和刷新认知,渐渐发现可以通过编程实现自动化的部署。昨日,已经实现了半自动化,仅需一部分人工的方式进行了更新。而本次,将通过调用ucloud sdk python3实现自动控制ulb后端开关。
整体步骤记录如下:
登录UCloud控制台,新增DEVOPS 公钥和私钥。
切换UCloud控制台到ULB界面,在传统负载均衡页面,获取ULB ID
查看相关页面,获取UCloud对应的“地域短ID”
通过查看ULB的页面操作内容,发现操作内容英文说明“UpdateULBAttribute”
翻看SDK说明,找到类似的方法“”
https://ucloud.github.io/ucloud-sdk-python3/services.html?highlight=ulb#ulb
update_backend_attribute(req: Optional[dict] = None, **kwargs) → dict[source]
UpdateBackendAttribute - 更新ULB后端资源实例(服务节点)属性
Request
ProjectId (str) - (Config) 项目ID。不填写为默认项目,子帐号必须填写。 请参考 GetProjectList接口
Region (str) - (Config) 地域。 参见 地域和可用区列表
BackendId (str) - (Required) 后端资源实例的ID(ULB后端ID,非资源自身ID)
ULBId (str) - (Required) 负载均衡资源ID
Enabled (int) - 后端实例状态开关
IsBackup (int) - 是否为backup0:主rs1:备rs默认为0
Port (int) - 后端资源服务端口,取值范围[1-65535]
Weight (int) - 所添加的后端RS权重(在加权轮询算法下有效),取值范围[0-100],默认为1
Response
开始编写代码
安装包
pip install ucloud-sdk-python3
python文件头部,引入sdk包
#!/bin/env python3
from ucloud.core import exc
from ucloud.client import Client
import sys
定义连接的主要信息
client = Client({
"region": "cn-bj2",
"project_id": "xxx",
"public_key": "xxx",
"private_key": "xxx",
})
定义获取目标ulb的详细信息
def get_nls_backendinfon():
try:
resp = client.ulb().describe_ulb({
'ULBId': 'ulb-xxx'
})
except exec.UCloudException as e:
print(e)
else:
print(resp)
找到其中的backend信息
编写开关主要函数
def turn_ulb_nls_to_update_mode():
try:
resp = client.ulb().update_backend_attribute({
'ULBId': 'ulb-xxx',
'BackendId': 'backend-1',
'Enabled': 1,
})
except exec.UCloudException as e:
print(e)
else:
print(resp)
try:
resp = client.ulb().update_backend_attribute({
'ULBId': 'ulb-xxx',
'BackendId': 'backend-2',
'Enabled': 0,
})
except exec.UCloudException as e:
print(e)
else:
print(resp)
try:
resp = client.ulb().update_backend_attribute({
'ULBId': 'ulb-xxx',
'BackendId': 'backend-3',
'Enabled': 0,
})
except exec.UCloudException as e:
print(e)
else:
print(resp)
def turn_ulb_nls_to_normal_mode():
try:
resp = client.ulb().update_backend_attribute({
'ULBId': 'ulb-xxx',
'BackendId': 'backend-1',
'Enabled': 0,
})
except exec.UCloudException as e:
print(e)
else:
print(resp)
try:
resp = client.ulb().update_backend_attribute({
'ULBId': 'ulb-xxx',
'BackendId': 'backend-2',
'Enabled': 1,
})
except exec.UCloudException as e:
print(e)
else:
print(resp)
try:
resp = client.ulb().update_backend_attribute({
'ULBId': 'ulb-xxx',
'BackendId': 'backend-3',
'Enabled': 1,
})
except exec.UCloudException as e:
print(e)
else:
print(resp)
最后,编写程序入口函数
if __name__ == '__main__':
if len(sys.argv) > 1:
# 获取第一个参数(索引1)
action = sys.argv[1]
if action == "get":
get_nls_backendinfon()
elif action == "start":
turn_ulb_nls_to_update_mode()
elif action == "stop":
turn_ulb_nls_to_normal_mode()
else:
print("输入的好像不对,请检查")
print("./ulb_nls.py get -- 获取ulb nls的信息")
print("./ulb_nls.py start -- 调整nls后端状态,进入ncs更新状态")
print("./ulb_nls.py stop -- 调整nls后端转改,进入ncs更新完毕状态")
else:
print("No action specified")
print("输入的好像不对,请检查")
print("./ulb_nls.py get -- 获取ulb nls的信息")
print("./ulb_nls.py start -- 调整nls后端状态,进入ncs更新状态")
print("./ulb_nls.py stop -- 调整nls后端转改,进入ncs更新完毕状态")
最终,实现的开关效果如下: