部署服务

作者:王蒙
标签:Python, Service, On-Demand Remote Execution, Configuration Management Tools, The Twelve-Factor App, setup.py
简介:介绍 python 如何部署 Saas 应用。

目标读者

网络服务,API

解决办法

The Twelve-Factor App

开发易于部署的 App 的 12 个关键要素:

  1. 基准代码。一份基准代码,多份部署。
  2. 依赖: 显示声明依赖关系。
  3. 配置:在环境中存储配置。
  4. 后端服务:把后端服务当做附加资源。
  5. 构建发布运行:严格分离构建和运行。
  6. 进程: 以一个或者多个无状态进程运行应用。
  7. 端口绑定: 通过端口绑定提供服务。
  8. 并发: 通过并发模型(todo: 具体并发模型有哪些,简述这些并发模型)进行扩展。
  9. 易处理:快速启动和优雅终止。
  10. 开发环境和线上环境等价。尽可能的保持开发,预发布,线上环境相同。
  11. 日志。把日志当做事件流。
  12. 管理进程。后台管理任务当作一次性进程运行。

使用 Fabric 自动部署

Fabric 能把代码远程部署到多台服务器。Fabric 能执行 shell 命令,能通过 ssh 在远程执行 shell 命令。 Fabric 还能交互式地输入密码验证。Fabric 中 run 和 local 是其中最重要的函数。

构建自己的 package index 和 PyPI 镜像

推荐使用 devpi 构建公司专属的 package index, 保证 package index 的可用性,方便发布代码。

PyPI mirroring

推荐使用 devpi 构建 package index:

  • 能缓存你需要的 Python 官方 PyPI 包。
  • 能周期更新你需要的 Python 官方 PyPI 包。

其他的搭建 PyPI 工具,要不不同步 Python 官方 PyPI 包,要不就是全备份导致磁盘占用特别高。相对来说 devpi 提供了 Python 官方 PyPI 包,同时又不占用过多的资源,唯一的缺点是 devpi 包缓存的官方 PyPI 包可能不是最新的。

使用包发布应用

setup.py 中能够自定义操作,这些操作可用于自动化部署应用。这些步骤一般会在开发环境执行。

MANIFEST.in 可以用于 bundle 很多文件,比如 SASS 或者 LESS 等等。

Using process supervision tools

应用经常会启动多个进程,所以需要使用进程管理工具。

在 Python 中,常用 SupervisorCircus 来管理用户应用进程。 Supervisor 暂时不支持 Python3, 所以可以使用 Circus。

不要使用超级用户部署

常常用和应用同名的用户,部署应用。

绝对不要以超级用户权限部署应用,那样的话,应用之间会相互影响。

反向代理

Nginx 还是很有必要学一下的。

使用反向代理的好处有:

  • TLS/SSL 一般会由 nginx 来做。
  • HTTP 一般服务于 80 端口,HTTPS 一般服务于 433 端口。普通用户没有权限绑定 80/443 端口。但是超级用户(反向代理一般使用超级用户权限执行)有权限。
  • Nginx 能高效地提供静态文件。
  • Nginx 可以伪装出多个 host。DNS 中一个 IP 可以对应多个域名。nginx 服务器中每个 server 通过 server_name 选项匹配域名,这样就实现了一台主机用多个域名,提供多种服务的功能。
  • nginx 可以提供缓存和负载均衡的功能。

Reloading processes gracefully

  1. 当接到 TERM 信号时,应用应该停止接受新的请求,并且处理完所有已经接受的请求,然后退出。
  2. 当接到 HUP 信号时,应用旧节点优雅退出(不再接受请求,但是会处理已经接受到的请求),新节点应该开始接受新的请求,确保服务没有间断。
  3. Python 中的 GunicornuWSGI 都支持不间断服务的重载方式。可以参考这两个框架的做法设计自己的应用。

todo: 我挺好奇 Gunicorn 是怎么实现这种优雅退出的。

监控维护应用

  1. 查看日志,比如不同返回码的日志有多少条。
  2. 错误日志和警告日志。
  3. 资源占用(比如 CPU, memory 和带宽等)。
  4. 和商业价值有关的指标(客户占有率,投资回报等)。

Logging Errors

不管程序写得多完美,都保不齐会发生错误。要做到及时发现错误。

一般从日志中发现错误,Sentry 是报告系统错误最有名的工具。

Sentry 开源的,可以自己维护 Sentry 服务,也可以选择付费使用 Sentry 服务。

使用 Sentry 服务,需要 DSN(Data Source Name)。 我去 Sentry 网注册了个 DSN(https://13c5b7dbdb544a7ea37177997fbc8e66:d68d511723e147f4bbdb132af22f04aa@sentry.io/1197614), 有了 DSN,就可以把错误日志写入到 DSN 中。

对于 Python,Sentry 提供了 raven 包。python 装上这个包之后,很容易与 Sentry 集成。具体的参见 Sentry

Monitoring system and application metrics

monitor performance 的工具非常多。比较常用的有:

  1. Munin
  2. StatsD
  3. Graphite

Dealing with application logs

根据 12 factor app 的建议,application code 以 event stream 的形式抛出日志。application code 本身不会收集和记录日志。收集和记录日志是当前执行环境要负责的。

Python logging 可以使用配置文件,配置应用的日志该怎么收集和记录。我认为这种方式已经是非常好了,使用配置文件,相当于是让当前执行环境负责收集和记录日志。

Circus 和 supervisor 等进程管理工具,也提供了收集和记录日志的功能。

Linux 中的 logrotate 提供了收集和记录日志的功能,《expert python programming》 一书推荐使用 logrotate 收集和记录日志。不过我认为这可能是因为该书作者用习惯 logrotate 了。

Tools for log process

日志中不仅有报错,还有与业务相关的很多信息。很多商业智能的工具从日志中挖掘商业信息。从日志中挖掘信息,最有名的工具是 ELK(Elasticsearch, Logstash 和 Kibana)。