Python Serverless 開源框架:Zappa(詳細教程)


本文面向有 Python Web 基礎的小伙伴

作者:HelloGitHub-吱吱

這里是 HelloGitHub 推出的《講解開源項目》系列,今天要向小伙伴們介紹一個 Python 無服務(Serverless)框架 Zappa。

Zappa 讓我們可以輕松部署 Python 應用程序:僅需幾條命令、打包代碼、上傳雲服務器、程序上線,bingo 一氣呵成!從此減少部署成本,放下運維的重擔。僅需你有一點點 Python Web 基礎!

它到底有多便捷?一條命令即刻部署!

項目地址:https://github.com/Miserlou/Zappa

下面就讓我們動手來試試吧!

一、前言

1.1 介紹 Serverless

剛開篇便提到了一個莫名其妙的名詞:無服務(Serverless),一開始我也是問號臉,經過多方搜證,我們可以簡單的認為 Serverless 是指不必擔心底層基礎結構,不需要管理服務器,從而來構建和運行應用程序。具體概念小課堂如下:

1.1.1 什么鬼?

回憶一下,平時上線一個簡單的 Python Web 應用的過程。

  • 一個 24 小時不間斷運行的服務器:比如雲主機,用以搭建代碼運行環境和進行系統配置,維持着運行我們的應用;
  • 部署 Web 服務器:我們需要選擇合適的 Web 服務器,經過配置和啟動,實現反向代理和負載均衡;
  • 域名綁定:最后如果要被廣泛用戶訪問,我們需要注冊域名,並且綁定在服務器;
  • 運營維護:配置和啟動在應用上線之后,我們還需要管理和維護我們的服務器,預防黑客攻擊,應對未來用戶訪問高峰期。

而對於使用 Serverless 架構的應用,我們只需要關心我們的應用編寫和核心業務,無需操心雲主機、操作系統、資源分配和 Web 服務器配置等相關問題,無需考慮服務器的規格大小、存儲類型、網絡帶寬、自動擴縮容問題,無需再對服務器進行運維、不斷打系統補丁和應用補丁、無需進行數據備份等工作。一切非核心業務都外包給了公共雲營運商,讓開發人員從復雜的部署和運維環境中脫身出來,專注於業務本身的價值。

用 Zappa 里的一句話說就是 “without any permanent infrastructure”(無需任何永久性基礎設施)。

敲黑板,盡管從名字上說是 Serverless,但是仍然需要物理服務器,只是我們開發人員成了甩手掌櫃。

1.1.2 好處有?

  • 降低運維需求和維護成本;
  • 完全自動化的彈性擴容和縮容:在業務高峰期時,產品的計算能力和容量自動擴大,承載更多的用戶請求;反之,在業務下降時,所使用的資源也會同時收縮,避免資源浪費;
  • 節省開支,全新的計量計費模式:開發者僅需根據使用量來付費。在無業務量的情況下,不會有空閑資源占用,也不會有費用產生。

1.1.3 普遍認為 Serverless = FaaS + BaaS

  • BaaS(Backedn as a Service 后端即服務)
    • 后端,指的就是各種雲產品和雲服務,例如對象存儲 OS ,消息隊列 MQ,雲數據庫 DB,雲緩存 Redis以及各種以 API 形式提供的服務。用戶直接開通即可使用,無需考慮部署、擴容、備份、安全等各種運維工作。
  • FaaS(Functions as a Service 函數即服務)
    • 是 Serverless 的核心,讓用戶僅需編寫和上傳核心業務代碼,交由平台完成部署、調度、流量分發和彈性伸縮等能力,它提供了一種新的方式來提供計算資源,進一步降低雲計算的使用門檻。

1.1.4 AWS Lambda

在該項目中,伸手白嫖 AWS 海外區域賬戶免費 AWS Lambda 套餐AWS Lambda 作為 Serverless 最早的框架產品由亞馬遜在2014年推出,是一種無服務器的計算服務,無需預置或管理服務器即可運行代碼。Lambda 幾乎可以為任何類型的應用程序或后端服務運行代碼,我們只需上傳相應的代碼,它會處理運行和擴展代碼所需的一切工作。

1.2 Python 的 Serverless 框架

本篇文章的主角:Zappa 登場!我們可以通過 Zappa 工具體驗一下 Serverless 技術,用它實現我們 Python 應用程序的無服務器部署,初步體驗無限伸縮擴展、零宕機、零維護的快捷。有了 Zappa,我們無需:

  • 配置 Web 服務器
  • 付費 24/7 服務器的正常運行時間
  • 擔心負載平衡和可擴展性
  • 保持自己的服務器時刻在線狀態

二、親自動手

實戰時間:已經實驗(踩坑)成功(不斷)的我就來分享部署一個簡單的 Flask 應用的過程,不要擔心跟着做你也可以~

2.1 環境

  1. Python版本要求:3.6/3.7/3.8
  2. 測試系統:Ubuntu 18.04.4 LTS

2.2 准備

  1. 保證自己的項目是運行在虛擬環境下。

    # 需要安裝 Python 3.x 版本
    python --version
    
    # 安裝 Pipenv
    pip install --user pipenv
    
    # 進入自己的項目
    cd demo
    
    # 實例化 pipfile 和 venv
    pipenv shell
    

  2. 安裝 Zappa 和 Flask,項目需要其他庫的話,可自行添加。

    $ pipenv install zappa flask
    

  3. 在目錄下創建 my_app.py 文件,寫入官方樣例,可以先 pipenv run python my_app.py看看是否能正常運行

    from flask import Flask
    app = Flask(__name__)
    
    @app.route('/')
    def hello():
        return "hello, from Zappa!\n"
    
    if __name__ == '__main__':
        app.run()
    
  4. 注冊 AWS 賬戶,並且正確安裝 AWS credentials file

    • 登錄 AWS,找到 My Security Credentials 下的 Access keys (access key ID and secret access key) ,如果沒有則創建一個,記住 access key IDsecret access key

    • 安裝 AWS 的命令行界面,添加 credentials

      # 在虛擬環境下安裝
      pipenv install awscli
      
      # 查看信息
      aws configure list
      
      # 添加,並且按照提示將 access key ID 和 secret access key 填入
      aws configure
      
      # 后兩個 region name 和 output format 選填
      

    • 此時在 ~/.aws 目錄下會出現兩個文件 config 和 credentials,credentials 中儲存了 AWS 的 access key IDsecret access key, config 中儲存了 region name 和 output format 信息。

    • 如果是在 Windows 上操作的同學,可以查看官方提供的安裝 AWS credentials file 的教程

2.3 安裝與配置

  1. 通過執行下面語句進行初始化,定義部署和配置的設置,自動檢測應用類型(Flask 或 Django)

    $ zappa init
    

    在執行過程中,可能需要如下設置,后續也可以在新生成的 zappa_setting.json 的配置文件中修改:

    完成后,我們的項目目錄中將有一個 zappa_settings.json 文件,里面是我們剛剛定義的基本部署設置,后期我們可以按照自己的需求修改此文件。

    {
        "dev": {
            "app_function": "my_app.app",
            "profile_name": null,
            "project_name": "demo",
            "runtime": "python3.6",
            "s3_bucket": "zappa-ti0ra29xi"
        }
    }
    
  2. 注意如果之前已經在 ~/.aws/config 文件中添加 region 信息,則會在 zappa init 的時候自動尋找到這些 region 信息,無需后續修改。

    如果之前沒有添加,則修改 zappa_settings.json,添加 region 信息如下:

    # 修改如下
    {
        "dev": {
            "app_function": "my_app.app",
            "profile_name": null,
            "project_name": "demo",
            "runtime": "python3.6",
            "s3_bucket": "zappa-ti0ra29xi"
            "aws_region": "us-west-2"
        }
    }
    

    region 的信息可以自行選擇,具體信息請移步

2.4 部署和使用

配置設置后,可以使用如下命令將應用程序打包並部署:

$ zappa deploy dev

當我們調用 deploy 時,Zappa 會自動將我們的應用程序和本地虛擬環境打包到 Lambda 兼容的 archive,用為 Lambda 預先編譯的版本替換所有依賴項,設置功能處理程序和必要的 WSGI 中間件,然后上傳 archive 到 S3,創建和管理必要的Amazon IAM 策略和角色,將其注冊為新的 Lambda function,創建新的 API 網關資源,為其創建 WSGI 兼容的路由,將其鏈接到新的 Lambda function,最后從 S3 bucket 中刪除 archive。

執行成功后,就會出現一個鏈接,點擊鏈接即可訪問我們的簡易 Web 應用。看到已上線的應用程序,心內竊喜,直呼快准狠。

三、其他命令

  1. 更新操作:假設應用程序已經部署完畢,並且只需要上傳新的Python代碼,而無需修改基礎路由,則可以執行以下操作:

    $ zappa update dev
    

    這將創建一個新的 archive,將其上傳到 S3 並更新 Lambda function 以使用新代碼。

  2. 查看部署和事件計划的狀態,只需使用命令:

    $ zappa status production
    
  3. 查看部署的日志:

    $ zappa tail dev
    
    # 過濾 HTTP 請求
    $ zappa tail dev --http
    
    # 執行相反操作,並且僅顯示非 HTTP 事件和日志消息
    $ zappa tail dev --non-http
    
    # 選擇時長
    $ zappa tail dev --since 4h # 4 hours
    
  4. 回滾操作: 通過提供要返回的修訂版本數將部署的代碼回滾到以前的版本。

    # 回滾到3年前部署的版本
    $ zappa rollback production -n 3
    
  5. 安排 function 定期執行:修改 zappa_setting.json ,加入如下內容:

    {
        "dev": {
            ...
            "events": [{
                // The function to execute
                "function": "your_module.your_function",
                // When to execute it (in cron or rate format)
                "expression": "rate(1 minute)" 
            }],
            ...
        }
    }
    

    然后執行如下操作,我們的 function 就會在每分鍾執行一次。

    $ zappa schedule dev
    
    # cancal
    $ zappa unschedule dev
    
  6. 取消部署:如果要刪除以前發布的 API Gateway 和 Lambda function,則只需:

    $ zappa unschedule dev
    

四、踩坑建議

在成功運行一次之前,踩坑千千萬萬遍,都是因為自己手殘眼瞎魔改了很多地方,把經歷過的報錯記錄下來,分享給和我一樣的小小白。

  1. “Unable to import module ‘handler’: attempted relative import with no known parent package”:原因是我們期望的依賴在虛擬的環境中沒有,需要查看自己虛擬環境中的依賴是否完整,解決請移步

  2. 出現如下報錯,可以更換一個 region 信息,解決請移步

    $ zappa deploy dev
    Calling deploy for stage dev..
    Creating demo-dev-ZappaLambdaExecutionRole IAM Role..
    Error: Failed to manage IAM roles!
    You may lack the necessary AWS permissions to automatically manage a Zappa execution role.
    Exception reported by AWS:An error occurred (InvalidClientTokenId) when calling the CreateRole operation: The security token included in the request is invalid.
    To fix this, see here: https://github.com/Miserlou/Zappa#custom-aws-iam-roles-and-policies-for-deployment
    
  3. 如果我們在 zappa init 的時候,不使用默認分配的 s3_bucket ,則須注意自己的名稱是不允許重名的,點擊查看官方方法,否則會報錯 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.

五、寫在最后

是不是當自己成功部署后,突然覺得妙不可言,一身輕松,好像再也沒有了之前所說的繁瑣的過程,反而幾條命令,白piao AWS 的服務,咱的應用程序就輕巧上線了呢,還不趕緊把生成的鏈接分享給小伙伴們點擊一下。

至此,我們已經可以基本實現快速部署一個簡單的 Flask 應用了,由於篇幅有限,還有部分 Zappa 的高級功能沒有提及,以及如何使用 Zappa 部署 Django 應用或者一個更為龐大的項目(包含數據庫等),希望感興趣的小伙伴們能夠多多嘗試,我已經開始期待的搓搓手了。如果大家對開源項目感興趣,請第一時間關注 HelloGitHub,我們將會為大家帶來更多有趣的干貨內容。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM