不知道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吧,人生苦短**。
本想再吐槽一些,技术(码农)界内所见的一些恶况。
但不浪费笔墨了。另外一方面,身份也很奇特,因为是一名产品设计师,就是很多人口中的产品经理。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.