关于消息变更的最佳实践

问题描述

      工作中遇到的场景拿出来分享一下:

      最初需求

      程序启动读取配置文件,然后根据这些配置项去做一些任务,具体的任务会多次读取相应的配置项。最初的设计如下。

      关于消息变更的最佳实践

        ConfigProperties主要是读取配置文件的,FileTask(线程任务)就是执行任务的类,在doTask中通过getProperties来获取相应的配置。这个设计本来没什么问题,而且也满足了单一职责的设计。

       需求变更

        想让配置文件改变可以动态生效,没必要重启生效。

        关于消息变更的最佳实践

        MessageChanged是另外一个线程,当有改变时触发去触发configProperties的操作。同事就是这样实现的,变成了一个标准的多线程模式,用锁去锁了临界资源——配置文件的具体项。这就要求读取配置的同时,不能更新配置项。业务需求(filecount,filename,filepath)三者必须用的是同一个版本。这样就要求读写必须是互斥的,加锁是满足了这个需求,但是FileTask获取三个配置的地方特别分散。加锁的范围特别大。这样效率一点也不好。两个线程持有锁的时间都太久了。

        关于消息变更的最佳实践

            于是做了一点更变,那就是把数据存储进行了一层包装,数据都是分组存放的,每个组都是volatile的。这样加锁的操作变成了对一个变量的赋值和取值。

消息通知的套路

        上述的模式已经比较明朗了,当遇到这种消息变更的,处理的方式其实都是相似的,主要就是锁分离。

        1,首先需要本地缓存,就是旧的配置需要一份。

        2,运行任务的整体配置得组装到一起,以便原子性的更新。

        3,消息通知模式

                观察者模式

                事件机制

                队列机制(变更消息写入队列,每次先都去读取一次队列,决定是本地缓存还是新传入的值)

                多次读取(上面使用的情况)

 

        

关于消息变更的最佳实践