Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

“现在pinus框架提供了 handler remoter crons的热更新方法,至此,基本可以实现完整的应用不停机热更新”怎么理解呢? #155

Closed
linguitang opened this issue Feb 19, 2021 · 15 comments

Comments

@linguitang
Copy link

假设有个公共的文件util/util.js有问题,怎么更新呢

@whtiehack
Copy link
Member

whtiehack commented Feb 20, 2021

wiki-pinus手动热更新方法 🔗

先清除 自己的逻辑文件缓存, 然后 调用框架的热更新方法

可以参考一下

       // 热更新自己的逻辑
        await logicHostUpdate()
        await new Promise((resolve) => {
            this.beforeStart(() => {
                resolve()
            })
        })
        // 框架的热更新方法
        console.log(this.app.getServerId(), 'logic hot update  handler')
        manualReloadHandlers(this.app)
        console.log(this.app.getServerId(), 'logic hot update  remoter')
        manualReloadRemoters(this.app)
        // manualReloadProxies(this.app)
        console.log(this.app.getServerId(), 'logic hot update  crons')
        manualReloadCrons(this.app)
        console.log(this.app.getServerId(), 'logic hot update  finished')

logicHostUpdate 里面的逻辑就是对自己的逻辑进行缓存清除

大概的逻辑是这样的 (这是node的东西,详细的可以百度或者gg)

        // 清除需要热更新的文件的require缓存
        const moduleObj = require.cache[f];
        if (!moduleObj) {
            continue;
        }
        if (moduleObj.parent) {
            moduleObj.parent.children.splice(moduleObj.parent.children.indexOf(moduleObj), 1);
        }
        delete require.cache[f];

@whtiehack whtiehack changed the title “现在pinus提供框架了 handler remoter crons的热更新方法,至此,基本可以实现完整的应用不停机热更新”怎么理解呢? “现在pinus框架提供了 handler remoter crons的热更新方法,至此,基本可以实现完整的应用不停机热更新”怎么理解呢? Feb 20, 2021
@Guozihong
Copy link
Contributor

如果用了nest,还能这么热更吗,我试了删除缓存没用? @whtiehack

@whtiehack
Copy link
Member

我们就是用的nest . 在清除自己的逻辑缓存后,要重新 create nest对象.

@Guozihong
Copy link
Contributor

Guozihong commented Feb 22, 2021

我们就是用的nest . 在清除自己的逻辑缓存后,要重新 create nest对象.

重新create的话,那旧的nest对象要怎么清除呢,旧的close,新的重新listen吗?能给点参考不,感谢!

@whtiehack
Copy link
Member

我们没有用到listen,只是用的它的模块机制, init一下就可以用了.

原来的 nest对象可以 orgNestapp.close() 用close关掉 ,也可以不管. 因为没有listen, 会自动释放掉.

@Guozihong
Copy link
Contributor

Guozihong commented Feb 23, 2021

我们没有用到listen,只是用的它的模块机制, init一下就可以用了.

原来的 nest对象可以 orgNestapp.close() 用close关掉 ,也可以不管. 因为没有listen, 会自动释放掉.

试了下,原来的不关闭的话typeorm会报‘connection with such name already exist’,如果关闭的话,http服务器的话基本就等于重启了,其它类型服务器,数据库连接等provider也会短暂没法使用吧,如果是这样的话感觉分布式部署,多个进程交替重启比较稳妥

@whtiehack
Copy link
Member

db和有状态的代码我们是单独放的,不热更新..

举个例子

provider.ts

export const cacheRedisProviders = [
    {
        provide: PROVIDERS.REDIS_CACHE,
        useFactory: async () => {
            const redisConfig: RedisConfig = LOGIC_FILEPATH.CONFIG_REDIS_CACHE;
            return redisFactory.getRedis(redisConfig);
        },
    },

];

redisFactory 这个对象里缓存了 redis的连接,这个对象是不清除缓存的.

其它的类似有状态的数据,同样也是不清除缓存的.所以可以做到代码热更新而不影响到db连接和有状态的内存数据.

@Guozihong
Copy link
Contributor

db和有状态的代码我们是单独放的,不热更新..

举个例子

provider.ts

export const cacheRedisProviders = [
    {
        provide: PROVIDERS.REDIS_CACHE,
        useFactory: async () => {
            const redisConfig: RedisConfig = LOGIC_FILEPATH.CONFIG_REDIS_CACHE;
            return redisFactory.getRedis(redisConfig);
        },
    },

];

redisFactory 这个对象里缓存了 redis的连接,这个对象是不清除缓存的.

其它的类似有状态的数据,同样也是不清除缓存的.所以可以做到代码热更新而不影响到db连接和有状态的内存数据.

了解,感谢,抽时间再试试!

@whtiehack whtiehack pinned this issue Feb 23, 2021
@linguitang
Copy link
Author

wiki-pinus手动热更新方法 🔗

先清除 自己的逻辑文件缓存, 然后 调用框架的热更新方法

可以参考一下

       // 热更新自己的逻辑
        await logicHostUpdate()
        await new Promise((resolve) => {
            this.beforeStart(() => {
                resolve()
            })
        })
        // 框架的热更新方法
        console.log(this.app.getServerId(), 'logic hot update  handler')
        manualReloadHandlers(this.app)
        console.log(this.app.getServerId(), 'logic hot update  remoter')
        manualReloadRemoters(this.app)
        // manualReloadProxies(this.app)
        console.log(this.app.getServerId(), 'logic hot update  crons')
        manualReloadCrons(this.app)
        console.log(this.app.getServerId(), 'logic hot update  finished')

logicHostUpdate 里面的逻辑就是对自己的逻辑进行缓存清除

大概的逻辑是这样的 (这是node的东西,详细的可以百度或者gg)

        // 清除需要热更新的文件的require缓存
        const moduleObj = require.cache[f];
        if (!moduleObj) {
            continue;
        }
        if (moduleObj.parent) {
            moduleObj.parent.children.splice(moduleObj.parent.children.indexOf(moduleObj), 1);
        }
        delete require.cache[f];

这个你们是通过pinus admin web来执行这段代码的吗

@whtiehack
Copy link
Member

@linguitan
方法很多,http, adminmodule, adminweb 都可以吧.我们是用的 adminmodule,和adminweb差不多.
http最简单.

@linguitang
Copy link
Author

感谢

@zhoujxMT
Copy link

我的是nest。按照步骤,最后 NestFactory.createApplicationContext(AppModule) ,缓存还是没有清除 @Guozihong @whtiehack

@Guozihong
Copy link
Contributor

我的是nest。按照步骤,最后 NestFactory.createApplicationContext(AppModule) ,缓存还是没有清除 @Guozihong @whtiehack

按步骤理论上是没问题的,估计就是你缓存没清除干净,NestFactory.createApplicationContext只是为了让nest框架本身重新加载代码,如果清除干净你想更新的require.cache,底层就会重新加载脚本的

@zhoujxMT
Copy link

大佬你是怎么做的热更新呢@Guozihong

@Guozihong
Copy link
Contributor

大佬你是怎么做的热更新呢@Guozihong
我不是大佬,我部分服务有用到http功能,如果关闭重新创建跟滚动重启感觉差不多,还没抽时间继续研究。不过原理是那个原理,大佬已经实践过了 @whtiehack 有什么疑惑的话,你可以向他请教请教。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants