Labelhub 是一家致力于為人工智能企業提供完善的資料與模型解決方案公司,可以幫助 AI 企業更好的管理資料,從而提高其核心 AI 產品迭代速度,Labelhub 擁有優秀的敏捷團隊,開發領域涉及機器學習、模型訓練以及軟體應用,目前已經與多家大中型企業進行深度合作,在行業相關比賽中也多次獲獎,

Labelhub 團隊在業務極速擴張的時期,選擇使用騰訊云 Serverless 技術來打造一個輕量的內部運維及資料可視化系統,通過使用 Tencent Serverless Framework,基于云上 Serverless 服務(云函式及觸發器等),無需配置和部署,即可快速開發一套定制化資料可視化系統,騰訊云 Serverless 技術不僅滿足了業務發展的需求,而且不需要耗費太多的人力和資金成本,是 Labelhub 的不二之選,
在實踐中,作者對騰訊云 Serverless 產品逐漸產生了濃厚的興趣,希望能把自己對騰訊云 Serverless 技術的理解,以及如何使用騰訊云 Serverless 技術進行專案開發的實踐經驗分享給大家,
前言
我所在的團隊開發了一款針對人工智能企業資料標注產品Labelhub,目前正式的銷售作業處于摸索階段,對于目標客戶,產品的定位,一直沒有很好進行梳理,隨著業務的逐漸開展,平臺的運維安全也并沒有進行系統的監控管理,因此我考慮將產品的業務資料、服務器資料及應用監控資料做一個基本的內部運維及資料可視化系統,
雖然有很多的開源工具選擇,但是都避免不了部署及配置,二次開發也比較麻煩,因此考慮自行開發一套簡單的按內部需求完全定制化的系統,
最終,我決定使用 Serverless 來打造這樣一個輕量的內部系統,Serverless 無疑是時下最熱的 IT 詞匯之一,作為一種新型的互聯網軟體產品架構,雖然早在 2012 年就被提出,但隨著近幾年容器技術、IoT、區塊鏈以及 5G技術的快速發展,Serverless的概念也借勢得以迅速發展,
它究竟能夠帶來什么,它的紅利是否有門檻,離我們究竟有多遠,值不值得現在開始投入,我會通過這一個專案的一系列文章來和大家一起探討,從一名普通開發者的角度去看看 Serverless,
概要說明
我希望此系列文章能夠淺顯易懂,我會盡可能詳細的介紹我在開發這個系統的程序中,對于Serverless 的理解,通過這一系列文章,我希望能夠提供給大家的內容包括:
- 如何開發一個
real world serverless app - 對于服務拆分的理解,如何更有效的利用資源
- 現有的BaaS遷移至FaaS的設想
(如果想到更多會繼續補全)
此系列文章是基于 騰訊Serverless Framework 工具,同時后端使用 Python 進行開發
專案構建
搭建后端專案結構
Serverless Framework 的檔案中心里,框架支持里目前有 Flask 以及 Django ,按照檔案示例中進行,會發現部署一個簡單的 rest api 十分容易,整個程序如官方宣稱的極速部署,
但看一下專案的結構會發現,只有一個 yml 組態檔、一個依賴文本和一個 app.py 檔案,由于組態檔中會使用 hooks 引數將依賴安裝到當前檔案夾,這是一個非常簡單的一個示例,
在搭建后端專案目錄的時候,通常情況下本地開發時并不需要考慮以下兩點:
- 三方庫的引入
- 公共函式的呼叫
對于 Serverless,則需要考慮這兩個問題,
當在示例中執行 sls deploy ,部署成功后可以在控制臺查看函式代碼,此時會發現依賴檔案也在檔案串列中,這很好的解釋了為什么說 一個函式是一個應用,
但是實際開發程序中,我們不可能每一個功能模塊都會去安裝一次依賴,因此我們可以借助公共模塊來解決這個問題,但是公共模塊如何進行引入呢,
由于 Serverless cli Component v2 已經取消了 include 配置,對于 v1 可以很輕松的使用 include 配置將公共組件包含在函式中,從而各子函式能夠很方便的進行呼叫,而對于 v2,其實我們可以通過 Layer 來解決這個問題,
對于 v1 和 v2 的區別以及詳細介紹,可參考Serverless Framework Cli的版本進化
模塊的拆分,我們則可以通過應用管理中的多實體管理來進行,
專案實踐
專案根目錄的處理
創建專案檔案夾
mkdir labelhub-dashboard
在專案根目錄下應用組態檔
cd labelhub-dashboard
touch serverless.yml
在應用組態檔中只用定義應用的名稱
app: labelhub-dashboard
公共檔案及三方依賴目錄的處理
在根目錄檔案夾下創建公共模塊檔案夾
mkdir common
我們將依賴以及公共函式放到common中便于其他模塊進行呼叫
# labelhub-dashboard/common
touch requirements.txt
# 創建資料庫連接工具類
touch dataUtils.py
由于只是測驗,也可以直接在 common 下運行 pip install pymysql -t ./ 將依賴安裝到當前路徑下,
這里使用pymysql來連接資料庫進行測驗
編輯 dataUtils.py 檔案:
import pymysql
class MysqlUtils:
def __init__(self):
self.getConn({
'host': 'xxx',
'user': 'xxx',
'port': 3306,
'db': 'xxx',
'password': 'xxx'
})
def getConn(self, conf):
self.connection = pymysql.connect(
host=conf['host'],
user=conf['user'],
password=conf['password'],
port=conf['port'],
db=conf['db'],
charset='utf8',
cursorclass=pymysql.cursors.DictCursor,
autocommit=1
)
def doAction(self, stmt, data):
try:
self.connection.ping(reconnect=True)
cursor = self.connection.cursor()
cursor.execute(stmt, data)
result = cursor
cursor.close()
return result
except Exception as e:
try:
cursor.close()
except:
pass
return False
準備就緒,就可以進行部署了,前面說過,因為 common 我們會作為 公共函式及三方庫 存放的地方,因此我們需要用 Layer 組件來進行部署,在 common 中創建組態檔
touch serverless.yml
編輯組態檔:
component: layer # 注意,這里使用的是layer組件
name: common-layer
org: labelhub-dashboard
app: labelhub-dashboard
stage: dev
inputs:
name: commonfiles # 記住這個名字
region: ap-guangzhou
src:
src: ./
exclude:
- .env
runtimes:
- Python3.6
description: packages
然后執行 sls deploy,Layer 層部署成功后,會出現函式的詳細資訊,需要注意其中version欄位的值,部署完成后我們開始創建功能模塊目錄,
功能模塊目錄的處理
在根目錄下創建一個測驗子模塊
mkdir user-data
創建測驗檔案
touch index.py
編輯測驗檔案
from mysqlUtils import MysqlUtils
import json
db = MysqlUtils()
def get_users():
search_stmt = (
"SELECT * FROM `user` limit 100;"
)
result = db.doAction(search_stmt, ())
if result == False:
return False
return result
def main_handler(event, context):
result = get_users()
data = https://www.cnblogs.com/serverlesscloud/archive/2020/10/27/[{'id': user['id'], 'name': str(user['name']), 'created_at': user['created_at'].strftime('%Y-%m-%d %H:%M:%S')} for user in result.fetchall()]
return data
這里有兩點需要說明:
- 明明
mysqlUtils是在common檔案夾中,而這里卻直接引入mysqlUtils,稍后在組態檔中會說明 - 查詢函式
get_users()為何寫在這里,其實也可以寫在mysqlUtils.py中,但是因為mysqlUtils.py是在Layer層,而Layer層的部署目前使用情況來看,比函陣列件部署要耗時更長,因此我把它放在需要使用的函式檔案中,即盡量不去修改common里的檔案,
準備就緒后就可以部署函式了,首先仍然是創建組態檔:
touch serverless.yml
編輯組態檔:
component: scf # 注意,這里使用的是scf組件
name: userdata
stage: dev
app: labelhub-dashboard
org: labelhub-dashboard
#組件引數
inputs:
name: ${name}-${stage}-${app} #函式名稱
src:
src: ./ #代碼路徑
exclude:
- .env
handler: index.main_handler #入口
runtime: Python3.6 # 云函式運行時的環境
region: ap-guangzhou # 云函式所在區域
layers:
- name: commonfiles
version: 1
events: # 觸發器
- apigw: # 網關觸發器
parameters:
endpoints:
- path: /
method: GET
通過組態檔,我們可以發現,其中的 layers 配置中的 name 以及 version ,就是在部署 common 時的名稱和部署成功后的版本號,
最后執行 sls deploy 完成部署,直接訪問生成的 url 地址,可以查看到正確的回傳資訊,
小結
最終檔案夾的結構為:
labelhub-dashboard/
------------------serverless.yml
------------------common/
------------------------requirements.txt
------------------------serverless.yml
------------------------mysqlUtils.py
------------------user-data/
---------------------------serverless.yml
---------------------------index.py
在部署 user-data 函式時,我們看到引入 mysqlUtils ,是通過直接引入的方式,而在 user-data 函式的組態檔中可以看到我們使用了對應的 layers 配置,從這里可以看出,在函式的配置中,layers 其實就相當于 v1 中的 include 配置,默認 Layer 組件中的檔案與函式檔案在相同目錄下,
其實我們可以將所有檔案創建好后,在根目錄中執行 sls deploy --all 來一次性進行部署,但在使用程序中會出現函陣列件部署報錯,找不到對應的 Layer 組件,這也是因為函陣列件部署程序中會去讀取 layers 的配置,而通過實際使用程序中發現 Layer 組件的部署幾乎都會比函陣列件慢很多,因此官方也是建議優先部署 Layer 組件,之后再統一部署函陣列件,那么我們就需要考慮,函式的應用根目錄,是否可以和公共組件目錄同級,這樣在使用 sls deploy --all 的時候,才可以避免同時更新 Layer 層,
至此,簡單的后端開發環境就已經搭建好了,相比于官方提供的檔案的示例,完善了對于實際開發程序中三方依賴和公共函式的處理,后續開發程序中若需要更多依賴,只需要在對應的組件中進行添加即可,而對于功能模塊的擴展,也只需要創建相應的目錄去進行擴展,
后面的文章,我會詳細介紹對于單個模塊功能的開發程序,更多依賴的添加進行嘗試,盡可能按照實際開發程序來進一步優化專案的結構,
One More Thing
立即體驗騰訊云 Serverless Demo,領取 Serverless 新用戶禮包 ?? serverless/start
歡迎訪問:Serverless 中文網!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/193909.html
標籤:其他
上一篇:歷史上的今天發生什么?
下一篇:《口才三絕》讀后感
