自动化脚本:从“手动点点点”到“躺平发版”的实战蜕变

温柔梦想家
2026-01-03 17:32
阅读 2219

刚入职新公司两个月,说实话,还在适应节奏。之前在滴滴干了四年司机端后端,天天和高并发、低延迟打交道,代码写得还算讲究。现在这家创业公司技术债有点多,但氛围挺好——至少没人半夜三点打电话说“司机接单超时了”。不过最近一次发版,让我又梦回被“重复操作”支配的恐惧。

事情是这样的:上周五晚上八点,产品经理小张(没错,就是那个总在周五下班前甩需求的张哥)跑过来:“兄弟,我们明天早上九点要上线一个紧急活动,需要把100多个司机白名单配置进系统。”
我第一反应是:“不能走配置中心吗?”
他说:“来不及改前端了,先用脚本吧。”

行吧。但你知道最痛苦的是什么吗?不是写脚本,而是每次都要手动登录服务器、连数据库、跑SQL、清缓存、重启服务……一套流程下来半小时,手都点麻了。更别提一不小心删错库,直接喜提P0事故大礼包。

那一刻我突然意识到:再不搞自动化,我就要变成人肉运维机器人了。


其实我对自动化脚本这事一直有点心虚。在滴滴那会儿,基础设施太完善了,CI/CD 流水线、蓝绿发布、自动回滚,啥都有。你只管提交代码,剩下的交给平台。但现在这小公司,很多流程还得靠“老中医式”手搓。好在这些年重度依赖 ChatGPT 和 Claude,遇到问题丢过去,它能给你生成个七七八八的脚本雏形——虽然经常漏掉鉴权或者路径分隔符,但至少省了查文档的时间。

于是周末两天,我决定把几个高频操作全自动化掉。目标很朴素:以后发版、配数据、查日志,只要敲一行命令就行。

从“复制粘贴”到“一键执行”

第一个要解决的就是白名单导入。原来的流程是:

  1. 打开 Excel,复制司机 ID 列
  2. 登录跳板机
  3. 进入生产 DB(战战兢兢)
  4. 手动拼 INSERT INTO whitelist (driver_id) VALUES (...)
  5. 清 Redis 缓存
  6. 发企业微信通知测试同学

光看步骤就知道有多反人类。我用 Python 写了个小工具,核心逻辑就几十行:

# import_whitelist.py
import os
import pandas as pd
import redis
import pymysql

def load_driver_ids_from_excel(file_path):
    df = pd.read_excel(file_path)
    return df['driver_id'].dropna().astype(str).tolist()

def insert_to_db(driver_ids):
    conn = pymysql.connect(
        host=os.getenv("DB_HOST"),
        user=os.getenv("DB_USER"),
        password=os.getenv("DB_PASS"),
        database="driver_service"
    )
    cursor = conn.cursor()
    values = [(did,) for did in driver_ids]
    cursor.executemany("INSERT IGNORE INTO whitelist (driver_id) VALUES (%s)", values)
    conn.commit()
    conn.close()

def clear_redis_cache():
    r = redis.Redis(host=os.getenv("REDIS_HOST"), port=6379, decode_responses=True)
    r.delete("driver:whitelist:cache")

if __name__ == "__main__":
    ids = load_driver_ids_from_excel("./whitelist.xlsx")
    insert_to_db(ids)
    clear_redis_cache()
    print(f"✅ 成功导入 {len(ids)} 个司机白名单,并刷新缓存!")

关键点在于:

  • INSERT IGNORE 避免主键冲突
  • 环境变量管理敏感信息(绝不硬编码!)
  • 最后打印明确的成功提示——毕竟运维同事可能要用

跑完脚本,自动发个企微机器人消息,测试同学秒收到通知。再也不用我手动@他们了。产品同学看到后眼睛都亮了:“这玩意能给我们运营也搞一个吗?”

自动化不只是“省时间”,更是“防人祸”

别小看这些脚本。去年双11我在滴滴值班时,就见过实习生手抖把 UPDATE drivers SET status = 0 漏了 WHERE 条件,结果全量司机下线。虽然有 binlog 回滚,但那十分钟的故障报警声,至今还在耳边回响。

所以这次写脚本,我强制加了三道保险:

  1. Dry-run 模式:加个 --dry-run 参数,只打印 SQL 不执行
  2. 权限最小化:数据库账号只给 INSERT/SELECT,不给 DELETE/UPDATE
  3. 操作日志审计:所有脚本执行记录写入 ELK,谁在什么时候跑了什么,清清楚楚
# 示例:安全第一!
$ python import_whitelist.py --dry-run
[DRY RUN] Would insert 128 driver IDs.
[DRY RUN] Would delete key 'driver:whitelist:cache' in Redis.

产品经理一开始嫌麻烦:“搞这么复杂干嘛,快点上线就行。”
但我坚持:“你可以不要命,但我得保住饭碗。”
后来他默默改了需求文档,加了一句:“需支持安全审计”。

脚本也要有“产品思维”

很多人觉得脚本就是临时工具,写完就扔。但如果你把它当成一个微型产品,体验会完全不同。

比如我给脚本加了:

  • 友好的 help 信息(--help 输出清晰)
  • 进度条(用 tqdm 显示导入进度)
  • 错误分类(网络超时 vs 数据格式错误,提示不一样)
  • 默认参数(Excel 文件名默认 ./whitelist.xlsx,不用每次都输)

甚至写了份简单的 README:

# 白名单导入工具

## 使用方式
```bash
python import_whitelist.py [--file path/to/file.xlsx] [--dry-run]

注意事项

  • 确保 .env 文件包含 DB 和 Redis 配置
  • Excel 必须有 driver_id 列,且为纯数字
  • 生产环境请务必先 dry-run!

结果运维小哥用了之后说:“这比我们某些正式服务还好用。”  
我心想:**这不是理所当然的吗?用户(哪怕是内部用户)体验差,迟早要背锅。**

## 技术选型:简单 > 完美

有人可能会问:为什么不直接上 Airflow 或 Jenkins?  
答:杀鸡焉用牛刀。

我们目前就几个固定场景:数据导入、日志分析、定时清理。用 Shell + Python 足够了。引入重型调度框架,反而增加维护成本。等哪天脚本数量超过 50 个、依赖关系复杂了,再考虑升级不迟。

另外,脚本语言选 Python 而不是 Go,原因很现实:
- 团队里 Python 更普及
- pandas 处理 Excel/CSV 太香了
- 快速原型,调试方便

| 方案 | 上手速度 | 维护成本 | 适用场景 |
|------|--------|--------|--------|
| Shell 脚本 | ⭐⭐⭐⭐ | ⭐⭐ | 简单命令组合 |
| Python 脚本 | ⭐⭐⭐ | ⭐⭐⭐ | 数据处理、复杂逻辑 |
| Airflow | ⭐ | ⭐⭐⭐⭐⭐ | 任务依赖、大规模调度 |

现阶段,Python 是甜点区。

## 最后的感悟:自动化是工程师的“防卷盔甲”

在滴滴那四年,我见过太多人陷在重复劳动里:每天查日志、对账、手动回滚。表面看是“负责”,实则是**把人力当机器用**。而真正优秀的团队,会不断把人的精力从机械操作中解放出来,去思考架构、体验、业务价值。

现在虽然公司小,但我也想守住这条线:**能自动化的,绝不手动;能一次写好,绝不反复救火。**

上周五那个白名单需求,现在只需要产品把 Excel 丢进指定目录,CI 监听到文件变化,自动触发脚本,全程无人值守。我甚至可以在家喝着咖啡看执行日志。

当然,老板还不知道这事——要是知道了,怕是要给我加更多“自动化需求”了 😅

但没关系。因为我知道,**每一次自动化,都是对“无效加班”的一次反抗。**

而这,或许就是我们写代码最朴素的意义。

评论 0

最热最新
暂无评论
温柔梦想家Lv.1
0
影响力
0
文章
0
粉丝