egg icon indicating copy to clipboard operation
egg copied to clipboard

egg  config  异步支持

Open Wooleners opened this issue 6 years ago • 14 comments

我们的业务场景是数据库用户名密码需要先调用服务才可以拿到 但是现在config好像是不支持异步的 请问这个有办法实现么

Wooleners avatar Nov 22 '18 09:11 Wooleners

应该写个插件去异步获取。

killagu avatar Nov 22 '18 14:11 killagu

可以自己手动完成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);

wanghsinche avatar Nov 28 '18 16:11 wanghsinche

这怕是要写个自定义framework了吧,原框架的加载顺序都是同步的,如果说你的plugin或者中间件在应用启动期间就需要配置信息的话,就不行了吧。如果实在太麻烦的话可以写个脚本,在应用启动之前先下载配置,然后再启动应用

guoshencheng avatar Dec 29 '18 06:12 guoshencheng

可以在app的钩子里进行配置。

tong3jie avatar Mar 04 '19 09:03 tong3jie

现在 configWillLoad 是同步的,只能在里面通过 execSync 来获取。

atian25 avatar Mar 04 '19 09:03 atian25

我们项目的配置也是存储在配置中心,需要启动前异步获取配置,可惜egg好像很坚持本地同步读配置文件,一直不能下决心改用egg

joyexpr avatar Apr 18 '19 11:04 joyexpr

3.x 里面可以做下这个

atian25 avatar Apr 24 '19 06:04 atian25

@joyexpr 就目前而言,其实也是可以用的,mysql 这些都是通过 addSingleton 来初始化的,它本身就有个 createInstance() 的方式,你们可以先不用 config.mysql.client 这个配置,而是自行在 hook 里面去 async 获取配置,然后自己 createInstance()

atian25 avatar Apr 24 '19 06:04 atian25

我们也有这需求,目前的 redis 配置是存储在数据库,但是后端是 java,我们需要使用 http 来获取配置,如果用 koa 就很容易实现,想迁移到 egg,但是异步配置这个问题不知道这么解决

zhengxs2018 avatar Sep 05 '19 01:09 zhengxs2018

目前有一种略微曲折的解决方案:

  • 在 agent 的生命周期里面去读取 http,然后写入文件
  • 在 app 的 config 里面 require 这个文件。

atian25 avatar Sep 05 '19 01:09 atian25

其实可以考虑试试同步的http请求库,比如 syncrequest 当然要自己考虑启动超时的后果

ngtmuzi avatar Oct 31 '19 06:10 ngtmuzi

目前我们的方案是读取完配置之后,注入到环境变量,然后再启动egg,config.default里去读取环境变量,然后merge

yuu2lee4 avatar Mar 09 '20 09:03 yuu2lee4

#https://github.com/eggjs/egg/issues/4243

mstar-kk avatar Apr 03 '20 12:04 mstar-kk

提供一个临时方案:https://github.com/atian25/egg-remote-config

atian25 avatar Jul 24 '20 06:07 atian25