☰
Archery SQL审核平台部署运维实战:从选型到落地避坑指南
2026/10/7 10:54:52 网站建设 项目流程

做SQL审核平台这件事,我一开始是拒绝的。团队里几十号人天天写SQL,上线全靠DBA人肉看,每次发版都像打仗。直到有一次一条漏看的DELETE语句把核心业务的流水表清了大半,我才下定决心把Archery这套开源方案部署起来。这篇文章不聊PPT上的架构图,就讲实际部署运维过程中踩过的坑、填过的土,以及最终跑起来之后到底解决了什么问题。如果你所在团队正在纠结要不要上SQL审核工具,或者已经在部署Archery但卡在某个环节,这篇手册就是给你写的。

1. 部署前的准备工作与架构设计

1.1 组件清单与版本选型

Archery本质上是一套基于Django开发的Web管理平台,它本身不直接执行“审核”,而是把众多开源工具的能力串起来。一个完整可用的最小集包含下面这几块:

  • Archery主服务:Python 3.6+(我用的3.8),Django框架,负责UI、工单流程、审批逻辑和后台任务调度。
  • MySQL元数据库:存放平台自身的用户、工单、资源组、实例配置等数据。建议独立实例,别和业务库混在一起。
  • Redis:用于存放Celery异步任务队列、会话缓存和一些临时状态。
  • goInception:这是整个审核链路的核心执行引擎。它负责解析SQL语法、检查执行计划、模拟回滚语句等。Archery通过API调用它。
  • 需要审核的MySQL实例:即你要纳管的业务数据库。
  • 可选组件:LDAP对接、邮件服务、钉钉/企业微信机器人、Sqladvisor(依赖Percona Toolkit)等。

版本选型上我吃过亏。早期图省事直接拉最新版,结果goInception和Archery的API对接出现字段不兼容,审核接口一直返回参数错误。后来老老实实按照官方release页面里的版本对照表来:Archery 1.9.x对应goInception某个固定release,Python用3.8,MySQL元数据库用5.7。这套组合我跑了近一年,稳定性没问题。不要追求新版,生产环境求的是组合兼容性,不是单个组件的新鲜度。

1.2 首次部署前的依赖准备

在拿到安装脚本之前,有几个前置条件务必先确认好,否则后面会反复折腾:

网络与仓库。Archery主程序通过pip安装依赖,服务器必须能访问Python包仓库。如果环境隔离,提前准备好内网pip源的镜像,把requirements.txt里的包都预拉下来。

系统用户规划。我建议单独创建一个archery系统账户,所有应用目录和服务进程都归属这个账户,避免用root跑应用导致权限混乱。

元数据库初始化权限。安装主服务时,它需要用一个高权限账户来创建元数据库和表结构。我建了一个archery_admin账户,只授予元数据库实例上的全部权限,业务实例权限一律不给。

端口占用检查。Archery默认监听8000端口,Celery Beat和Worker走Redis的6379端口。部署前用ss -lntp看一遍,尤其是8000端口,很多机器上会被其他Web服务占用,改端口不难,但后续写巡检脚本时容易漏。

目录规划。日志、上传的SQL附件、备份临时文件,这些最好都挂在独立的数据盘目录下,比如/data/archery_logs、/data/archery_upload。不要把东西塞进根分区,生产环境日志增长速度超出你想象。

2. 核心部署流程与安装步骤

2.1 基于Docker Compose的快速部署实践

我最终采用的是Docker Compose方式部署,原因很简单:依赖隔离、可复现、回滚方便。如果你的团队没有容器化运维基础,用官方提供的bin目录下的install.sh脚本同样可以,但后续升级时容易在依赖版本上折腾。

先把Compose编排文件的关键部分拆出来讲,这份文件决定了整个平台的运行形态:

version: '3' services: archery: image: hhyo/archery:1.9.2 container_name: archery ports: - "8000:8000" volumes: - /data/archery_logs:/usr/local/archery/logs - /data/archery_upload:/usr/local/archery/upload environment: - MYSQL_HOST=192.168.10.10 - MYSQL_PORT=3306 - MYSQL_DBNAME=archery - MYSQL_USERNAME=archery_admin - MYSQL_PASSWORD=xxxx - REDIS_HOST=192.168.10.11 - REDIS_PORT=6379 - REDIS_DB=0 restart: always

Compose里只起一个Archery容器,Redis和元数据库我选择用独立部署的实例,而不是一并容器化。起初贪图省事把三者叠在一个Compose里,结果一次宿主机重启后容器启动顺序错乱,Django因连不上数据库反复报错。后来把数据库和Redis挪出去,主服务容器只关注自身状态,稳定性提升一个量级。生产环境建议遵循这个思路:有状态服务独立部署,无状态应用容器化。

注意:Archery官方镜像的默认启动命令会先执行数据库迁移再启动服务,首次启动需要确保元数据库连接信息正确。如果填错了账密,容器会持续重启,必须用docker logs archery查看日志并修正环境变量后重新创建容器。

2.2 初始化与系统配置

容器跑起来之后,打开http://服务器IP:8000,默认管理账密是admin/archery,登录后第一件事是改密码,这没得商量。

接下来按顺序处理这些配置项:

消息通知配置。Archery的工单流转靠通知驱动,不配通知等于审核完没人知道。进入“系统管理 - 配置项管理”,把ding_robot_hook和mail这两大类参数填上。钉钉机器人的方式最简单,Webhook地址填进去,勾选“工单待办通知”即可。邮件配置需要注意,很多企业邮箱使用授权码而非登录密码,填错会一直报SMTP认证失败。

资源组与用户权限。Archery的权限模型是“用户-资源组-实例”三层。先创建资源组,比如“核心交易库组”,然后把对应的MySQL实例加入这个组,最后把DBA和开发人员拉进组并分配不同角色。这里有个容易踩的坑:开发人员如果没有加入任何资源组,登录后看不到任何实例,会误以为平台坏了。建议部署完成后先用一个普通测试账号完整走一遍“建组-加实例-分配人员-提交工单-审批-执行”的全流程,确认链路通了再正式开放给团队。

审核规则配置。Archery的审核规则源于goInception的能力,比如禁止不带WHERE条件的UPDATE/DELETE、禁止使用SELECT *、表名必须小写等。规则不是越多越好,默认规则集可以先全开,跑两周看看误报率。我遇到的情况是“禁止使用跨库查询”这条规则误伤了正常需求,后来改成白名单模式才消停。

Django Admin后台。如果你熟悉Django,可以直接通过/admin/路径管理更多底层配置,比如自定义工单状态流转、调整Celery任务频率。不熟也没关系,90%的日常运维操作在Arc h cry主界面就能完成。我习惯定期去Admin后台看看django_celery_beat的定时任务是否正常,这个后台暴露了Archery内部依赖的Celery调度状态,很有观察价值。

3. SQL审核功能配置与实操要点

3.1 上线前必改的几个安全参数

部署完成不等于能用,有几个安全参数是上线前必须确认的,否则审核功能形同虚设:

审核开关。在“实例管理”里每接入一个MySQL实例,都要明确勾选“启用审核”和“启用执行”。我第一次部署时漏勾了“启用执行”,导致开发提的工单卡在待执行状态,审批人通过后SQL依然没跑。你可以在实例列表里批量编辑,但建议养成每个实例接入后立即验证的习惯。

goInception连接配置。Archery需要配置与goInception的连接信息,包括host、port和鉴权token。这里有一个非常关键的点:goInception的token校验如果开启,Archery侧必须填一致。很多人部署完审核一直报错,排查半天发现是token不一致。默认配置里token通常是空的,如果没特殊需求就不要开,少一个变量少一个问题。

备份开关。执行DML语句时,Archery默认通过goInception生成回滚SQL。这个能力依赖binlog格式为ROW模式。如果你的业务库binlog_format不是ROW,回滚SQL生成会失败,执行工单直接报“备份失败”。这是线上执行最危险的情况——SQL可能已经执行了,但回滚脚本没生成。务必提前检查所有接入实例的binlog格式,同步开启binlog_row_image=FULL,否则抓不到镜像数据。

SQL过滤与拦截。在配置项中有一项sql_blacklist,可以配置禁止执行的SQL语句正则。我强烈建议把^drop\s+database、^truncate\s+table这类高危语句加入黑名单,哪怕流程有审批,多一层防护总没错。这条经验源于一次事件:某开发把TRUNCATE写进了迁移脚本,审核规则没拦截,审批人没细看直接点了通过,线下表直接被清。加入黑名单后,这类语句连工单都提交不上去,直接从源头堵住。

3.2 工单审核模式与拆分逻辑

Archery支持在线和离线两种审核模式,我在实际使用中总结了一套分工策略:

在线模式适用于MySQL实例可以直接连通平台的情况。开发提交SQL后,平台实时调用goInception解析,反馈语法错误、索引缺失、锁表风险等信息给提交人,开发按提示修改后重新提交。这个过程把很多低级的SQL问题拦截在DBA介入之前,极大释放DBA的重复劳动。

离线模式适用于目标实例不能从Archery服务器直连的场景(比如生产环境在网络隔离区,或者云数据库白名单严格控制)。开发上传SQL文件,平台离线解析,给出审核报告。执行阶段由DBA把审核通过的SQL带到生产环境手动执行。这里要注意离线模式下的回滚SQL生成依赖更多手工步骤,我在实践里要求DBA在手动执行后,立即手动登录实例记录回滚所需的binlog位点,不能依赖平台自动生成。

提交拆分是开发同学最常问的功能——一张工单能提交多条SQL吗?Archery允许一个工单包含多条语句,但会导致审核耗时变长、排查问题时定位困难。我建议开发团队约定:每条工单只提交一个变更操作的SQL,DDL和DML分开提。这样做的好处是审批人能快速理解变更意图,出现问题回滚时范围可控。为了推行这个约定,我在团队规范里写明了工单模板和拆分子单的规则,效果比单纯口头要求好很多。

4. 常见故障排查与运维经验实录

4.1 部署期高频报错及解决手记

整理线上环境下我遇到过的、以及社区里高频出现的几个部署故障,按出现概率排序:

问题一:Archery容器反复重启,日志报数据库连接超时

这是首次部署最常见的问题。原因通常是元数据库的访问权限没放开,或者Archery服务器到元数据库的网络不通。排查思路不要一上来就改Compose文件,先做链路测试:在宿主机上执行telnet 元数据库IP 3306,确认端口通不通;再用mysql客户端手动验证账密能否登录。我用这个流程解决过三次案例,每次都发现是网络策略或密码错误,没有一次是配置格式的问题。

问题二:登录后所有页面的数据加载缓慢

这类问题不是Archery本身性能差,而是元数据库连接配置中的连接池参数不合理。Archery使用Django ORM默认连接管理,在高并发访问时会频繁建连。调整元数据库的max_connections,并在Archery配置项里增加连接池复用参数。实测下来把元数据库的max_connections从默认151调整为500后,页面响应从7秒降到1秒以内。注意,如果是容器环境,元数据库实例本身的连接数上限也要相应调大。

问题三:goInception执行审核时超时

线上SQL复杂时,goInception解析耗时可能达到几十秒,而Archery默认的HTTP请求超时时间是30秒。遇到“审核超时”报错时,不要慌,先看goInception容器日志确认SQL解析是否完成。如果解析已完成只是返回超时,去Archery配置项中调大api_conn_timeout;如果goInception日志显示OOM,那要调大它的内存限制。我在一次排查中把goInception的max_allowed_packet从16M调到64M后,大批长SQL审核超时问题消除。

问题四:定时任务不执行,工单状态不流转

Archery依赖Celery Beat执行定时任务,比如待办提醒、工单关闭、数据统计。如果这些任务突然停了,绝大多数情况是Redis连接断开或者Celery Worker崩了。进入Archery容器执行ps aux | grep celery,确认worker进程在不在;再检查Redis内存占用,如果maxmemory策略是noeviction,Redis写满后任务队列写不进去,表现为“定时任务静默失败”。我把Redis的maxmemory-policy改为allkeys-lru后,这个问题再没出现过。

4.2 生产环境日常运维清单

平台稳定运行后,日常运维要有清单意识,我按日、周、月三个粒度整理了一份:

每日巡检:

  • 查看Archery日志中有无ERROR级别的异常,关注goInception调用失败和邮件发送失败两类报错。
  • 检查未闭环工单数量,昨日提交的工单至今未审批的,主动提醒对应审批人。
  • 检查Celery任务队列长度,如果积压过多,先排查Redis内存和Worker进程。

每周检查:

  • 清理三个月前的上传SQL附件和过期工单附件,Archery本身没有自动清理机制,手动清理不及时会占用大量磁盘。
  • 抽查几条已执行的DML工单,核对回滚SQL的可执行性——别等出事了才发现根本没生成回滚脚本。
  • 检查元数据库表的膨胀情况,information_schema.tables按数据大小排序,针对大表做归档。

每月复盘:

  • 导出本月所有审核不通过的SQL明细,按“语法错误、无索引、不规范写法、高危操作”分类统计,把高频问题汇总成培训材料发到研发群。
  • 验证备份数据的可恢复性,随机选一条线上最近执行过的DML,用生成的回滚SQL在测试库复跑,确认数据能恢复到执行前状态。

这套清单执行下来,团队SQL变更导致的线上事故从每个季度两三次降到了半年零次。平台的价值不只在“拦得住问题SQL”,更在于让整个变更流程变得可追溯、可复盘。

4.3 关于外部依赖与敏感操作的避险建议

Archery部署过程中不可避免地要处理一些敏感环节,这里单独说一下我的操作规范:

密码管理层面,平台配置的元数据库账密、业务库账密、goInception token,都属于核心敏感信息。生产环境必须通过环境变量或密钥管理服务注入,不能硬编码在Compose文件和配置文档里。我目前在用的方式是部署脚本从密钥服务器动态拉取配置,Archery容器本身不存储明文账密。

高危命令操作层面,无论遇到多紧急的问题,都避免在Archery服务器上直接执行针对业务库的高危SQL。先走平台工单或者至少先手动备份,确认影响范围后再操作。这个习惯无数次帮我避免从“解决一个问题”变成“制造另一个问题”。

变更时间窗口层面,Archery平台自身的升级、重启、配置改动,都要像业务变更一样走变更申请流程,并且选择业务低峰期操作。有一次我在白天高峰时段重启了Celery Worker,结果刚好有大批工单在队列里等待执行,重启后部分任务状态错乱,工单卡死,深更半夜才清理干净。

5. 落地扩展与团队协作经验

5.1 与现有流程的衔接方式

Archery上线不能只靠工具本身,更关键的是和团队现有流程串起来。我的做法是开发了一条明确的SQL发布路径:开发同学完成编码后在本地或测试环境用EXPLAIN分析通过的基础语句提交到Archery -> 平台自动审核并反馈修改建议 -> 开发修改通过后提交工单 -> 技术主管审批 -> DBA复核 -> 平台执行或人工执行。整个路径通过Archery的工单状态流转串联,责任人清晰,回溯有据。

这里有一个容易让团队抵触的点:以前开发自己连上数据库就能执行SQL,现在多了工单提交、审批、等待的环节,必然会觉得“变慢了”。我的应对策略是设置差异化的审核力度——对测试环境实例只开基础规则,不强制审批;对生产实例全量规则加双人审批。这样既守住了底线,又给日常开发保留了效率空间。实操下来团队接受度高了很多。

5.2 巡检脚本与监控告警的补充方法

Archery自身没有完善的监控告警体系,需要结合外部工具补齐。我用Zabbix + Prometheus双轨做了基础监控:

  • 进程存活监控:定期检测Archery容器状态、Celery Worker进程数、goInception容器存活。
  • 端口连通性检查:从监控机定时探测8000端口、6379端口、goInception的回调端口,三个端口任何一个不通都说明平台链路异常。
  • 工单积压量采集:写了一个小脚本,查询Archery元数据库中最近24小时内“待审批”工单量,超过阈值就告警。这个指标直接反映平台使用强度和卡点位置。

参考脚本逻辑大致如下:

import pymysql conn = pymysql.connect( host="元数据库IP", user="archery_admin", password="***", database="archery" ) cur = conn.cursor() cur.execute("SELECT COUNT(*) FROM workorder WHERE status IN ('等待审批') AND create_time > DATE_SUB(NOW(), INTERVAL 24 HOUR)") pending_count = cur.fetchone()[0] if pending_count > 10: # 触发告警推送 print("pending orders too many: %d" % pending_count)

这只是一个最小示意,实际推送我通过钉钉机器人和企业微信完成。脚本本身不难,难的是把“工单积压”这个业务指标联动到监控体系里的意识——监控不只是看CPU和内存,更要看流程健康度。

5.3 goInception规则的动态调优

审核规则必须像业务系统一样持续调优,不能定完就再也不动。Archery里的规则模块对应goInception的检测项,我每个月固定做一次规则回顾:

  • 统计当月被拦截的SQL类型,识别出高频拦截项。
  • 和开发负责人逐一确认这些拦截是“真问题”还是“误报”。
  • 对误报率过高的规则,在Archery里调整等级(如从“错误”降为“警告”)而不是直接删除,保留提示价值。
  • 对新型高危SQL模式(比如窗口函数的不规范使用),在goInception配置文件中新增检测项后,在Archery里同步刷新规则列表再手动启用。

规则调优要遵循“宁缺毋滥”的原则。规则过严会逼着开发绕过平台,私下找DBA执行——这就完全失去了平台的意义。规则过松则形同虚设。我有个土办法:每月随机抽10条线上复杂查询丢进Archery审核,看看会触发哪些规则,用真实用户行为来验证规则配置的合理性。

写在最后的几句实话

部署Archery这套平台,真正难的不是安装命令,而是后续围绕它建立的流程和习惯。平台只能帮你做语法检查、规范校验和流程管控,它替代不了DBA的经验和判断。我在实际使用中的一个深刻体会是:工具落地最大的阻力从来不是技术,而是团队习惯的改变。从上到下都愿意把SQL变更纳入统一管理,愿意花几分钟走工单流程,这才是项目成功的核心前提。

最后再分享一个小技巧:如果团队还在犹豫要不要上Archery,别急着搭完整环境,先花半小时用Docker把一套最小实例拉起来,让开发同学提交几条平时线上跑过的SQL看看审核报告。他们会立刻意识到,原来自己随手写的语句里有那么多隐藏的低级问题。这个直观冲击比任何宣讲都管用。

SQL审核平台的运维不是一锤子买卖,它是一条需要持续投入、持续调优的常态化道路。走在这条路上,你会慢慢发现,之前那些在会议室里争吵不休的问题,在透明的审核记录面前,突然都变得不那么需要争了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询