1. 程式人生 > >dubbo+zookeeper 分散式應用的快速入門

dubbo+zookeeper 分散式應用的快速入門

參考地址:https://blog.csdn.net/hua1586981/article/details/79195111

 網際網路的快速迭代,隨之而來的客戶需求的不斷變更,要求開發人員,具有敏捷的反應能力,快速應對需求變化。怎麼快速應對變化,當然一個高可用,低耦合的分散式框架少不了,接下來,我介紹dubbo+zookeeper一個分散式框架。

DUBBO架構流程圖:


dubbo:  是管理中間層的工具,在業務層到資料倉庫間有非常多服務的接入和服務提供者需要排程,dubbo提供一個框架解決這個問題.

zookeeper: 用來註冊服務和進行負載均衡,哪一個服務由哪一個機器來提供必需讓呼叫者知道,簡單來說就是ip地址和服務名稱的對應關係。當然也可以通過硬編碼的方式把這種對應關係在呼叫方業務程式碼中實現,但是如果提供服務的機器掛掉呼叫者無法知曉,如果不更改程式碼會繼續請求掛掉的機器提供服務。zookeeper通過心跳機制可以檢測掛掉的機器並將掛掉機器的ip和服務對應關係從列表中刪除。至於支援高併發,簡單來說就是橫向擴充套件,在不更改程式碼的情況通過新增機器來提高運算能力。通過新增新的機器向zookeeper註冊服務,服務的提供者多了能服務的客戶就多了。

一,安裝並啟動zookeeper

zookeeper下載地址

把包下載後,解壓到目錄,例如:D:\software\work\zookeeper (解壓後更名為zookeeper) 
複製zoo_sample.cfg 檔名(D:\software\work\zookeeper\conf) 為 zoo.cfg 
主要更改配置檔案裡面的日誌目錄,如下: 
dataDir=D:\zookeeper\data 
dataLogDir=D:\zookeeper\log

啟動 

進入到bin目錄,並且啟動zkServer.cmd。

二、建立maven工程

工程分為4個結構

  • dubbo 工程,主工程,主要匯入公共jar包等
  • dubbo-api 工程,公共介面
  • dubbo-provider 工程,服務提供者
  • dubbo-consumer-user 和 dubbo-consumer 工程,服務消費者 

三、建立dubbo專案

    主要負責公共的jar包。

pom.xml檔案如下:

<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>dubbo</groupId>
  <artifactId>dubbo</artifactId>
  <packaging>pom</packaging>
  <version>0.0.1-SNAPSHOT</version>
<!--  <modules>
    <module>dubbo-api</module>
    <module>dubbo-provider</module>
    <module>dubbo-consumer</module>
    <module>dubbo-consumer-user</module>
  </modules>-->
  <profiles>
    <profile>
      <modules>
        <module>dubbo-api</module>
        <module>dubbo-provider</module>
        <module>dubbo-consumer</module>
        <module>dubbo-consumer-user</module>
      </modules>
    </profile>
  </profiles>

  <name>dubbo Maven Webapp</name>
  <url>http://maven.apache.org</url>
  
  <properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

    <!-- spring版本號 -->
    <spring.version>4.2.5.RELEASE</spring.version>

    <!-- mybatis版本號 -->
    <mybatis.version>3.2.8</mybatis.version>

    <!-- mysql驅動版本號 -->
    <mysql-driver.version>5.1.29</mysql-driver.version>

    <!-- log4j日誌包版本號 -->
    <slf4j.version>1.7.18</slf4j.version>
    <log4j.version>1.2.17</log4j.version>

  </properties>
  <dependencies>
<!--    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>-->
    <!-- 新增jstl依賴 -->
    <dependency>
      <groupId>jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>

    <dependency>
      <groupId>javax</groupId>
      <artifactId>javaee-api</artifactId>
      <version>7.0</version>
    </dependency>

    <!-- 新增junit4依賴 -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <!-- 指定範圍,在測試時才會載入 -->
      <scope>test</scope>
    </dependency>

    <!-- 新增spring核心依賴 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-oxm</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context-support</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <!-- 新增mybatis依賴 -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>${mybatis.version}</version>
    </dependency>

    <!-- 新增mybatis/spring整合包依賴 -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>1.2.2</version>
    </dependency>

    <!-- 新增mysql驅動依賴 -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>${mysql-driver.version}</version>
    </dependency>
    <!-- 新增資料庫連線池依賴 -->
    <dependency>
      <groupId>commons-dbcp</groupId>
      <artifactId>commons-dbcp</artifactId>
      <version>1.2.2</version>
    </dependency>

    <!-- 新增fastjson -->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>1.2.22</version>
    </dependency>

    <!-- 新增日誌相關jar包 -->
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>${log4j.version}</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>${slf4j.version}</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>${slf4j.version}</version>
    </dependency>

    <!-- log end -->
    <!-- 映入JSON -->
    <dependency>
      <groupId>org.codehaus.jackson</groupId>
      <artifactId>jackson-mapper-asl</artifactId>
      <version>1.9.13</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>2.8.0</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.8.0</version>
    </dependency>

    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.3.1</version>
    </dependency>

    <dependency>
      <groupId>commons-io</groupId>
      <artifactId>commons-io</artifactId>
      <version>2.4</version>
    </dependency>

    <dependency>
      <groupId>commons-codec</groupId>
      <artifactId>commons-codec</artifactId>
      <version>1.9</version>
    </dependency>

    <dependency>
      <groupId>org.quartz-scheduler</groupId>
      <artifactId>quartz</artifactId>
      <version>2.2.1</version>
    </dependency>

    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-core</artifactId>
      <version>1.3.2</version>
    </dependency>
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-web</artifactId>
      <version>1.3.2</version>
    </dependency>
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-spring</artifactId>
      <version>1.3.2</version>
    </dependency>
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-ehcache</artifactId>
      <version>1.3.2</version>
    </dependency>
    <dependency>
      <groupId>org.apache.zookeeper</groupId>
      <artifactId>zookeeper</artifactId>
      <version>3.4.9</version>
    </dependency>
    <!-- dubbo -->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>dubbo</artifactId>
      <version>2.5.3</version>
      <exclusions>
        <exclusion>
          <groupId>org.springframework</groupId>
          <artifactId>spring</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>com.101tec</groupId>
      <artifactId>zkclient</artifactId>
      <version>0.10</version>
    </dependency>

  </dependencies>
  <build>
    <finalName>dubbo</finalName>
  </build>
</project>

四、dubbo-api專案

 封裝公共的介面

新建DemoService and UserService

 DemoService

public interface DemoService {
	
	List<String> getPermissions(Long id);
}

UserService

public interface UserService {
	
	String getName(String userId);
}

pom.xml  

<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">
    <parent>
        <artifactId>dubbo</artifactId>
        <groupId>dubbo</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>dubbo-api</artifactId>
    <packaging>war</packaging>
    <name>dubbo-api Maven Webapp</name>
    <url>http://maven.apache.org</url>
    <build>
        <finalName>dubbo-api</finalName>
    </build>
</project>

五、dubbo-provider

實現專案dubbo-api的介面

DemoServiceImpl

public class DemoServiceImpl implements DemoService{

	public List<String> getPermissions(Long id) {
		List<String> demo = new ArrayList<String>();
        demo.add(String.format("Permission_%d", id - 1));
        demo.add(String.format("Permission_%d", id));
        demo.add(String.format("Permission_%d", id + 1));
        return demo;
	}
	
}

UserServiceImpl

public class UserServiceImpl implements UserService{

	public String getName(String userId) {
		return "Andy"+userId;
	}
}

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: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-admin 或 dubbo-monitor 會顯示這個名字,方便識別 -->
	<dubbo:application name="admin-provider" owner="admin" organization="dubbox"/>
	<!-- 使用zookeeper 註冊中心暴露服務,注意要先開啟 zookeeper -->
	<dubbo:registry address="zookeeper://localhost:2181"/>
	<!-- 用dubbo協議在20880埠暴露服務 -->
	<dubbo:protocol name="dubbo" port="20880"/>
	<!-- 用dubbo 協議實現定義好的 api 介面 -->
	<dubbo:service interface="com.dubbo.service.DemoService" ref="demoService" protocol="dubbo"/>
	<dubbo:service interface="com.dubbo.service.UserService" ref="userService" protocol="dubbo"/>
	<!-- 具體實現介面的bean -->
	<bean id="demoService" class="com.dubbo.service.impl.DemoServiceImpl"/>
	<bean id="userService" class="com.dubbo.service.impl.UserServiceImpl"/>
	
</beans>

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>dubbo</artifactId>
        <groupId>dubbo</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>dubbo-provider</artifactId>

    <dependencies>
        <dependency>
            <groupId>dubbo</groupId>
            <artifactId>dubbo-api</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>dubbo</groupId>
            <artifactId>dubbo-api</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>
</project>

test中啟動服務

package test;

import java.io.IOException;

import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * 啟動服務
 */
public class Start {
	public static void main(String[] args) throws IOException {
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
		System.out.println(context.getDisplayName() + ":here");
		context.start();
		System.out.println("provider start");
		System.in.read();
	}
}

六、dubbo-consumer-user

服務消費者

注入dubbo-api的jar檔案,注入userServiceBean

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: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-admin 或 dubbo-monitor 會顯示這個名字,方便識別 -->
	<dubbo:application name="user-consumer" owner="user" organization="dubbox"/>
	<!-- 向zookeeper 訂閱provider 的地址,由zookeeper 定時推送 -->
	<dubbo:registry address="zookeeper://localhost:2181"/>
	<!-- 使用dubbo 協議呼叫定義好的 api 介面 -->
	<dubbo:reference id="userService" interface="com.dubbo.service.UserService"/>
	
</beans>

pom.xml

<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">
   <parent>
       <artifactId>dubbo</artifactId>
       <groupId>dubbo</groupId>
       <version>0.0.1-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <artifactId>dubbo-consumer-user</artifactId>

   <dependencies>
       <dependency>
           <groupId>dubbo</groupId>
           <artifactId>dubbo-api</artifactId>
           <version>0.0.1-SNAPSHOT</version>
       </dependency>
       <dependency>
           <groupId>dubbo</groupId>
           <artifactId>dubbo-api</artifactId>
           <version>0.0.1-SNAPSHOT</version>
       </dependency>
   </dependencies>
</project>

test中啟動類

/**
 * 消費者呼叫
 */
public class Start {
   public static void main(String[] args) {
      //測試常規服務
      ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
      context.start();
      System.out.println("consumer user start");
      UserService userService = context.getBean(UserService.class);
      System.out.println("consumer user");
      System.out.println(userService.getName("1"));
   }
}

啟動順序:先啟動zookeeper --> provider --> cousumer

這樣一套簡易的分佈是應用就構建好了,接下來介紹一個dubbo圖形化桌面工具

dubbo-admin的下載,可自行到官網下載:https://github.com/alibaba/dubbo 

下載後把war包放入tomcat的webapps的root目錄下,啟動tomcat

瀏覽器輸入:http://localhost:8080/dubbo-admin/ 

預設賬號: root 密碼:root


war的獲取:

開啟dubbo-admin,開啟終端,執行 mvn packer -Dmaven.test.skip =true // mvn -install -Dmaven.test.skip=true