TAC是一個基於java的微服務容器,提供從業務程式碼編寫、編譯、釋出、jar動態載入、執行等一系列常用開發流程的支援,是天貓App在服務端開發模式下的新嘗試。TAC和客戶端框架Tangram結合,極大提高開發效率;TAC目前在天貓App、手機淘寶特價版廣泛使用;
疼痛之初——產生背景
天貓App(以下簡稱貓客)首頁從2015年的坑位運營走向2016年的全面個性化,當時貓客首頁的個性化業務多大50多處。以首頁為例,這個過程中除了接入導購鏈路的二方服務之外,接入了大量的三方服務;同時我們發現:
- 首頁應用越來越複雜、龐大,應用程式碼修改、編譯部署耗費時間太長,大部分時間都是苦力勞動;
- 線上定位問題週期太長,從問題發現到定位再到處理,需要經過客戶端、服務端、下游各種服務提供方,鏈路太長影響業務快速支撐;
- 大量服務的接入導致釋出線上部署頻繁,一個簡單服務的接入,幾行程式碼的修改導致首頁應用重新開發編譯部署,影響整個首頁穩定性;
當時微服務的概念已經很火,同時阿里內部也開始大力推廣docker(現在大部分應用都跑在docker上)。我們想過將龐大的首頁應用拆分成微服務,但是和基礎服務不同,前臺業務變化快,修改頻繁,拆分之後開發同學依然要面臨各種服務接入等體力勞動,同時需要維護拆分之後的多個應用,反而增加了勞動成本,因此拆分成微服務的方式治標不治本;
解決之道——TAC
在此背景下TAC孕育而生,它提供低成本開發與釋出流程、低成本搭建與維護開發環境、高穩定性保障;TAC通過熱部署的方式使得研發同學夠從苦力勞動中解放出來,迴歸到業務開發中去,同時一個基礎服務接入之後,能夠提供給多個業務使用;在此模式下,業務能夠進行更細粒度的拆分,且故障隔離業務A的改動不會影響業務B;
在TAC的幫助下,頻繁修改的新業務可快速上線,不會出現因為修改一個欄位、幾行程式碼就需要重新發布整個應用的情況;同時與tangram結合,實現頁面卡片、坑位的快速調整;
經過近三年的沉澱,我們今日放出了開源版本,將集團版本的TAC剝離與阿里相關的中介軟體、網路、協議、部署環境等,保留其核心功能;開源版本提供了編譯、熱載入、執行的基礎能力;
TAC開源版本
系統結構
- 開源版本分兩部分,tac容器和tac控制檯,儲存和通訊都依賴redis。
- 為了簡便,容器與外部服務直接的互動只通過http進行;
- 同時為了提升開發體驗,提供了與gitlab整合的能力,使用者可直接gitlab提交程式碼並在控制檯操作釋出;快速驗證;
核心類載入器
上圖是tac的類載入器結構,每個線上的微服務例項都通過一個新的classloader載入,同時為了方便使用者擴充套件新的資料來源,在AppClassLoader上擴充套件了一個classloader以載入第三方資料來源(當然也可以直接在程式碼中擴充套件,見tac-infrastructure);
Quick Start —— 如何使用
- 安裝 redis
- 執行 container
java -jar tac-container.jar複製程式碼
- 執行 console 控制檯
java -jar tac-console.jar --admin複製程式碼
- 成功後可開啟控制檯
http://localhost:7001/#/tacMs/list複製程式碼
- 程式碼開發
- 新增 SDK 依賴
<
dependency>
<
groupId>
com.alibaba<
/groupId>
<
artifactId>
tac-sdk<
/artifactId>
<
version>
${project.version
}<
/version>
<
/dependency>
複製程式碼
- 編寫程式碼
public class HelloWorldTac implements TacHandler<
Object>
{
/** * 引入日誌服務 */ private TacLogger tacLogger = TacServiceFactory.getLogger();
/** * 編寫一個實現TacHandler介面的類 * * @param context * @return * @throws Exception */ @Override public TacResult<
Object>
execute(Context context) throws Exception {
// 執行邏輯 tacLogger.info("Hello World");
Map<
String, Object>
data = new HashMap<
>
();
data.put("name", "hellotac");
data.put("platform", "iPhone");
data.put("clientVersion", "7.0.2");
data.put("userName", "tac-userName");
return TacResult.newResult(data);
}
}複製程式碼
-
本地編譯、打包
-
釋出及測試
-
正式釋出
-
線上驗證
curl http://localhost:8001/api/tac/execute/helloworld -s|json複製程式碼
{
"success": true, "msgCode": null, "msgInfo": null, "data": {
"helloworld": {
"data": {
"name": "hellotac", "clientVersion": "7.0.2", "userName": "tac-userName", "platform": "iPhone"
}, "success": true, "msCode": "helloworld"
}
}, "hasMore": null, "ip": "127.0.0.1"
}複製程式碼