Archery通知机制与API接口开发
Archery作为专业的MySQL数据库管理平台,提供了强大的多通道消息通知机制和完善的RESTful API接口体系。本文全面解析了Archery的消息通知配置、Webhook集成、API接口设计以及安全认证机制,涵盖了邮件、钉钉、飞书等多种通知渠道的配置方法,工单管理、实例管理、用户管理等核心API接口的使用,以及基于JWT和权限控制的API安全体系。
多通道消息通知配置(钉钉、飞书、邮件)
Archery 提供了强大的多通道消息通知机制,支持通过邮件、钉钉、飞书等多种渠道发送工单审核状态、执行结果等重要通知。本文将详细介绍如何配置和使用这些消息通知功能。
消息通知架构设计
Archery 的消息通知系统采用模块化设计,通过统一的 MsgSender 类封装了所有消息发送功能,支持多种通知渠道:
邮件通知配置
邮件通知是 Archery 最基础也是最常用的通知方式,支持 SMTP 协议和 SSL 加密。
邮件配置参数
在系统设置中配置以下邮件参数:
| 参数名称 | 说明 | 示例值 |
|---|---|---|
| mail_smtp_server | SMTP 服务器地址 | smtp.qq.com |
| mail_smtp_port | SMTP 端口 | 465 |
| mail_ssl | 是否启用 SSL | True |
| mail_smtp_user | 发件人邮箱 | archery@example.com |
| mail_smtp_password | 邮箱密码/授权码 | your_password |
邮件发送示例代码
from common.utils.sendmsg import MsgSender
# 初始化邮件发送器
msg_sender = MsgSender()
# 发送邮件
result = msg_sender.send_email(
subject="SQL工单审核通知",
body="您的SQL工单已被审核通过,请及时查看。",
to=["user1@example.com", "user2@example.com"],
list_cc_addr=["manager@example.com"]
)
钉钉通知配置
Archery 支持两种钉钉通知方式:Webhook 机器人通知和个人消息通知。
钉钉 Webhook 配置
- 在钉钉群中添加自定义机器人
- 获取 Webhook URL
- 在系统设置中配置钉钉相关参数
| 参数名称 | 说明 | 示例值 |
|---|---|---|
| ding_agent_id | 钉钉应用AgentId | 123456 |
| ding_corp_id | 企业CorpId | ding123456 |
| ding_corp_secret | 应用密钥 | your_secret |
钉钉消息发送示例
# Webhook 方式发送
MsgSender.send_ding(
url="https://oapi.dingtalk.com/robot/send?access_token=xxx",
content="SQL工单审核通知:新的工单等待审核"
)
# 发送给指定用户
msg_sender.send_ding2user(
userid_list=["user123", "user456"],
content="您有新的SQL工单需要处理"
)
飞书通知配置
飞书通知同样支持 Webhook 和个人消息两种方式,提供了更丰富的消息格式支持。
飞书配置参数
| 参数名称 | 说明 | 示例值 |
|---|---|---|
| feishu_appid | 飞书应用AppID | cli_xxx |
| feishu_app_secret | 应用密钥 | your_secret |
飞书消息发送示例
# Webhook 方式发送
MsgSender.send_feishu_webhook(
url="https://open.feishu.cn/open-apis/bot/v2/hook/xxx",
title="SQL工单通知",
content="新的SQL工单已提交,请及时审核"
)
# 发送给指定用户
MsgSender.send_feishu_user(
title="工单审核提醒",
content="您有工单需要审核处理",
open_id="ou_xxx",
user_mail="user@example.com"
)
多通道通知工作流程
Archery 的消息通知遵循标准的工作流程,确保消息能够准确及时地送达:
通知模板配置
Archery 提供了丰富的通知模板,支持不同类型的工单和状态:
审核通知模板
| 通知类型 | 触发条件 | 接收对象 |
|---|---|---|
| 新工单申请 | WorkflowStatus.WAITING | 审核组所有成员 |
| 审核通过 | WorkflowStatus.PASSED | 申请人 |
| 审核驳回 | WorkflowStatus.REJECTED | 申请人 |
| 工单终止 | WorkflowStatus.ABORTED | 所有审核人 |
执行通知模板
| 通知类型 | 触发条件 | 接收对象 |
|---|---|---|
| 执行开始 | 工单开始执行 | 申请人、审核人 |
| 执行成功 | 工单执行成功 | 申请人、审核人 |
| 执行失败 | 工单执行失败 | 申请人、审核人 |
高级配置技巧
1. 自定义通知内容
可以通过重写 LegacyRender 类的渲染方法来自定义通知内容:
class CustomNotifier(LegacyRender):
def render_audit(self):
# 自定义渲染逻辑
super().render_audit()
# 修改消息内容
for message in self.messages:
message.msg_content += "\n自定义附加信息"
2. 多渠道同时通知
配置系统参数实现多渠道同时通知:
# 在系统设置中配置多个通知渠道
sys_config.set('mail_notify', 'true')
sys_config.set('ding_notify', 'true')
sys_config.set('feishu_notify', 'true')
3. 通知频率控制
通过配置参数控制通知频率,避免过多通知:
# 设置通知间隔时间(分钟)
sys_config.set('notify_interval', '5')
故障排查与日志
消息通知相关的日志记录在 default logger 中,可以通过查看日志来排查问题:
# 查看消息通知日志
tail -f /var/log/archery/default.log | grep "推送"
常见的故障排查点:
- SMTP 服务器连接问题
- 钉钉/飞书 API 密钥配置错误
- 网络连接问题
- 消息内容格式错误
通过合理配置多通道消息通知,可以确保 Archery 系统中的重要事件能够及时准确地通知到相关人员,提高工作效率和系统可靠性。
RESTful API接口设计与使用
Archery作为专业的MySQL数据库管理平台,提供了完整的RESTful API接口体系,支持开发者通过编程方式集成数据库管理功能到现有系统中。API设计遵循RESTful架构原则,采用标准的HTTP方法和状态码,确保接口的一致性和易用性。
API架构设计
Archery的API架构采用分层设计,包含认证层、业务逻辑层和数据访问层,确保接口的安全性和可扩展性。
认证机制
API采用JWT(JSON Web Token)认证方式,支持标准的Token获取、刷新和验证流程:
# 获取Token示例
import requests
auth_url = "http://archery.example.com/api/auth/token/"
payload = {
"username": "your_username",
"password": "your_password"
}
response = requests.post(auth_url, json=payload)
if response.status_code == 200:
token_data = response.json()
access_token = token_data["access"]
refresh_token = token_data["refresh"]
核心API接口
用户管理接口
用户管理接口提供完整的用户CRUD操作,支持用户信息的创建、查询、更新和删除:
| 接口路径 | HTTP方法 | 功能描述 | 权限要求 |
|---|---|---|---|
/api/v1/user/ | GET | 获取用户列表 | 管理员权限 |
/api/v1/user/ | POST | 创建新用户 | 管理员权限 |
/api/v1/user/<id>/ | PUT | 更新用户信息 | 管理员权限 |
/api/v1/user/<id>/ | DELETE | 删除用户 | 管理员权限 |
# 创建用户示例
def create_user(api_url, token, user_data):
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
response = requests.post(
f"{api_url}/v1/user/",
json=user_data,
headers=headers
)
if response.status_code == 201:
return response.json()
else:
raise Exception(f"创建用户失败: {response.text}")
# 使用示例
user_data = {
"username": "new_user",
"password": "secure_password123",
"display": "New User",
"email": "new.user@example.com",
"is_superuser": False
}
try:
result = create_user("http://archery.example.com/api", access_token, user_data)
print(f"用户创建成功: {result}")
except Exception as e:
print(f"错误: {e}")
实例管理接口
数据库实例管理接口支持MySQL实例的注册、查询和配置管理:
| 接口路径 | HTTP方法 | 功能描述 | 参数说明 |
|---|---|---|---|
/api/v1/instance/ | GET | 获取实例列表 | 支持分页和过滤 |
/api/v1/instance/ | POST | 创建新实例 | 需要实例配置信息 |
/api/v1/instance/<id>/ | GET | 获取实例详情 | 实例ID |
/api/v1/instance/<id>/ | PUT | 更新实例配置 | 实例ID和更新数据 |
/api/v1/instance/<id>/ | DELETE | 删除实例 | 实例ID |
# 获取实例列表示例
def list_instances(api_url, token, page=1, page_size=20):
headers = {"Authorization": f"Bearer {token}"}
params = {"page": page, "page_size": page_size}
response = requests.get(
f"{api_url}/v1/instance/",
headers=headers,
params=params
)
if response.status_code == 200:
return response.json()
else:
raise Exception(f"获取实例列表失败: {response.text}")
# 响应数据结构
{
"count": 15,
"next": "http://archery.example.com/api/v1/instance/?page=2",
"previous": None,
"results": [
{
"id": 1,
"instance_name": "生产MySQL主库",
"type": "mysql",
"db_type": "mysql",
"host": "192.168.1.100",
"port": 3306,
"user": "admin",
"password": "encrypted_password",
"charset": "utf8mb4",
"environment": "prod"
}
]
}
工单管理接口
SQL工单管理是Archery的核心功能,API提供完整的工单生命周期管理:
高级功能接口
SQL语法检查接口
# SQL语法检查示例
def check_sql_syntax(api_url, token, instance_id, db_name, sql_content):
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
payload = {
"instance_id": instance_id,
"db_name": db_name,
"full_sql": sql_content
}
response = requests.post(
f"{api_url}/v1/workflow/sqlcheck/",
json=payload,
headers=headers
)
if response.status_code == 200:
return response.json()
else:
raise Exception(f"SQL检查失败: {response.text}")
# 使用示例
check_result = check_sql_syntax(
"http://archery.example.com/api",
access_token,
instance_id=1,
db_name="test_db",
sql_content="SELECT * FROM users WHERE id = 1;"
)
print(f"检查结果: {check_result}")
批量操作接口
支持批量处理多个数据库实例或工单:
# 批量获取实例资源信息
def batch_get_instance_resources(api_url, token, instance_ids, resource_type):
headers = {"Authorization": f"Bearer {token}"}
results = {}
for instance_id in instance_ids:
try:
response = requests.post(
f"{api_url}/v1/instance/resource/",
json={
"instance_id": instance_id,
"resource_type": resource_type
},
headers=headers
)
if response.status_code == 200:
results[instance_id] = response.json()
except Exception as e:
results[instance_id] = {"error": str(e)}
return results
错误处理与状态码
API采用标准的HTTP状态码体系,确保客户端能够正确处理各种情况:
| 状态码 | 含义 | 典型场景 |
|---|---|---|
| 200 | 成功 | 查询操作成功 |
| 201 | 创建成功 | 资源创建成功 |
| 400 | 错误请求 | 参数验证失败 |
| 401 | 未授权 | Token无效或过期 |
| 403 | 禁止访问 | 权限不足 |
| 404 | 未找到 | 资源不存在 |
| 500 | 服务器错误 | 内部处理异常 |
# 完整的错误处理示例
def safe_api_call(api_func, *args, **kwargs):
try:
response = api_func(*args, **kwargs)
if response.status_code in [200, 201]:
return response.json()
elif response.status_code == 400:
raise ValueError(f"参数错误: {response.text}")
elif response.status_code == 401:
raise PermissionError("认证失败,请检查Token")
elif response.status_code == 403:
raise PermissionError("权限不足")
elif response.status_code == 404:
raise FileNotFoundError("资源不存在")
else:
raise Exception(f"API调用失败: {response.status_code} - {response.text}")
except requests.exceptions.RequestException as e:
raise Exception(f"网络请求错误: {e}")
性能优化建议
- 连接池管理: 使用HTTP连接池减少连接建立开销
- 批量操作: 尽量使用批量接口减少请求次数
- 缓存策略: 对频繁访问的数据实施缓存
- 异步处理: 对耗时操作采用异步调用方式
# 使用连接池的示例
from requests.adapters import HTTPAdapter
from requests.poolmanager import PoolManager
class ArcheryAPIClient:
def __init__(self, base_url, token):
self.base_url = base_url.rstrip('/')
self.token = token
self.session = requests.Session()
# 配置连接池
adapter = HTTPAdapter(
pool_connections=10,
pool_maxsize=10,
max_retries=3
)
self.session.mount('http://', adapter)
self.session.mount('https://', adapter)
self.session.headers.update({
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
})
def get_instances(self, page=1, page_size=20):
params = {"page": page, "page_size": page_size}
response = self.session.get(
f"{self.base_url}/api/v1/instance/",
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



