Tornado框架的模板热更新问题(实现html热更新)

本文介绍了如何在Tornado框架下实现模板的热更新,避免因修改HTML文件而频繁重启服务。通过利用Tornado模板加载器的reset()方法,可以在不关闭web程序的情况下使修改的HTML内容实时生效。文章提供了基于Redis的简单文件修改检测逻辑,实现在特定条件下触发模板热更新,从而提高开发效率和用户体验。
摘要由CSDN通过智能技术生成

       环境:win/linux下 Python3+Tornado 6

       阅读本文需要技术:Redis

       难度: ⭐

        长期以来,tornado框架的使用者多数是做的前后端分离,完全没有html模板热更新的需要。但是如果遇到条件限制,只能单机运行且单机性能不佳的情况下,就被迫不能做前后端分离了。

        一般情况下,我们在tornado框架的web程序中修改完了html文件后(内容修改),需要重启web程序来让修改生效。这样是十分低效且繁琐的,特别是生产环境需要临时变更,业务重启的那几秒都可能造成不小的损失,给用户带来不好的体验。

        于是,我翻阅了tornado官方文档中,和模板系统相关的文档。文档中对于tornado的模板系统的加载器是这样描述的

如图所示,加载器会在模板首次加载后进行缓存,这样做可以提高性能和响应速度。

        既然是叫“缓存”那么就一定会有办法可以刷新或者清空这个缓存,这下事情就好办了,继续阅读文档就可以发现reset()方法

        文档中的描述就是使用reset()可以重置缓存,之后我去 tornado.web.RequestHandler这个类(也就是我们使用过程中继承的类)里面查找reset()用法,发现了意外的东西。

        如图所示, RequestHandler类的execute方法内使用了reset(),但是我并不打算去研究这个execute方法是如何触发的,图中红框可以看到,它直接对RequestHandler类下的模板加载器进行了操作,取出的loader(加载器)中可以调用到reset方法。

        而我们使用tornado框架编写响应类时,也会继承RequestHandler类,于是乎,我们在自己的t代码中应该也可以直接调用到reset(),我们不妨尝试一下

class UserLogin(tornado.web.RequestHandler):
    # 用户登录页面(你自己的业务代码)
    def get(self):
        ...
        for loader in self._template_loaders.values():
            print(loader.namespace)
            loader.reset()
        ...

        在您的getpost方法内添加以上get方法内代码后启动程序,查看页面,在不关闭web程序的情况下修改html文件并保存,再次查看页面。不出意外的话您会和我一样,看到页面上发生了变化。

        通过简单的测试,我们发现这个方法是可行的,那么我们接下来需要做的就是根据具体业务需求和场景,设置不同的热更条件,我这里基于Redis实现了一个简单的文件修改后热更新逻辑,在普通业务量的系统中应该是够用的了。

class user_login(tornado.web.RequestHandler):
    # 用户登录页面
    def data_received(self, chunk: bytes) -> Optional[Awaitable[None]]:
        pass

    def get(self):
        ...

        # //模板热更新[开始]//
        # 官方技术参考1:https://tornado-zh.readthedocs.io/zh/latest/template.html#tornado.template.BaseLoader.reset
        # 官方技术参考2:https://tornado-zh.readthedocs.io/zh/latest/_modules/tornado/template.html#BaseLoader.reset
        # 该写法存在性能问题,因为每次请求页面都会去读取文件获取文件的修改时间,仅在部分页面实验性的使用,业务量大的请自行优化

        templates_name = 'qijian_login'
        t_time = MainRedis.get(f'template_file_{templates_name}')
        # MainRedis为一个实例化并且建立好连接的redis实例MainRedis = redis.Redis(host=redis_config['host'], port=redis_config['port'], decode_responses=True)

        if t_time is None:
            t_time = '0'
        n_time = str(os.path.getmtime(f'templates/{templates_name}.html'))
        if t_time != n_time:
            print("模板热更新")
            # print(t_time)
            # print(n_time)
            # 下方代码会将加载器内所有的模板缓存进行更新
            for loader in self._template_loaders.values():
                print(loader.namespace)
                loader.reset()
            MainRedis.setex(f'template_file_{templates_name}', 86400, n_time)  # 缓存24小时
        # //模板热更新[结束]//

        上面的代码较为基础,实际使用过程中还请根据自己的实际业务需求进行修改.

        文章如有遗漏或错误的地方还望指正,最后,希望各位可以给我点一点大拇指并关注。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无别052

你的鼓励是我最大的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值