发布于 2026-01-06 8 阅读
0

生产环境中运行脚本的技巧:1)跟踪进度;2)记录运行前后的状态;3)编写生产质量代码;4)请人审核脚本;5)使用 Screen 或 Tmux 运行长时间运行的脚本;设置运行数据更新脚本的框架;#6025 DEV 全球展示挑战赛,由 Mux 呈现:展示你的项目!

生产环境中运行脚本的技巧

1)跟踪你的进度

2)记录前后状态

3)编写生产级代码

4)请人审阅你的剧本

5) 使用ScreenTmux运行长时间运行的脚本

设置运行数据更新脚本的框架 #6025

由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!

替代文字

我知道,我怎么敢建议在生产环境中运行脚本呢?我是一名站点可靠性工程师,我绝不应该赞同这种疯狂的做法。但事实是,你很可能需要运行脚本来更新或清理一些数据。在这篇文章中,我将为你提供一些关于如何在生产环境中编写和执行脚本的技巧,以尽可能安全的方式进行操作。

1)跟踪你的进度

最糟糕的事情莫过于写一大段代码,把它粘贴到控制台,然后按下回车键,看着它呆在那里不动。你完全不知道这段代码在脚本中的位置,也不知道它在做什么,至少对我来说,这简直太可怕了。

因此,您始终需要确保脚本输出某种进度指示器。这样您就可以跟踪脚本的运行进度,了解其执行位置。如果您使用的是 Ruby,请考虑使用一些合适的 puts 语句。以下是我们最近在 DEV 团队中用于清理一些错误缓存数据的脚本。请注意脚本中穿插的 puts 语句,它们使我们能够跟踪脚本的执行过程。

invalid_articles = []
Tag.where(id: tag_ids).find_each do |tag|
  puts tag.taggings.count

  tag.taggings.each_with_index do |tagging, index|
    puts index if index%100 == 0
    article = tagging.taggable
    next unless article

    result = article.update(cached_tag_list: article.tags.pluck(:name).join(", "))
    if result
      puts "Artcle update success #{article.id}"
    else
      puts "Artcle update failure #{article.id}"
      invalid_articles << article
    end
  end
end
Enter fullscreen mode Exit fullscreen mode

还要注意,我们会记录运行此脚本时可能遇到的任何无效文章。尤其是在清理错误数据时,务必假设可能会遇到更多无效文章,并在脚本中做好相应的准备。这里我们使用语句if/else来捕获所有无效文章。您也可以使用begin/rescue代码块。

2)记录前后状态

更新记录时,总有可能出现意外情况。为了能够“回滚”,需要在更新过程中跟踪更新前的状态。如果我们更新上面的脚本来实现这一点,脚本会变成这样:

invalid_articles = []
before_update_tag_lists = {} 
Tag.where(id: tag_ids).find_each do |tag|
  tag.taggings.each_with_index do |tagging, index|
    puts index if index%100 == 0
    article = tagging.taggable
    next unless article
    # Record the current cached tag list for every article
    before_update_tag_lists[article.id] = article.cached_tag_list

    result = article.update(cached_tag_list: article.tags.pluck(:name).join(", "))
    if result
      puts "Artcle update success #{article.id}"
    else
      puts "Artcle update failure #{article.id}"
      invalid_articles << article
    end
  end
end
Enter fullscreen mode Exit fullscreen mode

如果脚本运行过程中出现任何错误,before_update_tag_lists哈希表中仍然包含所有原始数据。我们可以利用这些原始数据遍历文章,并在必要时用旧列表重新更新它们。

3)编写生产级代码

编写脚本时,人们很容易倾向于使用尽可能少的语法。通常这意味着到处使用单字母变量。你可能以后都不会再用到这段代码,所以何必浪费时间让它看起来美观易读呢?其实,让脚本美观易读是因为它更容易理解和遵循。易于理解的脚本有助于避免编写错误代码。

在上面的脚本示例中,我清楚地写出了我正在操作的每个对象。这使得几乎任何人都能阅读脚本并理解其功能。这引出了我的下一个脚本编写技巧。

4)请人审阅你的剧本

就像你绝不会在没有代码审查的情况下将代码部署到生产环境一样,你也不应该在没有代码审查的情况下在生产环境中运行脚本。这也是为什么你需要确保你的脚本易于理解和阅读的另一个原因,因为你希望其他人也能明白它的作用。

我们都知道让别人帮我们检查代码的价值。即使时间紧迫,需要尽快运行脚本,也要尽可能找人帮忙检查一遍。我数不清有多少次,多亏了别人的帮忙,我才避免了脚本更新出错。

5) 使用ScreenTmux运行长时间运行的脚本

Tmux 和 Screen 允许你在 shell 中启动 SSH 会话,并保持该 shell 会话处于活动状态,即使网络中断也是如此。这确保了即使脚本运行时连接中断,脚本运行也不会中断。感谢@kinduff的提醒!

如果任务耗时较长,则存在与 SSH 会话、互联网服务提供商等断开连接的风险。

为了避免这种情况,我建议使用 screen 运行这些脚本(尽管我完全不建议这样运行脚本)。它使用起来非常简单:

  1. 通过 SSH 连接到目标实例
  2. 使用以下命令启动新的屏幕会话screen
  3. 运行长时间运行的脚本
  4. Ctrl+键,a然后按 键d,即可分离会话
  5. 现在您可以关闭所有程序,包括 SSH 会话。
  6. 您可以使用以下方式重新连接到屏幕会话screen -r

Screen 有很多很棒的功能,一定要查看手册页

在生产环境中运行脚本从来都不是理想的做法,但如果你在运行脚本时运用这些技巧,就能让整个过程变得不那么令人畏惧。

祝您脚本编写愉快!

文章来源:https://dev.to/molly/tips-for-running-scripts-in-Production-4c72