前言
這篇文章适合所有的python開發新手、老鳥以及想準備學習開發python的程式猿。本文以一個基于django開源的
個人部落格移植到函數計算為例,向您講解如何使用阿裡雲函數計算快速建構或移植基于
wsgi applicaiton開發的web service。通過本文,您将會了解以下内容:
在本教程中,我們講解如何利用函數計算一步一步來建構web的server端,該案例是基于github上一個star很高的一個開源
,在本案例中,不讨論基于wsgi applicaiton的程式開發,本文旨在展示函數計算做web backend 能力,具體表現為以下幾點:
- 完善的基于django搭建的系統遷移到FC的成本不高
- FC打通了專有網絡vpc功能,使用者的函數可以配置通路專有網絡的雲資源,比如本案例中mysql
- fun工具自動化部署函數計算及相關資源的能力
案例體驗入口:
- 前台: http://1986114430573743.cn-hongkong.fc.aliyuncs.com/2016-08-15/proxy/blog-service/blog/
- 背景: http://1986114430573743.cn-hongkong.fc.aliyuncs.com/2016-08-15/proxy/blog-service/blog/admin
- 賬号:blog_demo
- 密碼:pwd_123456
- github位址
正常來說,使用者開發server端服務,常常面臨開發效率,運維成本高,機器資源彈性伸縮等痛點,而使用Serverless架構可以很好的解決上述問題。下面是傳統架構和Serverless架構的對比:

阿裡雲
函數計算是一個事件驅動的全托管計算服務。通過函數計算,您無需管理伺服器等基礎設施,隻需編寫代碼并上傳。函數計算會為您準備好計算資源,以彈性、可靠的方式運作您的代碼,并提供日志查詢,性能監控,報警等功能。借助于函數計算,您可以快速建構任何類型的應用和服務,無需管理和運維。
從上面的示例圖中,整體架構十分簡單明了, 用FC替代了web伺服器,但是換來的是免運維,彈性擴容,按需付費等一系列優點
Q1: FC python runtime 支援url 通路函數?
是的,函數計算具有http trigger 功能, 詳情
Q2: 函數計算url是 http://12345.cn-hongkong.fc.aliyuncs.com/2016-08-15/proxy/service_name/function_name/xxx, 怎麼讓django架構跳轉頁面的時候,知道目前的host是 http://12345.cn-hongkong.fc.aliyuncs.com/ ,并且虛拟目錄是/2016-08-15/proxy/service_name/function_name/
如 入口函數代碼 所示, 在調用django application之前設定好和
HTTP_HOST
,
SCRIPT_NAME
HTTP_HOST
具體意義可以參考 wsgi pep-0333
SCRIPT_NAME
Q3: 某些網頁引用了static目錄中js,css等檔案,會出現找不到的情況
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATIC_FC_URL = STATIC_URL
所示, 在調用django application之前設定好settings.STATIC_URL,同時在urls.py 設定好路由:
urlpatterns += static(settings.STATIC_FC_URL, document_root=settings.STATIC_ROOT)
Q4: 之前的資料庫資料如何遷移,或者說如何直接初始化需要的資料庫
- 正常的資料庫遷移,先導出資料庫資料,然後直接導入,很多用戶端工具或者指令行工具都支援
- 初始化資料庫,直接配置好對應的配置檔案,使用
指令即可
python manage.py migrate
Q5:python 3.6 中沒有MySQLdb, 如何使用django?
python 3.6, django 1.11 配置mysql資料庫
Q6: 如果是上傳檔案的需求,函數計算将怎麼儲存上傳的檔案
可以将檔案上傳到oss,然後在html頁面上引用oss link
# 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__)), "blogproject"))
import django
print (django.__version__)
from urllib.parse import urlparse
from blogproject.wsgi import application
from django.conf import settings
base_path = None
def handler(environ, start_response):
# 如果沒有使用自定義域名
if environ['fc.request_uri'].startswith("/2016-08-15/proxy"):
request_uri = environ['fc.request_uri']
parsed_tuple = 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)
準備工作
- 預先安裝python3, virtualenv, mysql,注:後面的python環境指的都是python3
- 建立并激活虛拟環境,在指令行進入到儲存虛拟環境的檔案夾,輸入如下指令建立并激活虛拟環境:
virtualenv blogproject_env # windows blogproject_env\Scripts\activate # linux/mac source blogproject_env/bin/activate
如果不想使用虛拟環境,可以跳過這一步
- 克隆需要遷移的項目到本地
git clone https://github.com/zmrenwu/django-blog-tutorial.git
-
下載下傳項目依賴到本地
如果使用了虛拟環境,確定激活并進入了虛拟環境,在指令行進入項目所在的django-blog檔案夾,運作如下指令:
pip install -t . -r requirements.txt
- 修改相應的配置檔案,確定在本地能正常運轉
- 使用本地的django庫,修改的檔案
, 在函數邏輯之前增加兩句如下代碼:manage.py
sys.path.insert(0,os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) import django
- 修改setting.py 中的DATABASES,修改成連接配接自己本地mysql
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'django-blog', #資料庫名 'USER': 'root', #使用者名 'PASSWORD': 'Passw0rd', #密碼 'HOST': '127.0.0.1', 'PORT': '3306', 'CHARSET':'utf8',##設定字元集,不然會出現中文亂碼 } }
- 修改setting.py中的ALLOWED_HOSTS成
ALLOWED_HOSTS = ['*']
- 使用本地的django庫,修改的檔案
- 遷移資料庫
python manage.py migrate
如果這裡正常執行,應該會自己本地mysql資料庫能看到相關table建立成功
- 建立背景管理者賬戶
python manage.py createsuperuser
- 運作開發伺服器
python manage.py runserver
在浏覽器輸入:127.0.0.1:8000
-
進入背景釋出文章
在浏覽器輸入:127.0.0.1:8000/admin, 用上一步建立的user應該能登入成功
建立RDS mysql資料庫, 并做好相應的配置和初始化工作
由于函數運作時的IP是不固定的,您需要設定RDS允許所有IP通路。但是這樣會有風險,不建議這樣做。在本教程中,我們将建立一個rds mysql 資料庫,并将它置于一個專有網絡VPC環境内,函數計算會支援VPC功能,使用者可以通過授權的方式安全地通路VPC中的資源。
- 開通購買rds-mysql,登入 rds控制台 ,建立資料庫
,并建構vpc環境django-blog
十分鐘上線-在函數計算上部署基于django開發的個人部落格系統 - vpc 的詳情如下:
十分鐘上線-在函數計算上部署基于django開發的個人部落格系統
- vpc 的詳情如下:
, 假設配置完畢後,我們這裡的vpc config 如下:
VpcConfig:
VpcId: 'vpc-j6c4u85w9m4ovnvf45x76'
VSwitchIds: [ 'vsw-j6cuqvtuc041zyvm415xx' ]
SecurityGroupId: 'sg-j6c35vamnn01ekx91xx'
InternetAccess: true
- 初始化django-blog資料庫,這裡有個示例可以下載下傳: blog.sql ,示例中
利用fun工具,對相應的工程進行自動化部署
1.安裝fun工具
npm install git://github.com/aliyun/fun.git --save -g
2. 編寫入口函數檔案 main.py
main.py
3. 更改對應的配置和内容
注:涉及到setting的修改,可以使用 函數計算的環境變量功能 , 不用将這些配置資訊寫死到代碼中,大大提高了函數靈活性。環境變量是在函數級别的,以鍵值對的方式存儲作為函數配置的一部分,即一個服務的不同函數擁有不同的環境變量,并且互不影響。環境變量的主要用途是代碼和配置相分離,提高代碼的靈活性和可移植性。比如 DATABASES
DATABASES = {
'default': {
'ENGINE': os.environ['CUSTOM_DB_ENGINE'], # engine,django.db.backends.mysql
'NAME': os.environ['CUSTOM_DB_NAME'], # 資料庫名, django-blog
'USER': os.environ['CUSTOM_DB_USER_NAME'], # 使用者名,root
'PASSWORD': os.environ['CUSTOM_DB_USER_PWD'], # 密碼,Passw0rd
'HOST': os.environ['CUSTOM_DB_HOST'] # 比如 '127.0.0.1',
'PORT': os.environ['CUSTOM_DB_PORT'] # 比如'3306',
'CHARSET':'utf8', #設定字元集,不然會出現中文亂碼
}
}
4. 開通使用的相關阿裡雲産品: 函數計算、日志服務
5. 編寫fun的配置檔案 template.yml
.env
template.yml
.env
- template.yml example
ROSTemplateFormatVersion: '2015-09-01' Transform: 'Aliyun::Serverless-2018-04-03' Resources: blog-pro: Type: 'Aliyun::Serverless::Log' Properties: Description: 'blog log pro' fc-log: Type: 'Aliyun::Serverless::Log::Logstore' Properties: TTL: 362 ShardCount: 1 blog-service: Type: 'Aliyun::Serverless::Service' Properties: Description: 'django blog demo' Policies: - AliyunOSSFullAccess LogConfig: Project: 'blog-pro' Logstore: 'fc-log' VpcConfig: VpcId: 'vpc-j6c4u85w9m4ovnvfxxxxx' VSwitchIds: [ 'vsw-j6cuqvtuc04xxxxxx5m6' ] SecurityGroupId: 'sg-j6c35vabbbbbbbx91vh6' InternetAccess: true blog: Type: 'Aliyun::Serverless::Function' Properties: Handler: main.handler CodeUri: './' Description: 'django blog http function' Runtime: python3 Timeout: 60 MemorySize: 512 Events: http-test: Type: Http Properties: AuthType: ANONYMOUS Methods: ['GET', 'POST', 'PUT']
- .env example
DEFAULT_REGION=cn-hongkong ACCOUNT_ID=12345 ENDPOINT=http://12345.cn-hongkong.fc.aliyuncs.com ACCESS_KEY_ID=LTAItxxxx ACCESS_KEY_SECRET=WIcnJJO7ZGoTUyyyyyyyyyy
6. 執行 fun deploy
, template.yml 裡面的相關資源就能準确建立和配置
fun deploy
7. 部署成功後,直接通過url通路首頁, url的格式為:
http://${account_id}.${region}.fc.aliyuncs.com/2016-08-15/proxy/$(seevice_name}/{function_name}/
比如:
http://1221968287646227.cn-hongkong.fc.aliyuncs.com/2016-08-15/proxy/blog-service/blog/
使用者可以在
下載下傳完整的案例代碼
Improvement
- 對于 裡Q3中的靜态檔案解法問題,這個隻是快速遷移的方案,真正遷移強烈建議把檔案托管到OSS或者CDN,這個雖然會增加點遷移工作量,但是會減少函數調用(資源請求也是一次函數調用), 也會大大減少代碼包的大小,提高函數計算冷啟動的表現。
- 對于敏感的配置資訊,強烈建議不要寫在代碼檔案裡面,而是通過設定函數的環境變量實作,比如本案例中資料庫的配置;以及不要上傳fun 工具使用的.env檔案(本案例為了展示而上傳)
總結
函數計算有如下優勢:
- 無需采購和管理伺服器等基礎設施
- 專注業務邏輯的開發
- 提供日志查詢、性能監控、報警等功能快速排查故障
- 以事件驅動的方式觸發應用響應使用者請求
- 毫秒級别彈性伸縮,快速實作底層擴容以應對峰值壓力
- 按需付費。隻需為實際使用的計算資源付費,适合有明顯波峰波谷的使用者通路場景
除了上面所列的優勢,FC 可以做為web backend,隻需要修改一些配置檔案就可以将wsgi 架構開發的工程遷移到FC,進而從傳統的web網站運維,監控等繁瑣的事務中解放出來
聲明
-
在此聲明,這個案例僅僅是做學習交流展示使用,并沒有涉及商業化,使用的素材來自
github上一個開源的
-
歡迎大家通過掃碼加入我們使用者群中,搭建過程中有問題或者有其他問題可以在群裡提出來。
函數計算官網客戶群(11721331)。