
社交,是游戲玩家的一項基本需求,那么,在游戲中,成熟穩定的聊天系統擔負著玩家交流的重要使命,
做為一家從不 996 的游戲創業公司,我們的兩款產品《世界爭霸》和《農場小鎮》都在使用自研的聊天系統,隨著在線人數逐漸增多,系統的穩定性和成本面臨著更多的考驗,于是,升級技術堆疊勢在必行,
至此,核心目標已經出現,以保障性能為前提,同時做到省事和省錢,最終,騰訊云的云函式產品進入了我們的視線,
云函式,無需服務器,省去運維煩惱,只需要關注于業務邏輯代碼,可謂省事,按量付費,用多少花多少,避免業務低谷期的資源浪費,可謂省錢,非常適合游戲聊天系統 API 這種復雜度低的中小型需求,
那么接下來我們關注的是,現有系統能不能無縫遷移過去,也就是云函式能不能滿足目前所有的特定需求,我們一個一個來說,
第一個需求:少改代碼
原來的 API 部分是采用 swoole 做為底層擴展,部署在騰訊云的 CVM 上,并使用騰訊云的負載均衡來接收外部請求,代碼層面則是使用了 composer 進行包管理,一款開源的 easyswoole 框架做為 http 業務的架子,
換用云函式的方案的話,非代碼層面就變成了騰訊云 API 網關加云函式來提供服務,而為了方便,依然需要繼續使用 composer 進行包管理,原來基于 swoole 的 http 框架無法繼續使用,改代碼的重點就在這里,

首先就是邏輯入口,我們需要確保用一個云函式來處理所有請求,畢竟云函式個數是有限的,而業務需求是無限的,
那么入口其實就只是一個路由而已,而我們需要做的,就是定義一種簡單的路由格式,并在云函式入口代碼處得到需要的資訊,并轉給原有的類進行處理,并回傳特定的內容,
以下是一個簡單的 url 格式例子:https://url/controller/action?query
只需要決議云函式給出的 path,就能得到 controller 和 action,做一些判斷后,呼叫相應類的方法,然后回傳,基于這樣的入口,原有的邏輯處理類就可以被呼叫到了,
其次,需要處理一下原來的邏輯處理類的父類,棄用框架后需要自己來做一個基本功能的父類,比如獲取 querystring 內容、決議 body,回傳統一格式的回傳值等,這里就不細說,

上圖中用 php 作為示例,不同的語言,思路都類似,說白了就是個適配問題,
另外代碼里還有一些需要改動的地方,比如資料庫配置資訊,云函式可以用環境變數來傳遞,比如原來的耗時任務的異步操作,這個后續會說到,
第二個需求:快速發布
快速發布的能力很重要,因為我們在遷移程序中,會反復得嘗試各種東西,那為什么不用本地測驗呢?因為進行遷移時云函式本地測驗的功能還不支持 PHP,使用 API 網關和云函式的組合時,發布流程是這樣子的:
- 開發代碼
- 部署云函式
$LATEST版本 - 基于
$LATEST版本打一個新版本號 - API 網關對應路徑切換版本
- API 網關發布測驗版本
- API 網關線上使用版本切換
這是一個很麻煩的程序,一開始做遷移時,第三步還不支持 API 呼叫,無法做自動化步驟,當然后來已經支持了這個能力,也有更簡單的方案:API 網關直接指向云函式的 $LATEST 版本,然后部署云函式即可,不過這個方案只適合測驗階段,不適合線上階段的發布,
我們這邊是兩者結合起來進行,穩定的功能,用穩妥的版本發布流程走,新的功能,新建一個 API 路徑,指向 $LATEST 版本,這樣隨時發布云函式也不會影響線上功能,
這里我們曾遇到過一個坑,就是發布 API 網關時,有時會遇到資源超限的情況,后來查明是因為云函式的并發實體有限,當發布新的 API 版本時,請求會進入新的實體,而舊實體此時還沒有釋放,兩種實體數量相加就會遇到超限的情況,這時候需要向騰訊云申請提高限額才行,
第三個需求:內網互通
由于是遷移,那原有系統里依然還有許多部分需要繼續使用,因此需要云函式可以和原有的內網進行通信,云函式本身支持部署到已有的內網中,因此內網互通很容易做到,
但是此時又遇到了一個坑,由于我們的 API 服務需要向外發出請求,而內網云函式沒有訪問外網的能力,這時候就需要一個 NAT 網關才可以讓云函式訪問外網,具體的方案可以參考騰訊云檔案,這里不再贅述,
需要注意的是,NAT 網關的外網解決方案下,最好單獨給云函式分配一個子網,因為使用已有的子網系結 NAT 網關,會導致出口 IP 變化,如果該子網下的機器 IP 剛好在某些白名單下,就會造成影響,
第四個需求:日志查詢
以前的日志都是直接落盤,定期壓縮轉儲,而遷移到云函式之后,就需要利用云函式的日志機制了,云函式可以直接投遞日志到騰訊云的日志服務中,任何直接輸出的資訊,都會直接作為日志投遞,因此需要規劃一下日志內容,
我們這邊把函式入口的原始資訊、URL 路徑、客戶端 IP、決議后的引數以及業務日志等等都進行了輸出,方便快速定位和查詢,另外不需要單獨輸出一次回傳值,云函式自己會列印出來,
還有一點需要注意的就是關于日志索引的問題,開啟日志投遞后,需要打開索引才能看到日志,如果日志內容中,包含索引分詞符,設定索引時要記得從分詞符中洗掉相應的關鍵字,否則那個內容就被分割了,
其實云函式日志這塊還存在著一些不足,比如跟 API 網關的日志是分離的,畢竟 HTTP 的原始入口是 API 網關,這就導致一些問題追蹤比較困難,
第五個需求:耗時任務處理
前文中提到了耗時任務需要改造,這里來細說一下,我們原來的方案是用 swoole 的 task 去處理耗時任務,而由于騰訊云函式的 PHP 環境支持 swoole,于是可以這樣改造:

但是這種方案制造出來的行程不歸我們管理,經過測驗發現,列印出來的日志,跑到其他請求里去了,也不知道這個行程的計時怎么算,會不會暗地里被干掉,所以我們采用了保險一點的方案 —— 訊息佇列,
騰訊云的訊息佇列服務有 ckafka,我們封裝了一個通用結構的訊息體,發給 ckafka,然后 ckafka 會觸發另一個云函式(運行著耗時任務的代碼),采用通用結構的好處是,我們可以忽略訊息佇列的主題,有任何想要異步操作的任務,只需寫在被 ckafka 觸發的云函式里,然后把要觸發的名字和引數發給 ckafka 就行了,

使用 Ckafka 時也遇到過一些小問題:Ckafka 主題默認開一個磁區,如果消費速度不理想,可以新增磁區試試,此時要記得云函式這邊先刪一下觸發器,再加回來,
第六個需求:組態檔更新
這里的組態檔指的不是資料庫配置之類比較小的內容,而是需要經常更新的大文本,比如我們是聊天服務,那就會涉及到屏蔽詞庫,這個檔案很大,而且會經常更新,
原來的方案是這樣的:組態檔單獨有個 git 庫,策劃提交后,執行 jenkins,然后由 jenkins 上傳檔案到 cvm,并進行 reload,改成云函式后,沒有辦法單獨上傳組態檔了,只能將檔案放在代碼里,然后步驟變成了策劃提交 git,通知程式員,然后程式員發布云函式,這種方式太不優雅了,所以我們最終改成了這種方法:策劃提交 git,jenkins 從 git 拿下來往 cos 上傳,然后云函式去 cos 拉取,

但這里有個性能問題,就是云函式拉取 cos 這一步可能會慢,因此不能每一個請求,都去拉一次檔案,那就意味著需要把一次拉取的內容保存在記憶體里,但是這樣就無法保證實時變更,因為我們無法統一管理云函式的記憶體,于是我們采用了折中方案,記憶體中保存檔案內容和上一次拉取時間,如果超過 5 分鐘,就重新拉取一次,這樣可以保證相對的實時性和性能,對于目前的需求來說,也足夠了,

就這樣,我們遷移程序中的特定需求都可以搞定,遷移作業也就順利推進下去了,接下來說一下我們遷移到云函式之后帶來的一些好處:
- 首先,不用維護 API 服務器了,不用再考慮 CPU 是不是滿了,記憶體是不是不夠了,請求量增加也不用想著需不需要再加臺服務器了,
- 其次,監控內容比較詳細,可以更好地看整體的運行效率,是不是有慢請求,訪問趨勢什么樣,有沒有錯誤之類的,
- 再次,用訊息佇列拆分后,解耦徹底,可以確保訊息不會丟失,訊息佇列觸發云函式的用法對于這種不斷累積形式的慢任務,非常好用,
- 最后,版本管理這點,有問題,隨時切回版本,不用像以前一樣,再重新拉代碼分支發布,
騰訊云云函式給我們帶來了這么多好處,我們也在盤點,還有哪些功能是可以使用騰訊云云函式的!
- 首先,無狀態的 HTTP 服務,比如客服訊息接收、支付回呼介面,
- 其次,無須回傳的異步任務,比如微信小游戲上報玩家排名,
- 再就是定時任務,比如我們會定期給玩家推送相關的活動資訊,
最后,我再談談自己在云函式使用程序中的一些體會:
第一點,云函式本質上,是拿一部分 CPU 和記憶體出來幫用戶執行一次代碼,所以代碼的時間復雜度和空間復雜度很重要,我們在使用時一定要優化代碼邏輯,否則就會多花錢,
第二點,如果云函式能夠由開發者來觸發安全殺死舊行程就更好了,這意味著我們可以自己管理記憶體初始化的時機,可以確保在某一時刻之后,所有實體的記憶體都是我們想要的狀態,可以把它理解為一種重啟,
第三點,云函式屬于被觸發型的服務,目前在進行問題追蹤時,源頭分散在其他服務上,很難追蹤全部流程,這個就需要業界同仁一起的努力啦,
近期,騰訊云云函式又增加了新功能:灰度發布、層(Layer)、默認的高級日志檢索等,非常實用,也期待未來更多新特性發布!
Serverless Framework 30 天試用計劃
我們誠邀您來體驗最便捷的 Serverless 開發和部署方式,在試用期內,相關聯的產品及服務均提供免費資源和專業的技術支持,幫助您的業務快速、便捷地實作 Serverless!
詳情可查閱:Serverless Framework 試用計劃
One More Thing
3 秒你能做什么?喝一口水,看一封郵件,還是 —— 部署一個完整的 Serverless 應用?
復制鏈接至 PC 瀏覽器訪問:https://serverless.cloud.tencent.com/deploy/express
3 秒極速部署,立即體驗史上最快的 Serverless HTTP 實戰開發!
傳送門:
- GitHub: github.com/serverless
- 官網:serverless.com
歡迎訪問:Serverless 中文網,您可以在 最佳實踐 里體驗更多關于 Serverless 應用的開發!
推薦閱讀:《Serverless 架構:從原理、設計到專案實戰》
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/6769.html
標籤:其他
