玩轉迭代開發

玩轉迭代開發

如今互聯網開發都處於快速迭代開發的狀態。這裏咱們來討論一下迭代開發中的生命週期,代碼版本,兼容性設計等話題。html

生命週期

一般,一個產品都具備兩個環境:java

  1. 測試環境:用於開發,測試搭建的環境
  2. 線上環境:正式面向用戶的環境

而每一個版本的生命週期一般會經歷以下幾個階段(忽略需求和設計等輔助階段):git

  1. 開發:處於編碼狀態,須要不定時的發佈到測試環境中進行測試
  2. 測試:本版本功能開發完成,此時將代碼完整的發佈到測試環境中,進行內部測試
  3. 預發佈:此時APP的後臺系統已經部署到線上環境中,可是還須要**一部分用戶(內部人員,被 邀請的體驗用戶等)**進行線上測試最新的APP,若是出現問題,能及時的回滾
  4. 正式發佈:此時APP已經處於徹底推廣狀態,通知舊版本的用戶進行升級到最新的APP版本可用, 固然舊版本仍是能保持一段時間的可用狀態,不能立刻不可用。

因此針對APP,可能會出現同一個時間,線上存在多個不一樣版本的APP。因此咱們須要注意:sql

  1. 測試的時候:須要測試那些比較活躍的老版本APP,而不是僅僅測試最新發布的APP。
  2. API開發的時候:須要保持活躍版本APP的API兼容性。

代碼版本

在開發過程當中,會遇到代碼版本的管理問題,好比說:一個線上的BUG,如何進行修改和發佈。這須要一個合理的代碼版本管理。數據庫

版本號

一般,咱們會採用x.y.z的格式來定義版本號,而考慮到機器和人的區別,出現了兩種方式的版本號定義:api

  • versionName:也就是x.y.z,便於人類識別的版本號
  • versionCode:經過x.y.z計算出來的數值,便於計算機識別的版本號

versionName的公式爲:安全

versionName = x.y.z , 且 x.y.z 都爲數字服務器

  • x -> 主版本號,無上限
  • y -> 小功能版本號,上限 99(能夠根據實際狀況調整)
  • z -> 修訂版本號(修復BUG),上限 99(能夠根據實際狀況調整)

versionCode計算公式爲:網絡

versionCode = x * 10000 + y * 100 + z 的格式命名數據結構

一般採用versionCode做爲系統內部的版本對比數值

代碼版本結構

代碼版本結構(採用git管理):

/tag 標籤
    /tag-v1.0.0         v1.0.0版本
    /tag-v1.0.1         v1.0.1版本, 修復了v1.0.0版本的某些BUG
/branch 分支
    /master             最後一次發佈的代碼版本,發佈完成後須要打tag
    /dev-v2.0.0         v2.0.0 版本開發分支
    /dev-v2.0.0-{todo}  v2.0.0 todo功能開發分支,開發完成後,merge到dev-v2.0.0中
    /fix-v1.0.2         v1.0.2 版本修復分支
    /test-{todo}        實驗性質的分支,不一樣步到repo上

注意:對於Android APP的發佈後,打tag的時候須要上傳apk和mapping文件,方便以後定位線上bug

兼容性設計

基本概念

這裏寫一些通用的概念:

  • APP版本廢棄: 活躍用戶不在這個被廢棄的APP版本,而且服務器限制該版本APP使用。

服務器

在保持兼容的過程當中,服務器的兼容性仍是比較好處理的,由於服務器的升級徹底處於咱們本身的控制中, 不會出現服務器處於不一樣的版本狀態。因此,只要處理好**數據庫,HTTP接口,推送協議,**基本能保證 迭代無反作用。

數據庫

在業務的開發過程當中,不可避免的就是添加新的字段和刪除原來舊的字段,對於新的字段添加,基本上可 以保證舊的業務正常的運行,而刪除字段,則可能致使舊的業務不能正常的運行,因此須要慎重選擇。 固然咱們也不是不能刪除字段,通常的作法是先保留舊的字段,而後等待APP版本廢棄,以後就可 以進行刪除該字段了。

HTTP接口

URL 兼容性

對於HTTP接口,在迭代過程當中,會出現以下幾種狀況:

  • 添加API
  • 刪除API
  • 修改API
    • 添加字段
    • 刪除字段

這幾種狀況,爲了保證已經上線的APP能正常的運行,因此咱們須要對API作兼容性工做。API格式爲:

http://host/module/service[...N]

當對一個API進行更新的時候,而且沒法作到兼容的時候(刪除字段等),咱們新建一個

http://host/module/service2

這種格式的API,而且使用註解標記原先API爲廢棄狀態(禁止新開發版本使用該API,而且版本迭代 到後面幾個版本後,能夠剔除該API)。這種API設計方式有以下的優勢:

  1. API更新的表示很是的簡潔,只用添加版本號到最後便可
  2. 廢棄的API和新的API都在同一個代碼文件中,維護比較方便

然而,這種方式有一個缺點:對同一個API修改的次數過多,會致使造成過多的 API 版本(1,2,3,4,5) 不是很是的好看,咱們能夠經過設置一個版本滑動窗口來解決。

版本滑動窗口:當API版本迭代到10的時候,自動又從0開始,固然了0版本號的api須要早早的被廢棄掉。

固然,還有其餘解決URL兼容性的方法,好比說:採用http://host/v1/module/service 的方式,可是這個方式存在一個比較致命的地方:每次修改API,都須要FORK出新的代碼版本,而每每咱們還須要維護舊版本代碼,致使維護難度(修改同一個API的時候,須要打開該API的多個代碼版本進行維護)。

固然了,若是是刪除字段的API,咱們也能夠僅僅標記這個API中的某個字段被廢棄,新版本APP不在使用這個API的這個刪除字段,而後等待使用該字段的APP版本廢棄就能夠真實的刪除這個字段了。這個方法的優勢就是不須要新建立一個API,缺點就是刪除字段的時候比較麻煩。

API擴展性

不只僅是API的URL須要保持兼容性,針對返回的數據,咱們也須要作到必定程度的擴展性

例子一 : 朋友圈主題不一樣類型

在最先的時候,朋友圈仍是隻能處於發發圖片和文字的狀態,後來加入了一些額外的元素, 如音樂,視頻,圖文等內容。然而在加入了新的主題類型後,舊的用戶不必定會立刻升級, 因此要保持朋友圈的兼容性。有大體兩個作法:

  1. 添加host/module/server2這種類型的API,使得它支持新擴展的音樂,視頻,圖文
  2. 返回數據結構中添加TYPE屬性,APP僅僅處理能識別TYPE的數據,過濾掉不能識別TYPE的數據(音頻,圖文等)。

方案1雖說也能處理這些狀況,可是整體來講沒有方案2來的更加優雅。

TOKEN 認證

對於HTTP接口設計中身份驗證,一般採用TOKEN的方式。由於TOKEN比較方便存儲,以及顯示的使用。

返回JSON

HTTP 返回的數據格式,一般採用JSON格式:{code:-1|0|1,msg:String,data:any}。

  • code: 狀態碼,負數爲系通通一錯誤代碼,0爲成功,正數爲業務錯誤代碼。
  • msg:執行結果提示,String類型
  • data:須要返回的數據,可能爲空,也能夠爲任何數據類型JSONObject,JSONArray,Int,Double,String.
HTTPS

爲了通訊的安全,咱們還須要採用HTTPS鏈接方式,避免中間人攻擊等常見的網絡攻擊手段。

推送協議

開發移動APP的時候,不可避免的就是使用長鏈接推送一些及時消息,好比說新聞,廣告,強制下線通知等。而推送協議的格式基本上爲:

{ module: 模塊類型, function:操做類型, [data]:{msg:"hello world"}}。

當APP端接收到推送的時候。採用以下的步驟處理推送:

  1. 判斷業務模塊module是否能處理
  2. 判斷function是否能進行處理
  3. 讀取data數據
  4. 根據 module,function 使用data做爲參數,調用具體的處理函數。

處理過程當中,注意使用

try{
	...logic
}catch(Exception e){

}

避免處理過程當中,致使APP奔潰。

當出現推送協議徹底不兼容(刪除字段等)的狀況的時候,咱們須要針對推送協議作兼容處理,一般咱們能夠採用function[..N]的方式來兼容。在兼容期階段,咱們能夠採用:

  1. 檢測鏈接APP的版本,選擇正確的推送格式function 仍是 function2 格式
  2. 同時發送function 和 function2 協議,新版本APP刪除function支持,僅僅處理function2。而舊版本APP僅僅只能處理function協議,忽略了function2的協議處理。
  3. 預先埋點,在幾個版本以前就嵌入function2的邏輯,當function邏輯的版本APP都廢棄後,就能夠統一採用function2 協議推送。

上述兩種方法各有優缺點:方案1比較智能,可是開發量比較大。而方案二比較方便,可是比較損耗流量。而方案3須要時間來過分。

針對刪除字段的狀況,咱們也能夠和URL兼容同樣,標記這個字段被廢棄,新版本APP再也不使用這個刪除的字段,維持一段時間繼續推送這個字段,當使用該字段的APP版本廢棄後,就能夠刪除這個字段不進行推送了。這個方法的優勢就是能比較完美的兼容以前的協議,可是缺點就是刪除字段的時候比較麻煩。

移動端

移動端升級,主要涉及到**本地數據(數據庫,磁盤文件),APP全局升級補丁,協議兼容性(HTTP,推送), 以及APP版本檢測,**而JAVA代碼和資源文件,固然就不須要進行處理了。

數據庫

數據庫升級仍是比較方便的,這裏咱們採用APP版本代碼(versionCode)做爲SQLite的版本號, SQLite已經爲咱們提供好了onUpgrade接口,在升級的時候,SQLite會給出舊的版本號,和最新的版本號, 此時咱們只要作:

app sqlite upgrade

就能夠保證對數據庫的正確升級了。

App全局升級補丁

除了數據庫升級,對於磁盤文件,升級後的引導頁面等須要處理的雜項,能夠在APP全局升級補丁中進行 處理。好比說,某個版本,能夠刪除某些磁盤文件,那麼,就能夠在全局補丁中編寫代碼。具體的作法爲:

  1. 每次打開APP初始化application的時候onCreate(),讀取記錄在本地數據庫的APP版本號和APK中的versionCode進行對比
  2. 若是不一致,那麼,就有多是升級後,從新打開APP的狀況,那麼,咱們就能夠進行升級補丁操做
  3. 升級完成後, 把最新的APK中的versionCode寫入本地數據庫,避免下一次打開APP的時候,重複升級

升級代碼大體以下:

app upgrade

能夠發現,使用versionCode做爲升級代碼點,能比較清晰的區分出不一樣版本作了什麼事情。並且對於從比較老的版本直接升級過來,也是OK的。

APP版本檢測

APP版本檢測和是升級是比較核心的功能模塊。主要實現的功能有:

  1. 定時檢測 APP 是否須要升級,而且進行提示。
  2. 判斷用戶是否能夠繼續使用該APP,即當前APP須要強制升級。

因此,APP檢測的時候,給定服務器最新的版本信息數據便可,格式基本是這個樣子:

app version

含義:

  • versionName:最新版本名稱 x.y.z
  • versionCode: 最新版本代碼
  • deadVersionCode:若是APP#versionCode <= Server#deadVersionCode,須要進行強制升級,不能再使用其餘功能。

當檢測到新的APP版本後,還須要在界面上進行ALERT,通知用戶進行升級。強制升級的話,須要禁用全部 的功能(避免APP奔潰)。而後進行ALERT用戶。

APP版本檢測功能,應該算是APP快速迭代的保證。可讓服務端來控制APP是否能夠繼續使用和升級。

總結

固然了,還有一些其餘方面的迭代開發話題,以後再補充上去。

參考

相關文章
相關標籤/搜索