系统简介
分布式异常报警系统就是收集系统运行过程中产生的未处理异常,检查系统运行的状态,并将异常信息统一发送到服务端,由服务端将信息通知到相关的责任人。
问题
我们在项目开发中可能遇到以下几个问题:
1. 项目在运行的过程中, 会因为意外情况产生异常, 对于一些异常, 我们会通过try..catch来捕获,并记录到日志。 但是对于某些异常,我们在编码的时候并没有预料到,也没有try..catch捕获,结果异常被抛到了最外层, 因为这些异常我们并没有捕获到, 所以也没有办法去记录, 导致系统一些不稳定的情况存在。
2. 对于异常, 会随其他的一些日志信息一起记录到本地文件中, 如果要查看, 就需要登录到服务器上去查看,如果线上服务器有权限管理, 要登录上去还是一件麻烦的事情。 另外日志也仅仅是被记录, 并没有及时通知到相关责任人。
3. 对于正在运行的系统,我们也会对其进行监控, 我们一般会采用zabbix之类的软件监控CPU, 硬盘, 网络, 内存等信息, 除了这些信息, 我们可能还关心我们的软件系统是否正常运行, 因为有可能在CPU, 硬盘, 网络, 内存等一些正常,软件系统却不能工作了,比如我们的软件系统依赖A服务, A服务宕机了, 我们的软件系统所在的服务器看上去一切正常, 但是此时软件系统已经不能算是正常状态了。
解决
对于以上的三种情况, 都已经有了对应的解决方案,
对于第一种情况: 可以在Application_Error中捕获异常, 也可以注册一个module,在module中捕获,或者在编码层面上考虑的尽可能全面。 来杜绝这种全局异常。
对于第二种情况, 会有专业的分布式日志系统来帮助我们收集日志, 集中分析处理。 并通知到责任人。
对于第三种情况: 除了系统级的监控,对于某些业务, 我们会在代码中通过"埋点"的方式来进行更细粒度监控来发现问题。 另外现在的服务都是集群部署, 负载均衡软件可以检查到异常服务器, 并将异常服务器从集群中剔除。
项目由来
对于以上的解决方案, 有些显得“非常专业”, 对于一些普通的项目, 还没有必要“杀鸡用牛刀”,基于这种情况, 我决定开发一套自己的异常报警系统,主要功能如下:
1. 记录项目中那些没有被捕获的全局异常,
2. 将记录到的全局异常, 通过网络发送到服务端, 对于那些已经在项目中使用Application_Error捕获全局异常或者在流程中通过try..catch捕获的异常的情况, 依然可以使用此项目, 项目会提供API接口, 可以通过API将异常发送到服务端,
3. 除了记录异常,我们也会主动地去监控站点健康情况, 方式就是通过模拟web请求去访问指定的页面, 如果返回http的status是200,或者返回内容为ok 那就表示这个站点是正常的, 这个页面可以是普通的首页, 当然如果有条件, 建议开发一个特定的页面, 在这个页面内, 对这个系统所以来的环境进行检查。 (比如, 这个系统依赖数据库和A服务, 那在这个页面中就去尝试访问以下数据库和A服务,如果一切正常, 那就返回ok)
4. 对于发送到服务端的异常信息, 通过邮件, 短信的方式通知到相关的负责人。
5. 异常会记录到持久化的数据库, 方便后台查看和统计。
开发简介
开发语言为C#。
开发工具包括Visual studio 2013, sql server 2008R2 , Redis。
适用于.net Web项目, 对于其他winform或则Java项目, 提供了基于http的接口, 数据格式为json, 可以通过此接口上传异常信息。
项目架构
项目架构图如下:
1. 客户端通过module捕获全局异常, 并且包装了http接口,将异常信息发送到服务端
2. 服务端采用http协议, 接收客户端传递的异常,并发送异常到Redis
3. HandleService从redis中读取异常信息并进行处理, 主要包括入库, 查找相关负责人,通知到相关责任人。
4. HealthyCheckService读取站点信息, 并对站点进行访问, 检查状态,并将异常信息上传到服务端。
5. Admin后台管理, 主要是查看异常信息, 管理站点及网站负责人信息。
后记
最后, 对项目做一些额外的说明:
1. 项目的想法来源于elmah,它主要功能是记录网站异常信息,并提供邮件通知功能, 但是他只能记录单个网站, 没有办法做多个网站的日志汇总。 如果你网站规模不大,或者想有针对性的监控, 使用它做异常监控绝对是一个不错的选择, 此项目开源, 可以扩展。
2. 对于一个服务端项目来说, 异常并不是经常发生的, 但是发生后,需要立刻知道, 所以我并没有在本地做local queue, 也没有批量上传,而是选择立刻上传。
3. 在项目开发过程中, 博客园小胡子哥的http://www.cnblogs.com/hustskyking/p/fe-monitor.html 这篇博客介绍了前端的异常日志收集,非常精彩, 异常收集的方式和这个项目类似,可以结合小胡子哥的做法扩展为可收集前端异常。
4. 日志的报警信息通过短信和邮件发送, 因为短信是需要连接短信网关的, 所以在这个项目中并没有实现, 但是有一个细节问题:在做短信通知的时候, 要做一个缓存。比如站点因为某些原因, 一下子产生了100个相同异常, 我们短信通知一次就可以了。
5. 异常信息比较敏感, 对于专业人士, 可以根据异常信息来猜测你系统的漏洞, 所以异常信息要保存在相对安全的地方。