如何在一天之内上线一款WSGI兼容的Python Web App

2020-11-22  本文已影响0人  科技狂人

如何在一天之内上线一款WSGI兼容的Python Web App

这篇指南将通过以下4步来帮助你在一天之内上线一款WSGI兼容的Python Web App

开箱即用的云原生解决方案

module_load_balancer模块用于创建WSGI兼容Web App所依赖的环境,非常适合只有Python技术栈的团队。在使用它之前,你需要参考这里来准备研发环境和了解一些注意事项。这个解决方案能够帮助你创建以下环境,你只需要提供图中Web App部分(它是基于Python来编写的并且是WSGI兼容的)。

image

现实情况

你拥有一支非常擅长Python的研发团队,然而却缺乏DevOps和软件工程经验。你迫切希望,你的团队能够研发一款面向互联网的服务,并能快速接入互联网。

准备和实现

首先,你需要使用Python研发一个Web App,它是WSGI兼容的,然后将其打包成tar.gz格式,包中的目录结构如下所示:

.
  |-web-app-root
  |  |-web-app
  |  |  |-wsgiapp.py
  |  |-requirements.txt
  1. web-app-root是包中的根目录,你可以重命名成其它
  2. web-app是你的Web App所有可执行性文件所在的目录
  3. wsgiapp.py是你的Web App的入口,里面定义了一个WSGI对象
  4. requirements.txt是你的Web App所依赖的Python库

其次,你需要创建main.tf文件,内容如下:

terraform {
  required_version = "= 0.12.19"
}

provider "aws" {
  version = "= 2.58"
  region = "ap-northeast-1"
}

module "load_balance" {
  source       = "github.com/2cloudlab/module_load_balancer//modules/load_balancer?ref=<tag>"
  download_url = <your-WSGI-Compatible-Python-Package-URL>
  package_base_dir         = <your-root-folder-name-in-web-app-package>
  app_dir = <your-web-app-folder>
  envs     = <your-app-environment-variables>
  wsgi_app = <WSGI-Entry>
}

output "alb_dns_name" {
  value       = module.load_balance.alb_dns_name
  description = "The domain name of the load balancer"
}

你只需要指定以下几点

  1. ref=<tag>中的tag需要替换成该模块的版本号,比如v.0.0.3
  2. download_url指向了WSGI兼容的Web App的tar.gz包,比如"https://github.com/digolds/digolds_sample/archive/v0.0.1.tar.gz"
  3. package_base_dirtar.gz中的根目录
  4. app_dir是WSGI兼容的Web App所有执行文件所在tar.gz中的目录
  5. envs是WSGI兼容的Web App所依赖的环境变量
  6. wsgi_app是WSGI兼容的Web App的调用入口,关于该模块的详细用法,你可以参考这里

指定之后,cdmain.tf所在的目录,然后执行以下命令来创建WSGI兼容的Web App:

terraform init
terraform plan
terraform apply

成功之后,你将看到以下类似的输出:

Apply complete! Resources: 10 added, 0 changed, 0 destroyed.

Outputs:

alb_dns_name = alb-1-712872544.us-west-1.elb.amazonaws.com

等待几分钟之后,你的WSGI兼容的Web App就已经在互联网中运行了,此时,你可以在浏览器里输入alb_dns_name所对应的值,来查看结果。

以上脚本帮你做了2件事情:

  1. 下载你的WSGI兼容的Web App包
  2. 在互联网上创建一个负载均衡器ALB(用于分发请求)、一族EC2实例(每个实例对应一台虚拟机,并运行着你的WSGI兼容的Web App、Nignx、gunicorn、supervisor)、一个Auto Scale资源(用于自动增加或减少EC2实例)

具体案例

下面,我将通过一个案例来说明这个模块的使用。假设,你想上线一款轻博客服务,它是用Python来实现的,而且兼容WSGI规范,这个博客应用的源码托管在这里,它对外发布的完整的tar.gz包存储在这里:"https://github.com/digolds/digolds_sample/archive/v0.0.1.tar.gz",包中的目录结构如下所示:

.
  |-digolds_sample-0.0.1
  |  |-.gitignore
  |  |-deployment
  |  |  |-load-balancer
  |  |  |  |-main.tf
  |  |  |  |-service.sh
  |  |  |-nosql
  |  |  |  |-main.tf
  |  |-personal-blog
  |  |  |-controllers
  |  |  |  |-articles_controller.py
  |  |  |  |-main_controller.py
  |  |  |  |-sign_in.py
  |  |  |-favicon.ico
  |  |  |-middlewares
  |  |  |  |-logger_middleware.py
  |  |  |-model
  |  |  |  |-articles_content.py
  |  |  |  |-in_memory_db.py
  |  |  |-static
  |  |  |  |-images
  |  |  |  |  |-digolds.png
  |  |  |-views
  |  |  |  |-blogs.html
  |  |  |  |-edit-article.html
  |  |  |  |-home.html
  |  |  |  |-sign-in.html
  |  |  |  |-single_article.html
  |  |  |  |-__base__.html
  |  |  |-wsgiapp.py
  |  |-requirements.txt

其中wsgiapp.py中的内容如下所示,尤其是要注意最后一行,我定义了一个WSGI对象wsgi_app

#!/usr/bin/env python

__author__ = 'SLZ'

'''
digwebs framework demo.
'''

import logging
logging.basicConfig(level=logging.INFO)

from digwebs.web import get_app
import os
dir_path = os.path.dirname(os.path.realpath(__file__))
digwebs_app = get_app({'root_path':dir_path})
digwebs_app.init_all()
if __name__ == '__main__':
    import os
    os.environ['TABLE_NAME'] = 'personal-articles-table'
    os.environ['INDEX_NAME'] = 'ContentGlobalIndex'

    os.environ['USER_NAME'] = 'slz'
    os.environ['PASSWORD'] = 'abc'
    digwebs_app.run(9999, host='0.0.0.0')
else:
    wsgi_app = digwebs_app.get_wsgi_application()

接下来,编写一个main.tf文件,其内容如下所示:

terraform {
  required_version = "= 0.12.19"
}

provider "aws" {
  version = "= 2.58"
  region = "ap-northeast-1"
}

data "terraform_remote_state" "dynamodb" {
  backend = "local"

  config = {
    path = "../nosql/terraform.tfstate"
  }
}

module "load_balance" {
  source       = "github.com/2cloudlab/module_load_balancer//modules/load_balancer?ref=v0.0.4"
  download_url = "https://github.com/digolds/digolds_sample/archive/v0.0.1.tar.gz"
  package_base_dir         = "digolds_sample-0.0.1"
  app_dir = "personal-blog"
  envs     = ["USER_NAME=slz", "PASSWORD=abc"]
  wsgi_app = "wsgiapp:wsgi_app"
}

output "alb_dns_name" {
  value       = module.load_balance.alb_dns_name
  description = "The domain name of the load balancer"
}

在上面的脚本中,你要特别注意以下变量与之前的目录结构的关系:

另外由于这个博客应用会用到环境变量USER_NAMEPASSWORD,因此我通过envs来设置博客应用所需的环境变量。

最后,我在wsgiapp.py文件里定义了一个WSGI对象wsgi_app,因此变量wsgi_app的值应该如下所示:

wsgi_app = "wsgiapp:wsgi_app"

cd到文件main.tf所在的目录,执行以下指令来上线这个博客应用:

terraform init
terraform apply

成功之后,你将看到以下输出结果:

Apply complete! Resources: 10 added, 0 changed, 0 destroyed.

Outputs:

alb_dns_name = alb-1-712872544.us-west-1.elb.amazonaws.com

你必须等待几分钟左右,然后在浏览器中输入alb_dns_name所指向的url,访问这个博客应用,结果页面如下所示:

image

存在的问题

这个开箱即用的解决方案依然存在许多问题,如下所示:

  1. 它目前只支持80端口
  2. 在创建成功之后,你需要等待大约几分钟的时间,才能上线Web App
  3. 如果你需要更新Web App,那么你需要重新执行以上步骤,这也就意味着,你需要暂停之前的Web App
  4. 由于这套方案创建了ALB,一族EC2实例,因此这些资源如果闲置的时候依然会计费
上一篇下一篇

猜你喜欢

热点阅读