5分鐘實(shí)現(xiàn)SpringBoot整合Dubbo構(gòu)建分布式服務(wù)
概述:
Dubbo是Alibaba開源的分布式服務(wù)框架,它最大的特點(diǎn)是按照分層的方式來架構(gòu),使用這種方式可以使各個層之間解耦合(或者最大限度地松耦合)。從服務(wù)模型的角度來看,Dubbo采用的是一種非常簡單的模型,要么是提供方提供服務(wù),要么是消費(fèi)方消費(fèi)服務(wù),所以基于這一點(diǎn)可以抽象出服務(wù)提供方(Provider)和服務(wù)消費(fèi)方(Consumer)兩個角色。
我們來看一下Dubbo 的RPC 調(diào)用流程,這里主要涉及到4個模塊:
- Registry:服務(wù)注冊,我們一般會采取Zookeeper 作為我們的注冊中心
 - Provider:服務(wù)提供者(生產(chǎn)者),提供具體的服務(wù)實(shí)現(xiàn)
 - Consumer:消費(fèi)者,從注冊中心中訂閱服務(wù)
 - Monitor:監(jiān)控中心,RPC調(diào)用次數(shù)和調(diào)用時間監(jiān)控
 
從上圖中我們可以了解到整個RPC 服務(wù)調(diào)用的過程主要為:
- 生產(chǎn)者發(fā)布服務(wù)到服務(wù)注冊中心中
 - 消費(fèi)者在服務(wù)注冊中心中訂閱服務(wù)
 - 消費(fèi)者調(diào)用已經(jīng)注冊的服務(wù)
 
一、項(xiàng)目構(gòu)建
開發(fā)環(huán)境主要涉及以下幾個方面:
- Spring-boot
 - JDK 8
 - Dubbo
 - Zookeeper
 
項(xiàng)目構(gòu)建通過: http://start.spring.io/ 快速構(gòu)建web 項(xiàng)目,具體操作可以參考
http://www.cnblogs.com/jaycekon/p/7562688.html
由于Dubbo 中需要使用到服務(wù)注冊中心,我們這里將使用Zookeeper 作為服務(wù)注冊中心,具體安裝配置,可以參考
http://www.cnblogs.com/jaycekon/p/7553909.html
在基礎(chǔ)環(huán)境確定好了之后,我們項(xiàng)目的目錄結(jié)構(gòu)如下:
上圖所示,我們項(xiàng)目主要分為了兩個模塊,一部分是生產(chǎn)者:spring-boot-dubbo ,一部分是:spring-boot-consumer。
整個項(xiàng)目的結(jié)構(gòu)非常簡單,這很符合Spring-Boot 的特性,簡單便捷,下面我們開始一步步的剖析整個項(xiàng)目的結(jié)構(gòu)
二、Productor
2.1、Pom.xml
項(xiàng)目依賴這一塊主要使用到了基本的Spring-Boot-Web 依賴,然后我們需要額外引入Dubbo 與Zookeeper的依賴(詳細(xì)依賴可參考源碼,博文底部會有項(xiàng)目Github 地址):
- <dependency>
 - <groupId>io.dubbo.springboot</groupId>
 - <artifactId>spring-boot-starter-dubbo</artifactId>
 - <version>1.0.0</version>
 - </dependency>
 - <dependency>
 - <groupId>org.apache.zookeeper</groupId>
 - <artifactId>zookeeper</artifactId>
 - <version>3.4.6</version>
 - <exclusions>
 - <exclusion>
 - <groupId>org.slf4j</groupId>
 - <artifactId>slf4j-log4j12</artifactId>
 - </exclusion>
 - <exclusion>
 - <groupId>log4j</groupId>
 - <artifactId>log4j</artifactId>
 - </exclusion>
 - </exclusions>
 - </dependency>
 
2.2、配置文件
由于我們底層使用的是Spring-Boot 進(jìn)行開發(fā),那么我們就應(yīng)該善于利用Spring-Boot 給我們帶來的優(yōu)勢,因此我們可以直接在Application.properties 文件中配置Dubbo 服務(wù):
- ## Dubbo 服務(wù)提供者配置
 - spring.dubbo.application.name=provider --服務(wù)名稱
 - spring.dubbo.registry.address=zookeeper://127.0.0.1:2181 -- 注冊中心地址
 - spring.dubbo.protocol.name=dubbo -- dubbo 協(xié)議
 - spring.dubbo.protocol.port=20880
 - spring.dubbo.scan=com.jaycekon.dubbo.service --聲明需要暴露的服務(wù)接口
 
如果不采用Spring-Boot 進(jìn)行自動配置,大家可以參考一下的配置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">
 - <!-- 提供方應(yīng)用信息 -->
 - <dubbo:application name="provider" />
 - <!-- 注冊中心服務(wù)地址 -->
 - <dubbo:registry protocol="zookeeper" address="127.0.0.1" check="false" />
 - <!-- 用dubbo協(xié)議-->
 - <dubbo:protocol name="dubbo" port="-1" dispather="all" check="false" />
 - <dubbo:provider timeout="10000" threads="10" threadpool="fixed" loadbalance="roundrobin"/>
 - <!-- 聲明需要暴露的服務(wù)接口 -->
 - <dubbo:service interface="com.jaycekon.dubbo.service" ref="userService"/> </beans>
 
2.3、服務(wù)提供
在服務(wù)提供主要包括兩部分,一個是暴露服務(wù),一個是服務(wù)實(shí)現(xiàn)
暴露服務(wù):即我們平常開發(fā)中所使用的的接口,這里我們創(chuàng)建一個 UserService 的接口,主要包括一個保存用戶的方法。
- import com.jaycekon.dubbo.domain.User;
 - /**
 - * Created by Jaycekon on 2017/9/19.
 - */
 - public interface UserService {
 - User saveUser(User user);
 - }
 
服務(wù)實(shí)現(xiàn):服務(wù)實(shí)現(xiàn),與我們平常的服務(wù)一樣,對接口進(jìn)行實(shí)現(xiàn),比較特別的是,我們這里需要使用到Dubbo 的 @Service 注解。更多springboot實(shí)戰(zhàn)內(nèi)容,Java知音公眾號內(nèi)回復(fù)“springboot聚合”
- import com.alibaba.dubbo.config.annotation.Service;
 - import com.jaycekon.dubbo.domain.User;
 - import com.jaycekon.dubbo.service.UserService;
 - /**
 - * Created by Jaycekon on 2017/9/19.
 - */
 - @Service
 - public class UserServiceImpl implements UserService {
 - @Override
 - public User saveUser(User user) {
 - user.setId(1);
 - System.out.println(user.toString());
 - return user;
 - }
 - }
 
2.4、總體結(jié)構(gòu)
Dubbo 的服務(wù)提供端,已經(jīng)總體開發(fā)完成,非常簡單,總體的目錄結(jié)構(gòu)如下:
三、Consumer
3.1、pom.xml
消費(fèi)者的相關(guān)依賴,與生產(chǎn)者的依賴一致。
- <?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.jaycekon</groupId>
 - <artifactId>spring-boot-consumer</artifactId>
 - <version>0.0.1-SNAPSHOT</version>
 - <packaging>jar</packaging>
 - <name>spring-boot-consumer</name>
 - <description>Demo project for Spring Boot</description>
 - <parent>
 - <groupId>org.springframework.boot</groupId>
 - <artifactId>spring-boot-starter-parent</artifactId>
 - <version>1.5.7.RELEASE</version>
 - <relativePath/> <!-- lookup parent from repository -->
 - </parent>
 - <properties>
 - <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 - <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
 - <java.version>1.8</java.version>
 - </properties>
 - <dependencies>
 - <dependency>
 - <groupId>org.springframework.boot</groupId>
 - <artifactId>spring-boot-starter-web</artifactId>
 - </dependency>
 - <dependency>
 - <groupId>org.springframework.boot</groupId>
 - <artifactId>spring-boot-starter-test</artifactId>
 - <scope>test</scope>
 - </dependency>
 - <!-- Spring Boot Dubbo 依賴 -->
 - <dependency>
 - <groupId>io.dubbo.springboot</groupId>
 - <artifactId>spring-boot-starter-dubbo</artifactId>
 - <version>1.0.0</version>
 - </dependency>
 - <dependency>
 - <groupId>org.apache.zookeeper</groupId>
 - <artifactId>zookeeper</artifactId>
 - <version>3.4.6</version>
 - <exclusions>
 - <exclusion>
 - <groupId>org.slf4j</groupId>
 - <artifactId>slf4j-log4j12</artifactId>
 - </exclusion>
 - <exclusion>
 - <groupId>log4j</groupId>
 - <artifactId>log4j</artifactId>
 - </exclusion>
 - </exclusions>
 - </dependency>
 - <!-- mvn spring-boot:run 熱部署啟動 -->
 - <dependency>
 - <groupId>org.springframework</groupId>
 - <artifactId>springloaded</artifactId>
 - <version>1.2.3.RELEASE</version>
 - </dependency>
 - <dependency>
 - <groupId>org.projectlombok</groupId>
 - <artifactId>lombok</artifactId>
 - <version>1.16.18</version>
 - <scope>provided</scope>
 - </dependency>
 - </dependencies>
 - <build>
 - <plugins>
 - <plugin>
 - <groupId>org.springframework.boot</groupId>
 - <artifactId>spring-boot-maven-plugin</artifactId>
 - </plugin>
 - </plugins>
 - </build>
 - </project>
 
3.2、配置文件
配置文件與生產(chǎn)者稍有區(qū)別:
- ## 避免和 server 工程端口沖突
 - server.port=8081
 - ## Dubbo 服務(wù)消費(fèi)者配置
 - spring.dubbo.application.name=consumer
 - spring.dubbo.registry.address=zookeeper://127.0.0.1:2181
 - spring.dubbo.scan=com.jaycekon.dubbo.service
 
基于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">
 - <!-- 提供方應(yīng)用信息 -->
 - <dubbo:application name="provider" />
 - <!-- 注冊中心服務(wù)地址 -->
 - <dubbo:registry protocol="zookeeper" address="${dubbo.registry.address}" check="false" />
 - <!-- 用dubbo協(xié)議-->
 - <dubbo:protocol name="dubbo" port="-1" dispather="all" check="false" />
 - <dubbo:provider timeout="10000" threads="10" threadpool="fixed" loadbalance="roundrobin"/>
 - <!-- 聲明需要暴露的服務(wù)接口 -->
 - <dubbo:service interface="com.jaycekon.dubbo.service" ref="userService"/>
 - </beans>
 
3.3、服務(wù)實(shí)現(xiàn)
在這里,如果我們需要調(diào)用注冊服務(wù)中的相關(guān)服務(wù),則需要實(shí)現(xiàn)相關(guān)的接口。
- import com.jaycekon.dubbo.domain.User;
 - /**
 - * Created by Jaycekon on 2017/9/19.
 - */
 - public interface UserService {
 - User saveUser(User user);
 - }
 
例如,在這里我們需要使用到生產(chǎn)者中的 saveUser(User user) 方法,則需要創(chuàng)建一個接口,然后再調(diào)用時,使用 @Reference 注解進(jìn)行引用:
- import com.alibaba.dubbo.config.annotation.Reference;
 - import com.jaycekon.dubbo.domain.City;
 - import com.jaycekon.dubbo.domain.User;
 - import org.springframework.stereotype.Component;
 - /**
 - * 城市 Dubbo 服務(wù)消費(fèi)者
 - * <p>
 - * Created by Jaycekon on 20/09/2017.
 - */
 - @Component
 - public class CityDubboConsumerService {
 - @Reference
 - CityDubboService cityDubboService;
 - @Reference
 - UserService userService;
 - public void printCity() {
 - String cityName = "廣州";
 - City city = cityDubboService.findCityByName(cityName);
 - System.out.println(city.toString());
 - }
 - public User saveUser() {
 - User user = new User();
 - user.setUsername("jaycekon")
 - .setPassword("jaycekong824");
 - return userService.saveUser(user);
 - }
 - }
 
3.4、服務(wù)調(diào)用
最后,我們需要實(shí)現(xiàn)一個RESTful 接口,提供給用戶調(diào)用:
- import com.jaycekon.dubbo.service.CityDubboConsumerService;
 - import org.springframework.beans.factory.annotation.Autowired;
 - import org.springframework.web.bind.annotation.RequestMapping;
 - import org.springframework.web.bind.annotation.RestController;
 - /**
 - * Created by Jaycekon on 2017/9/19.
 - */
 - @RestController
 - public class UserController {
 - @Autowired
 - private CityDubboConsumerService service;
 - @RequestMapping("/save")
 - public Object saveUser() {
 - return service.saveUser();
 - }
 - }
 
3.5、目錄結(jié)構(gòu)
四、總結(jié)
本篇博客主要是博主在學(xué)習(xí)Spring-boot 的時候,總結(jié)下來的。在經(jīng)過一些列的對比后,感覺Dubbo 與Spring-Cloud 還是有點(diǎn)差距的,不管是從服務(wù)提供,還是社區(qū)活躍來說,Spring-Cloud 還是會強(qiáng)一點(diǎn)。但是由于公司內(nèi)部使用的是Dubbo,因此還是需要學(xué)習(xí)一下,后續(xù)的話,會對Spring-Cloud 進(jìn)行學(xué)習(xí)以及分項(xiàng)。
GitHub地址
https://github.com/jaycekon/SpringBoot


















 
 
 









 
 
 
 