前言
大家好,很久沒有寫博客了,最近半年也是比較的忙,所以給關注我的粉絲們道個歉。去年和朱永光大哥聊的時候提了一下我們的這個方案,他說讓我有空寫篇博客講一下,之前是非常的忙,所以這次趁着有些時間就寫一下我們這邊關於版本控制的方案吧。
那么今天給大家分享一個我們正在使用的一個基於k8s以及kong網關的WebApi多版本管理的解決方案,這種方案已經在我們的生產環境運行了將近兩年,也迭代了很多個版本,我們覺得這個方案非常的適合用在微服務當中。
什么是 WebApi 多版本
版本的概念大家應該都知道,那么什么是 WebApi 的版本呢?
開發App后端的兄弟應該都非常清楚了,在給 App 提供 WebApi 接口的時候,由於安裝在用戶手機上的 App 存在多個客戶端版本的問題,這些版本大部分時候需要進行共存,由於現在 Android 和 IOS 基本上都不允許App內置升級功能,當然有些時候是用戶不願意或者拒絕升級,很多時候業務需求在不停的變化,就避免不了對接口進行調整和增加新功能,所以我們需要保證后端接口的向前兼容性,那些沒有升級的客戶端App仍然要讓它們能夠正常工作,這就需要使用到多個不同版本的Api接口來進行控制,很多時候我們是保留舊接口,增加新接口,為了區分不同的客戶端,然后給接口進行版本編號,這就是WebApi的多版本控制管理。
應用場景
了解了WebApi多版本的概念之后,應用場景就自然也就明白了。
除了 App 的服務端會用到之后,同樣也適用於那些客戶端非瀏覽器的項目的服務端,例如給一些桌面程序提供接口等等。
有些時候針對一些特性的App客戶端提供不同的功能也是其應用場景之一。
解決方案
解決方案就是App在請求的時候攜帶一個版本信息到服務端,然后服務端就能夠提供不同的功能了。
Api 請求服務端攜帶版本信息可以通過兩種方式:
- 通過在 URL 中追加版本號或作為查詢字符串參數。
- 通過Http自定義標頭。
ASP.NET Core 中解決方案
在 ASP.NET Core 中的方案,我不打算進行詳細介紹了,感興趣的可以看下下面這個大兄弟的這篇文章:
菠蘿吹雪-Code : ASP.Net Core WebApi幾種版本控制
基於 K8s 和 Kong 的解決方案
由於我們使用的是基於 Kubernetes 的多版本解決方案,所以此處就詳細說明一下。
我們采用的是在 URL 中追加版本號來實現的版本控制,這樣做有兩個好處:
1、方便 kong 進行路由解析,可以直接通過配置方式實現,如果通過 header 來路由的話,需要自己進行擴展才行。
2、從日志記錄的時候可以很直觀到看到當前的 API 版本,在發生問題時候可以快速定位的具體版本的服務。
下面是我畫的一個我們的基於 Kubernets 的大致的架構圖,像 CDN 這些我就給省掉了。
主要流程分為以下幾個步驟:
1、App 端不同的版本會請求不同的 Api 接口,這些 Api 接口以版本區分,不同的版本可以提供不同的結果。
2、Kong 網關針對 URL 中攜帶的版本號信息進行路由轉發,在配置路由轉發的時候需要把攜帶路徑參數開啟,例如 /api/v1/ordering/list
這個請求地址,我們可以新建一個路由,然后配置 /api/v1/ordering
這個前綴的URL 轉發的到 ordering 這個服務,同時把路徑帶過去,假如說我們 ordering 微服務的地址為 /api/ordering
,那么就可以配置服務的路徑為 /api/ordering
,由於路由配置了攜帶路徑,所以此時我們的微服務接收到的請求地址就變成了 /api/ordering/list
。
3、Kong 網關以 NodePort 方式部署到 Kubernets 集群中,路由服務指向 Kubernets 內部服務的dns集群地址。Kong 的多個實例他們之間共享配置信息,可以把配置存儲到 PostgreSql 或者 Cassandra 中。
4、后端微服務集群內部提供集群地址配置到Kong的Service中。
業務需求的配合
這整個方案中有一個重要的點就是開發人員和產品或者業務人員的一個配合問題,也就是整個開發進度的規划需要符合敏捷開發的流程,這樣不會導致每個小版本都會有變化非常大的接口這種需求的出現,可以做到平滑升級。
以我司來舉例,當有對接口進行大改的需求時,我們會將其規划到大的迭代主版本中,這樣在大版本發布的時候,會新起一套大版本的服務集群環境來進行支撐,此時老的版本仍然不會刪除,這樣就會新舊版本同時共存,當新的版本再迭代幾個小版本時候大部分用戶其實已經自動升上來了,這個時候就可以把舊的大版本進行強制升級提示了,這樣終端App用戶就會全部升級到新的版本上了,從而把影響降低到最小。
所以,此處遵循一個原則:小版本做兼容升級,大版本做重大特性的提供以及 Break Changes 和代碼重構等工作。
DevOps 的配合
在進行大版本升級的時候,微服務的DevOps基礎設施就顯得非常重要了,此時我們需要動態的創建路由到kong,這就需要利用DevOps的配合,你可以將創建調用kong提供的rest接口來創建路由,也許一開始會花費比較多的時間,但是從長遠來看的話還是非常重要的,可以節約后續的很多時間。
以我司來舉例,當進行大版本升級時,DevOps 腳本中會檢測到版本號為大版本,此時就會運行創建新環境的腳本,這個腳本負責初始化新的 大版本的 k8s 集群環境以及kong的服務和路由配置,然后自動發布新版本的各個服務,最終會提供出來一個新的服務地址出來,類似 /api/v2/xxxx
數據中間件服務的配合
在進行新的大版本開發和迭代的過程中,還會涉及到一些關於新版本數據和舊版本不兼容的情況,比如 Redis 的緩存數據結構變化,消息隊列的數據結構的變化,以及 Elasticsearch 等索引數據結構的變化。
那么如何處理以上數據服務的版本兼容問題呢? 最簡單的方案是起一套新的環境,新版本完全使用一套新的中間件服務環境來進行運行,但是這樣有一個缺點就是會使用更多的服務器資源,照成服務器資源浪費的情況,當然如果是土豪公司可以無視了。
那如果想不同的版本使用相同的數據中間件服務怎么辦呢? 其實辦法也是有的,大部分數據中間件都是支持版本划分的,比如 Elasticsearch,CAP 等都支持使用版本來區分數據,對於不支持的可以在程序中進行控制了,比如像 Redis 這種就可以使用不同的邏輯DB來區分。
總結
本篇文章主要講述了如果利用 kong 網關和 k8s 服務來處理 webapi 多版本的問題。
同時還講述了在開發的過程中一些不同版本的數據應該如何處理以及需求的規划等,希望以上的東西能夠幫助到有需要的人。
如果你覺得本篇文章對您有幫助的話,感謝您的【推薦】。
如果你對 .NET Core 有興趣的話可以關注我,我會定期的在博客分享我的學習心得。
本文地址:http://www.cnblogs.com/savorboard/p/webapi-versions.html
作者博客:Savorboard
本文原創授權為:署名 - 非商業性使用 - 禁止演繹,協議普通文本 | 協議法律文本