V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
yakczh
V2EX  ›  Python

python web 脚本为什么不能热更新

  •  
  •   yakczh · 2015-05-13 08:37:43 +08:00 · 10736 次点击
    这是一个创建于 3484 天前的主题,其中的信息可能已经有所发展或是发生改变。

    java应用服务器启动以后,要把web项目下用的所有类文件都要加载到内存,修改了源代码,只能重启服务器,但是python应该是动态脚本,为什么修改了脚本以后要用 tornado.autoreload.start() 这样重启服务器

    30 条回复    2015-05-15 08:55:56 +08:00
    ksc010
        1
    ksc010  
       2015-05-13 08:54:55 +08:00
    python启动后是常住内存的
    不跟php一样每次请求“都加载一次”
    yakczh
        2
    yakczh  
    OP
       2015-05-13 09:00:56 +08:00
    那如果项目变大了,import的文件越多,占用的内存就越大, 跟java一样了
    binux
        3
    binux  
       2015-05-13 09:02:26 +08:00 via Android   ❤️ 1
    从未听说过,一个项目被抱怨代码多了,占内存大的。
    clino
        4
    clino  
       2015-05-13 09:04:19 +08:00
    理论上应该也能做到热更新吧,比如说不少uliweb的调试服务器之类为了调试方便就是改完马上应用的,但要是生产环境这么做,出问题的时候不知道是不是用了热更新导致的莫名其妙的问题,估计很少人在生产环境下会这么用
    kingname
        5
    kingname  
       2015-05-13 09:06:16 +08:00
    其实是可以热更新的。如果你见过flask的debug模式,你就知道,你改了一个文件,它自动就加载了。
    yakczh
        6
    yakczh  
    OP
       2015-05-13 09:32:49 +08:00
    @kingname flask 也是扫苗lib site-packages 下的所有文件, 有更新就重启服务器
    yakczh
        7
    yakczh  
    OP
       2015-05-13 09:36:02 +08:00
    如果你安装的package比较多,还不如直接ctrl+c 来得快
    est
        8
    est  
       2015-05-13 09:40:08 +08:00
    > 为什么修改了脚本以后要用 tornado.autoreload.start() 这样重启服务器

    因为显式重启比较好?

    框架也可以非显式重启,那么会影响性能的。
    awanabe
        9
    awanabe  
       2015-05-13 10:04:25 +08:00
    python代码编译成pyc..你更新了py代码, 需要重启编辑一次...这个就是非编译语言的做法...
    yakczh
        10
    yakczh  
    OP
       2015-05-13 10:06:15 +08:00
    @awanabe 那这样python是不是跟java一样了?
    laoyuan
        11
    laoyuan  
       2015-05-13 10:24:11 +08:00
    所以说PHP是。。。我学Python 就是为了写爬虫!
    gamexg
        12
    gamexg  
       2015-05-13 10:32:48 +08:00
    说实在的还是手动重启比较好。
    比如你这次更新需要修改了10个文件,你刚修改了1个文件,这时候有人访问,如果自动加载新代码的话访问的是更新了半截的网站,出现各种意外都不奇怪。
    mkeith
        13
    mkeith  
       2015-05-13 10:33:29 +08:00
    怎么Python就和Java一样了啊
    hahastudio
        14
    hahastudio  
       2015-05-13 10:41:59 +08:00
    理论上是可以的,有 imp module https://docs.python.org/3/library/imp.html
    2.7 也有 reload 函数 https://docs.python.org/2/library/functions.html#reload

    不过正如文档里提到的, The init function of extension modules is not called a second time.
    当然你可以手工做,但总会出现这样那样的问题。我看到更多的是玩具性质的 script
    实际生产环境的话,也许一个临时的 hotfix 用这个机制挺有效,但是真的更新的话,还是重启 server 比较好
    caoyue
        15
    caoyue  
       2015-05-13 11:09:45 +08:00
    我觉得不是不能,是没必要=-=
    只有设计的时候就考虑了不能重启必须热更新的情况,比如 Erlang 之于电信服务,那支持热更新就是顺理成章的了
    weyou
        16
    weyou  
       2015-05-13 11:10:00 +08:00
    实现一个动态加载的功能就可以了, 需要重新load模块,发个信号给主进程就行了。
    raptor
        17
    raptor  
       2015-05-13 11:21:00 +08:00
    即时重启与否并不是最重要的,重要是能否优雅地重启——即在不中断当前连接的情况下对新连接使用新服务。
    bydmm
        18
    bydmm  
       2015-05-13 11:22:27 +08:00
    应该可以热更新 问题是热更新带来的脏读脏写怎么办? 而且项目启动的时候,很多class是需要做缓存来优化性能的。

    我不太懂python,但是ruby的 ruby on rails框架就有支持热更新的开发模式和需要重启的生产模式。 我猜应该和楼主的问题有相同的原因
    bydmm
        19
    bydmm  
       2015-05-13 11:24:03 +08:00
    @raptor 对服务器进行逐批重启就搞定了,这个java都ok
    yakczh
        20
    yakczh  
    OP
       2015-05-13 11:31:23 +08:00
    @bydmm ruby怎么实现的? 是不是把app下要用到的rb脚本启动的时候一次性加载到内存里?
    kslr
        21
    kslr  
       2015-05-13 11:52:20 +08:00
    自动加载有什么好的
    ibigbug
        22
    ibigbug  
       2015-05-13 12:06:05 +08:00
    为什么要能?
    rcmerci
        23
    rcmerci  
       2015-05-13 12:09:49 +08:00
    你代码里开个线程每隔5秒检查一下有没有文件改变。
    改变了然后就重启。
    这样就可以算热更新把
    feilaoda
        24
    feilaoda  
       2015-05-13 12:09:50 +08:00
    还曾想写个好用的支持热部署的web服务器,有了docker之后,就感觉热部署不再那么需要了。
    loveyu
        25
    loveyu  
       2015-05-13 12:25:10 +08:00
    最近一直在想JAVA热更新问题,虽然目前没这个必要,但感觉要不中断现有链接且保证链接不中断好难。有想过使用两台服务器做来切换不知道是否可行。
    caixiexin
        26
    caixiexin  
       2015-05-13 12:26:49 +08:00
    刚学flask的时候我也发现了,也许惯性思维觉得解释型语言(php,js)都是要用再加载的?
    FrankFang128
        27
    FrankFang128  
       2015-05-13 12:37:00 +08:00
    一般需要开启 debug 模式
    raptor
        28
    raptor  
       2015-05-14 08:58:16 +08:00
    @bydmm 那么当前连接在被重启服务器上的用户就会被强制断开
    bydmm
        29
    bydmm  
       2015-05-14 11:18:59 +08:00
    @raptor
    @loveyu
    阿里就是通过分批次重启解决的, 首先让某些服务器停止接受新请求,剩余的请求最多30秒就断开了(超过30秒就超时了)然后这台服务器重启, 第一批重启完之后是第二批,第三批。
    raptor
        30
    raptor  
       2015-05-15 08:55:56 +08:00
    @bydmm 是啊,重点就在于让准备重启的服务器暂时停止接受新请求,并等待现有请求处理完成。
    这事跟有没有多服务器没有关系,单个服务器也需要考虑这个问题,比如apache的graceful,nginx的kill -HUP。python的web server也可以,比如gunicorn就可以
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1256 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 18:08 · PVG 02:08 · LAX 10:08 · JFK 13:08
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.