Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android系統架構之微服務架構

Android系統架構之微服務架構

編輯:關於Android編程

目錄

一、微服務架構模式
1.1 模式描述 1.2 模式拓撲 1.3 避免依賴與調度 1.4 注意事項 1.5 模式分析 二、Android中的微服務架構 三、結語

前段時間我們翻譯的《軟件架構模式》( 完整書籍的地址 ) 對外發布之後得到了大家的一致好評,書中講述了五種經典、流行的軟件架構模式,同時分析了五種模式的實現、優缺點等,為我們的開發工作提供了很有價值的指導。但是《軟件架構模式》的問題在於沒有結合具體的示例來讓這些理論知識更易於吸收,因此有些同學在我的開發群反饋: 書看起來是挺好的,但是沒有具體的示例感覺看得迷迷糊糊的。因此在下打算寫一些結合Android源碼或者開發的文章來更深入的講述這些架構模式,理論與實踐相結合,讓大家更深刻、更具體的學習到這些架構的魅力所在。

 

一、微服務架構模式

由於微服務架構模式的高度靈活性、伸縮性等因特性,近年來在業內發展迅猛。但由於這個架構模式仍然在不斷的發展中,業內人士對這個模式也存在很多困惑,例如這個模式是關於什麼的?它是如何實現的?本文首先為講述這個模式的關鍵概念、基礎知識以及這個架構模式的優缺點,因為只有在對它有深入的了解之後你才能根據實際情況來判斷你的應用是否適合這種架構。

 

1.1 模式描述

不管你選擇哪種實現,有幾個常見的核心概念都需要進行了解。第一個概念是獨立部署單元。如圖4-1所示,微服務架構的每個組件都作為一個獨立單元進行部署,讓每個單元可以通過有效、簡化的傳輸管道進行通信,同時它還有很強的擴展性,應用和組件之間高度解耦,使得部署更為簡單。

也許要理解這種模式,最重要的概念就是服務組件。不要考慮微服務架構內部的服務,最好是考慮服務組件,從粒度上講它可以小到單一的模塊,或者大至一個應用程序。服務組件包含一個或多個模塊(如Java類),這些模塊可以提供一個單一功能,例如為特定的城市或城鎮提供天氣情況,或也可以作為一個大型商業應用的一個獨立部分,例如火車票的余票查詢系統。在微服務架構中,正確設計服務組件的粒度也是一個很大的挑戰。在接下來的服務組件部分對這一挑戰進行了詳細的討論。

4-1
微服務架構模式的另一個關鍵概念是它可能是一個分布式的架構,這意味著架構內部的所有組件之間是完全解耦的,並通過某種遠程訪問協議(例如, JMS, AMQP, REST, SOAP, RMI等)進行訪問。這種架構的分布式特性是它實現一些優越的可擴展性和部署特性的關鍵所在。<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwPs6it/7O8bzcubnB7dK7uPbB7sjL0Mu33LXEzNjQ1MrHy/zKx9PJxuTL+7OjvPu83Lm5xKPKvbTm1Nq1xM7KzOLR3buvwLS1xKOstviyu8rH1/fOqtK7uPa94r72t72wuLG7tLTU7LP2wLS1yLT9zsrM4rP2z9aho86it/7O8bzcubm1xNHdu6/T0MG9uPbW99KqwLTUtKO6yrnTw7fWsuO83Lm5xKPKvbXEtaXM5dOm08O6zcq508PD5s/yt/7O8bzcubm1xLfWsrzKvdOm08OhozwvcD4NCjxibG9ja3F1b3RlPg0KCTxwPszhyr4gOiC1pczl06bTwywgvLTSu7j206bTw77NysfSu7j21fvM5aGjPC9wPg0KPC9ibG9ja3F1b3RlPg0KPHA+tNO1pczl06bTw7W9zqK3/s7xtcS3otW5uf2zzNb30qrKx9PJs9bQ+L27uLa/qreitNmzybXEoaO1pczl06bTw82os6PKx9PJvfTx7rrPtcTX6bz+1+mzyaOs1eLQqdfpvP7NrMqx09bKx8Ht0ru49rWl0ru/ybK/yvC1pdSqtcTSu7K/t9ajrNXiyrm1w8v8t7HL9qOsxNHS1LjEseShorLiytS6zbK/yvDTptPDoaPV4tCp0vLL2M2os6O74bW81sLTptPDseS1w7TgyPWjrNLU1sHT2sO/tM7T0NK7tePQwrmmxNyyv8rwuvOjrMjnufvTydPa1eLQqdDCuabE3NL9t6LBy9Lss6OjrMTHw7TV+7j206bTw77NsrvE3NTL0NCho86it/7O8bzcubnEo8q9zai5/b2r06bTw7fWuPSzybbguPa/ybK/yvC1xLWl1KqjqLf+zvHX6bz+o6m1xLe9t6jAtL3ivvbV4tK7zsrM4qOs1eLQqbf+zvHX6bz+v8nS1LbAwaLT2sbky/u3/s7x1+m8/r340NC1pbbAv6q3oqGisuLK1LrNsr/K8KGjPC9wPg0KPHA+we3Su7j2tbzWws6it/7O8bzcubnEo8q9svrJ+rXE0d27r7n9s8zKx9PJw+bP8rf+zvG83Lm5xKPKvaOoU09Bo6nTptPDs8zQ8rTm1Nq1xM7KzOLS/cbwtcSho8vkyLtTT0HEo8q9t8ezo8e/tPOjrMzhuanBy87e0+vC17HItcSz6c/zvLax8KGi0uy5ucGsvdOhorf+zvG197bIo6yyorGj1qTNqLn9SVTE3MGmtffV+9K1zvHEv7Hqo6y1q8v8yNTIu8rHuLTU07XEoaKwurnztcQsy/y63MTRwO294rrNyrXP1qOsttS087bgyv3TptPDs8zQ8sC0y7XL/Ln909rW2MG/vLaho86it/7O8bzcubnNqLn9vPK7r7f+zvG4xcTuo6zP+7P9tfe2yNDox/Ohorzyu6+3/s7x1+m8/sGsvdO6zbfDzsrAtL3ivva4tNTTtsjOyszioaM8L3A+DQo8cD4mbmJzcDs8L3A+DQo8aDMgaWQ9"12-模式拓撲">1.2 模式拓撲

雖然有很多方法來實現微服務架構模式,但三個主要的拓撲結構脫穎而出,最常見和流行的有:基於REST API的拓撲結構,基於REST的應用拓撲結構和集中式消息拓撲結構。

基於REST的API拓撲
基於REST的API拓撲適用於網站,通過某些API對外提供小型的、自包含的服務。這種拓撲結構,如圖4 - 2所示,由粒度非常細的服務組件(因此得名微服務)組成,這些服務組件包含一個或兩個模塊並獨立於其他服務來執行特定業務功能。在這種拓結構撲中,這些細粒度的服務組件通常被REST-based的接口訪問,而這個接口是通過一個單獨部署的web API層實現的。這種拓撲的例子包含一些常見的專用的、基於雲的RESTful web service,大型網站像Yahoo, Google, and Amazon都在使用。

4-2
圖 4-2

基於REST的應用拓撲結構
基於REST的應用拓撲結構與基於REST API有所不同,它通過傳統的基於web的應用或者客戶端應用來接收客戶端請求,而不是通過一個簡單的API層。如圖4-3所示,應用的UI層是一個web應用,可以通過簡單的基於REST的接口訪問單獨部署的服務組件。該拓撲結構中的服務組件與基於REST API拓撲結構中的不同,這些服務組件往往會更大、粒度更粗、代表整個業務應用程序的一小部分,而不是細粒度的、單一操作的服務。這種拓撲結構常見於中小型企業等復程度相對較低的應用程序。

4-3
圖 4-3

集中式消息拓撲
微服務架構模式中另一個常見的方法是集中式消息拓撲,如圖4-4所示。該拓撲與前面提到的基於REST的應用拓撲類似,不同的是基於REST的應用拓撲結構使用REST進行遠程訪問,而該拓撲結構則使用一個輕量級的集中式消息中間件(如,ActiveMQ, HornetQ等等)。不要將該拓撲與面向服務的架構模式混淆或將其當做SOA簡化版,這點是極其重要的。該拓撲中的輕量級消息中間件(Lightweight Message Broker)不執行任何調度,轉換,或復雜的路由;相反,它只是一個輕量級訪問遠程服務組件的傳輸工具。
集中式消息拓撲結構通常應用在較大的業務應用程序中,或對於某些對傳輸層到用戶接口層或者到服務組件層有較復雜的控制邏輯的應用程序中。該拓撲較之先前討論的簡單基於REST的拓撲結構,其好處是有先進的排隊機制、異步消息傳遞、監控、錯誤處理和更好的負載均衡和可擴展性。與集中式代理相關的單點故障和架構瓶頸問題已通過代理集群和代理聯盟(將一個代理實例為分多個代理實例,把基於系統功能區域的吞吐量負載劃分開處理)解決。

4-4
圖 4-4

 

1.3 避免依賴和調度

微服務架構模式的主要挑戰之一就是決定服務組件的粒度級別。如果服務組件粒度過粗,那你可能不會意識到這個架構模式帶來的好處(部署、可擴展性、可測試性和松耦合)。然而,服務組件粒度過細將導致額外的服務調度,這可能會導致將微服務架構模式變成一個復雜、容易混淆、代價昂貴並易於出錯的、重量級的面向服務架構。

如果你發現需要從應用內部的用戶接口或API層調度服務組件,那麼很有可能你服務組件的粒度太細了。同樣的,如果你發現你需要在服務組件之間執行服務間通信來處理單個請求,要麼是你服務組件的粒度太細了,要麼是沒有從業務功能角度正確劃分服務組件。

服務間通信,可能導致組件之間產生耦合,但可以通過共享數據庫進行處理。例如,若一個服務組件處理網絡訂單而需要用戶信息時,它可以去數據庫檢索必要的數據,而不是調用客戶服務組件的功能。

共享數據庫可以處理信息需求,但是共享功能呢?如果一個服務組件需要的功能包含在另一個服務組件內,或是一個公共的功能,那麼有時你可以將服務組件的共享功能復制一份,因此違反了DRY規則。為了保持服務組件獨立和部署分離,微服務架構模式實現中會存在一小部分由重復的業務邏輯而造成的冗余,這在大多數業務應用程序中是一個相當常見的問題。小工具類可能屬於這一類重復的代碼。

提示 : DRY,即don’t repeat yourself.

如果你發現就算不考慮服務組件粒度的級別,你仍不能避免服務組件調度,這是一個好跡象,可能此架構模式不適用於你的應用。由於這種模式的分布式特性,很難維護服務組件之間的單一工作事務單元。這種做法需要某種事務補償框架回滾事務,這對此相對簡單而優雅的架構模式來說,顯著增加了復雜性。

 

1.4 注意事項

微服務架構模式解決了很多單體應用和面向服務架構應用存在的問題。由於主要應用組件被分成更小的、單獨部署單元,使用微服務架構模式構建的應用程序通常更健壯,並提供更好的可擴展性,支持持續交付也更容易。

該模式的另一個優點是,它提供了實時生產部署能力,從而大大減少了傳統的月度或周末“大爆炸”生產部署的需求。因為變化通常被隔離成特定的服務組件,只有變化的服務組件才需要部署。如果你的服務組件只有一個實例,你可以在用戶界面程序編寫專門的代碼用於檢測一個活躍的熱部署,一旦檢測到就將用戶重定向到一個錯誤頁面或等待頁面。你也可以在實時部署期間,將服務組件的多個實例進行交換,允許應用程序在部署期間保持持續可用性(分層架構模式很難做到這點)。

最後一個要重視的考慮是,由於微服務架構模式可能是分布式的架構,他與事件驅動架構模式具有一些共同的復雜的問題,包括約定的創建、維護,和管理、遠程系統的可用性、遠程訪問身份驗證和授權等。

 

1.5 模式分析

下面這個表中包含了微服務架構模式的特點分析和評級,每個特性的評級是基於其自身特點,基於典型模式實現的能力特性,以及該模式是以什麼聞名的。

特性 評級 分析 整體靈活性 高 整體的靈活性是能夠快速響應不斷變化的環境。由於服務是獨立部署單元,因此變化通常被隔離成單獨的服務組件,使得部署變得快捷、簡單。同時,使用這種模式構建的應用往往是松耦合的,也有助於促進改變。 易於部署 高 每個服務組件都是一個獨立的部署單元,使得每個部署單元都相對比較簡單,也降低了部署的復雜度。易於部署成為了微服務架構的一大優勢。 可測試性 高 由於業務功能被分離成獨立的應用模塊,可以在局部范圍內進行測試,這樣測試工作就更有針對性。對一個特定的服務組件進行回歸測試比對整個單體應用程序進行回歸測試更簡單、更可行。而且,由於這種模式的服務組件是松散耦合的,從開發角度來看,由一個變化導致應用其他部分也跟著變化的幾率很小,也不會出現由於一個微小的變化而對整個應用程序進行測試的蛋疼情況。 性能 較低 雖然你該模式有很多的優勢,但由於微服務架構模式的分布式或者跨進程特性,客戶程序與服務之間的通信會降低效率,因此它並不適用於高性能的應用程序。 伸縮性 高 由於應用程序被分為單獨的部署單元,每個服務組件可以單獨擴展,並允許對應用程序進行擴展調整。例如,股票交易的管理員功能模塊可能不需要擴展,因為使用該功能的用戶比較有限。但是交易數據請求服務組件可能需要擴展,因為這裡每時每刻可能都有無數的人在請求,因此需要較高的擴展性。 易於開發 高 由於功能被分隔成不同的服務組件,由於開發范圍更小且被隔離,開發變得更簡單。程序員在一個服務組件做出一個變化影響其他服務組件的幾率是很小的,從而減少開發人員或開發團隊之間的協調。

 

Android中的微服務架構

在Android領域中,我們最常看到的就是如圖4-5的Android體系架構。

image-4-5
圖4-5

這是一個典型的分層架構,分為應用層、Framework層、Native層、內核層。這似乎與我們今天要說的微服務架構沒有任何關系!大家需要注意的是這是一個更為宏觀的架構,在這個分層架構之下還有其他的架構模式,微服務架構就是其中最為明顯的一個。Android系統按照職責分為不同的層次,但是在Java層( Java應用程序和應用程序框架)與系統服務層( Android運行環境 )這兩個層之間則是通過本地C/S模式進行通信,也就是我們的微服務架構。

我們知道在Android系統啟動時,大致會執行如下四步:

init進程啟動;; System Server啟動; Android系統服務啟動,將服務注冊到ServiceManager中; Android運行環境建立,並且啟動Launcher程序。

在init進程啟動後,會調用init_parse_config_file方法解析init.rc文件,然後將init.rc中指定的命令、服務等啟動起來。

int main(int argc, char **argv)
{
    // 代碼省略

    // 創建系統文件夾
    mkdir("/dev", 0755);
    mkdir("/proc", 0755);
    mkdir("/sys", 0755);
    // 代碼省略

    // 初始化內核
    open_devnull_stdio();
    klog_init();
    property_init();
    process_kernel_cmdline();
    // 代碼省略

    // 解析init.rc文件
    init_parse_config_file("/init.rc");

    // 代碼省略
    return 0;
}

init.rc是由一種被稱為“Android初始化語言”的腳本寫成的文件。在該文件中描述了一些動作、命令、服務、選項等,我們這裡只關心服務這一項。init.rc中的一個服務描述大致是這樣的。

service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
    class main
    socket zygote stream 660 root system
    onrestart write /sys/android_power/request_state wake
    onrestart write /sys/power/state on
    onrestart restart media
    onrestart restart netd

在上述代碼中指定了一個zygote服務,這個服務會啟動一個叫做zygote的進程,zygote是Android世界的萬物之源,所以的進程都有它孵化。在啟動zygote時又會啟動System Server進程,System Server是所有系統服務的棲息地,也是應用與Zygote進程通信的中樞,例如需要啟動某個應用時會通過System Server通知zygote fork一個新的進程。在System Server啟動之後會調用com_ android_ server_ SystemServer. cpp類中的android_server_SystemServer_nativeInit函數,在該函數中會獲取ServiceManager實例以及啟動一些Native服務。最後會調用SystemServer內部類ServerThread的initAndLoop函數將WindowManagerService、ActivityManagerService等系統服務注冊到ServiceManager中,這些服務為系統提供各種各樣的功能,最後啟動系統消息循環,此時Android的運行環境基本構建起來了。

public class SystemServer {
// 主函數
public static void main(String[] args) {
       // 代碼省略

        // Initialize native services.
        nativeInit();

        // This used to be its own separate thread, but now it is
        // just the loop we run on the main thread.
        ServerThread thr = new ServerThread();
        thr.initAndLoop();
    }
}

// 內部類
class ServerThread {

    public void initAndLoop() {

        // 1、啟動主線程消息循環
        Looper.prepareMainLooper();
        // 代碼省略
        try {
            // 2、將各個系統服務注冊到ServiceManager中
            // 添加PackageManagerService
            pm = PackageManagerService.main(context, installer,
            wm = WindowManagerService.main(context, power, display, inputManager,
                    wmHandler, factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL,
                    !firstBoot, onlyCore);
            // 添加 WindowManagerService
            ServiceManager.addService(Context.WINDOW_SERVICE, wm);

            // 數十種服務的注冊,代碼省略
        } catch (RuntimeException e) {
        }
        // 3、啟動消息循環
        Looper.loop();
    }
} // end of ServiceThread

} // end of SystemServer

Framework層(客戶端)與Native系統服務(服務端)之間並不是直接調用的,而是通過Binder機制,客戶端代碼通過Java端的服務代理與Bidner機制向Native服務發起請求,具體的工作交給Native系統服務來實現。因此Framework和Native層的架構是如圖 4-6 所示。

4-6

這種架構就是類似上文所說的基於API的微服務架構,Native層系統服務完成具體的功能,Java層提供訪問Native系統服務的接口,它們之間通過Binder機制進行通信,Java層與Native層就是一個本地的C/S架構。如果以一個有網絡請求的App做比喻的話,App客戶端就扮演了Java層的角色,Native層系統服務對應的是服務端,而通信機制則由http變成了Binder。Native層的系統服務多達數十種,每個系統服務的職責明確、單一,具有良好的內聚性。例如WindowManagerService只負責管理屏幕窗口相關的操作。通過這種微服務架構,使得Java層與Native層耦合性很低、伸縮性很高,也對Java層隱藏了復雜的實現,使得整個系統更為清晰、靈活。

 

總結

微服務架構以其優秀的靈活性、伸縮性在各個架構模式中脫穎而出,但是它的一個弱點是性能相對較低。因為客戶端與服務提供端需要進行IPC甚至是網絡請求,這就通信成本較高。在Android中客戶端和服務端都在本地,因此需要IPC機制。Android並沒有選擇像Socket、管道等傳統的IPC機制,而是選擇了更為靈活、簡潔和快速、低內存消耗的Binder,這也在很大程度上提升了微服務架構在Android系統中性能以及開銷。因此,如果在普通應用中運用這種架構時,首先需要考慮的就是性能的開銷,靈活度、內存帶來的益處是否大於性能降低帶來的弊端,這些就需要大家以自身情況而定了。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved