使用twisted中的twistd托管应用到daemon运行

====================
使用twistd托管应用
====================

:作者: gashero
:日期: 2009-08-26

.. contents:: 目录
.. sectnum::

简介
------

系统开发中经常遇到要把应用放到daemon中运行的情况,话说这个倒是不难,有很多现成的模块可用,就算是自己写也没几行代码。但是daemon托管的同时再捕捉所有屏幕输出日志,自动切换到其他uid/gid,切换运行目录chroot等等高级功能就不那么容易自己搞定了。

而使用twisted框架的daemon托管程序twistd来执行这些任务则是轻车熟路,功能全面而且稳定可靠。

使用twistd托管应用
--------------------

使用twistd托管应用需要实现以下几个要求:

    #. 启动函数非阻塞
    #. 定义启动模块全局变量 `application`

第二个条件倒是相对容易实现,但是对于绝大多数框架来说,第一个条件几乎是不可能的任务。下面给出一个符合上面要求的启动脚本结构::

    from twisted.internet import reactor,protocol,defer
    from twisted.application import service,internet
    from twisted.python import log

    def main():
        print 'started!'
        return

    if __name__=='__main__':
        main()
    elif __name__=='__builtin__':
        main()
        application=service.Application('hello')
 



假设如上模块叫做 ``sample.py`` ,那么可以通过如下脚本启动使其进入daemon模式运行::

    twistd -y sample.py

如上启动后会自动托管屏幕输出日志。需要关闭该应用时可以用::

    kill `cat twistd.pid`

对于主函数中需要阻塞的情况,也就是几乎绝大多数情况下,可以使用 `reactor.callLater()` 函数使得在启动函数中不阻塞,而在其后的主循环中阻塞的方式运行。如下(只显示启动脚本部分)::

 

    if __name__=='__main__':
        main()
    elif __name__=='__builtin__':
        reactor.callLater(1,main)
        application=service.Application('hello')

 

当然,你也许想到了为什么不把 `main()` 放入线程中运行。这是因为很多框架的启动函数中同时会注册信号处理器,而这些注册行为必须要在主线程中执行。当然如果你足够幸运的话,也可以用如下的形式碰碰运气::

 

    if __name__=='__main__':
        main()
    elif __name__=='__builtin__':
        reactor.callInThread(main)
        application=service.Application('hello')


这里建议使用twisted自带的线程管理函数,而不是自己用threading和thread模块的线程,因为后者的错误日志可能会消失的无影无踪。

好了,按照如上改造后,就可以使用twisted托管了。日志是按照不超过1MB来轮询的,在 ``twistd.log.<N>`` 中的数字N会持续增加,新日志的N比较小。建议用一个crontab来定期清理多余的日志。

控制脚本
----------

为了更方便的使用托管,还可以编写一个控制脚本实现进程的启动、退出、阻塞方式调试、日志查看等工作。内容如下,我一般叫做 ``ctlapp.sh`` ::

    #! /usr/bin/env sh
    MAIN_MODULE=sample.py

    case $1 in
        start)
            PYTHONPATH=.:$PYTHONPATH twistd -y $MAIN_MODULE
            ;;
        stop)
            kill `cat twistd.pid`
            ;;
        restart)
            kill `cat twistd.pid`
            sleep 1
            PYTHONPATH=.:$PYTHONPATH twistd -y $MAIN_MODULE
            ;;
        log)
            tail -f twistd.log
            ;;
        *)
            echo "Usage: ./ctlapp.sh start | stop | restart | log"
            ;;
    esac
 


使用该控制脚本的4个参数可以方便的控制应用。注意其中设置PYTHONPATH部分,是因为某些编译版本的twistd无法找到当前路径下的模块。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值