1. 程式人生 > >dubbo+zookeeper構建微服務架構

dubbo+zookeeper構建微服務架構

  微服務架構成了當下的技術熱點,實現微服務是要付出很大成本的,但也許是因為微服務的優點太過於吸引人,以至於大部分開發者都將它當成未來的發展趨勢。

        微服務架構的演進過程

        dubbo的使用者手冊中介紹了服務化架構的進化過程,如下圖:


圖一、服務化架構的演進過程

        1.orm – 單一應用架構
        一個高內聚版本,所有功能部署在一起。資料訪問框架(orm)成為關鍵。這個架構很少被人使用,幾乎接近滅絕了吧。
        優點:成本低,適合功能少又簡單 缺點:很多,比如無法適應高流量,二次開發難,部署成本高

        2.mvc架構 - 垂直應用架構
        當訪問量漸漸增大,慢慢演化成用的很多的mvc架構。雖然還是所有的功能都是部署在同一個程序中,但是可以通過雙機或者前置負載均衡來實現負載分流。這樣應用也可以拆分成不同的幾個應用,以提升效能和效率。
        此時,mvc架構用於分離前後端邏輯。一方面,有一定的模組化。另一方面,加速和方便了開發。

        3.rpc架構 - 分散式服務架構
        當mvc垂直應用分成不同應用時,越來越多的情況下。不可避免的事應用a與應用b之間的互動。此時將核心和公共的 業務功能抽出來,作為單獨的服務,並實現前後端邏輯分離。
        此時則就需要提高業務的複用及整合的分散式rpc框架,例如dubbo等。

        4.soa架構 - 流動計算架構
        當rpc架構中的服務越來越多時,服務的生命週期的管控,容量的評估等各種問題會出現,使服務化成為瓶頸。需要增加一個排程中心來進行對服務管控,監督等。         5.微服務架構        在soa的基礎上,人們又提出了微服務架構,它就是將功能分散到各個離散的服務中然後實現對方案的解耦。服務更原子,自治更小,然後高密度部署服務。

        微服務的技術關注點

        要實現一個微服務的架構,我們需要關注的技術點包括:服務註冊、發現、負載均衡和健康檢查,前端路由(閘道器),容錯,服務框架的選擇,動態配置管理等模組。這些模組可以組成一個簡化的微服務架構圖如下:

        

圖二、簡化的微服務架構圖

        筆者使用螞蟻金融雲有一年的時間,螞蟻金服通過螞蟻金融雲輸出了積累多年的技術元件。給其他企業的服務化體系和框架建設提供了很好的設計思路。除了微服務所需要的基礎元件之外,還提供了分散式訊息元件,分庫分表元件,分散式排程元件等企業開發常用的中介軟體。根據螞蟻金融雲的設計思路,一個網站的基礎元件架構圖如下:


圖三、網站的基礎元件架構圖

        可惜螞蟻金融雲中的產品並不是開源的,一個企業想擁有屬於自己的網站架構,就要選出最適合的開源的服務框架實現這些元件,從而使後續開發者更關注於業務邏輯實現。

        這些元件的實現方式以後有時間的話會一一講解,這篇文章接下來先介紹一下dubbo+zookeeper來實現微服務中的前端服務、後端通用服務、服務註冊中心中所涉及到的功能。

        使用dubbo+zookeeper實現簡化的微服務架構

        dubbo是一個分散式服務框架,是阿里巴巴SOA服務化治理方案的核心框架。zookeeper是一個為分散式應用提供一致性服務的軟體,提供的功能包括:配置維護、域名服務、分散式同步、組服務等。zookeeper可以作為dubbo服務的註冊中心,兩者結合起來可以實現微服務中的 服務註冊、發現、負載均衡和健康檢查,容錯,動態配置管理的功能。由於dubbo沒有提供前端路由的功能,所以我們還需實現一個具備監控、安全認證、限流、服務反向路由功能的閘道器元件才能實現完整的微服務。這個元件實現起來比較複雜,在這篇文章中不做介紹,我們先用springMVC將dubbo服務暴露成瀏覽器可訪問的http介面。

        第一步:zookeeper叢集的部署

        使用zookeeper作為dubbo的註冊中心,部署起來並不麻煩。為了保持註冊中心的高可用性,在生產環境下我們需要配置多個zookeeper協同執行。在叢集模式下,zookeeper會基於Paxos演算法從叢集中選擇一臺作為leader,其他機器作為follower,註冊中心的資料都以leader為準。一臺zk機器成為leader的條件是超過這臺機器是可用的,且被超過半數的機器選舉為leader。基於這種實現方式,我們選擇zk叢集的數量時最好為奇數個,最少為3個,這樣只要有超過半數的zk機器存活那註冊中心就是可用的。

        注:如果我們選擇2臺機器作為zk的叢集,那隻要有一臺zk掛掉,另一臺機器就無法得到超過半數的選票,那麼這個zk叢集就直接失效了。因此選2臺機器作為zk叢集的穩定性在理論上不如一臺機器作為註冊中心的穩定性。

        以3臺機器作為zk叢集為例,每臺zk的具體部署方式為:

        1、下載安裝包並解壓到安裝目錄,zookeeper安裝包的下載地址為:http://www.apache.org/dist/zookeeper/

        2、進入解壓目錄的conf資料夾,配置zookeeper啟動的基本引數。

             在conf資料夾下有一個 zoo_sample.cfg的檔案,是zk啟動的配置樣例,zookeeper程序在啟動的時候會找zoo.cfg檔案作為預設的配置檔案,所以我們複製一個名稱為zoo.cfg的檔案,並編輯其中的配置資訊如下:


圖四、zookeeper的配置檔案

            圖中用紅框標出來的地方是zk啟動需要額外注意的引數:

            dataDir為記憶體資料庫快照的存放位置,

            clientPort 為zk程序的監聽埠

            server.A=B:C:D

            A為數字,標識這條配置為第幾個zk伺服器,即機器id

            B為host名,標識這個伺服器的主機地址

            C和D為zk叢集的成員用於選舉leader時的通訊埠

        3、在dataDir路徑下建立myid檔案,標識這臺機器對應的機器id

        4、執行zookeeper程序,在zookeeper目錄下的bin資料夾中,執行

            ./zkServer.sh start

            ps: 停止方法——執行 ./zkServer.sh stop

        5、服務驗證

            zk程序啟動後,預設會從三臺機器中選出一個leader,2個follower,在bin目錄下執行./zkServer.sh status可以檢視zk程序的執行狀態




圖五、三臺機器zookeeper的執行狀態

            如圖所示,叢集選擇zoo2作為leader,其他機器作為 follower 的方式執行。

       第二步:開發前端服務和後端通用服務

        第二步需要建立兩個專案:

            我們使用springMVC模組代替一下服務前端路由,與前端服務合成一個專案,作為服務的呼叫者。

            開發一個後端通用服務介面,作為服務的提供者。

        如果開發者是用maven做的專案管理,給大家推薦一個十分實用的多模組專案結構,模組的分層和依賴關係如下:


圖六:專案模組劃分

        如果專案的資料層操作比較複雜,可以在DAO層前面加一個領域層,模組依賴關係如下:


圖七:專案模組劃分(帶領域層)

        按照圖中的maven模組結構,我們生成服務提供方和服務呼叫方兩個專案,如圖:


圖八、服務提供方專案結構


圖九、服務呼叫方專案結構

        我們將服務提供方命名為dubboservice,服務呼叫方命名為dubboclient。

        首先在dubboservice專案中實現一個簡單的Hello World 服務。

        1、介面:

  1. public interface TestService {
  2. String sayHello(String name);
  3. }


        2、實現類:

  1. @Service("testService")
  2. public class TestServiceImpl implements TestService {
  3. @Override
  4. public String sayHello(String name) {
  5. return String.format("Hi! Client_%s! ", name);
  6. }
  7. }

        3、然後在dubboservice中引入dubbo,zookeeper所用的依賴,座標如下:

  1. <dependency>
  2. <groupId>com.alibaba</groupId>
  3. <artifactId>dubbo</artifactId>
  4. <version>2.5.3</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.apache.zookeeper</groupId>
  8. <artifactId>zookeeper</artifactId>
  9. <version>3.4.5</version>
  10. </dependency>
  11. <dependency>
  12. <groupId>com.github.sgroschupf</groupId>
  13. <artifactId>zkclient</artifactId>
  14. <version>0.1</version>
  15. </dependency>


      4、將Hello World服務在spring的配置檔案中暴露出來,如圖:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
  6. xmlns:tx="http://www.springframework.org/schema/tx" xmlns:task="http://www.springframework.org/schema/task"
  7. xsi:schemaLocation="
  8. http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
  9. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
  10. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
  11. http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
  12. http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
  13. http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd
  14. http://code.alibabatech.com/schema/dubbo
  15. http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
  16. <context:property-placeholder location="classpath:/META-INF/app.properties" />
  17. <!--提供方應用資訊,用於計算依賴關係-->
  18. <dubbo:application name="dubboservice_provider" />
  19. <!--使用zookeeper註冊中心暴露服務地址-->
  20. <dubbo:registry protocol="zookeeper" address="10.139.99.231:2181,10.139.106.145:2181,10.139.103.116:2181"/>
  21. <!--宣告需要暴露的服務介面-->
  22. <dubbo:service interface="org.zhdd.test.dubboservice.service.TestService" ref="testService"/>
  23. </beans>


       5、將dubboservice專案啟動,我們便向註冊中心提供了一個簡易的後端通用服務。

       然後在dubboclient專案中實現對後端服務的引用,和對外的路由

        1、除了在dubboclient中引入dubbo,zookeeper所用的依賴之外,我們還需要引入dubboservice中所用到的服務依賴,如下:

  1. <dependency>
  2. <groupId>com.alibaba</groupId>
  3. <artifactId>dubbo</artifactId>
  4. <version>2.5.3</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.apache.zookeeper</groupId>
  8. <artifactId>zookeeper</artifactId>
  9. <version>3.4.5</version>
  10. </dependency>
  11. <dependency>
  12. <groupId>com.github.sgroschupf</groupId>
  13. <artifactId>zkclient</artifactId>
  14. <version>0.1</version>
  15. </dependency>
  16. <!--
  17. 服務提供方的介面依賴
  18. -->
  19. <dependency>
  20. <groupId>org.zhdd.test</groupId>
  21. <artifactId>dubboservice-service</artifactId>
  22. <version>1.0.0-SNAPSHOT</version>
  23. </dependency>

        2、在spring的配置檔案中宣告所引用的服務:

  1. <!--提供方應用資訊,用於計算依賴關係-->
  2. <dubbo:application name="dubboservice_consumer" />
  3. <!--使用zookeeper註冊中心暴露服務地址-->
  4. <dubbo:registry protocol="zookeeper" address="10.139.99.231:2181,10.139.106.145:2181,10.139.103.116:2181"/>
  5. <!--宣告需要暴露的服務介面-->
  6. <dubbo:reference interface="org.zhdd.test.dubboservice.service.TestService" id="testService"/>

        3、新建一個controller,將引用的服務通過controller暴露出去,程式碼如下:

  1. @Controller
  2. public class HelloController {
  3. @Autowired
  4. private TestService testService;
  5. @RequestMapping("/hello/{name}")
  6. @ResponseBody
  7. public String hello(@PathVariable String name){
  8. String rslt=testService.sayHello(name);
  9. return rslt;
  10. }
  11. }


        4、啟動專案,這個時候dubboclient 就成功引用到了dubboservice的服務        我們通過瀏覽器訪問dubboclient暴露出來的介面,確保dubboclient可以正常呼叫到dubboservice的具體實現,如圖所示:

        這樣我們就成功部署了一個簡易的微服務架構。

        我們可以通過zookeeper的檢視工具更直觀的檢視dubbo在zookeeper中的註冊和訂閱資訊,此時的註冊和訂閱資訊如下:


後續:

        dubbo與zookeeper的複雜配置還有很多,本文只介紹了dubbo與zookeeper最基本的用法。要想了解更多的資訊可以通過官方文件進行學習:

        dubbo中文文件:http://dubbo.io/

        zookeeper文件:http://zookeeper.apache.org/

轉自: http://blog.csdn.net/zhdd99/article/details/52263609