今天咱们来看看怎么利用Spring Boot整合Dubbox来开发去中心化的微服务。
本文基于Jdk1.8/Maven 3.3.9/Spring Boot 1.4.2.RELEASE/Dubbo 2.8.5.SNAPSHOT(Dubbox后续开源版本)/ZooKeeper3.4.8
wget http://mirrors.hust.edu.cn/apache/zookeeper/zookeeper-3.4.8/
tar -zxf zookeeper-3.4.8.tar.gz
cd zookeeper-3.4.8/conf
cp zoo_sample.cfg zoo.cfg # zookeeper 默认是用../conf/zoo.cfg 如果没有这个文件则报错
vim zoo.cfg
好吧 我们不改了,我们使用默认的配置.哈!
cd zookeeper-3.4.8/bin
./start.sh start #启动zookeeper 关闭: ./start.sh stop
zookeeper准备好了,先放着 一会再用.下面我们来准备下Dubbox.
dubbox是当当网基于dubbo开源的组件
为什么使用dubbox?
因为dubbox支持更新的spring版本…
Dubbox在maven中央仓库并没有对应的依赖,所以我们需要自己动手将其发布到我们的本地仓库来使用.
我们这次从码云下载
git clone https://git.oschina.net/wuyu15255872976/dubbox.git
cd dubbox
mvn clean install -Dmaven.test.skip
等待 … 等待…
之后我们在我们的maven本地仓库/com/alibaba/dubbo/2.8.5-SNAPSHOT中会发现这么一个东西:
dubbo-2.8.5-SNAPSHOT.jar
这个玩意就是我们需要的Dubbx的jar包…
dubbox的jar包准备好了,行,咱先放着.一会再用.
下面来介绍下spring-boot-starter-dubbo项目的准备.
我们可能以前在使用dubbo的时候都是用的xml配置.在整合Spring Boot的时候呢是用的@ImportResource
注解来引入的dubbo的xml配置.
但是Spring Boot本身并不推荐xml配置.怎么解决这个矛盾,我们可以自己准备一个Spring Boot Starter dubbo的项目来引导Spring Boot对Dubbo的自动化配置.
git clone https://git.oschina.net/wuyu15255872976/spring-boot-starter-dubbo.git
感谢这位悲伤的大神的开源贡献!. 顶一个,赞两个.
option
都是true
,我懒所以我想在其他项目依赖这个项目的时候不要再写一遍,所以我把
都给干掉了…… 干不干掉这个倒是随意哈.dubbo
的版本为2.8.5-SNAPSHOT
完整pom.xml文件如下:
4.0.0
org.springframework.boot
spring-boot-starter-parent
1.4.2.RELEASE
spring-boot-starter-dubbo
1.4.2.RELEASE
Spring Boot Dubbo Rpc
Spring Boot Dubbo Rpc
http://projects.spring.io/spring-boot/
Pivotal Software, Inc.
http://www.spring.io
UTF-8
1.8
org.springframework.boot
spring-boot-actuator
org.springframework.boot
spring-boot-configuration-processor
com.alibaba
dubbo
2.8.5-SNAPSHOT
spring
org.springframework
com.github.sgroschupf
zkclient
0.1
org.springframework.boot
spring-boot-dependencies
1.4.2.RELEASE
pom
import
maven-source-plugin
true
compile
jar
上面我们对于spring-boot-starter-dubbo的准备工作完成,我们现在打包编译
mvn clean install -Dmaven.test.skip
然后我们去maven本地仓库中找到它:
xxx/org/springframework/boot/spring-boot-starter-dubbo/1.4.2.RELEASE/spring-boot-starter-dubbo-1.4.2.RELEASE.jar
这里我们使用韩都衣舍马老师提供的dubbo-monitor
git clone https://git.oschina.net/handu/dubbo-monitor.git
根据项目README.MD我们先创建一个叫monitor
的数据库,然后maven打包运行,我们也可以导入到IDE中直接运行,当然生产环境我们不能这么干.
我们的home页面:
一会儿我们需要在这里验证我们的provider和consumer是否已经成功.
基本工作已经准备妥当,我们来看下我们怎么使用它.
首先我们来看一下整个maven项目的目录结构:
business
--consumer
----pom.xml
----src/main/java
--provier
----pom.xml
----src/main/java
--service
----src/main/java
--pom.xml
service是提供domain和接口service的项目
为什么要单独把service
建module
呢?
因为我们写的service(java interface)
和domain(java bean)
是需要在consumer和provider
端共享的.
单独打成jar包有利用我们的代码重用和序列化反序列化
.
基本结构介绍完成,下面我们分每一个模块来详细探讨.
既然business作为maven父项目,就做点它应该干的事.
4.0.0
cn.veryjava
business
pom
1.0
business
business
veryjava
http://blog.veryjava.cn
sunshineasbefore
[email protected]
UTF-8
UTF-8
1.8
1.4.2.RELEASE
1.4.2.RELEASE
org.springframework.boot
spring-boot-starter-parent
1.4.2.RELEASE
service
provider
consumer
org.springframework.boot
spring-boot-starter-web
${spring-boot.version}
true
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-starter-dubbo
${spring-boot-dubbo.version}
true
在其中我们引入spring-boot-starter-parent
spring-boot-starter-web
spring-boot-starter-test
spring-boot-starter-dubbo
,其中除了spring-boot-starter-parent
我们定义其他依赖都可选.
没了…
service子项目提供domain和service接口.
business
cn.veryjava
1.0
jar
4.0.0
service
定义一下parent
和artifactId
完事.
package cn.veryjava.business.domain;
import java.io.Serializable;
public class BusinessDomain implements Serializable{
private int id;
private String name;
public BusinessDomain(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
定义我们需要在provider和consumer中使用的domain,实现java.io.Serializable来进行序列化.
dubbo支持的序列化方式很多,这个可以参考dubbo.io里关于协议和序列化的介绍,我们使用默认的协议dubbo
.
package cn.veryjava.business.service;
import cn.veryjava.business.domain.BusinessDomain;
public interface BusinessService {
BusinessDomain findBusiness(int id, String name);
}
定义我们需要在provider和consumer中使用的接口方法.
我们的服务提供者.
business
cn.veryjava
1.0
4.0.0
provider
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-dubbo
${spring-boot-dubbo.version}
cn.veryjava
service
1.0
定义parent
和artifactId
并引入spring-boot-starter-web
spring-boot-starter-dubbo
service
依赖.
server:
port: 8081
spring:
dubbo:
application:
name: business-provider
registry:
protocol: zookeeper
address: localhost:2181,192.168.2.23:2181
protocol:
name: dubbo
port: 20880
host: localhost
scan: cn.veryjava.business.provider
定义我们的dubbo配置.
服务注册发现使用zookeeper
.协议使用dubbo
,包扫描路径写cn.veryjava.business.provider
package cn.veryjava.business.provider;
import com.alibaba.boot.dubbo.EnableDubboAutoConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@EnableDubboAutoConfiguration
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}
这是我们服务提供者的引导类.重点是@EnableDubboAutoConfiguration
这个注解将引导我们自动化配置dubbox
package cn.veryjava.business.provider;
import cn.veryjava.business.domain.BusinessDomain;
import cn.veryjava.business.service.BusinessService;
import com.alibaba.dubbo.config.annotation.Service;
@Service(version = "1.0.0")
public class BusinessServiceImpl implements BusinessService {
@Override
public BusinessDomain findBusiness(int id, String name) {
return new BusinessDomain(id,name);
}
}
这个是我们需要提供的服务,重点是@Service
这个注解,需要注意的是此@Service
非彼@Service
.
我们在这个地方使用的@Service
是dubbo提供的,注意看import部分.然后,dubbo的springBoot自动化配置会自动发现这个类并将其注册到zookeeper.
当然我们使用spring提供的@Service
也是可以的,不过这种方式比较麻烦.这个地方我们就不介绍了,有想了解的同学可以去dubbo.io去详细了解
代码写好了,服务提供了,我们来验证下我们提供的服务是否能够成功注册并被发现.
启动后我们打开dubbo-monitor
的Services
页面,如果看到如下情况,则证明我们的服务已经注册成功:
注意观察其中cn.veryjava.business.service.BusinessService
我们发现这个时候的BusinessService
已经被提供但是还没有相应的消费者来使用.那么我们接下来看一下消费者怎么去使用.
这个是我们的服务消费者
business
cn.veryjava
1.0
4.0.0
consumer
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-dubbo
${spring-boot-dubbo.version}
cn.veryjava
service
1.0
定义parent
artifactId
并引入spring-boot-starter-web
spring-boot-starter-dubbo
service
依赖.
server:
port: 8777
spring:
dubbo:
application:
name: business-consumer
registry:
protocol: zookeeper
address: localhost:2181,192.168.2.23:2181
protocol:
name: dubbo
port: 20880
host: localhost
scan: cn.veryjava.business.consumer.controller
实测 不写scan
不行,可能是我刚开始理解有问题….我刚开始以为scan
只是用来进行服务发现的,结果跟消费者进行消费也有关系…
package cn.veryjava.business.consumer;
import com.alibaba.boot.dubbo.EnableDubboAutoConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@EnableDubboAutoConfiguration
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}
服务消费者引导类,@EnableDubboAutoConfiguration
注解也得写,原因同上.
package cn.veryjava.business.consumer.controller;
import cn.veryjava.business.domain.BusinessDomain;
import cn.veryjava.business.service.BusinessService;
import com.alibaba.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class BusinessConsumerController {
@Reference(version = "1.0.0")
public BusinessService businessService;
@RequestMapping("/business")
@ResponseBody
public BusinessDomain getBusiness() {
return businessService.findBusiness(1, "businessaaa");
}
}
我们的BusinessService
服务是怎么被消费的,怎么被依赖的.其实就是使用了dubbo提供的@Reference
注解… 告诉dubbo我要使用哪个版本服务,就是这么简单….
我们来测一下dubbo-monitor
能否监控到服务的消费者吧.
启动后我们打开dubbo-monitor
的Services
页面,如果看到如下情况,则证明我们的服务已经注册成功并且消费者已经能够发现:
然后我们调用一下这个接口,看看到底是不是我们想要的数据.
curl -L http://localhost:8777/business
输出如下:
{"id":1,"name":"businessaaa"}
好吧,到这一步,我们的服务发现和服务消费都可以成功了.
我们发现,dubbo的使用还是很简单的,几乎没有任何的侵入性,也非常符合Spring的IOC/DI
的理论概念.可以说跟spring的结合非常完美!
我们的这个小项目,仅仅只是用来学习的小项目,不过我们可以在此基础上对zookeeper,对各个provider/consumer进行集群配置.这样我们就可以慢慢实现后台服务的去中心化,很大程度上提高了我们架构的可用性.
希望各位在Java的路上越走越好.!
springboot整合dubbox的实例一枚
springboot整合dubbox的实例一枚