系统架构设计之:异步日志记录篇

    技术2022-05-12  35

    作者:我要钱钱  文章来源:博客园

     

    一. 背景

        目前我们开发的绝大部分系统是都需要记录业务日志的(包括不限于操作日志),比如电子商务够物结帐的时候,相关的购买信息,支付信息你要记录下来吧,因为 将来某一天你可能要和客户对帐的.再举个例子,平时大家都会去银行转帐,银行背地里一定把你转帐的相关信息都记录下来了,比如,转出帐户,转出时间,转出 金额,转入帐户等等.银行也经常说要多久以后到帐(比如5分钟),如果不到的话你可以凭单去银行对帐的.

    二. 现状

        目前绝大部分系统设计之初都是把日志这个动作,作为同步记录的,下面以伪码描述一下.

        using(transcation a){

             book.pay();//购买一本书并付款

             operate.add(); //增加一条事务日志.        

        }

    三. 问题分析

        1. 并发访问下的数据连接,在这个最简单的事务里打开两个连接,book一个,operate一个.考虑.net数据连接池默认100个情况,只考虑这个简单业务操作的话,强并发最多只能支持50个客户同时访问.

        2.网络访问,数据库访问是一个非常耗时的操作,将一个正常事务执行时间延长1倍,客户体验效率不好.

        3.每个业务操作都要调用,日志函数,导致日志不能批量写入,性能比较差

        4.业务日志有可能和生产库放在同一个数据库,不利于维护和查询优化以及数据量巨大时,数据分区等操作.不利于提交生产数据库性能

    四. 解决方案

        1. 支持两种数据写入方法,一种同步日志写入,即上面以前做法,一种异步日志,异步日志是对同步日志的一种包装.

        2. 异步日志主要是利用一日志文件来保证异步写入,比如日志文件为operate.log. 当系统调用需要写日志时,异步日志方法将日志写入到operate.log文件中,然后返回.

        3. 后台有个独立线程每隔X秒,读取全部日志文件,调用同步日志类中批量写方法写入日志数据库.

        4. 伪代码如下:

            using(transcation a){

               book.pay();//购买一本书并付款

               operate.aysAdd(); //异步增加一条事务日志.        

            }

            aysAdd(){

            FileStream stream = File.Open(path);

            stream.WriteLine();

            }

    五. 方案分析以及保障制度

        1. 不是同步保存,那我系统断电,或者IIS重起怎么办 答:当实例化日志类时候,将首先读取operate.log,并保存入库,保证日志文件不会丢失.

        2. 如果写文件过程中写入失败怎么办答:这里说了,异步日志是对同步模型的一个包装,是一个典型的装饰器模式.如果写文件失败,则转成同步模式去保存数据,不会丢失任何业务数据.

        3. 你那里是同步写还是异步写如果是异步写文件那断电怎么办如果是同步写日志,那性能和以前对比有什么提高吗

            答: 1. 同步写日志文件,即一定要保证日志文件能写入到文本文件,才能提交整个事务.

                 2. 只有异步写入数据的时候才会遇到这种问题,突然断电,日志文件丢失.

                 3. 做了一个性能测试,每秒可以写入1,000,000条业务日志到文件里,极高提升系统性能.批量提交日志文件到数据库,共享一个连接,而且Sql组成批语句,更可以节省数量级的性能损耗


    最新回复(0)