V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Tornado Documentation
http://www.v2ex.com/tornado/
Tornado on GitHub
https://github.com/facebook/tornado/
Tornado Gists
http://tornadogists.org/
mywaiting
V2EX  ›  Tornado

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

  •  
  •   mywaiting · 2015-11-26 22:24:16 +08:00 · 12655 次点击
    这是一个创建于 3276 天前的主题,其中的信息可能已经有所发展或是发生改变。
    用了 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:00
    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   ·   实用小工具   ·   1026 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 20:46 · PVG 04:46 · LAX 12:46 · JFK 15:46
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.