Skip to content

Commit 1c3b081

Browse files
committed
add Zappa
1 parent 37d01a9 commit 1c3b081

File tree

9 files changed

+298
-0
lines changed

9 files changed

+298
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
1. [Python 命令行之旅](contents/Python/cmdline/catalog.md)
1919
2. [用 Python 生成有"灵魂"的二维码:QRcode](contents/Python/QRcode/content.md)
2020
3. [聊聊 Python 的单元测试框架](contents/Python/unittest/catalog.md)
21+
4. [上线 Python 应用仅需一条命令的开源框架:Zappa](contents/Python/Zappa/content.md)
2122

2223
#### Java 系列
2324

contents/Python/Zappa/content.md

+297
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,297 @@
1+
# 上线 Python 应用仅需一条命令的开源框架:Zappa(详细教程)
2+
3+
> 本文面向有 Python Web 基础的小伙伴
4+
5+
![](cover.jpeg)
6+
7+
作者:HelloGitHub-吱吱
8+
9+
这里是 **HelloGitHub 推出的[《讲解开源项目》](https://github.com/HelloGitHub-Team/Article)系列**,今天要向小伙伴们介绍一个 Python 无服务(Serverless)框架 Zappa。
10+
11+
Zappa 让我们可以轻松部署 Python 应用程序:仅需几条命令、打包代码、上传云服务器、程序上线,bingo 一气呵成!从此减少部署成本,放下运维的重担。仅需你有一点点 Python Web 基础!
12+
13+
它到底有多便捷?下面就让我们上手来试试吧!
14+
15+
![](img/1.png)
16+
17+
> 项目地址:https://github.com/Miserlou/Zappa
18+
19+
## 一、前言
20+
21+
### 1.1 介绍 Serverless
22+
23+
刚开篇便提到了一个~~莫名其妙~~的名词:**无服务(Serverless)**,一开始我也是问号脸,经过多方搜证,我们可以简单的认为 Serverless 是指不必担心底层基础结构,不需要管理服务器,从而来构建和运行应用程序。具体概念小课堂如下:
24+
25+
#### 1.1.1 什么鬼?
26+
27+
回忆一下,平时上线一个简单的 Python Web 应用的过程。
28+
29+
- 一个 24 小时不间断运行的服务器:比如云主机,用以搭建代码运行环境和进行系统配置,维持着运行我们的应用;
30+
- 部署 Web 服务器:我们需要选择合适的 Web 服务器,经过配置和启动,实现反向代理和负载均衡;
31+
- 域名绑定:最后如果要被广泛用户访问,我们需要注册域名,并且绑定在服务器;
32+
- 运营维护:配置和启动在应用上线之后,我们还需要管理和维护我们的服务器,预防黑客攻击,应对未来用户访问高峰期。
33+
34+
而对于使用 Serverless 架构的应用,我们只需要关心我们的应用编写和核心业务,无需操心云主机、操作系统、资源分配和 Web 服务器配置等相关问题,无需考虑服务器的规格大小、存储类型、网络带宽、自动扩缩容问题,无需再对服务器进行运维、不断打系统补丁和应用补丁、无需进行数据备份等工作。一切非核心业务都外包给了公共云营运商,让开发人员从复杂的部署和运维环境中脱身出来,专注于业务本身的价值。
35+
36+
用 Zappa 里的一句话说就是 **“without any permanent infrastructure”**(无需任何永久性基础设施)。
37+
38+
敲黑板,尽管从名字上说是 Serverless,但是仍然需要物理服务器,只是我们开发人员成了甩手掌柜。
39+
40+
#### 1.1.2 好处有?
41+
42+
- 降低运维需求和维护成本;
43+
- 完全自动化的弹性扩容和缩容:在业务高峰期时,产品的计算能力和容量自动扩大,承载更多的用户请求;反之,在业务下降时,所使用的资源也会同时收缩,避免资源浪费;
44+
- 节省开支,全新的计量计费模式:开发者仅需根据使用量来付费。在无业务量的情况下,不会有空闲资源占用,也不会有费用产生。
45+
46+
#### 1.1.3 普遍认为 Serverless = FaaS + BaaS
47+
48+
- BaaS(Backedn as a Service 后端即服务)
49+
- 后端,指的就是各种云产品和云服务,例如对象存储 OS ,消息队列 MQ,云数据库 DB,云缓存 Redis以及各种以 API 形式提供的服务。用户直接开通即可使用,无需考虑部署、扩容、备份、安全等各种运维工作。
50+
- FaaS(Functions as a Service 函数即服务)
51+
- 是 Serverless 的核心,让用户仅需编写和上传核心业务代码,交由平台完成部署、调度、流量分发和弹性伸缩等能力,它提供了一种新的方式来提供计算资源,进一步降低云计算的使用门槛。
52+
53+
#### 1.1.4 AWS Lambda
54+
55+
在该项目中,伸手白嫖[ AWS 海外区域账户免费 AWS Lambda 套餐](https://amazonaws-china.com/cn/free/?cs-awsft-actsft&sc_channel=ta&sc_campaign=freetier_crosslink&sc_country=cn&sc_geo=chna&sc_category=mult&sc_outcome=acq&trkCampaign=freetier_crosslink_acts&trk=request_for_pilot_account&all-free-tier.sort-by=item.additionalFields.SortRank&all-free-tier.sort-order=asc)[AWS Lambda](https://amazonaws-china.com/cn/lambda/?did=ft_card&trk=ft_card) 作为 Serverless 最早的框架产品由亚马逊在2014年推出,是一种无服务器的计算服务,无需预置或管理服务器即可运行代码。Lambda 几乎可以为任何类型的应用程序或后端服务运行代码,我们只需上传相应的代码,它会处理运行和扩展代码所需的一切工作。
56+
57+
![](img/2.png)
58+
59+
### 1.2 Python 的 Serverless 框架
60+
61+
本篇文章的主角:Zappa 登场!我们可以通过 Zappa 工具体验一下 Serverless 技术,用它实现我们 Python 应用程序的无服务器部署,初步体验无限伸缩扩展、零宕机、零维护的快捷。有了 Zappa,我们无需:
62+
63+
- **配置** Web 服务器
64+
- **付费** 24/7 服务器的正常运行时间
65+
- **担心**负载平衡和可扩展性
66+
- **保持**自己的服务器时刻在线状态
67+
68+
## 二、亲自动手
69+
70+
实战时间:已经实验(踩坑)成功(不断)的我就来分享部署一个简单的 `Flask` 应用的过程,不要担心跟着做你也可以~
71+
72+
### 2.1 环境
73+
74+
1. Python版本要求:3.6/3.7/3.8
75+
2. 测试系统:Ubuntu 18.04.4 LTS
76+
77+
### 2.2 准备
78+
79+
1. **保证**自己的项目是运行在[虚拟环境](https://docs.python-guide.org/dev/virtualenvs/)下。
80+
81+
```bash
82+
# 需要安装 Python 3.x 版本
83+
python --version
84+
85+
# 安装 Pipenv
86+
pip install --user pipenv
87+
88+
# 进入自己的项目
89+
cd demo
90+
91+
# 实例化 pipfile 和 venv
92+
pipenv shell
93+
```
94+
95+
![](img/3.png)
96+
97+
2. **安装** Zappa 和 Flask,项目需要其他库的话,可自行添加。
98+
99+
```bash
100+
$ pipenv install zappa flask
101+
```
102+
103+
![](4.png)
104+
105+
3. 在目录下创建 `my_app.py` 文件,写入官方样例,可以先 `pipenv run python my_app.py`看看是否能正常运行
106+
107+
```python
108+
from flask import Flask
109+
app = Flask(__name__)
110+
111+
@app.route('/')
112+
def hello():
113+
return "hello, from Zappa!\n"
114+
115+
if __name__ == '__main__':
116+
app.run()
117+
```
118+
119+
4. [注册 AWS 账户](https://portal.aws.amazon.com/gp/aws/developer/registration/index.html?nc2=h_ct&src=default),并且正确安装 AWS credentials file
120+
121+
- 登录 AWS,找到 `My Security Credentials` 下的 `Access keys (access key ID and secret access key)` ,如果没有则创建一个,记住 `access key ID``secret access key`
122+
123+
- 安装 AWS 的命令行界面,添加 credentials
124+
125+
```bash
126+
# 在虚拟环境下安装
127+
pipenv install awscli
128+
129+
# 查看信息
130+
aws configure list
131+
132+
# 添加,并且按照提示将 access key ID 和 secret access key 填入
133+
aws configure
134+
135+
# 后两个 region name 和 output format 选填
136+
```
137+
138+
![](img/5.png)
139+
140+
- 此时在 `~/.aws` 目录下会出现两个文件 config 和 credentials,credentials 中储存了 AWS 的 ` access key ID``secret access key`, config 中储存了 region name 和 output format 信息。
141+
- 如果是在 Windows 上操作的同学,可以查看官方提供的安装 AWS credentials file 的[教程](https://amazonaws-china.com/cn/blogs/security/a-new-and-standardized-way-to-manage-credentials-in-the-aws-sdks/)。
142+
143+
### 2.3 安装与配置
144+
145+
1. 通过执行下面语句进行初始化,定义部署和配置的设置,自动检测应用类型(Flask 或 Django)
146+
147+
```bash
148+
$ zappa init
149+
```
150+
151+
在执行过程中,可能需要如下设置,后续也可以在新生成的 `zappa_setting.json` 的配置文件中修改:
152+
153+
![](img/6.png)
154+
155+
完成后,我们的项目目录中将有一个 `zappa_settings.json` 文件,里面是我们刚刚定义的基本部署设置,后期我们可以按照自己的需求修改此文件。
156+
157+
```json
158+
{
159+
"dev": {
160+
"app_function": "my_app.app",
161+
"profile_name": null,
162+
"project_name": "demo",
163+
"runtime": "python3.6",
164+
"s3_bucket": "zappa-ti0ra29xi"
165+
}
166+
}
167+
```
168+
169+
2. 注意如果之前已经在 `~/.aws/config` 文件中添加 region 信息,则会在 `zappa init` 的时候自动寻找到这些 region 信息,无需后续修改。
170+
171+
如果之前没有添加,则修改 `zappa_settings.json`,添加 region 信息如下:
172+
173+
```bash
174+
# 修改如下
175+
{
176+
"dev": {
177+
"app_function": "my_app.app",
178+
"profile_name": null,
179+
"project_name": "demo",
180+
"runtime": "python3.6",
181+
"s3_bucket": "zappa-ti0ra29xi"
182+
"aws_region": "us-west-2"
183+
}
184+
}
185+
```
186+
187+
region 的信息可以自行选择,[具体信息请移步](https://docs.aws.amazon.com/zh_cn/general/latest/gr/rande.html)。
188+
189+
### 2.4 部署和使用
190+
191+
配置设置后,可以使用如下命令将应用程序打包并部署:
192+
193+
```bash
194+
$ zappa deploy dev
195+
```
196+
197+
当我们调用 deploy 时,Zappa 会自动将我们的应用程序和本地虚拟环境打包到 Lambda 兼容的 archive,用为 Lambda 预先编译的版本替换所有依赖项,设置功能处理程序和必要的 WSGI 中间件,然后上传 archive 到 S3,创建和管理必要的Amazon IAM 策略和角色,将其注册为新的 Lambda function,创建新的 API 网关资源,为其创建 WSGI 兼容的路由,将其链接到新的 Lambda function,最后从 S3 bucket 中删除 archive。
198+
199+
执行成功后,就会出现一个链接,点击链接即可访问我们的简易 Web 应用。看到已上线的应用程序,心内窃喜,直呼快准狠。
200+
201+
![](img/1.png)
202+
203+
## 三、其他命令
204+
205+
1. 更新操作:假设应用程序已经部署完毕,并且只需要上传新的Python代码,而无需修改基础路由,则可以执行以下操作:
206+
207+
```bash
208+
$ zappa update dev
209+
```
210+
211+
这将创建一个新的 archive,将其上传到 S3 并更新 Lambda function 以使用新代码。
212+
213+
2. 查看部署和事件计划的状态,只需使用命令:
214+
215+
```bash
216+
$ zappa status production
217+
```
218+
219+
3. 查看部署的日志:
220+
221+
```bash
222+
$ zappa tail dev
223+
224+
# 过滤 HTTP 请求
225+
$ zappa tail dev --http
226+
227+
# 执行相反操作,并且仅显示非 HTTP 事件和日志消息
228+
$ zappa tail dev --non-http
229+
230+
# 选择时长
231+
$ zappa tail dev --since 4h # 4 hours
232+
```
233+
234+
4. 回滚操作: 通过提供要返回的修订版本数将部署的代码回滚到以前的版本。
235+
236+
```bash
237+
# 回滚到3年前部署的版本
238+
$ zappa rollback production -n 3
239+
```
240+
241+
5. 安排 function 定期执行:修改 `zappa_setting.json` ,加入如下内容:
242+
243+
```json
244+
{
245+
"dev": {
246+
...
247+
"events": [{
248+
// The function to execute
249+
"function": "your_module.your_function",
250+
// When to execute it (in cron or rate format)
251+
"expression": "rate(1 minute)"
252+
}],
253+
...
254+
}
255+
}
256+
```
257+
258+
然后执行如下操作,我们的 function 就会在每分钟执行一次。
259+
260+
```bash
261+
$ zappa schedule dev
262+
263+
# cancal
264+
$ zappa unschedule dev
265+
```
266+
267+
6. 取消部署:如果要删除以前发布的 API Gateway 和 Lambda function,则只需:
268+
269+
```bash
270+
$ zappa unschedule dev
271+
```
272+
273+
## 四、踩坑建议
274+
275+
在成功运行一次之前,踩坑千千万万遍,都是因为自己手残眼瞎魔改了很多地方,把经历过的报错记录下来,分享给和我一样的小小白。
276+
277+
1. `“Unable to import module ‘handler’: attempted relative import with no known parent package”`:原因是我们期望的依赖在虚拟的环境中没有,需要查看自己虚拟环境中的依赖是否完整,[解决请移步](https://medium.com/@gregorypierce/unable-to-import-module-handler-attempted-relative-import-with-no-known-parent-package-f3545ab91df1)。
278+
279+
2. 出现如下报错,可以更换一个 region 信息,[解决请移步](https://github.com/Miserlou/Zappa/issues/1194)。
280+
281+
```bash
282+
$ zappa deploy dev
283+
Calling deploy for stage dev..
284+
Creating demo-dev-ZappaLambdaExecutionRole IAM Role..
285+
Error: Failed to manage IAM roles!
286+
You may lack the necessary AWS permissions to automatically manage a Zappa execution role.
287+
Exception reported by AWS:An error occurred (InvalidClientTokenId) when calling the CreateRole operation: The security token included in the request is invalid.
288+
To fix this, see here: https://github.com/Miserlou/Zappa#custom-aws-iam-roles-and-policies-for-deployment
289+
```
290+
291+
3. 如果我们在 `zappa init` 的时候,不使用默认分配的 `s3_bucket` ,则须注意自己的名称是不允许重名的,点击查看[官方方法](https://amazonaws-china.com/cn/premiumsupport/knowledge-center/s3-error-bucket-already-exists/),否则会报错 `botocore.errorfactory.BucketAlreadyExists: An error occurred (BucketAlreadyExists) when calling the CreateBucket operation: The requested bucket name is not available. The bucket namespace is shared by all users of the system. Please select a different name and try again.`
292+
293+
## 五、写在最后
294+
295+
是不是当自己成功部署后,突然觉得妙不可言,一身轻松,好像再也没有了之前所说的繁琐的过程,反而几条命令,白嫖 AWS 的服务,咱的应用程序就轻巧上线了呢,还不赶紧把生成的链接分享给小伙伴们点击一下。
296+
297+
至此,我们已经可以基本实现快速部署一个简单的 Flask 应用了,由于篇幅有限,还有部分 Zappa 的高级功能没有提及,以及如何使用 Zappa 部署 Django 应用或者一个更为庞大的项目(包含数据库等),希望感兴趣的小伙伴们能够多多尝试,我已经开始期待的搓搓手了。如果大家对开源项目感兴趣,请第一时间关注我们 HelloGitHub,我们将会为大家带来更多有趣的干货内容。

contents/Python/Zappa/cover.jpeg

859 KB
Loading

contents/Python/Zappa/img/1.png

128 KB
Loading

contents/Python/Zappa/img/2.png

162 KB
Loading

contents/Python/Zappa/img/3.png

68.2 KB
Loading

contents/Python/Zappa/img/4.png

101 KB
Loading

contents/Python/Zappa/img/5.png

93.9 KB
Loading

contents/Python/Zappa/img/6.png

150 KB
Loading

0 commit comments

Comments
 (0)