統跳協議的前身是一套叫做internal的協議,internal要重點解決的問題是在webview和推送通知中如何跳轉到指定的介面,進一步在任何動態場景下如何跳轉到指定介面。在這樣的思路下,internal中定義了多種協議格式,如:
tmall://tmallclient/?
internal:url=
link:url=
tmall:
統跳協議設計之初就保留了很強的可擴充套件性,為接下來更豐富的場景預留了能力。上文講到了統跳協議在介面跳轉中作用,而事實上介面跳轉僅僅是這套方案的乙個典型場景,乙個最佳實踐。介面跳轉在統跳協議的框架中被認為成乙個服務,而跳轉到哪乙個介面則是由服務內部實現決定的。
統跳協議要求呼叫服務的url必須是符合w3c url標準的,服務註冊使用的url只能包括host和path兩部分,其中host是必須的,path則可選。當統跳協議接收乙個跳轉請求的url後,先根據該url的host和path兩部分作為條件查詢已註冊的服務,再初始化對應服務,把url交給服務例項執行後續操作。
統跳協議宣告了乙個服務介面,這個介面中只有乙個方法,服務必須由該介面實現而來。每乙個服務可以通過實現介面中宣告的方法,使用引數中傳遞來的完整url,引數列表和呼叫發起者指標,執行具體業務邏輯。
例如分享服務,以ios為例:實現了tmshareurlhandler
服務。
@inte***ce
tmshareurlhandler
:nsobject
<
>
@end
@implementation
tmshareurlhandler
#pragma mark - url呼叫分享元件-(
id)handleurl
:(nsurl*)
urlwithtarget
:(id
)target
withparams
:(id
)params
@end
在分享模組的配置檔案中宣告該服務的url為sharekit.tm/doshare
。
這份配置檔案在分享模組裡:
分享模組的配置檔案sharekit_bundle.plist
也註冊到統跳協議中。
這份配置檔案在統跳協議模組裡:
介面跳轉是統跳協議的初衷,也是統跳協議最重要的任務。因此在統跳協議服務註冊機制中,為介面服務註冊做了更精細的定製開發。
上文提到跳轉服務是乙個單一服務,而介面則成百上千,所以在介面註冊和服務註冊**現了衝突。本著降低開發成本的原則,我們又希望把同乙個模組中介面註冊和服務註冊放在一起。所以在統跳協議中做了如下訂製:
如此一來,在統跳協議初始化過程中,預設載入跳轉服務。當呼叫發生,解析url查詢到的對應物件帶有#
,則認為這是乙個介面,則初始化這個物件,但不對其呼叫處理url的方法,而是託管給已註冊的跳轉服務。跳轉服務則根據url和初始化的介面物件執行跳轉服務。
rewrite引擎的原理非常簡單,模擬web容器(apache/nginx等)的rewrite配置,根據配置把傳入的原始url進行重寫,返回重寫後的目標url,交給統跳協議處理。
配置是通過正規表示式描述的rewrite規則列表,這份列表通過貓客的配置中心實現動態更新。
rewrite規則按行整理,並自上而下按順序逐行匹配
變數名:數字(從0開始),列舉(scheme,host,port,path,query,fragment,shopid)
標記位即上述規則中的標記位
取出規則列表中的首條規則
以模式串為模板對原始url做匹配,並得到模式串定義的參數列
若匹配成功則繼續進行,否則進入下一條規則,從2開始進行下一輪匹配
檢視該條規則是否包含s
標記位,若包含,則使用原始串做一次個性網域名稱的查詢
使用1的結果和重寫串對原始url進行重寫操作,得到目標url
檢視該條規則是否包含l
標記位:
直到最後一條規則結束,返回目標url
上述提到過商品詳情頁的例子,在rewrite配置中就體現為:
模式串轉換串
標記位^(?:https?:)?\/\/detail(?:.m)?.tmall.com\/?item.htm\?(.*)
tmall:
l統跳協議和rewrite引擎在剛剛過去的雙11期間,在全鏈路介面降級方案和會場上下線中發揮了重要作用。
統跳協議在設計過程中預留了很好的擴充套件能力,所以在介面解耦之外還承擔了更多的服務呼叫功能。rewrite引擎為實現平台一致性而設計,而在實際應用過程中又挖掘出更多的場景和功能。
在統跳協議和rewrite引擎接下來的發展過程中,將更注重android和ios雙平台的高度一致性,並嘗試開放更多api,讓所有人一起挖掘這套方案的潛力。
MQ,網際網路架構解耦神器
乙個架構常識 當呼叫方需要關心執行結果,通常使用rpc呼叫。ret passportservice userauth name,pass switch ret case yes return yeshtml case no return nohtml case jump return 304html...