百科问答小站 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哲学。功能越专一、方案越简洁,反而越灵活、越方便扩展,越能支持千变万化的需求、甚至作为基础设施,扩展成一个庞大而复杂的项目——注意复杂是简无可简,并不是自寻烦恼。

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




  

相关话题

  Rust, Go 等新兴语言未来在国内好不好找工作? 
  if嵌套的代码风格哪种好? 
  做一个优秀的程序员到底难在哪里? 
  用JavaScript做其他语言擅长的事情“好”么? 
  为什么 Linux 如此安全,却不把 Linux 设计成像 Windows 一样的图形界面来使用? 
  汇编过程调用是怎样操作栈的? 
  黑客比普通程序员高在哪里? 
  各个编程语言都有哪些「黑点」? 
  优化代码中大量的if/else,你有什么方案? 
  如何通俗地理解「分布式系统」,它解决了哪些问题,有什么优缺点? 

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





© 2024-11-24 - tinynew.org. All Rights Reserved.
© 2024-11-24 - tinynew.org. 保留所有权利