egg
egg copied to clipboard
egg config 异步支持
我们的业务场景是数据库用户名密码需要先调用服务才可以拿到 但是现在config好像是不支持异步的 请问这个有办法实现么
应该写个插件去异步获取。
可以自己手动完成addSingleton方法做的一些事。
比如异步获取config后,调用createInstance方法创建实例,并把实例添加到那个map中.
比如说定义一个mongo创建函数:
async function createMyMongo(config: EggAppConfig, app: Application) {
const FLAG = '$mymongohost$';
const mongodbURL = new URL(`mongodb://${FLAG}/`);
mongodbURL.pathname = config.dbName;
// 创建实例
const url = mongodbURL.href.replace(FLAG, config.host); // 因为不支持多个host
const client: MongoClient = new MongoClient(url, {
// poolSize: config.poolSize,
reconnectInterval: 5 * 60 * 1000, // 5 min
reconnectTries: 3, // 3 times
useNewUrlParser: true, // current URL string parser is deprecated, and will be removed in a future version. To use the new parser, pass option { useNewUrlParser: true } to MongoClient.connect.
});
app.logger.info(`[my-mongo]: init ${url}`);
client.on('open', () => {
app.logger.info(`[my-mongo] Open ${url}.`);
});
await client.connect();
return client;
}
在app beforeStart 的hook里调用:
app.addSingleton('myMongo', createMyMongo);
在获取到动态配置后,就可以调用createMyMongo
,创建实例,并添加到clients中。
const instance = await app.myMongo.createInstanceAsync(config);
myMongo.clients.set(clientId, instance);
这怕是要写个自定义framework了吧,原框架的加载顺序都是同步的,如果说你的plugin或者中间件在应用启动期间就需要配置信息的话,就不行了吧。如果实在太麻烦的话可以写个脚本,在应用启动之前先下载配置,然后再启动应用
可以在app的钩子里进行配置。
现在 configWillLoad
是同步的,只能在里面通过 execSync
来获取。
我们项目的配置也是存储在配置中心,需要启动前异步获取配置,可惜egg好像很坚持本地同步读配置文件,一直不能下决心改用egg
3.x 里面可以做下这个
@joyexpr 就目前而言,其实也是可以用的,mysql 这些都是通过 addSingleton
来初始化的,它本身就有个 createInstance()
的方式,你们可以先不用 config.mysql.client
这个配置,而是自行在 hook 里面去 async 获取配置,然后自己 createInstance()
我们也有这需求,目前的 redis 配置是存储在数据库,但是后端是 java,我们需要使用 http 来获取配置,如果用 koa 就很容易实现,想迁移到 egg,但是异步配置这个问题不知道这么解决
目前有一种略微曲折的解决方案:
- 在 agent 的生命周期里面去读取 http,然后写入文件
- 在 app 的 config 里面 require 这个文件。
其实可以考虑试试同步的http请求库,比如 syncrequest 当然要自己考虑启动超时的后果
目前我们的方案是读取完配置之后,注入到环境变量,然后再启动egg,config.default里去读取环境变量,然后merge
#https://github.com/eggjs/egg/issues/4243
提供一个临时方案:https://github.com/atian25/egg-remote-config