前几天帮助其他项目组的一个小伙伴解决了一个代码上的问题,他们代码的主要功能是这样的(这里只写伪代码):
流程上是没有问题的,但其实有两步是重复操作,一是读取本地密钥文件,二是从数据库中查询请求 url ;
每次发送请求的时候,都要做这两步操作,其实完全是可以把密钥文件和 url 放在静态变量中,初始化一次,然后每次发送报文时直接使用,这样就可以让你的代码少干点儿活儿。
接收参数;
读取本地密钥文件;
对接收参数进行加密;
从数据库中查询请求url;
发送加密后的报文;
让我们看看修改后的代码:
静态变量:
byte[] 存放读取出来的密钥文件 和 url ;
单独的方法:
如果 byte[] 为空,初始化;不为空,则返回;
如果 url 为空,初始化;不为空,则返回;接收参数;
通过方法获取静态变量 byte[] ;
对接收参数进行加密;
通过方法获取静态变量 url ;
发送加密后的报文;
缓存数据加载时间
让我们对比一下改造前后的代码(改造后的代码并不是没有缺点):
- 每次使用加载:使用过程中,实时取数据库中的配置,好处是当数据库中的配置发生了修改,可以实时地得到;缺点也显而易见,就是每次都要做一次操作,影响效率;
- 项目启动时加载:如果在项目启动的时候做初始化,好处是只做一次操作,但是要考虑初始化的过程中,是否会概率发生异常;一旦发生异常,这些配置没有被加载到内存中,也是很危险的;
- 第一次使用加载:第三种就是我们所使用的,在第一次使用的时候初始化;相比前两种方法,效率更高并且更保险;缺点是配置信息发生变化,除非重启服务,否则不会加载最新的配置;针对这一点,需要写额外的代码,比如加载到内存中的缓存,设置超时时间(定期刷新缓存);或者留有接口或页面功能,主动刷新缓存;当然这些额外的开发会增加代码的复杂程度。
缓存数据存放位置
另外,将配置信息直接放在一个静态变量中缓存,也不是什么特别好的办法,还有更优的做法:
- 设置一个静态的 **HashMap **,把这些缓存数据统一存放;为防止缓存数量太大,可以采用LRU等策略淘汰缓存;
- 使用**缓存框架,例如 Ehcache **,让框架帮助我们做缓存存放及淘汰的工作;
- 如果配置信息变化的频率比较快,实时性要求很高,可以考虑把它们存放在**第三方缓存系统中,比如 Redis **,并通过有效的手段更新缓存信息;当然,每次调用Redis也会消耗一定的时间,尽管这个时间会很短;
- 如果项目有开发能力的话,可以搭建统一的配置中心。
当然,考虑到这个项目非常老,不太可能加入复杂的架构,所以就采用了看起来“不是特别好的方法”,把配置信息加载到静态变量中。