Tornado 如何组织中大型项目,你们都是怎么样做的? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
mywaiting
V2EX    Tornado

Tornado 如何组织中大型项目,你们都是怎么样做的?

  •  
  •   mywaiting 2015-11-26 22:24:16 +08:00 13591 次点击
    这是一个创建于 3605 天前的主题,其中的信息可能已经有所发展或是发生改变。
    用了 tornado 也写网站,无它,当初就是因为喜欢,因为 tornado 的代码写得真心漂亮。

    一开始我是这样组织项目的,你没有看错,真心只有这几个文件:

    + project
    | - app.py (基本所有的 handler 都在这里了)
    | - models.py (数据库相关的)
    | + templates
    | + static

    如果要给个参考例子,那 BT 大大的项目来参考吧 https://github.com/finiteloop/socialcookbook 刚刚开始写 tornado 的项目的时候没有那么多的东西,一切都很简洁很美好!

    然后呢,项目越来越多功能了,需要组织的代码越来越多,需要 Seesion ,需要 form 检验等一堆东西,于是重构为这样来组织项目:

    + project
    | + controllers
    | | - acontroller.py
    | | - bcontroller.py
    | | ....
    | + models
    | | - amodel.py
    | | - bmodel.py
    | | ....
    | + templates
    | + forms
    | | - aform.py
    | | - bform.py
    | | ....
    | + helpers
    | | - ahelper.py
    | | - bhelper.py
    | | ....
    | - application.py
    | - urls.py
    | - settings.py

    很直接也很明显,这是拿 Tornado 来做 MVC 这龌龊的事情了,把先前越来越大的 app.py 分开成 controllers 目录, models 目录页一样,增加了 forms 目录和 helpers 目录。 application.py 放置整个 project 的启动、关闭, URL 放在 urls.py , settings 嘛就是配置。

    这样安好运行了好长一段时间,毕竟一个小网站,长成这样已经很对得起我拿的工资了。但是这样的项目结构随着业务的增多感觉越来越力不从心:

    1 、首先业务关联比较多,类似于门户网站那样的 CMS 类型的,这样就无法分出几个项目来应用上面的代码组织了。
    2 、子域名的需求众多,基本一个子域名 a.example.comb.example.com 的代码逻辑是完全不一样的,但是数据库后面的数据却有很多需求重合的。同时原因见 1 ,又无法分出好几个 project 来组织代码

    感觉越来越臃肿的代码结构,越来越多的东西加入到 Tornado 这个大杂烩里面,感觉项目长得越来越像 Django 的项目,但是组织却远不如 Django 的项目组织得好!

    看了一下 Flask 的 Blueprint ,这货貌似在架构大型项目的时候很实用的样子。

    就像这篇文章 https://spacewander.github.io/explore-flask-zh/7-blueprints.html 说到的按照功能(functional)或者分区(divisional)来组织代码。

    按照 分区(divisional) 来组织代码貌似有天生的适合大型的且内部可以松耦合的项目,而类似我上面的 按照功能(functional) 来组织项目就适合组织功能相对内聚的项目。

    按照我这么重构下去,迟早要弄个 Django 出来的感觉。有点后悔当初怎么不直接用 Django 而用上了 Tornado 来自己造各种轮子。

    各位在架构 Tornado 的中大型项目,有什么经验可以分享吗?

    谢谢!
    23 条回复    2021-05-14 18:14:46 +08:00
    janxin
        1
    janxin  
       2015-11-26 23:13:28 +08:00 via iPhone
    本质上蓝图组织方式 tornado 里也能用,只不过是需要拆分就好了。至于蓝图的 url 组织形式, tornado 里也有人实现过了 url 修饰器功能,修改一下就可以用了。

    模型复用比较多的时候,我的项目组织比较类似,不过 controller 部分进行了模块拆分。

    其实我也觉得 django 挺好的,除了性能…
    mywaiting
        2
    mywaiting  
    OP
       2015-11-26 23:27:16 +08:00
    @janxin 跑在 Gunicorn 中,有 Gevent 、 Eventlet 的加持,不会差很多吧
    janxin
        3
    janxin  
       2015-11-26 23:30:29 +08:00 via iPhone
    @mywaiting 提升有,但是还是会有性能影响
    zhuangzhuang1988
        4
    zhuangzhuang1988  
       2015-11-26 23:31:26 +08:00
    大型项目? 没做过. 不过看过 ipython notebook 中的代码的
    https://github.com/ipython/ipython/blob/3.x/IPython/html/notebookapp.py#L223
    mywaiting
        5
    mywaiting  
    OP
       2015-11-26 23:36:23 +08:00
    @zhuangzhuang1988 没有想到 IPython 里面也有这个,....

    谢谢了~
    fwee
        6
    fwee  
       2015-11-26 23:42:12 +08:00
    我也是最近刚用,不是按照 MVC ,而是按照功能模块放在不同的 package 里,然后多拆分 handler
    wingyiu
        7
    wingyiu  
       2015-11-26 23:43:32 +08:00
    不一定要在同一个项目吧?比如那个不同子域名的。拆分成不同的小 tornado 项目 单独部署不也是一种方式吗?重复的部分搞成一个库咯?
    mywaiting
        8
    mywaiting  
    OP
       2015-11-26 23:53:11 +08:00
    @wingyiu 主要拆分成小的 project ,那会很小啊,懒得拆了再开多一个 git 仓库了。其实 django 或者 flask 那样类似 package 组织的话,可以组织得挺好的 :)
    slixurd
        9
    slixurd  
       2015-11-27 00:47:41 +08:00
    RPC 啊 SOA 啊
    好吧,我受 Java 荼毒太深。
    zeayes
        10
    zeayes  
       2015-11-27 08:47:15 +08:00   1
    拆分一下项目吧,做下服务化,是明智的选择。
    tuteng
        11
    tuteng  
       2015-11-27 09:15:53 +08:00
    同感
    yueyoum
        12
    yueyoum  
       2015-11-27 10:08:02 +08:0
    python web 生态圈 为何 Django 一家独大?

    因为其他框架 做到后面, 基本都是你自己添加各种东西,拼凑出一个 Django 来
    但是 远没有 Django 本身优雅
    janxin
        13
    janxin  
       2015-11-27 10:53:56 +08:00
    @yueyoum Django 到现在都不支持 MongoDB 这个让我挺遗憾的...
    mywaiting
        14
    mywaiting  
    OP
       2015-11-27 11:07:29 +08:00
    @yueyoum 基本都是这样的吧,因为 web 开发都是这些东西,要是用 tornado 、 flask 这样的,那就只能不断去拼凑了,最后都差不多整成 django 这样或者近似 django 等大型框架这样。

    但是不能否认,这么拼凑的过程中,自己不断造轮子可以对 web 开发的理解深刻好多。回头再来用 django ,那就基本是稍微翻翻文档的事情吧。
    lianghui
        15
    lianghui  
       2015-11-27 11:18:39 +08:00   1
    把最近的 tornado 项目分层结构参考 分享下。 吸收了 scala 框架与一些其他语言框架的特性, 使用了 tow scope 的概念,使用了 hocon 配置,使其可被文件配置。


    https://github.com/whiteclover/Zephyr


    /CODE/ZEPHY
    │ requirement.txt
    setup.py
    │ zephyrd

    ├─conf
    │ app.conf # hocon 配置
    ├─schema
    │ mysql
    └─zephyr
    app.py # 应用
    autoload.py # 自动加载容器
    breeze.py #核心容器实现
    cmd.py
    feed.py
    flash.py
    helper.py
    jinja2t.py
    log.py
    options.py
    orm.py
    patch.py
    pedis.py
    session.py
    util.py
    __init__.py

    ├─asset #静态文件
    │ ├─js
    │ └─theme
    │ └─default
    │ ├─css
    │ ├─img
    │ └─js
    ├─boot # 命令控制
    asset.py
    database.py
    jinja2t.py
    pedis.py
    site.py
    __init__.py

    ├─config # 配置加载 lexer 类
    errors.py
    hocon.py
    _config.py
    __init__.py

    ├─lang
    │ │ __init__.py
    │ ├─en_GB
    │ ├─zh_CN
    │ └─zh_TW

    ├─lib
    image.py
    memoize.py
    paginator.py
    validator.py
    __init__.py

    ├─module # 模块 api 分割
    │ │ __init__.py
    │ │
    │ ├─category
    │ ├─comment
    │ ├─extend
    │ │ │ mapper.py # orm 层
    │ │ │ model.py # 领域类, 可以进一步分成模块文件夹
    │ │ │ thing.py # 逻辑层
    │ │ │ __init__.py
    │ │ │
    │ │ └─view # url 控制与 url 路由
    │ │ field.py
    │ │ __init__.py
    │ │
    │ ├─front
    │ │ mixin.py
    │ │ view.py
    │ │ __init__.py
    │ │
    │ ├─menu
    │ │ thing.py
    │ │ view.py
    │ │ __init__.py
    │ └─user
    mapper.py
    model.py
    thing.py
    view.py
    __init__.py

    └─template
    ├─admin
    │ ├─extend
    │ │ ├─field
    │ │ ├─metadata
    │ │ └─plugin
    │ ├─layout
    │ │ edit.html
    │ │ footer.html
    │ │ header.html
    ├─component
    │ views.html #组件
    └─theme
    └─default
    felixzhu
        16
    felixzhu  
       2015-11-27 11:39:14 +08:00
    其实都是这样的,慢慢的到最后就会做成 Django 。。

    楼主可以参考下网上的开源项目的结构,比方说 sentry 之类的,然后自己拓展一下
    waytwoex
        17
    waytwoex  
       2015-11-27 12:35:45 +08:00
    受到 php 的荼毒,我这个架构其实也不怎么样。。仅供参考……
    https://github.com/phith0n/Minos
    northisland
        18
    northisland  
       2015-11-27 20:11:17 +08:00
    @lianghui 请问这图是怎么生成的?
    shajiquan
        19
    shajiquan  
       2015-11-27 20:25:27 +08:00
    @northisland 这不是文字么。用 tree 命令就生成了。
    northisland
        20
    northisland  
       2015-11-28 11:05:59 +08:00
    @shajiquan 刚装上 tree ,多谢了~
    inevermore
        21
    inevermore  
       2015-11-28 13:29:54 +08:00
    @mywaiting 赞同,一开始使用 rails 或者 django ,看似很方便,其实不知所以然
    shajiquan
        22
    shajiquan  
       2015-11-30 23:51:52 +08:00
    @northisland You are very welcome.
    roundgis
        23
    roundgis  
       2021-05-14 18:14:46 +08:00 via Android
    和 django 一
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     997 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 18:13 PVG 02:13 LAX 11:13 JFK 14:13
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86