1. 程式人生 > >Dubbo + zookeeper搭建分散式服務入門(帶原始碼)

Dubbo + zookeeper搭建分散式服務入門(帶原始碼)

dubbo + zookeeper 搭建分散式服務入門

dubbo是阿里開源的高效能RPC框架,框架圖如下:
<img src="./dubbo-architecture.png" width="550" height="350" /><br>
可以分為4個部分,註冊中心,消費者,提供者和監控中心,這也是一般分散式服務的常見架構。
本文作為dubbo入門例子,採用zookeeper作為註冊中心,可分為兩個部分,如下:
- 搭建zookeeper註冊中心
- 利用dubbo搭建分散式服務

搭建zookeeper註冊中心

我們學習dubbo,可以在本機上搭建一個zookeeper註冊中心,zookeeper在主流作業系統上都可以執行(windows,linux等)。需要注意的是zookeeper是依賴jdk的,在安裝zookeeper前先安裝java。無論在windows還是linux


在windows上安裝zookeeper

1、直接在官網下載zookeeper壓縮包zookeeper-x.x.xx.tar.gz(x.x.xx是版本號),解壓到本地資料夾。
2、修改conf資料夾下zoo_sample.cfg檔名為zoo.cfg,並將檔案內容替換為下面:

tickTime=2000
dataDir=/var/lib/zookeeper
clientPort=2181
在ubuntu中安裝zookeeper

在生產環境,很少會把zookeeper安裝的windows下,所以為了學習更多linux相關知識,我在本機上裝了一個虛擬機器。
1、安裝virtualBox虛擬機器軟體。
2、新建虛擬機器,並安裝ubuntu系統。
3、用xsheel遠端連線ubuntu,並把zookeeper壓縮包上傳至伺服器,建議用root使用者登入,一般使用者遠端連線,傳輸檔案時經常沒有許可權被拒絕,ubuntu系統預設不支援root使用者遠端連線,需要修改配置,配置教程:

https://www.cnblogs.com/TechSnail/p/7695090.html
4、解壓zookeeper檔案。
5、在/etc/profile檔案中設定PATH。
修改profile檔案:指令 sudo vim /etc/profile,

export ZOOKEEPER_HOME=/xxx/xx/zookeeper-3.4.3
PATH=$ZOOKEEPER_HOME/bin:$PATH
export PATH

注意,ZOOKEEPER_HOME的值是解壓zookeeper的路徑。
6、啟動zookeeper。
指令:zkServer.sh start
檢視狀態:zkServer.sh status.
注意:若在虛擬機器中安裝zookeeper,需要修改虛擬機器網路的配置(配置NAT轉換和host-only網絡卡),新增埠對映

才能連線到虛擬機器的zookeeper。
到此,zookeeper服務註冊中心已經搭建完畢,下面講講利用dubbo搭建分散式服務。

利用dubbo搭建分散式服務

本利為加深對分散式服務的理解,以一個學生資訊(Student)的增刪查為例進行講解。
服務端(提供者)實現對學生資訊的插入,查詢和刪除三項操作。
客戶端(消費者)可以遠端呼叫服務端介面,實現資訊的操作。
專案地址:https://github.com/xubaodian/dubbo-study ,可下載參考
專案結構如下:
<img src="./project.PNG" width="300" height="250" /><br>
簡單介紹下工程結構,這是一個maven工程,包括三個模組(module),分別為consumer(消費者、客戶端),demoapi(都依賴的一些介面和實體類)和provider(服務提供者、服務端)。
最外層pom依賴進行依賴管理,把本專案所有的依賴都新增進來.
注意:各項依賴之間存在隱性依賴,可能會產生衝突,利用 標籤消除依賴衝突,具體可百度。

<?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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.xbd</groupId>
    <artifactId>dubbo-study</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>provider</module>
        <module>demoapi</module>
        <module>consumer</module>
    </modules>
    <properties>
        <junit.version>4.11</junit.version>
        <spring.version>4.3.16.RELEASE</spring.version>
        <slf4j.version>1.6.4</slf4j.version>
        <dubbo.version>2.6.2</dubbo.version>
        <zk.version>3.4.10</zk.version>
        <log4j.version>1.2.17</log4j.version>
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>dubbo</artifactId>
                <version>${dubbo.version}</version>
                <exclusions>
                    <exclusion>
                        <groupId>org.springframework</groupId>
                        <artifactId>spring</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.apache.zookeeper</groupId>
                <artifactId>zookeeper</artifactId>
                <version>${zk.version}</version>
            </dependency>
            <!--日誌依賴-->
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>${log4j.version}</version>
            </dependency>
            <!-- spring相關 -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-beans</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-jdbc</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-webmvc</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-tx</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-orm</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-test</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jms</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjrt</artifactId>
                <version>1.6.11</version>
            </dependency>
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjweaver</artifactId>
                <version>1.6.11</version>
            </dependency>
            <dependency>
                <groupId>org.apache.curator</groupId>
                <artifactId>curator-recipes</artifactId>
                <version>2.4.2</version>
                <exclusions>
                    <exclusion>
                        <groupId>org.apache.zookeeper</groupId>
                        <artifactId>zookeeper</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

按順序介紹三個模組

demoapi模組

該模組包括兩個實體類和一個介面,實體類分別是Student.java學生資訊類,RetMessage操作資訊類,提示消費者操作是否成功及操作失敗原因。
一個介面DemoApi.java,提供學生資訊增刪改介面。

//學生資訊實體類
package com.xbd.demoapi.entity;
import java.io.Serializable;

public class Student implements Serializable {
    private static final long serialVersionUID = 0L;
    private String stuId;
    private String name;
    private int age;
    private int grade;

    public String getStuId() {
        return stuId;
    }

    public void setStuId(String stuId) {
        this.stuId = stuId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getGrade() {
        return grade;
    }

    public void setGrade(int grade) {
        this.grade = grade;
    }
}
//RetMessage操作資訊類
package com.xbd.demoapi.entity;

import java.io.Serializable;

public class RetMessage implements Serializable {
    private static final long serialVersionUID = 1L;
    private boolean success;
    private String message;

    public boolean isSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

//DemoApi介面
package com.xbd.demoapi.service;

import com.xbd.demoapi.entity.RetMessage;
import com.xbd.demoapi.entity.Student;

public interface DemoApi {
    public Student getInfoById(String Id);
    public RetMessage insertInfo(Student stu);
    public RetMessage deleteById(String Id);
}
provider模組

該模組依賴我就不多說了,主要介紹下spring配置檔案,dubbo-provider.xml,該檔案內容如下,各個語句都有註釋:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
       http://dubbo.apache.org/schema/dubbo
       http://dubbo.apache.org/schema/dubbo/dubbo.xsd">

    <!-- provider's application name, used for tracing dependency relationship -->
    <!--服務提供者名稱-->
    <dubbo:application name="provider"/>

    <!-- use multicast registry center to export service -->
    <!-- <dubbo:registry protocol="zookeeper" address="localhost:2181"/>-->
    <!--zookeeper註冊中心地址-->
    <dubbo:registry protocol="zookeeper" address="zookeeper://192.168.56.10:10000"/>

    <!-- use dubbo protocol to export service on port 20880 -->
    <!--服務名稱和埠號-->
    <dubbo:protocol name="dubbo" port="20880"/>

    <!-- service implementation, as same as regular local bean -->
    <!--介面的執行類-->
    <bean id="demoService" class="com.xbd.provider.DemoApiImpl"/>

    <!-- declare the service interface to be exported -->
    <!--宣告介面-->
    <dubbo:service interface="com.xbd.demoapi.service.DemoApi" ref="demoService"/>

</beans>

服務實現類為DemoApiImpl.java,如下,各個介面的意義意義在註釋中有解釋。

package com.xbd.provider;

import com.xbd.demoapi.entity.RetMessage;
import com.xbd.demoapi.entity.Student;
import com.xbd.demoapi.service.DemoApi;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class DemoApiImpl implements DemoApi {
    /**
     * 學生資訊List,存放學生資訊,本來打算在資料庫中增刪,為了簡化例子,直接用一個List代替;
     * 若是連線資料庫進行增刪改查,在此處呼叫dao層介面即可
     */
    List<Student> stuList = new ArrayList<>();

    /**
     * 根據Id獲取學生資訊,若是連線資料庫,呼叫dao層介面查詢學生資訊
     * @param Id String
     * @return Student
     **/
    @Override
    public Student getInfoById(String Id) {
        Student stu = this.getInfo(Id);
        return stu;
    }

    /**
     * 插入學生資訊,並判斷是否插入成功,返回操作資訊
     * @param stu
     */
    @Override
    public RetMessage insertInfo(Student stu) {
        RetMessage ret = new RetMessage();
        ret.setSuccess(false);
        if(stu!=null && !isBlank(stu.getStuId()) && !isBlank(stu.getName())){
            Student stuVo = this.getInfo(stu.getStuId());
            if(stuVo != null) {
                ret.setMessage("該使用者已存在!");
            } else{
                stuList.add(stu);
                ret.setSuccess(true);
                ret.setMessage("成功");
            }
        } else {
            ret.setMessage("資料不全,請檢查!");
        }
        return ret;
    }

    /**
     * 刪除學生資訊
     * @param Id
     * @return RetMessage
     */
    @Override
    public RetMessage deleteById(String Id) {
        RetMessage ret = new RetMessage();
        ret.setSuccess(false);
        if(!isBlank(Id)) {
            int len = stuList.size();
            for(int i = 0; i < len; i++) {
                if(Id.equals(stuList.get(i).getStuId())){
                    stuList.remove(i);
                    ret.setSuccess(true);
                    ret.setMessage("成功!");
                    break;
                }
            }
        } else {
            ret.setMessage("Id為空,請檢查輸入資料");
        }
        return ret;
    }

    private Student getInfo(String Id){
        Iterator<Student> it = stuList.iterator();
        Student stu = null;
        while (it.hasNext()) {
            stu = it.next();
            if(stu.getStuId().equals(Id)){
                break;
            }
        }
        return stu;
    }

    private boolean isBlank(String value){
        return value == null || "".equals(value) || "null".equals(value);
    }
}

啟動類provider.java如下,在程式碼中啟動了spring支援。

package com.xbd.provider;

import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException;

public class Provider {
    public static void main(String [] args) throws IOException {
        System.setProperty("java.net.preferIPv4Stack", "true");
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"META-INF/spring/dubbo-provider.xml"});
        context.start();
        System.out.println("the server start");
        System.in.read(); // press any key to exit
    }
}
消費者模組(consumer)

消費者模組程式碼如下:

package com.xbd;

import com.xbd.demoapi.entity.RetMessage;
import com.xbd.demoapi.entity.Student;
import com.xbd.demoapi.service.DemoApi;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Consumer {
    public static void main(String [] args){
        System.setProperty("java.net.preferIPv4Stack", "true");
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"META-INF/spring/dubbo-consumer.xml"});
        context.start();
        DemoApi demoService = (DemoApi) context.getBean("demoService"); // get remote service proxy
        Student student = new Student();
        student.setStuId("111");
        student.setName("xxx");
        RetMessage retMessage1 = demoService.insertInfo(student);
        System.out.println(retMessage1.getMessage());
        RetMessage retMessage2 = demoService.insertInfo(student);
        System.out.println(retMessage2.getMessage());
    }
}

同樣的資訊插入了兩次,列印資訊如下:

成功
該使用者已存在!

對照DemoServiceImpl中的實現,我們想要實現的功能已經跑通了,趕緊動手試一試吧。

相關推薦

Dubbo + zookeeper搭建分散式服務入門原始碼

dubbo + zookeeper 搭建分散式服務入門 dubbo是阿里開源的高效能RPC框架,框架圖如下: 可以分為4個部分,註冊中心,消費者,提供者和監控中心,這也是一般分散式服務的常見架構。 本文作為dubbo入門例子,採用zookeeper作為註冊

【Java】Dubbo+zookeeper搭建分散式服務框架

一、前言      前一段時間,小編工作的架構換成了Dubbo的分散式架構,專案也改成了SOA(面向服務的架構),在專案中分成了六個服務,每個服務可以單獨執行,服務之間也可以互相呼叫。下面小編就Dubbo官網提供的一個簡單的Demo來帶領大家實現一個分散式服務框架。二、環境要

Centos6.5搭建郵件服務Postfix+Dovecot

Linux Centos6.5 Postfix Dovecot 參考博文:http://blog.jjonline.cn/linux/185.html http://blog.51cto.com/11038104/1916669第一步、關閉iptables、selinux /et

如何快速用openresty搭建高效能服務Nginx+lua

高效能服務端兩個重要要素:快取+語言支援非同步非堵塞 快取:記憶體>SSD>機械磁碟 本機>網路 程序內>程序間 非同步非阻塞:事件驅動方式(事件完成後再通知) OpenResty:顛覆了高效能服務端的開發模式(Nginx+LuaJI

Spring Cloud構建微服務架構:分散式服務跟蹤收集原理【Dalston版】

                在本節內容之前,我們已經對如何引入Sleuth跟蹤資訊和搭建Zipkin服務端分析跟蹤延遲的過程做了詳細的介紹,相信大家對於Sleuth和Zipkin已經有了一定的感性認識。接下來,我們介紹一下關於Zipkin收集跟蹤資訊的過程細節,以幫助我們更好地理解Sleuth生產跟蹤資訊

Eclipse搭建SpringBoot程式入門 整合mybatis

目錄 Springboot 理解: spring boot其實不是什麼新的框架,它預設配置了很多框架的使用方式,就像maven整合了所有的jar包,spring boot整合了許多優秀框架,它能夠簡單、快速、方便為我們搭建好框架。 接下來進入搭建環節

Spring Cloud構建微服務架構:分散式服務跟蹤跟蹤原理

通過上一篇《分散式服務跟蹤(入門)》的例子,我們已經通過Spring Cloud Sleuth往微服務應用中添加了實現分散式跟蹤具備的基本要素。下面通過本文來詳細說說實現分散式服務跟蹤的一些要點。分散式系統中的服務跟蹤在理論上並不複雜,它主要包括下面兩個關鍵點:為了實現請求跟

中小型手機棋牌網路遊戲服務端架構設計原始碼

承接自己《中小型棋牌類網路遊戲服務端架構》博文,用Golang實現基礎架構邏輯後,準備再次談談我的想法。 已實現的邏輯與前文描述有幾點不同: 1. Gateway更名為Proxy,DBProxy更名為DB 2. Proxy同時持有與(Login, Game

java下載檔案案例原始碼

前言: web開發中上傳和下載是最基本的內容了。前幾天寫了一篇上傳的案例,今天總結一下下載。 案例說明: 1.本案例是使用myeclipse編寫 2.需要下載的檔案存放的 /download_demo/WebRoot/WEB-INF/attac

Spring Security 4 整合Hibernate 實現持久化登入驗證原始碼

【相關已翻譯的本系列其他文章,點選分類裡面的spring security 4】 本教程將使用Spring Security 4 和hibernate向你展示持久化登入驗證. 在持久化登入驗證中,應用通過session記住使用者特徵。 一般來說,在登入介面,當你

Spring 4 Hello World 例子原始碼

<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/P

Spring Security 4 整合Hibernate Bcrypt密碼加密原始碼

【相關已翻譯的本系列其他文章,點選分類裡面的spring security 4】 【 翻譯by 明明如月 QQ 605283073】 上一篇文章: Spring Security 4 Hibernate整合 註解和xml例子(帶原始碼) 本教程演示 使用 Spri

Android 實時濾鏡 高斯模糊原始碼

最近在做一個這樣一個需求,一個控制元件可以實時預覽攝像頭的內容,並且對此影象進行高斯模糊處理,現在來記錄一下。  基本的實現思路 1,攝像頭實時預覽的資料會回撥給onPreviewFrame(byte[] data, Camera camera) ,通過這個獲取YU

最簡單的直播禮物連刷特效製作原始碼

直播禮物連刷能有效的提升主播與使用者的互動,從而提升使用者刷禮物的數量,那現在咱們來做一個簡單的直播禮物連刷教程吧。 先貼出效果圖: 1. 首先從簡單的開始,文字描邊+連擊效果,這個比較簡單,只要重寫 UILabel 的 - (void)drawTextInRect:(

Spring MVC 4使用Servlet 3 MultiPartConfigElement實現檔案上傳原始碼

package com.websystique.springmvc.controller; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; impor

用Winform 利用多執行緒做的一個網站壓力測試小工具原始碼

我們一直在做網站,但在我河南這塊,對測試工作,特別是壓力測試一般都不怎麼在意,都是自己訪問一下速度不錯就行了,再就是資料庫訪問速度測試也是同樣情況 程式設計師在寫Sql程式碼時,一般是一個人寫完之後,一執行可快完事 其實這些是不夠的,我們根本沒有進行過多使用者多執行緒的測試,如果是100個,一千個要同時訪問,

Spring MVC 4 使用常規的fileupload上傳檔案原始碼

package com.websystique.springmvc.controller; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; impor

SSM框架下的分散式服務方案基於Dubbo+Zookeeper

原始碼https://github.com/wosyingjun/beauty_ssm_dubbo.git ###Dubbo服務的簡單應用及部署可以參見:DubboxDemo Maven(模組化構建) Spring(IOC DI AOP 宣告式事務處理) SpringMVC

Dubbo分散式服務框架入門實戰原始碼

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Dubbo分散式服務框架入門附工程

要想了解Dubbo是什麼,我們不防先了解它有什麼用。 使用場景:比如我想開發一個網上商城專案,這個網上商城呢,比較複雜,分為pc端web管理後臺,微信端銷售公眾號,那麼我們分成四個專案,pc端網站,微信端網站,還有一個後臺服務專案,介面服務專案。 對資料庫的