百科问答小站 logo
百科问答小站 font logo



golang,告警业务,每个告警源都有不同的分发频率,告警源可能新增or删除,该如何设计? 第1页

  

user avatar   s.invalid 网友的相关建议: 
      

这……第一次见到这种设计 LOL


不要这样搞。缺陷太多了:

  • 复杂度太高,稍不留意就出错
  • 压力全丢给OS调度了,效率太低;生产环境如果添加了成千上万甚至更多的源,这个方案本身就能拖垮性能一般的上位机
  • 扩展复杂,难以添加/删除告警源
  • 难以测试,比如因为数据相关导致某个线程总是得不到执行时,你就要付出许多许多倍的努力才能排错


其实这类工作业界早有成熟的模型,压根不需要多线程,也不需要搞什么复杂的增加/删除源的逻辑。

要点:

  • 使用单一的基础定时器。比如利用Linux的crontab或者Windows的计划任务,每分钟唤醒应用(视具体需要,可以每分钟、每五分、十分、半小时唤醒)
  • 应用自己累计,每分钟/五分钟/三十分钟/一小时执行监控流程
  • 需要监控的源的配置信息放到配置文件/数据库里,按频率分区放置。比如弄一系列目录,一个叫minutely,里面的源每分钟轮询一次;一个叫hourly,每小时轮询一次;daily,每天一次。
  • 监控流程从不同的目录读取告警源配置信息,执行检查、汇总、上报等工作


具体来说,你可以写两个程序。第一个程序可以叫scheduler,第二个叫worker。


scheduler由crontab或计划任务每分钟启动;它要在某个文件里记住自己已经被调用了多少次(可以通过系统时钟双重确认,但并不必要);每分钟/十分/十五分/半小时/一小时(同样做到配置文件里)调用worker。

比如,scheduler.ini里面有一项是:

[schedule_008]
interval=30 #每30分钟调用
worker=/path/to/worker #检查执行者所在路径
argument=/path/to/half_hourly #告警源配置文件所在路径

注意我用了Linux路径风格。Windows下把“/”改成“”就行了。

scheduler读取scheduler.ini,发现schedule_008的interval是30,意思就是每三十分钟执行worker指定的命令;执行这个命令时,要给它传递一个命令行参数,也就是下面的argument。


worker被执行时,从自己得到的命令行参数指定目录读取所有配置文件。这些配置文件里面就是告警源信息。

比如:

ip=192.168.0.123
port=3339
user=user
passwd=123456

换句话说,worker完全可以不知道自己的被调用频率;它只是在被唤醒时连接到192.168.0.123的3339端口,然后以user用户登录(密码123456)、检查有无告警、若有告警执行既定流程罢了。


你看,这个设计把各种功能全部解耦,平常不占用资源,每分钟周期性检查、执行时才载入告警源配置信息。

你完全可以随时随地添加一个worker(比如加个每7分钟检查的worker)、随时随地更换worker(比如有告警就发短信的worker、有告警就发邮件的worker、有告警就拉防空警报的worker,等等。没错,你甚至可以添加告警级别支持,把普通、严重、危急等告警分开:很简单,在硬盘上建立一个新的目录,然后配置一个不同的worker即可)。

同样的,你也可以随时随地导入一百万个告警源,或者一条rm命令删除所有告警源,os本身就可以保证这个操作的安全性——反正你的worker就是读取配置文件、然后遍历里面列出的每一个告警源而已(当然,如果有必要,你也可以在worker里面并行,从而提高处理速率。比如你需要处理一百万或者更多告警源时,可能就有必要这么做了)。


总之,这个设计是极其灵活却又极度简洁的。最简单的worker甚至可以只是一个脚本,读取配置后用wget取得信息然后grep再执行个alarm命令即可。

这个方案好写、好测,效率极高,又允许你随意扩展——比如增加一个ram加速插件,监控硬盘,把所有配置文件处理后同步到RAMDisk;然后修改scheduler.ini里面的路径信息,从而让worker到RAMDisk读取配置信息;再比如添加一个图形化的管理工具,自动展示/添加/删除/修改甚至临时禁用/使能某个被监控的源;还有前面提到的,通过目录分划给不同告警的检查频率、严重程度分类,等等——可以支持几乎无限的需求。

只要业务水平不太差,这个方案一旦写好便一劳永逸,以后随便要什么需求也不过是多写一个独立的简单小程序的事。它完美实现了“对扩展开放”和“对修改封闭”这两个设计目标,彻底免除了码农们加班改bug、996/007但是工作还是完不成之苦……

因此,这个思路在很多地方得到了应用——比如Linux的crontab配置就是这样做的,它的init level、Debian系的source list等等等等,也都是这个思路。


少即是多,这就是Linux哲学。功能越专一、方案越简洁,反而越灵活、越方便扩展,越能支持千变万化的需求、甚至作为基础设施,扩展成一个庞大而复杂的项目——注意复杂是简无可简,并不是自寻烦恼。

把一个项目搞的很麻烦、没有一个人知道全貌、甚至几乎没人能读懂、这很容易,水平越低越容易做到;但想要把一个项目做简单、然后用简单到明显没有错误的代码完成多变复杂的需求,这反而需要极深的功底。




  

相关话题

  编程最基本的术语「bug」该怎么翻译? 
  如何在运行时初始化静态成员变量? 
  上古时期的程序员都有哪些当今普通程序员无法想象的神级操作? 
  如何看待北京理工大学2018-2019求是书院C语言期末? 
  go语言,局部变量什么时候回收? 
  在宿舍写代码总被一个室友认为在装逼,该怎么办? 
  CSS的样式表 内联外部和内部优先级? 
  你们说的ABI,Application Binary Interface到底是什么东西? 
  想在业余时间刷leetcode,配合什么书籍/课程/视频网站一起刷leetcode的效率最高? 
  如何才能创造一门世界顶尖的中文编程语言? 

前一个讨论
请问solidworks对电脑配置有哪些要求?
下一个讨论
为了把防冻液彻底换干净,拆下水管后,打着车怠速让发动机升温直到节温器打开这段时间会不会损害发动机?





© 2024-05-18 - tinynew.org. All Rights Reserved.
© 2024-05-18 - tinynew.org. 保留所有权利