最大化良好运行(Python全栈项目描述)

如果你喜欢干货,想要直接了解一些关于python项目部署的操作性内容,请直接看后半部分

所有编程人员都是乐观主义者

年轻人总是有些乐观注意——无论什么样的程序,结果是毋庸置疑的:“这次它肯定会运行。”或者“我刚刚找出了最后一个错误。”———摘自《人月神话》

没有银弹

在所有恐怖民间传说的妖怪中,最可怕的是人狼,因为它们可以完全出乎意料地从熟悉的面孔编程可怕的妖怪。为了对付人狼,我们在寻找可以消灭它们的银弹。 ———摘自《人月神话》

对于DEV和OPS

既然大家都是乐观主义者大部分情况下一时不到bug的存在,而且有没有可以一劳永逸彻底消灭bug的银弹

三点问题

首先,在开发中我们必然是会犯错误,有些bug甚至一直存在而我们却束手无策。
其次,在生产环境中尤其是基于网络的程序,我们会遇到各种各样在开发时完全没有预测到的问题
最后,DEV和OPS完全是两回事,开发环境和生产环境截然不同的。

如何解决

要确保一个产品的稳定及良好的用户体验,单就开发层面来说:

  • 需要开发人员丰富的经验,事实证明踩过得坑和产品的稳定性成正比

早在2009年的时候,我就遇到一个程序员习惯性的把用户姓名字段在数据中设置的很大,后来才知道,这里面有一个段子:他曾经给某机场做过项目,后来出现了一个让人啼笑皆非的事情。是有一个新疆同胞因为中文名字太长(超过32个字节)以至于系统不能出票。

  • 需要项目负责人对项目良好的规划和对情况的预判

比如有一个web项目起初只是传统的web应用,后来要做移动端app。然而在开发初期并没有考虑设计API,以至于项目在已经有海量数据和用户的情况下被大规模的重构,甚至开发人员直接在生产服务器上修改代码。这很危险,真的!

  • 需要开发团队有良好的技术规范

天知道代码跑起来以后会不会失控,在不同的平台,不同的环境下。唯一好的办法是保持良好的代码规范,如果是python的话,我希望大家可以用几乎变态的PEP8来培养自己良好的编码规范(折磨自己)。
同时再给一点忠告:一般情况下:开发的时候永远不要想当然,比如“我的代码只需要在Ubuntu系统下运行良好就行了”

那么,从运维层面来说:

  • 需要谨慎的选择最合适项目的稳定平台

从服务器提供商到节点选择操作系统版本选择,服务器配置选择,软件版本选择等等等 每一点都不应被忽视

  • 需要提高自己系统的容错能力

虽然大部分的错误都会在开发测试的迭代中被解决,但总会有那么一些漏网之鱼,或者以写目前确实无法很好解决的问题,这个时候就需要OPS去构建一套良好的容错系统
比如,某些开源软件总会有一些issue一直拖着没有解决,开发中又没有好的解决办法,此时恰好又没有替代品,或者重构成本太大。这个时候只能暂时寄希望于OPS了。稍后会在一个python项目中详细阐述这一点。

  • 必要的时候,定制一套完善的监控系统

监控系统并不能解决产品运行的实际问题,但是他确实有效。比如你可以对某一个核心进程进行监控,对某一个进程所占用的内存进行监控,这都是十分有效的。当然,对于一般系统,服务器提供商一般都会自带一套监控系统(告警系统),也就足够了!

使用一个Python项目来描述上述问题

项目简介和技术构架

这个项目是一个提供高质量数据的API,他包含一个后台服务(负责爬取数据)和一个flask程序(负责提供数据):

有关项目的详情,可以参考我之前的文章从python开始一个全栈项目 程序员&设计师福利篇

我们要讨论的第一个问题是,环境的分离

virtualenv可以很方便的分离python项目,但是它如何运行呢?
解决的办法是使用supervisor去运行项目,在项目程序推出的时候还可以自动重启:
那么,用我的项目来说,首先我需要flask运行,通过uwsgi启动设置代理,通过nginx来做最外层服务器。
首先,安装uwsgi(虚拟环境下)并作配置

uwsgi通过一个配置文件启动,配置文件大致如下:

[uwsgi]
# uwsgi 启动时所使用的地址与端口
socket = 127.0.0.1:8001 
# 指向flask程序的目录
chdir = /home/www/design 
# python 启动程序文件
wsgi-file = rest.py 
# python 程序内用以启动的 application 变量名
callable = app 
# 处理器数
processes = 1
# 线程数
threads = 1
#状态检测地址
stats = 127.0.0.1:9191

然后,用supervisor来执行uwsgi

superviso 安装好以后是一个系统服务,在ubuntu下使用如下命令控制,其他系统类似:
service superviso start|stop|status
它需要从配置文件读取信息,从而启动某一个程序:
ubuntu下配置文件的地址 /etc/superviso/conf.d/
你可以在conf.d目录下新建自己的配置文件已对应需要使用superviso来管理的应用
flask.conf

# 指向网站目录
chdir = /home/www/design 
# python 启动程序文件
wsgi-file = rest.py 
# python 程序内用以启动的 application 变量名
callable = app 
# 处理器数
processes = 1
# 线程数
threads = 1
#状态检测地址
stats = 127.0.0.1:9191
root@iZ62zfrrhbsZ:~# cat /etc/supervisor/conf.d/d
dataservice.conf        design_supervisor.conf  
root@iZ62zfrrhbsZ:~# cat /etc/supervisor/conf.d/design_supervisor.conf 
[program:design]
# 启动命令入口(使用虚拟环境下的uwsgi启动)
command=/home/design/python-design/bin/uwsgi  /home/www/design/config.ini
# 命令程序所在目录(虚拟环境下的命令程序目录)
directory=/home/design/python-design
#运行命令的用户名
user=root       
autostart=true
autorestart=true
#日志地址
stdout_logfile=/home/www/design/logs/uwsgi_supervisor.log

最后,启动nginx
service nginx start
这样的话,flask能够运行起来了。

后台服务的技术构架
  • redis负责存储数据并作持久化(使用快照)。
  • selenium + phantomJS + pyquery 负责进行数据的爬取。

开发过程中,我可以保证程序工作的状态是可维护的:

  1. 数据不能丢失(这个交给redis快照,不需要操太多心)
  2. 进度的保存。(当我爬取了某一个页面程序突然退出的话,下一次程序依旧能够从改进读继续执行)
  3. 保证程序能7×24小时不间断运行。(事实上phantomJS经常会假死,从而导致程序假死,开发层面很难解决)

那么,这几个问题,我在生产环境是如何解决的呢?

后台服务运行的干将莫邪

关于数据和进度保存,根据项目对数据的要求,我很放心的把数据的持久话交给redis的快照做,即使断电了,我的程序依旧可以在下一次重启之后依靠快照和快照内的进度继续进行。
那么,问题来了:phantomJS老是假死,怎么办呢?
解决办法是这样的,我可以每一个小时让程序自行断掉,然后再自己运行起来。
但是,我可以轻松的关掉进程,但是如何让重新启动呀?我的程序可是在虚拟环境下的呀!
答案一就是supervisor呀!停掉以后,它可以自己启动呢!
在配置文件目录(上面提到过的conf.d,不同系统应该不同)添加一个后台服务启动的命令配置文件就好了:
dataservice.conf

command=/home/design/python-design/bin/python /home/design/service/mining.py
directory=/home/design/service
user=root

这样的话,进程就能在推出时被supervisor启动了,那么如何定时结束这个进程呢?
答案是Linux定时任务Crontab
首先编写一个定时关闭mining.py这个进程的脚本:
stopMin.sh:

ps -ef|grep mining.py -v grep|cut -c 9-15|xargs kill

然后添加这个脚本每一个小时自动执行:
编辑/etc/crontab文件,添加一行:

00 1 * * * /path/to/stopMin.sh

关于contab可以惨开这篇文章[Linux定时任务Crontab详解 ]

TIPS
你可以使用 tail命令打开日志的最后50行,并且实时更新哦:

tail -n -50 -f /path/to/xxx.log
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容