最近在使用EGGJS开发网站,这个框架整体上手难度不是很大,但是EGG的文档有些地方说得不是很详细,一些最佳实践就需要自己开发中逐渐摸索。本文就是我在实践中总结出来的一个小技巧:巧用ctx扩展减少数据库访问,希望能和大家一起探讨。
我们通常会在网站后台做一个配置管理页面,对一些常用参数进行管理。这些配置项参数是不需要经常变化的,譬如网站标题、第三方接口的url等等,但是每次调用时都需要去数据库进行读取,浪费服务器性能和时间,这个时候我们通常会用缓存去处理,先从缓存读取数据,如果不存在则从数据库读取。这样做看上去还不错,但问题是缓存容易丢失,冗余的数据库操作依然存在,而代码写起来也有点麻烦,那么在EGGJS中,我们该如何完美解决这个问题呢?
我首先想到的是EGGJS中有个app.js
的入口文件,这个文件可以在后台启动时自定义执行方法。那么我们在后台刚启动时就把这些常用配置项参数加载进来如何?答案是可行的,在app.js
中可以直接执行如下方法:
async didReady() {
const { app } = this;
const ctx = await app.createAnonymousContext();
// 读取数据库常用配置参数
const params = await ctx.model.Params.findAll();
// 存储
}
那么我们从数据库抽取出来的这些参数该保存到哪里呢?传统的内存管理器都有时效性,并且在服务器部署类似Redis的工具也很麻烦,杀鸡焉用牛刀?这里,我想到的是把抽取到的参数保存在EGGJS的ctx
变量中,ctx变量的生命周期就是EGG服务的生命周期,不用担心会丢失。所以我们扩展了context.js
文件,添加了一个专门存放参数的对象:
paramConfig: {
gate: {
}
}
后面的存储就简单了,直接调用ctx.paramConfig
变量进行赋值操作即可。但是别忘了一点,这些常用配置项虽然不经常变化,但有时候还是要进行编辑操作,改变value的。所以不要忘了在这些参数的保存修改接口中添加对ctx变量的同步操作!
当然本文的这个小技巧是针对少量低频变动参数的,相信每个系统都会有这种变量。离开少量低频变动这个场景,该用数据库的用数据库,该用Redis用Redis,该干嘛就干嘛。