生产环境中运行脚本的技巧
1)跟踪你的进度
2)记录前后状态
3)编写生产级代码
4)请人审阅你的剧本
5) 使用Screen或Tmux运行长时间运行的脚本
设置运行数据更新脚本的框架 #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
还要注意,我们会记录运行此脚本时可能遇到的任何无效文章。尤其是在清理错误数据时,务必假设可能会遇到更多无效文章,并在脚本中做好相应的准备。这里我们使用语句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
如果脚本运行过程中出现任何错误,before_update_tag_lists哈希表中仍然包含所有原始数据。我们可以利用这些原始数据遍历文章,并在必要时用旧列表重新更新它们。
3)编写生产级代码
编写脚本时,人们很容易倾向于使用尽可能少的语法。通常这意味着到处使用单字母变量。你可能以后都不会再用到这段代码,所以何必浪费时间让它看起来美观易读呢?其实,让脚本美观易读是因为它更容易理解和遵循。易于理解的脚本有助于避免编写错误代码。
在上面的脚本示例中,我清楚地写出了我正在操作的每个对象。这使得几乎任何人都能阅读脚本并理解其功能。这引出了我的下一个脚本编写技巧。
4)请人审阅你的剧本
就像你绝不会在没有代码审查的情况下将代码部署到生产环境一样,你也不应该在没有代码审查的情况下在生产环境中运行脚本。这也是为什么你需要确保你的脚本易于理解和阅读的另一个原因,因为你希望其他人也能明白它的作用。
我们都知道让别人帮我们检查代码的价值。即使时间紧迫,需要尽快运行脚本,也要尽可能找人帮忙检查一遍。我数不清有多少次,多亏了别人的帮忙,我才避免了脚本更新出错。
5) 使用Screen或Tmux运行长时间运行的脚本
Tmux 和 Screen 允许你在 shell 中启动 SSH 会话,并保持该 shell 会话处于活动状态,即使网络中断也是如此。这确保了即使脚本运行时连接中断,脚本运行也不会中断。感谢@kinduff的提醒!
在生产环境中运行脚本从来都不是理想的做法,但如果你在运行脚本时运用这些技巧,就能让整个过程变得不那么令人畏惧。
祝您脚本编写愉快!
文章来源:https://dev.to/molly/tips-for-running-scripts-in-Production-4c72

如果任务耗时较长,则存在与 SSH 会话、互联网服务提供商等断开连接的风险。
为了避免这种情况,我建议使用 screen 运行这些脚本(尽管我完全不建议这样运行脚本)。它使用起来非常简单:
screenCtrl+键,a然后按 键d,即可分离会话screen -rScreen 有很多很棒的功能,一定要查看手册页。