Spring+Dubbo+Zookeeper框架搭建–<三>服務註冊示例

SOA

一個基本的面向服務編程(soa)的分佈式項目需要provider和consumer,也就是最基本的服務提供方和服務消費方,其中provider還可以細分爲Interface和IService的實現關係進一步在業務上細分服務。本實例就不細分provider了,爲了方便理解僅做最基本的provider和consumer劃分。

注:本實例的一切注入方式均爲註解掃描注入方式。

服務提供者Provider

一個已集成spring框架的項目,項目名爲Provider,項目結構圖如下。
這裏寫圖片描述

本實例中,新建的項目類型爲Maven Project->maven-archetype-webapp。

Dynamic Web Module爲2.5
JDK爲1.7

這裏寫圖片描述
這裏寫圖片描述

1、Pom.xml
除了基本的springframework以外,主要需要引入以下包:
Zookeeper

<!-- zookeeper -->
<dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>3.3.6</version>
    <exclusions>
        <exclusion>
            <artifactId>netty</artifactId>
            <groupId>io.netty</groupId>
        </exclusion>
    </exclusions>
</dependency>

Dubbo

<!-- dubbo -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>dubbo</artifactId>
    <version>2.5.3</version>
    <exclusions>
        <exclusion>
            <artifactId>spring</artifactId>
            <groupId>org.springframework</groupId>
        </exclusion>
        <exclusion>
            <artifactId>netty</artifactId>
            <groupId>io.netty</groupId>
        </exclusion>
    </exclusions>
</dependency>

zkClient

<!-- zkclient -->
<dependency>
    <groupId>com.github.sgroschupf</groupId>
    <artifactId>zkclient</artifactId>
    <version>0.1</version>
    <exclusions>
        <exclusion>
            <artifactId>netty</artifactId>
            <groupId>io.netty</groupId>
        </exclusion>
    </exclusions>
</dependency>

配置pom.xml的過程中可能會遇到很多編譯上的報錯,多是由包與包之間的依賴關係引起,也和開發環境有關,自行百度,具體問題具體解決。搭建過程中遇到太多問題了,有空會將常見問題做一個彙總,如配置過程中遇到瓶頸問題,請在本文下方留言聯繫我

2、Web.xml
做最基本的spring集成配置即可,配好ContextLoaderListener和DispatcherServlet,同時建立好applicationContext.xml和dubbo-provider.xml的上下文引用即可。

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    <!-- 配置web.xml,使其具有springmvc特性,主要配置兩處,一個是ContextLoaderListener,一個是DispatcherServlet -->
    <!-- ContextLoaderListener初始化Spring上下文時需要使用到的contextConfigLocation參數 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:applicationContext.xml,classpath*:dubbo-provider.xml</param-value>
    </context-param>

    <!-- spring mvc 配置 -->
    <!-- 配置DispatcherServlet表示,該工程將採用springmvc的方式。啓動時也會默認在/WEB-INF目錄下查找XXX-servlet.xml作爲配置文件,
        XXX就是DispatcherServlet的名字,該文件中將配置兩項重要的mvc特性:HandlerMapping,負責爲DispatcherServlet這個前端控制器的請求查找Controller;
        ViewResolver,負責爲DispatcherServlet查找ModelAndView的視圖解析器。
         此處使用指定的配置文件spring-mvc.xml -->
    <!-- 優點:支持rest風格,Url美觀
           缺點:會攔截靜態資源 -->
    <servlet>
        <servlet-name>contacts</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>  
            <param-name>contextConfigLocation</param-name>  
            <!--<param-value>/WEB-INF/classes/spring-mvc-servlet.xml</param-value>-->
            <param-value>classpath*:/spring-mvc.xml</param-value>
        </init-param>  
        <load-on-startup>1</load-on-startup>  
    </servlet>
    <!-- url-pattern配置爲/,不帶文件後綴,會造成其它靜態文件(js,css等)不能訪問。如配爲*.do,則不影響靜態文件的訪問 --> 
    <servlet-mapping>
        <servlet-name>contacts</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <welcome-file-list>  
        <welcome-file>index.jsp</welcome-file>  
    </welcome-file-list>  
</web-app>

3、applicationContext.xml
這裏的applicationContext.xml配置很簡單,只需要一個註解掃描的配置即可。

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd 
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd 
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">

    <!-- 加入spring註解掃描-->
    <context:component-scan base-package="com.lhx."/>
</beans>

掃描com.lhx.路徑下的所以class文件和jar包內的文件的註解,註冊到beanFactory中。
注:這裏的配置與後面的UserService的註解有一些聯繫,暫且記住這麼一回事,後面會詳細說明

4、dubbo-provider.xml
具體配置如下:

<?xml version="1.0" encoding="UTF-8"?>   
<beans xmlns="http://www.springframework.org/schema/beans"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xmlns:context="http://www.springframework.org/schema/context"  
    xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans   
        http://www.springframework.org/schema/beans/spring-beans.xsd   
        http://www.springframework.org/schema/context   
        http://www.springframework.org/schema/context/spring-context-3.1.xsd  
        http://code.alibabatech.com/schema/dubbo   
        http://code.alibabatech.com/schema/dubbo/dubbo.xsd   
        ">

    <!-- 提供方應用信息,用於計算依賴關係 -->
    <dubbo:application name="dubbo_provider" />

    <!-- 使用zookeeper註冊中心暴露服務地址 端口是zookeeper 中配置的2181 -->
    <dubbo:registry address="zookeeper://127.0.0.1:2181" />
    <!-- <dubbo:registry address="multicast://224.5.6.7:1234" /> -->

    <!-- 用dubbo協議在20880端口暴露服務 -->
    <dubbo:protocol name="dubbo" port="20880" />

    <!-- 使用註解方式暴露接口 -->
    <dubbo:annotation package="com.lhx.user"/>

</beans>

配置項含義如代碼行註釋所示。

這裏的有一點要說明的是,因爲之前已經提過,本實例的一切注入方式均爲註解注入,所以後面再配置註解的時候要十分注意註解的引用,也就是import的包是來自於spring還是dubbo。

5、UserServiceImpl
基於第3步的鋪墊,這裏要着重說明一下服務的實現類。
UserServiceImpl
這裏寫圖片描述
如上圖所示
@Service的引用是來自於com.alibaba.dubbo.config.annotation.Service
@Component的引用是來自於org.springframework.stereotype.Component
這裏比較有意思了,一般我們使用註解方式注入bean的話,@Service是拿來專門注入Service服務層的註解,@Component是實例化普通POJO的,可以拿來注入Controller、Service、Repository等,只有當組件不好歸類的時候,我們可以使用這個註解進行標註。

爲什麼我們在這裏注入UserServiceImpl的服務實現類的時候要用@Component,是因爲@Service要留給dubbo去暴露服務,因爲註解重名的原因,我們只能用@Component去作爲替代。所以引用@Service這個註解時一定要注意是不是import的com.alibaba.dubbo.config.annotation.Service,否則就會出現zookeeper無法捕捉dubbo暴露的服務,從而無法在zookeeper中註冊這個服務。

6、UserService
就是一個接口,註解方式暴露服務依託於接口實現類,xml方式暴露的話配置依賴會涉及到接口,但是我認爲xml方式暴露服務相比於註解暴露太麻煩,在這裏就不多提了。

package com.lhx.user.service;

import org.springframework.stereotype.Service;

public interface UserService {
    public String sayHello();
}

服務消費者Consumer

1、pom.xml
插件引用於Provider一致,配置dubbo/zookeeper/zkClient即可,有一點不同就是消費者Consumer需要引用服務提供者Provider的Jar包。

右鍵Provider項目,Run As->Maven Install可將項目編譯打包,打包的格式有jar、war、rar等,供外部程序引用自然是打包成Jar包,打包格式的設置在pom.xml中定義。
這裏寫圖片描述

2、Web.xml
同服務提供者,做最基本的spring集成配置即可,配好ContextLoaderListener和DispatcherServlet,同時建立好applicationContext.xml和dubbo-provider.xml的上下文引用即可。

3、applicationContext.xml
同服務提供者,這裏的applicationContext.xml配置很簡單,只需要一個註解掃描的配置即可。

4、dubbo-consumer.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://code.alibabatech.com/schema/dubbo
        http://code.alibabatech.com/schema/dubbo/dubbo.xsd
        ">


    <!-- 提供方應用信息,用於計算依賴關係 -->
    <dubbo:application name="dubbo_consumer" />

    <!-- 使用zookeeper註冊中心暴露服務地址 端口是zookeeper 中配置的2181 -->
    <dubbo:registry address="zookeeper://127.0.0.1:2181" />
    <!-- <dubbo:registry address="multicast://224.5.6.7:1234" /> -->

    <!-- 用dubbo協議在20880端口暴露服務 -->
    <dubbo:protocol name="dubbo" port="20880" />

    <!-- 使用註解方式註冊消費者 -->
    <dubbo:annotation package="com.lhx.user.controller"/>
</beans>

5、UserController
除了spring的註解以外,就是消費者需要註冊調用的服務,用dubbo的Reference註解即可。

package com.lhx.user.controller;


import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.dubbo.config.annotation.Reference;
import com.lhx.user.service.UserService;

@Controller
public class UserController {

    @Reference
    private UserService userService;

    @RequestMapping(value="/hello", method=RequestMethod.GET)
    public @ResponseBody String hello() {  
        return userService.sayHello();
    }  

}

運行效果

值得一提的是,dubbo將服務發佈在zookeeper上這一步驟是無需依託於相應的消費者是否存在的,服務可以獨立存在,即使沒有消費者。
所以本實例建議在編寫完Provider後即可運行查看dubbo-admin的管理頁面是否已經註冊到了我們新加的服務,只有在服務確認發佈(暴露)成功後再編寫相應的消費者纔是有的放夭。

1、服務者(Provider)
這裏寫圖片描述

2、消費者(Consumer)
這裏寫圖片描述

結語

學會搭建dubbo+zookeeper只是摸到了分佈式框架的門檻,真正入門還需要學習很多其他方面的知識,諸如分佈式事務、分佈式緩存、負載均衡等等。
博主由於工作上的需要,也正處於這樣的一個學習階段,希望能夠憑藉着自己的努力把一些個人心得在這裏分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章