我们的Web开发与部署 -- 一名python党

2012-11-30 17:43:04 +08:00
 hepochen
不知道Markdown格式会变成什么样子,原文地址如下:

http://ued.com.cn/post/tech/web-dev-and-deploy

## 背景

最近做了一个产品,原本估计10来天就足够了;idea虽然简单,但产品化的过程中,时间超了几番。

我们在用Amazon的AWS服务,后台语言是python,Web框架使用了Flask,数据库为Mongodb;前端Web服务器Nginx,Application服务器Gunicorn;驱动Web的数据任务使用的是Gevent。

前端框架?呃,这次没用。以往是Mootools,这次产品返璞归真,就写了十几行的原生javascript。css这次也把设计压缩到尽可能少的地步,直接原生,未用框架。


- - - - - - - - - - - - -


## 开发

### Flask
原来一直都使用Django,但Django有些重,这种“重”可能只有意会了。接触Flask的时候,里面很多设计很漂亮,也有些代码的写法,相信是Flask作者们长期积累的结果。以前常在Django中试图hack的东西,到了Flask中,就native了。当然,pocoo小组出品的东西,不会差。

实际上,Web框架的差异,本质上都不会太大。

因为数据库选择的是Mongodb,在驱动引擎上的选择,用的是原生pymongo。虽然ORM有它的好处,但性能上会降低不少。另外很重要的一点,选择Flask就是为了离开Django中的各种black boxes,自然也不愿去碰ORM中的黑盒。

还有个插曲是,之前跟一个朋友一起测过好几个ORM的性能。所以,心里大概有底。同时,理解NoSQL,就要尽可能避开ORM。

### PyCharm

PyCharm是一个python的IDE,以前用Django的时候,PyCharm提升了不少效率。目前版本同样很好得支持了Flask,同时在DEBUG的模式中,也支持Gevent.

因为这个产品的测试用例,不想写;而且之前被pylint、pep8(都可以认为是python语法、代码的校验器)折腾过之后,做Start Up的时候,会下意识的绕开它。其实之前,跟David之间有比较大的争议,他接触python时间不长,但死忠得执行这些约定,但为了适应Django的写法,很多pylint的规则要重写……(anyway,基本的pythonic语法必须要保证,比如对类的、全局变量等的命名规则;因为,这些不是写给机器看的,是写给人类看的,“约定”是要保证的。)

而PyCharm本身就可以当pylint、pep8来用。更重要的是,它是即时的。

特性还有不少,恰到好处,用“神器”来形容它,并不过分。曾有一段时间,我用它来调试node.js……

PyCharm于我而言,除了Debug方便外,另外最好用的功能是ALT键按住,然后点(代码的)命令名、属性名,就可以直接去看源码。这非常重要!我的技艺提升,多数情况下是靠这个操作。


### TOX

[Tox](http://tox.testrun.org/), vision: merge packaging, testing and release.

其实无须多言。这是一个非常棒的工具。它是基于virtualenv,所以,你还可以把它当普通的virtualenv来使用,但基本上该没有这个必要了。

曾经有个问题,要不要在virtualenv的基础上直接进行开发?实践证明,呃,还是弄自己的开发环境吧,剩下的交给Tox好了。

另外,Tox是在github上逛着发现的,不做土鳖其实好处蛮多的。所以,吐个槽,前段时间,360技术博客有一篇介绍他们的技术实践,看起来用了不少名词,其实是有些弱的。

### Gevent

如果你用python,你非常有必要去实际用用Gevent。

这是一个协程的工具。并发能力很强,在实际涉及第三方API的开发时,还额外增加了一些限制,避免它并发得太多,被API提供方503掉。

使用Gevent最大的感受,就是在python里同时控制同步、异步的逻辑,便捷了很多。在这方面,不知道node.js现在有没有好的解决方案,之前也使用过node一段时间,呃,回调很苦……



### Sentry
[Sentry](https://www.getsentry.com/)是大名鼎鼎的[DISQUS](http://disqus.com)副产的一个工具。

他们有官方的付费服务,但sentry本身是开源(基于django的框架),自己也可以git一份出来,跑在服务器上就好了。

因为我们的大部分数据运作是基于Gevent的,所以,还要做个patch,这样gevent运行的任务也能捕获到错误信息。

import traceback
# patch greenlet._report_error
def print_exception(*exc_info):
sentry_client.captureException(exc_info)
# 这个sentry_client,如果你用了sentry,应该就明了的。
if ON_PRODUCT:
traceback.print_exception = print_exception

- - - - - - - - - - - - -


## 我们使用AMAZON的服务

- 我们的主机是EC2(跑ubuntu),sentry跑在一个micro instance上,因为有一年免费期;主APP目前跑在small instance上。
- 我们的存储,以及js、css等静态资源,放在S3上。
- 我们的Mongodb数据放在EBS上。
- 我们的DNS服务使用的是route53。

目前是数据库与APP跑在一台服务器上,如果流量扩增,随时准备独立数据库服务器,然后多个APP服务器可以并行运作。按照目前的操作来看,这个应对过程的实现时间会很短。


- - - - - - - - - - - - -

## 部署

感觉没有什么好说的,就是nginx在前面扛着,gunicorn(python写的)在后面高速运作着的。另外一方面,gunicorn可以实现更新代码的时候,服务不停。

另外,在代码层次,我们是在settings.py中自动分离了生产环境和开发环境。

然后,我们还做了一个额外的脚本,就是自动同步一些resources(如css/js)到Amazon的S3存储中,如有变动,会修改sync_log;而APP端运行的时候,会去读sync_log的变动时间戳,以处理css/js的缓存问题。

平时的更新与bug修复,直接通过github进行处理并进一步部署。

### Supervisor

但必须要介绍[Supervisor](http://supervisord.org),它相当于一个任务(线程)管理器,python写的。

运行<code>supervisord</code>可以启动这个服务,另外,可以开一个web可浏览的管理后台,也可以直接使用命令来操控自己的任务。

如果只是普通的Web服务器,则没有必要使用supervisor,如果有附加的脚本在执行的,它就显得非常便利了。

- - - - - - - - - - - - -

## 写在最后

我是商(文)科毕业,没有技术基础,也从未靠代码谋生。

如果有朋友对写代码有兴趣,**用python吧,人生苦短**。

本想再吐槽一些,技术(码农)界内所见的一些恶况。

但不浪费笔墨了。另外一方面,身份也很奇特,因为是一名产品设计师,就是很多人口中的产品经理。
9525 次点击
所在节点    程序员
21 条回复
buru
2013-06-05 09:36:29 +08:00
@hepochen Nginx和gunicorn是怎么配合使用的?Nginx只是用来应对静态文件的请求吗?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/53744

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX