阿里云函数计算平台
阿里云函数计算(FC),旨在帮助用户采用弹性伸缩、动态分配资源的方式,来执行业务逻辑.让用户无需购买部署服务器,无需考虑业务负载,就能快速搭建可处理高并发的后台服务.
基于WSGI标准的项目能够很方便的迁移至函数计算平台. 本文介绍如何将一个通用的django web项目,通过FC提供的fun命令行工具快速部署到FC平台。
1. django web项目预览
示例项目是一个简单的值班oncall系统,按照人员列表已一周为周期排班,并支持钉钉群发消息推送.
django项目目录结构:
2. 部署到函数计算平台
- 2.1 在项目目录安装依赖库(很重要)
FC平台上函数的运行环境对不同语言都有部分默认支持的三方库可直接使用,请参考:函数计算python运行环境文档
对于其他的依赖库,用户需自行安装在项目目录,发布时fun工具会将这些库以及用户代码一并打包上传到FC平台. 示例中需要安装django以及数据库工具pymsql
-
安装django
pip install -t . django
-
安装pymysql
pip install -t . pymysql
django中python2.7使用pymysql, 必须先修改下安装为MySQLdb:
安装完成后项目目录结构:
- 2.2 设置静态资源路径
为了让系统在FC上运行时,能找到对应的静态资源文件(js/css),必须先修改配置下静态资源路径 -
修改settings.py
STATIC_URL = '/static/' # STATICFILES_DIRS = [ # os.path.join(BASE_DIR, "static"), # ] STATIC_FC_URL = STATIC_URL STATIC_ROOT = os.path.join(BASE_DIR, 'static')
-
修改urls.py
为上面配置的资源路径,设置url映射.from django.conf.urls import url from django.conf import settings from django.conf.urls.static import static urlpatterns += static(settings.STATIC_FC_URL, document_root=settings.STATIC_ROOT)
- 修改静态页面中引用方式:
-
2.3 创建入口文件main.py
# coding=utf-8 import sys import os # load local django sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), "OnCallSys(改成你的工程目录)")) import django from django.conf import settings print (django.__version__) import urlparse from OnCallSys.wsgi import application base_path = None def handler(environ, start_response): request_uri = environ['fc.request_uri'] parsed_tuple = urlparse.urlparse(request_uri) li = parsed_tuple.path.split('/') global base_path if not base_path: base_path = "/".join(li[0:5]) settings.STATIC_URL = base_path + settings.STATIC_FC_URL context = environ['fc.context'] environ['HTTP_HOST'] = '{}.{}.fc.aliyuncs.com'.format(context.account_id, context.region) environ['SCRIPT_NAME'] = base_path + '/' return application(environ, start_response)
-
2.4 创建文件tick.py定时调用Oncall系统的/tick接口(非必要,只是OnCall系统的示例所需)
# -*- coding: utf-8 -*- import logging import os import hashlib from OnCallSys.views.Util import Util def handler(event, context): print 'tick ...' url = os.environ['TICK_URL'] name = os.environ['ADMIN_NAME'] pwd = os.environ['ADMIN_PWD'] pwd_md5 = hashlib.md5(pwd).hexdigest() url += '?username=' + name + '&pwd=' + pwd_md5 print Util.http_get(url)
- 2.5 编写FC fun工具的部署配置文件(保存到工程根目录)
-
.env文件
DEFAULT_REGION=cn-hangzhou ACCOUNT_ID= ENDPOINT= ACCESS_KEY_ID= ACCESS_KEY_SECRET=
-
templates.yml
ROSTemplateFormatVersion: '2015-09-01' # 无需修改 Transform: 'Aliyun::Serverless-2018-04-03' # 无需修改 Resources: oncall-log: # 创建logproject和logstore(需事先在阿里云平台开通日志服务) Type: 'Aliyun::Serverless::Log' Properties: Description: 'oncall system log' oncall-logstore: Type: 'Aliyun::Serverless::Log::Logstore' Properties: TTL: 362 ShardCount: 1 oncall-service: # 1. 创建service, 名字随意取(可以理解为存放代码的包) Type: 'Aliyun::Serverless::Service' Properties: Description: 'oncall system' Policies: # 设置权限 - AliyunOSSFullAccess # OSS[对象存储服务]权限(需事先在阿里云平台开通) - AliyunLogFullAccess # log权限 LogConfig: # 配置项目的输出日志 Project: oncall-log # 上面创建的logproject Logstore: oncall-logstore # 上面创建的logstore InternetAccess: true # 设置项目代码是否能访问公网 oncall: # 2. 创建function, oncall函数对应本地的main.py文件 Type: 'Aliyun::Serverless::Function' Properties: Handler: main.handler # 入口函数main.py的handler函数 CodeUri: './' Description: 'oncall system function' Runtime: python2.7 Timeout: 60 MemorySize: 512 EnvironmentVariables: # 函数oncall的环境变量, 可在本函数中读取, 并能够在控制台修改 'CUSTOM_DB_NAME': '' 'CUSTOM_DB_USER': 'CUSTOM_DB_PWD': 'CUSTOM_DB_HOST': 'CUSTOM_DB_PORT': '3306' 'WEB_HOOK_URL': 'ONCALL_SYS_URL': 'ADMIN_NAME': 'ADMIN_PWD': 'TOKEN_EXPIRE': Events: # 函数oncall的事件触发器, 这里web服务用的是http触发器 http-trigger: # trigger name Type: HTTP # trigger type Properties: AuthType: ANONYMOUS # 匿名访问 Methods: ['GET', 'POST'] tick: # 创建function,tick函数(类似上面的oncall函数, 不需要可以不创建,只是示例所需) Type: 'Aliyun::Serverless::Function' Properties: Handler: tick.handler CodeUri: './' Description: 'oncall system tick function' Runtime: python2.7 Timeout: 60 MemorySize: 512 EnvironmentVariables: 'TICK_URL': 'ADMIN_NAME': 'ADMIN_PWD': Events: tick-trigger: # trigger name Type: Timer # 定时触发器, 会根据以下cron表达式的规则定时触发当前函数 Properties: CronExpression: '0 0 1 ? * MON-FRI' # utc+8, 9:00 am, 周一到周五 Enable: true
PS: yml文件对indent有严格要求,请注意各行代码的indent
- 2.6 部署到FC函数计算
-
在django工程根目录下执行
fun deploy
部署成功!
- 在阿里云FC控制台查看
- 使用测试
在浏览器中输入复制的链接地址即可访问django项目中对应的web资源(页面或API)
到此,恭喜迁移成功!
问题解答
Q: 代码中怎么使用template.yml中配置的环境变量
A: 通过os.environ字典读取
Q: 本地测试时怎么设置环境变量
A: 可在settings.py中添加测试代码(部署时注释掉)
相关链接:
如果您有任何反馈或疑问,欢迎通过 阿里云聆听、官方论坛 和 云栖社区 联系我们。您也可以加入钉钉用户群(钉钉群号:11721331)与函数计算工程师即时沟通。