阿里雲函數計算平臺
阿里雲函數計算(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)與函數計算工程師即時溝通。