1. 程式人生 > >【Dubbo三】SSM整合Dubbo+Zookeeper實現服務化

【Dubbo三】SSM整合Dubbo+Zookeeper實現服務化

前言

最近在做一個小專案,基於Maven構建,框架使用現在主流的:SpringMVC(4.1)+spring(4.1)+MyBatis(3.4.0),實現基本增刪改查,頁面國際化。資料來源採用阿里開源的Druid,前端採用基於Bootstrap封裝的模板AdminLTE(2.3.6)及Bootstrap的一些外掛。上個週末剛好有時間,將專案進行拆分,整合Dubbo2.5.3+Zookeeper3.4.6,實現服務化。後續逐步將MQ、Reds等進行整合實現服務呼叫非同步解耦、快取機制等。

實現

本文建立兩個工程,分別是:dubbo-service、dubbo-client,採用Maven構建。

  • dubbo-service提供服務,提供資料增刪改查服務,無頁面及Controller。
  • dubbo_client提供頁面訪問,具體的增刪改查條用dubbo-service遠端服務。

Pom依賴

服務端和客戶端一致。在SSM基礎上加入Dubbo和Zookeeper依賴。

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
>
<modelVersion>4.0.0</modelVersion> <groupId>com.cyh</groupId> <artifactId>dubbo-service</artifactId> <packaging>war</packaging> <version>1.0.0.0</version> <name>dubbo-service</name> <url>http://maven.apache.org</url
>
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <!-- libs --> <junit.version>4.11</junit.version> <jstl.version>1.2</jstl.version> <javaee-api.version>7.0</javaee-api.version> <cglib.version>3.2.2</cglib.version> <aspectjrt.version>1.8.0</aspectjrt.version> <aspectjweaver.version>1.8.0</aspectjweaver.version> <spring.version>4.1.7.RELEASE</spring.version> <mybatis-spring.version>1.3.0</mybatis-spring.version> <mybatis.version>3.4.0</mybatis.version> <log4j.version>1.2.17</log4j.version> <slf4j.version>1.7.21</slf4j.version> <fileupload.version>1.3.1</fileupload.version> <mysql.version>5.1.35</mysql.version> <druid.version>1.0.19</druid.version> <fastjson.version>1.2.11</fastjson.version> <gson.version>2.3.1</gson.version> <!-- <commons-lang.version>2.6</commons-lang.version> <commons-io.version>2.5</commons-io.version> <jdom.version>2.0.2</jdom.version> <activeMQ.version>5.11.4</activeMQ.version> <javassist.version>3.12.1.GA</javassist.version> <transaction.version>1.1</transaction.version> --> </properties> <!-- 依賴包集合 --> <dependencies> <!-- 1. junit 依賴 begin junit3.0使用程式設計方式執行,junit4.0使用註解方式執行 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> </dependency> <!-- junit 依賴 end --> <!-- 2. Servlet web相關依賴 begin--> <dependency> <groupId>javax</groupId> <artifactId>javaee-api</artifactId> <version>${javaee-api.version}</version> </dependency> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>${jstl.version}</version> </dependency> <!-- Servlet web相關依賴 end--> <!-- 3. aspectjweaver 依賴 begin --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>${aspectjweaver.version}</version> </dependency> <!-- aspectjweaver 依賴 end --> <!-- 4. spring依賴 begin--> <!-- spring核心依賴--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <!-- spring ioc依賴 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${spring.version}</version> </dependency> <!-- spring aop依賴 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring.version}</version> </dependency> <!-- spring 擴充套件依賴 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <!--spring dao層依賴--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${spring.version}</version> </dependency> <!-- spring web相關依賴 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <!-- spring test相關依賴 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> </dependency> <!-- spring依賴 end--> <!-- 5. mybatis依賴 begin--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>${mybatis.version}</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>${mybatis-spring.version}</version> </dependency> <!-- mybatis依賴 end--> <!-- 6. 資料庫相關依賴 begin--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql.version}</version> <scope>runtime</scope> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>${druid.version}</version> </dependency> <!-- 資料庫相關依賴 end--> <!-- 7. log日誌依賴 begin--> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>${log4j.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>${slf4j.version}</version> </dependency> <!--log日誌依賴 end--> <!-- Dubbo 依賴 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.5.3</version> <exclusions> <exclusion> <artifactId>spring</artifactId> <groupId>org.springframework</groupId> </exclusion> </exclusions> </dependency> <!-- Zookeeper 依賴 --> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.6</version> <exclusions> <exclusion> <artifactId>log4j</artifactId> <groupId>log4j</groupId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>0.10</version> </dependency> <!-- 10. 其他依賴 begin --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>${fastjson.version}</version> </dependency> <!-- fileupload 檔案上傳 --> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>${fileupload.version}</version> </dependency> <!-- POI 相關依賴 --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.10-FINAL</version> </dependency> <!-- 二維碼依賴 --> <dependency> <groupId>com.google.zxing</groupId> <artifactId>core</artifactId> <version>3.3.0</version> </dependency> <!-- gson依賴 --> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>${gson.version}</version> </dependency> <dependency> <groupId>org.json</groupId> <artifactId>json</artifactId> <version>20160212</version> </dependency> </dependencies> </project>

服務端配置

服務介面

/**
 * @描述:國家資訊service介面
 * @作者:CYH
 * @版本:V1.0
 * @建立時間::2016-12-14 下午3:43:16
 */
public interface IAreaService{

    /**
     * 功能描述:獲取所有國家資訊
     * @return
     */
    public List<Area> getAllArea();

    /**
     * 功能描述:根據條件獲取國家資訊
     * @return
     */
    public DatatablesView<Area> getAreaByCondition(QueryCondition query);

    /**
     * 功能描述:根據ID獲取國家資訊
     * @param AreaId
     * @return
     */
    public Area getAreaById(long areaId);

    /**
     * 功能描述:新增國家資訊
     * @param Area
     * @return
     */
    public int addArea(Area area);

    /**
     * 功能描述:修改國家資訊
     * @param Area
     * @return
     */
    public int editArea(Area area);

    /**
     * @功能描述:刪除國家資訊
     * @param areaId
     * @return int
     */
    public int removeArea(long areaId);

}

實現

/**
 * @描述:國家資訊service
 * @作者:CYH
 * @版本:V1.0
 * @建立時間::2016-12-14 下午3:42:45
 */
@Service("areaService")
public class AreaService implements IAreaService{

    @Resource
    private AreaDao areaDao;

    public DatatablesView<Area> getAreaByCondition(QueryCondition query) {
        DatatablesView<Area> dataView = new DatatablesView<Area>();

        //構建查詢條件
        WherePrams where = areaDao.structureConditon(query);

        Long count = areaDao.count(where);
        List<Area> list = areaDao.list(where);

        dataView.setRecordsTotal(count.intValue());
        dataView.setData(list);

        return dataView;
    }

    public List<Area> getAllArea(){
        return areaDao.list();
    }

    public Area getAreaById(long areaId){
        return areaDao.get(areaId);
    }

    public int addArea(Area area){
        return areaDao.addLocal(area);
    }

    public int editArea(Area area){
        area.setUpdateTime(DateUtil.getNowTime());
        WherePrams where = new WherePrams();
        where.and("areaId", C.EQ, area.getAreaId());
        return areaDao.updateLocal(area,where);
    }

    public int removeArea(long areaId){
        return areaDao.del(areaId);
    }

}

Dubbo服務宣告

<?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:p="http://www.springframework.org/schema/p"
    xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
    http://code.alibabatech.com/schema/dubbo
    http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

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

    <!-- 使用zookeeper註冊中心暴露服務地址 -->
    <dubbo:registry address="zookeeper://127.0.0.1:2181" />

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

    <!-- 宣告需要暴露的服務介面  areaService 使用註解已經宣告-->
    <dubbo:service interface="com.cyh.sy.service.IAreaService"  ref="areaService" />

    <!-- 宣告需要暴露的服務介面 companyService使用註解已經宣告-->
    <dubbo:service interface="com.cyh.sy.service.ICompanyService"  ref="companyService" />

</beans>

Web.xml配置

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

    <display-name>zy</display-name>

    <!-- 自定義Listener -->
    <listener>
        <listener-class>com.cyh.sy.common.listener.Listener</listener-class>
    </listener>

    <!-- 載入Spring容器配置 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <!-- 設定Spring容器載入配置檔案路徑 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-config/spring-*.xml</param-value>
    </context-param>

    <!-- Spring 重新整理Introspector防止記憶體洩露 -->  
    <listener>
        <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
    </listener>

    <!--配置Springmvc核心控制器-->
    <servlet>
        <servlet-name>spmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-config/spring-mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
        <async-supported>true</async-supported>
    </servlet>
    <servlet-mapping>
        <servlet-name>spmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
        <init-param>  
            <param-name>forceEncoding</param-name>  
            <param-value>true</param-value>  
        </init-param>  
    </filter>
     <filter-mapping>  
        <filter-name>encodingFilter</filter-name>  
        <url-pattern>/*</url-pattern>  
    </filter-mapping>  

    <session-config>
        <session-timeout>60</session-timeout>
    </session-config>

    <welcome-file-list>
        <welcome-file>/</welcome-file>
    </welcome-file-list>

安裝Dubbo-admin

需要將Zookeeper註冊中心先啟動。

這裡下載Dubbo-admin2.5.3.war,將war複製到Tomcat/webapp/ROOT/目錄下,啟動Tomcat
http://127.0.0.1:8803/dubbo-admin/ 使用者名稱:root 密碼:root
我這裡安裝了4個Tomcat分別是8800,8801,8802,8803,dubbo部署在第四個Tomcat中。
這裡寫圖片描述

由於服務端和客戶端都沒有啟用,所有服務、提供者、消費者均為0.

啟動Service端

將Service部署在Tomcat1中,啟動Tomcat1,重新整理Dubbo-admin頁面,檢視已經有兩個服務提供者。
一個應用,兩個服務提供者
這裡寫圖片描述

具體服務
點選服務治理–服務,檢視具體服務
這裡寫圖片描述

客戶端配置

介面宣告

同樣需要將服務介面在客戶端宣告。
這裡寫圖片描述

dubbo服務宣告

<?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:p="http://www.springframework.org/schema/p"
    xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
        http://code.alibabatech.com/schema/dubbo
        http://code.alibabatech.com/schema/dubbo/dubbo.xsd"
        >

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

    <!-- 使用zookeeper註冊中心暴露服務地址 -->
    <dubbo:registry address="zookeeper://127.0.0.1:2181" />

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

    <!-- 宣告需要暴露的服務介面 -->
    <dubbo:reference interface="com.cyh.sy.service.IAreaService"  id="areaService" check="false"/>

    <!-- 宣告需要暴露的服務介面 -->
    <dubbo:reference interface="com.cyh.sy.service.ICompanyService"  id="companyService" check="false"/>

</beans>

實體類宣告

說明:服務端和客戶端中需要互動的實體類必須實現Serializable介面

/**
 * @描述:國家資訊實體
 * @作者:CYH
 * @版本:V1.0
 * @建立時間::2016-12-14 下午3:41:31
 */
@SuppressWarnings("serial")
public class Area implements Serializable{

    private Long   areaId;                  //國家ID

    private String areaIdStr;               

    private String areaNameCn="";           //國家中文名稱

    private String areaNameEn;              //國際英文名稱

    private String createTime;              //建立時間

    private String updateTime;              //修改時間

    public Area() {
        super();
    }

    public Area(String areaNameCn, String areaNameEn) {
        this.areaNameCn = areaNameCn;
        this.areaNameEn = areaNameEn;
    }

    public Long getAreaId() {
        return areaId;
    }

    public void setAreaId(Long areaId) {
        this.areaIdStr = areaId.toString();
        this.areaId = areaId;
    }

    public String getAreaIdStr() {
        return areaIdStr;
    }

    public void setAreaIdStr(String areaIdStr) {
        this.areaIdStr = areaIdStr;
    }

    public String getAreaNameCn() {
        return areaNameCn;
    }

    public void setAreaNameCn(String areaNameCn) {
        this.areaNameCn = areaNameCn;
    }

    public String getAreaNameEn() {
        return areaNameEn;
    }

    public void setAreaNameEn(String areaNameEn) {
        this.areaNameEn = areaNameEn;
    }

    public String getCreateTime() {
        return createTime;
    }

    public void setCreateTime(String createTime) {
        this.createTime = createTime;
    }

    public String getUpdateTime() {
        return updateTime;
    }

    public void setUpdateTime(String updateTime) {
        this.updateTime = updateTime;
    }

    @Override
    public String toString() {
        return "Area [areaId=" + areaId + ", areaIdStr=" + areaIdStr
                + ", areaNameCn=" + areaNameCn + ", areaNameEn=" + areaNameEn
                + ", createTime=" + createTime + ", updateTime=" + updateTime
                + "]";
    }

}

客戶端部署啟用

將client部署在Tomcat2中,啟動Tomcat2,重新整理Dubbo-admin頁面,已經多了兩個服務消費者。
這裡寫圖片描述

效果

總結

Dubbo採用全Spring配置方式,透明化接入應用,對應用沒有任何API侵入,只需用Spring載入Dubbo的配置即可,Dubbo基於Spring的Schema擴充套件進行載入。

主要核心部件:
• Remoting: 網路通訊框架,實現了 sync-over-async 和 request-response 訊息機制.
• RPC: 一個遠端過程呼叫的抽象,支援負載均衡、容災和叢集功能
• Registry: 服務目錄框架用於服務的註冊和服務事件釋出和訂閱

原始碼地址:下載