ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Archery SQL审核平台部署与运维全流程指南

Archery SQL审核平台部署与运维全流程指南 1. 为什么DBA群体需要一套完整的SQL审核流程1.1 从一次凌晨变更事故说起做运维和数据库管理这些年我最怕的不是服务器半夜宕机而是业务方过来说一句“我就改个字段类型你帮我执行一下。”看似简单的需求背后往往是几万行核心表一旦字段类型变更引发隐式转换索引失效慢查询瞬间堆满数据库整个业务链路直接雪崩。更让人后怕的是很多执行的SQL没有任何评审记录不知道是谁提的、为什么要改、有没有备份方案出了事情连回滚都无从下手。Archery SQL审核平台就是冲着这个痛点来的。它把“SQL从哪里来、谁审核、如何执行、执行后能不能回滚”这条链条完整地治理起来核心不是替DBA执行一条语句而是把变更流程规范化、可视化。在我落地过的几个团队里引入这套平台之前每周都有两三次因为线上直接执行SQL引发的小故障引入之后类似的变更事故基本绝迹了。这篇文章就是我基于实际部署经验整理的一份运维部署手册从架构认知、环境准备、安装步骤到日常维护都会讲到适合正在做DB运维规范化、或者准备在公司内部搭建SQL审核流程的DBA和运维工程师参考。1.2 Archery的定位审核、上线与查询的闭环很多人第一次接触Archery容易把它理解成“一个能在网页上执行SQL的工具”。这个理解就偏差了。Archery本质上是一个基于Django框架开发的工单系统它把数据库变更按照“提交—审核—执行—追踪”的流程去管理。开发同学提交SQL上线工单指定负责审核的人审核通过后DBA点击执行整个过程在平台里留痕可追溯。它和gh-ost、pt-online-schema-change这类在线DDL工具不是替代关系而是协作关系。Archery负责流程治理和权限控制真正执行大表结构变更时底层可以对接到这些变更工具做到不锁表、可回滚。平台对库表结构、慢日志、查询记录都有统一的管理入口避免了开发人员拿着生产库账号直接连客户端执行SQL这种高危操作。我现在所在的团队所有生产环境变更都必须走平台没有工单编号的SQL语句不允许在正式环境出现。1.3 核心组件解析不是一个进程就能跑完的Archery部署起来看起来简单但里面其实包含了三个核心进程我见过不少人在部署时只启动了Django Web服务结果工单点了上线按钮却没反应或者定时任务完全不触发就是这个原因。组件职责说明对应进程Archery WebDjango应用提供Web页面和API入口处理用户请求、登录认证、工单流转python manage.py runserver 或 gunicornCelery Worker异步执行SQL上线的实际任务、查询任务、慢日志采集等所有“干活”的动作都发生在Worker里celery -A sql_web workerCelery Beat定时调度器负责周期扫描待执行工单、清理过期会话、刷新优化建议等celery -A sql_web beatMySQL存储平台自身的元数据包括用户信息、工单记录、实例配置、审核规则等注意不是业务数据库独立MySQL实例Redis作为Celery的消息队列和缓存承载工单任务的分发与存储独立Redis实例理解了这张表部署思路就清晰了Web负责“界面”Worker负责“干活”Beat负责“定时”MySQL和Redis负责“存储和通信”。后面所有配置和排障都是围绕这几个角色的关系展开的。2. 部署前的软硬件规划版本、端口与目录布局2.1 版本选型别在起点就埋雷Archery对运行环境有一定要求我建议在一开始就确定一套经过验证的版本组合而不是什么都装最新版。操作系统层面CentOS 7/8、Ubuntu 18.04/20.04这些常见发行版都没问题Python版本建议选择3.6到3.8之间我实际用的是3.8跑得很稳定太新的Python版本反而可能遇到部分依赖包没来得及适配的情况。元数据库MySQL建议5.7以上8.0也可以但要注意一点如果使用MySQL 8.0需要额外确保Python连接库的兼容性因为8.0默认的caching_sha2_password认证插件会让部分旧版本的pymysql报认证失败。解决的办法是安装新版本的cryptography库或者在部署时直接用5.7版本省心一些。Redis建议5.0以上基本没什么特殊限制。还有一点比较关键Archery平台自己的元数据库一定不要和业务数据库混用。我见过有人图省事直接拿一个业务实例的MySQL来装Archery的元数据结果平台本身的备份策略和业务备份策略互相干扰出了问题两边都受影响。单独准备一个小规格的MySQL实例给平台用数据量不大但隔离性很重要。2.2 操作系统基础依赖先补齐编译环境在用pip安装Archery的Python依赖时很多包需要通过源码编译比如MySQL连接驱动、加密相关库。如果操作系统缺少编译工具链pip会在安装过程中报错报错信息通常是“Failed building wheel”或者缺少某个头文件。提前把系统依赖装好能省掉后面一大半麻烦。CentOS/RHEL系统执行yum install -y gcc python3-devel openssl-devel zlib-devel libffi-develUbuntu/Debian系统执行apt-get update apt-get install -y build-essential python3-dev libssl-dev zlib1g-dev libffi-dev这些包分别对应什么作用我简单解释一下gcc是编译C扩展的编译器python3-devel提供Python头文件openssl-devel是为了让pip能正常编译带SSL支持的扩展libffi-devel则和cffi库相关Python连接MySQL驱动时经常用到。没有它们pip安装阶段就会卡住而且报错信息对新手很不友好容易让人误判成网络问题。另外建议把pip源替换成国内镜像源比如清华源或阿里源。Archery的依赖项里包含不少体积较大的包直接用官方PyPI源在部分网络环境下会非常慢甚至超时。在虚拟环境里执行pip install pip -U pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple之后再安装依赖速度差别是体感级别的。2.3 目录、端口与日志规划部署目录我习惯统一放在/opt/archery下代码放/opt/archery/Archery虚拟环境放/opt/archery/venv日志统一放/opt/archery/logs。这样备份、迁移、权限控制都很清晰。端口规划上Archery Web服务默认监听8000端口Celery的Worker和Beat不需要对外暴露端口Redis监听6379MySQL监听3306。如果全部部署在同一台机器上要提前确认这些端口没有被占用尤其是Redis和MySQL很多机器会预装或者历史遗留进程占用端口启动后看起来正常但连不上排查起来很费劲。日志规划容易被忽略。Archery运行时的日志主要有两类一类是Django的请求日志和Celery的任务日志可以通过nohup重定向输出到文件另一类是平台内部的错误日志默认会写入代码目录下的logs目录。我在部署时会统一做一个logrotate切割配置避免日志文件无限增长把磁盘撑爆。这个细节后面在运维章节里会详细展开。3. 从源码到可用核心服务安装步骤3.1 拉取代码与创建Python虚拟环境先把代码克隆到本地。Archery项目的源码托管在GitHub上仓库地址是github.com/hhyo/Archery直接clone最新稳定版本即可。mkdir -p /opt/archery cd /opt/archery git clone https://github.com/hhyo/Archery.git cd Archery这里有一个很重要的建议始终使用虚拟环境不要让依赖包装到系统Python里。用虚拟环境的好处是如果后面升级或者重装只需删掉venv目录重新创建不会污染系统环境也不会和系统自带的Python包冲突。cd /opt/archery python3 -m venv venv source venv/bin/activate cd Archery pip install -r requirements.txtrequirements.txt文件在Archery源码的根目录下里面包含了Django、Celery、MySQL驱动、Redis客户端等所有运行依赖。安装完成后可以用pip list快速检查关键包是否就位。这一步如果前面的系统依赖装好了基本是几分钟的事不会卡住。3.2 修改核心配置数据库连接与RedisArchery的配置文件是archery/settings.py在开始初始化之前必须把数据库和Redis的连接信息改成自己的环境。这里需要注意Archery本身依赖的配置项很多但核心就那几项不需要所有配置都看懂才能部署。# archery/settings.py 关键配置片段路径以实际代码为准 ALLOWED_HOSTS [*] DATABASES { default: { ENGINE: django.db.backends.mysql, NAME: archery, USER: archery_user, PASSWORD: 在这里填强密码, HOST: 127.0.0.1, PORT: 3306, OPTIONS: { charset: utf8mb4, }, } } REDIS { host: 127.0.0.1, port: 6379, password: , db: 0, } CELERY_BROKER_URL redis://127.0.0.1:6379/0 CELERY_RESULT_BACKEND redis://127.0.0.1:6379/0ALLOWED_HOSTS默认是空列表如果不改成包含实际访问域名或直接使用通配符Django会拒绝非本机host的请求页面直接返回400。初期内网部署可以直接写[*]但如果暴露到公网环境务必改成具体的域名。Redis如果设置了密码上面的URL也要带上密码格式是redis://:密码127.0.0.1:6379/0。我遇到过新手部署时Redis明明有密码但配置文件里没写结果页面能打开工单一提交就卡住不动日志里全是连接Redis认证失败的报错。3.3 初始化平台数据库配置改好之后需要创建元数据库并执行数据迁移。首先在MySQL里建库和建账号UTF8MB4字符集是必须的不然存中文的工单描述、SQL文本会出现乱码后续排查问题会非常痛苦。mysql -uroot -p CREATE DATABASE archery DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; CREATE USER archery_user% IDENTIFIED BY 强密码; GRANT ALL PRIVILEGES ON archery.* TO archery_user%; FLUSH PRIVILEGES;然后执行迁移cd /opt/archery/Archery source /opt/archery/venv/bin/activate python manage.py makemigrations python manage.py migratemigrate执行成功之后平台的表结构就建好了。Archery在初始化时会自动创建管理员账号默认的管理员账号通常是admin初始密码取决于具体版本官方README里会注明。我第一次部署时是按默认密码登录的但强烈建议登录成功后立即修改管理员密码并且不要把这个账号共享给多人。3.4 启动Web、Worker与Beat三个进程初始化完成就可以试启动。一定要先在前台启动验证一次不要直接一把nohup丢后台否则日志会掩盖启动错误。python manage.py runserver 0.0.0.0:8000浏览器访问 http://服务器IP:8000能出现登录页面说明Web服务正常。确认没问题后按CtrlC停止再把三个进程全部用后台方式拉起cd /opt/archery/Archery source /opt/archery/venv/bin/activate nohup python manage.py runserver 0.0.0.0:8000 /opt/archery/logs/archery_web.log 21 nohup celery -A sql_web worker -l info /opt/archery/logs/celery_worker.log 21 nohup celery -A sql_web beat -l info /opt/archery/logs/celery_beat.log 21 注意Celery的-A参数指定的是sql_web这是Archery项目里定义的Celery应用模块名不是所有项目都叫这个名字排障时看到日志里的sql_web不要觉得奇怪。启动后建议用tail -f检查日志看到类似“ready”的关键字基本就是起来了。三个进程缺一不可尤其是Worker如果没启动工单点了执行永远不会有反应。4. 接入Nginx并让平台真正可用4.1 用gunicorn替代runserver更符合生产要求Django自带的runserver开发服务器性能一般而且官方明确说不建议用于生产环境。部署Archery到正式使用阶段我会把Web服务切换到gunicorn配合多worker运行并发能力会好很多。pip install gunicorn启动方式cd /opt/archery/Archery source /opt/archery/venv/bin/activate nohup gunicorn -w 4 -b 127.0.0.1:8000 sql_web.wsgi:application /opt/archery/logs/gunicorn.log 21 注意这里gunicorn绑定的地址是127.0.0.1不是0.0.0.0。原因很简单生产环境我们会在前面架一层Nginx让Nginx监听对外端口比如80或443然后把请求转发到后端的gunicorn这样Archery本身不直接对外暴露减少攻击面。如果直接在8000端口对外提供服务安全性和灵活度都会差很多。4.2 Nginx反向代理配置要点Nginx配置本身不复杂但有两个容易踩坑的点一个是请求体大小限制一个是长连接超时时间。SQL审核工单在提交时SQL文本可能很大尤其是一次提交几十条批量上线语句。Nginx默认的client_max_body_size只有1m提交稍微大一点的工单就会报413错误。还有查询工单执行时间可能比较长Nginx默认的proxy_read_timeout是60秒超时就会返回504而SQL查询或者大表结构变更执行几分钟都很正常必须把超时时间调长。server { listen 80; server_name your_domain_or_ip; client_max_body_size 50m; location / { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_read_timeout 300s; proxy_connect_timeout 300s; } access_log /opt/archery/logs/nginx_access.log; error_log /opt/archery/logs/nginx_error.log; }50m的client_max_body_size对于绝大多数SQL工单场景足够用了如果你们团队日常提交的SQL脚本特别大可以再往上调但最好同时在平台层面限制单次提交的SQL条数防止有人把整个数据库的初始化脚本一次性贴进来。配置完后nginx -t检查语法reload生效。到这一步浏览器的访问路径就从8000端口平滑变成了80端口用户体验好很多。4.3 首次登录后的基础设置能打开登录页面说明部署成功了一大半。用默认管理员账号登录进去之后除了改密码我还建议按以下顺序把平台基础设置做一遍修改平台名称和logo避免默认的Archery品牌直接暴露给公司内部用户也显得更正式。配置管理员邮箱地址后续平台发送邮件通知时会用到。检查时区设置确保工单显示的提交时间和执行时间和服务器本地时间一致避免因为时区偏差导致定时执行工单提前或延后触发。开启用户注册审核。默认情况下平台允许注册用户但如果开了注册我建议在系统设置里开启注册审核管理员审批后才能登录防止外部人员随意注册获取系统权限。这些设置都集中在平台的后台管理页面里边走边看就能找到。核心逻辑是平台上线前把基础信息维护好再开始拉真实用户进来不要一登录就急着接实例。5. 把平台用起来实例、资源组、审核规则与通知配置5.1 接入数据库实例最小权限账号原则Archery部署好之后下一步是把需要管理的数据库实例接入平台。在“实例管理”里点新增实例需要填写的信息包括实例类型、实例环境测试/生产、主机地址、端口、数据库账号密码等。这里我要强调一个建议为Archery创建专用的数据库账号不要直接用root或者业务账号。因为这个账号会被平台用来获取库表结构、采集慢日志、执行上线SQL如果权限给太大一旦平台账号泄露或者被误用影响范围会非常大。最小权限的MySQL账号示例CREATE USER archery_conn% IDENTIFIED BY 强密码; GRANT SELECT, INSERT, UPDATE, DELETE ON *.* TO archery_conn%; GRANT SHOW DATABASES, PROCESS, SUPER ON *.* TO archery_conn%;具体权限组合要根据你们要使用的功能来确定比如要在大表执行DDL时使用pt-osc就需要额外的权限要做数据订正就需要INSERT/UPDATE/DELETE权限。核心原则就一条每个功能对应最小权限宁可后续缺权限再加也不要一开始就放开所有权限。5.2 资源组Archery权限模型的核心Archery里的权限控制核心是“资源组”不是简单的“管理员/普通用户”两级权限。一个典型的配置是创建“业务系统A”这个资源组把业务系统A的数据库实例、负责该系统的研发账号、审核角色全部放进去然后这个资源组里的用户在工单流转时只能看到该系统相关的实例和工单做到了逻辑隔离。我强烈建议在正式推广前先按照公司的业务线把资源组架构规划好。这个规划做得好后续权限维护会非常省事如果等用户量大了再调整资源组每个工单的归属都要重新梳理很麻烦。一个业务线一个资源组里面放对应的实例和人员这是目前我见过最清晰的模式。5.3 审核规则从“错误”级别开始逐步放宽Archery内置了几百条SQL审核规则包括常见的“禁用SELECT *”“UPDATE/DELETE语句必须带WHERE条件”“禁止使用子查询”“限制影响行数”“建议使用索引”等等。每条规则可以设置级别通常是“警告”和“错误”两档。我的建议是刚开始部署时先把规则调到偏严尤其是“错误”级别让所有不符合规范的SQL直接被拦截。团队会有一些不适但磨合一两周开发同学就会习惯规范写法。之后再根据实际反馈把个别太严的规则比如某些公司确实需要SELECT *的场景降为“警告”而不是彻底关掉。有一个经验值得分享审核规则要跟着业务的SQL风格迭代不是一成不变的。初期按默认规则跑看平台积累的审核驳回记录每季度审视一次规则清单把高频误伤的规则调准这样平台才不会变成“开发同学绕道走的摆设”。5.4 消息通知让工单流转不依赖盯页面Archery支持对接钉钉、企业微信、飞书等IM的机器人Webhook。配置好之后工单提交、审核通过、执行完成、执行失败等关键节点都会自动推送通知到对应的群或负责人。这一步非常提升使用体验。不然每个工单审核都要人等页面刷新推广阻力会很大。在系统配置里填入Webhook地址再勾选需要通知的事件类型即可。要注意的是Webhook如果填错地址平台本身不会报错只会默默推送失败所以在配置完以后最好真实走一遍提交工单的流程验证通知能不能正常收到别等上线了才发现消息一直没发出去。6. 日常运维日志、备份、升级与常见故障排查6.1 进程管理用systemd取代裸nohup部署初期用nohup拉起服务没毛病但长期运维建议改用systemd管理这样服务崩了能自动重启开机也能自动拉起。我通常会为三个进程各写一个Unit文件下面以Worker为例[Unit] DescriptionArchery Celery Worker Afternetwork.target redis.service mysql.service [Service] Userarchery Grouparchery WorkingDirectory/opt/archery/Archery ExecStart/opt/archery/venv/bin/celery -A sql_web worker -l info Restartalways RestartSec5 [Install] WantedBymulti-user.targetWeb服务和Beat进程同理。切换到systemd之后systemctl status随时能查状态日志统一交给journald管理比翻nohup日志文件方便得多。这里顺带提醒一下如果代码目录、虚拟环境、日志目录的属主不是运行用户启动会报权限错误创建目录时就要用chown把权限理顺。6.2 数据备份与恢复备份元数据库就够了Archery平台自身的业务数据都存在MySQL元数据库里包括用户信息、资源组配置、工单记录、审核日志。备份策略很简单就是定时mysqldump这个库mysqldump -uarchery_user -p archery --single-transaction --quick /backup/archery_$(date %Y%m%d).sql配合crontab每天凌晨执行一次保留最近30天的备份文件。恢复时更简单mysql -uarchery_user -p archery /backup/archery_20250101.sql除了数据库系统的settings.py配置文件、nginx配置、systemd配置这些文件虽然小但丢了会非常麻烦建议一起纳入备份范围。恢复时如果不小心弄丢了光靠重新配置可能要花一小时而备份只需要一秒钟。6.3 升级注意事项先备份、看变更、再操作Archery的版本迭代还是挺积极的新版本会修复漏洞、增加审核规则、优化界面。升级前有三件事必须做完整备份元数据库这是所有操作的前提阅读官方Changelog确认目标版本的配置变更、依赖变更有些大版本升级需要额外执行数据脚本在测试环境先升一遍确认功能正常后再动生产。升级时通常只需要拉取新代码、安装新的依赖包、执行数据库迁移然后重启三个服务。这里最忌讳的是跨多个大版本一次性升级中间的数据结构和逻辑变化可能直接让migrate报错。我习惯的做法是小版本跟随大版本跳跃时先找官方文档确认升级路径必要时中间版本过渡一轮。6.4 常见故障排查一张表解决80%的问题运维Archery半年到一年常见的坑基本就那几个。我把它们整理成一张表遇到问题先对号入座现象可能原因处理方式pip安装依赖失败系统缺少编译工具链按2.2安装gcc、python3-devel、openssl-devel等页面能打开但工单执行没反应Celery Worker进程没启动检查celery worker日志确认进程存活定时任务不触发Celery Beat进程没启动启动beat进程检查日志提交工单报连接Redis失败Redis配置错误或密码没填检查settings.py中Redis配置和CELERY_BROKER_URL登录后没有任何权限新用户未分配到资源组进入权限管理把用户加入对应资源组页面返回400 Bad RequestALLOWED_HOSTS未配置修改settings.py中ALLOWED_HOSTS后重启上传SQL文件报413Nginx client_max_body_size太小调整Nginx配置为50m或更大工单执行返回504Nginx代理超时时间太短调大proxy_read_timeout和proxy_connect_timeout中文显示乱码元数据库字符集不对确认数据库初始化为utf8mb4连接配置charsetutf8mb4登录后密码不对初始密码被修改过或版本不同查看官方README确认默认密码必要时重置管理员密码这套排查思路的核心是先从进程是否存活入手再看日志最后看配置。我遇到过很多人卡在“页面能打开”这一步就以为部署成功了实际上Worker和Beat都没起来导致平台只能看不能用。验证平台真正可用的标准是完整走一遍“提交工单—审核—执行—收到通知”的流程。6.5 我的几点落地经验最后分享几个我在实际运维过程中沉淀下来的习惯不一定所有人都认同但对团队落地很有帮助。第一先试点再推广。不要第一天就把所有生产库实例接进来而是选一个非核心业务系统作为试点跑通全流程把审核规则调好团队熟悉了操作方式再逐步扩大覆盖范围。上来就全面覆盖最容易引发业务团队反弹。第二管理员账号只用来做系统管理日常工单审核和执行要给DBA分配独立账号。这样每个操作都能定位到具体责任人也方便审计。第三定期查看平台的慢日志和审核驳回记录。Archery的价值不只是上线前把关更重要的是积累SQL质量数据。每月看一次驳回记录能清晰看到各团队SQL质量的变化趋势这些数据用来推动研发规范落地比口头强调有力得多。第四不要迷信平台的自动化执行高危操作如DROP TABLE、批量UPDATE影响行数过大建议开启人工复核或者直接由平台管理员二次确认后再执行。审核平台是辅助手段最终对生产环境负责的还是人。第五配置文件和备份脚本要纳入版本管理或者至少放在独立目录。服务器本身有可能出问题但只要备份齐全、配置有记录重新部署一台机器做到半小时内恢复是完全可行的。Archery本身不复杂按这套流程走一遍基本上一个下午就能跑起来。真正需要投入精力的是把审核规则、资源组、权限模型这些东西结合自己团队的业务形态打磨好。工具只是骨架流程和规范才是让平台真正发挥价值的关键。
返回列表