目录
一:Dubbo的介绍
二:SpringBoot搭建多模块项目
三:Windows下配置Zookeeper–作为Dubbo的服务注册中心
四:Dubbo与SpringBoot的集成
一:Dubbo的介绍
随着微服务架构的兴起,人们越来越推崇将服务解耦,一般都是根据业务进行服务的划分,希望每个服务之间能够独立运行,相互之间可以相互调用,达到服务分布式部署的目的。 Dubbo作为一个远程服务调用(RPC)的分布式框架,能够很好的实现面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。
二:SpringBoot搭建多模块项目
Dubbo在使用时,需要使用到服务的提供者(provider),消费者(consumer)以及注册中心(registry)等,所以在使用时,希望将提供者和消费者模块放在一个项目中,注册中心通过zookeeper实现,在第三部分中介绍,而多模块项目刚好可以满足这种需求,所以我们需要先基于SpringBoot搭建一个多模块的项目。
项目结构:
模块说明:
(1) dubbo-interface:定义了一些常见的接口,作为公共模块,可以被其他模块继承。
(2) dubbo-consumer:作为消费者,调用远程服务的服务消费方。
(3) dubbo-provider:暴露服务的服务提供方。
多模块搭建步骤:
第一步:
定义父模块,即本项目最外层的Dubbo,在父模块的pom文件中,声明三个子模块,并添加依赖管理。
声明三个子模块:
定义三个子模块的依赖管理:
第二步:
创建各个子模块,每个子模块都是一个独立的SpringBoot模块,都可以独立打包、运行,模块之间的依赖关系如下,consumer依赖provider,provider依赖interface,下面演示一个模块的创建,另外两个模块类似。
在父模块下,新建module:
选择SpringBoot模板,按照图中提示一步步执行即可:
最后,点击Finish即可完成interface子模块的创建,其他两个模块的创建过程相同,这里就不逐个演示了。
第三步:各个模块之间的依赖关系的建立
通过上面的介绍,我们知道各个模块之间的依赖关系是:consumer依赖provider,provider依赖interface,所以,我们需要在每个模块的pom文件中,配置彼此之间的依赖关系。例如:provider依赖interface,我们需要在provider中添加对interface父模块的依赖,如下图所示:
这里,需要注意的是,在parent的relativePath中,一定要找到父模块的pom文件,否则在打包时会报错。consumer模块和provider模块之间的依赖关系和上述的类似,这里也不再赘述了。
在打包时,我们需要注意在pom文件中,下面依赖的作用:
<!---->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
该依赖表示,该模块可以打包运行,生成一个可执行的jar包,而我们的interface模块仅仅是作为公共模块,用来本其他模块所依赖,不需要生成可执行的jar,只需要生成一个可以被provider所依赖的jar包即可,所以我们需要在interface模块中,跳过该依赖,如下代码所示:
<!---->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
另外,provider和consumer模块需要生成可执行的jar,所以,要添加对该插件的支持,除此之外,还需要指定打包时的启动类。如下代码所示:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.soyuan.dubboprovider.DubboProviderApplication</mainClass>
</configuration>
</plugin>
</plugins>
</build>
除此之外,这里还有一个坑需要注意,就是在打包时,由于我们最后需要得到provider和consumer的可执行jar包,但是这三个模块之间存在依赖关系,当我们想得到一个provider的可执行的jar时,我们需要进入到provider的目录文件下,执行mvn clean package -DskipTests=true命令,但是,此时会出现报错,错误是:找不到dubbo-interface的jar包!还记得我们之前的模块依赖关系么,想到这里也就清楚了,我们需要进入interface目录下,将该模块打包,便于provider模块依赖;consumer和provder之间的关系也是类似的!
1.先在interface目录下打包,并将该模块的打包方式由pom改为jar:
2.然后在provider目录下打包,,将interface模块的打包方式改为pom,将provider模块的打包方式改为jar,打包成功后,在由jar改为pom:
给consumer模块打包时,操作类似,到这里,我们的多模块项目也就搭建完成了。
三:Windows配置Zookeeper–作为Dubbo的服务注册中心以及监控中心页面的配置
第一步:Windows下安装zookeeper
准备好zookeeper的压缩包之后,将压缩包解压到指定文件夹,解压后进入zookeeper的conf文件夹修改zoo-simple.cfg 为 zoo.cfg,因为zookeeper在启动时,会加载该配置文件。之后进入到bin目录下,点击zkServer.cmd,即可以启动zookeeper。
当出现如下界面时,就表示zookeeper注册中心已经搭建成功,是不是很简单?
第二步:配置zookeeper监控中心页面
当注册中心搭建完成后,我们期望能够看到所有的服务提供者和消费者,这里我们可以通过配置监控中心来实现!!!
监控中心其实就是一个war包,可以在网上下载,这里我的版本是我的版本是dubbo-admin-2.5.4.war,大家可以在网上下载到,解压后放到tomcat安装处的webapps下!
这里注意,如果监控中心与注册中心在同一台服务器上,可以不需要任何配置。如果不在同一台,则需要修改解压文件后的WEB-INF下的dubbo.properties文件,这里的ip地址就需要修改了。
dubbo.registry.address=zookeeper://127.0.0.1:2181
启动Tomcat,输入网址 http://localhost:8080/dubbo-admin-2.5.4-jdk1.8/,当看到如下界面时,就说明监控中心配置成功!
这里记录一个我在配置该页面时碰到的一个问题,当我输入网址后,访问默认跳到jenkins的登录页面,一开始摸不到头脑,最后想起来,查看端口的占用情况,将8080端口关闭之后,重新启动,再次访问,页面就出来了,这里是由于端口被占用造成的!
四:Dubbo与SpringBoot的集成
通过上面,我们已经将项目搭建完成,并且,注册中心和监控中心也配置成功,接下来我们就看下SpringBoot与Dubbo的集成,我就在刚才搭建的项目里,添加一个服务提供者和服务消费者,来演示整个流程!
第一步:添加服务提供者(Provider)
还记得我们的三个模块么,其中interface作为公共模块,被其他模块依赖,这里我们在interface模块中定义了两个公共接口类,IDubboService和IDubboTestService,我们在provider模块中继承这两个接口,并且实现它!如下图所示:
接下来,在pom中添加Dubbo依赖以及配置yml:
<!-- dubbo -->
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>0.2.0</version>
</dependency>
<!-- zookeeper -->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.8</version>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
<exclusion>
<artifactId>log4j</artifactId>
<groupId>log4j</groupId>
</exclusion>
<exclusion>
<artifactId>slf4j-log4j12</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
这里需要注意的是:在引入的zookeep包中,会存在日志包冲突的问题,需要去除对相关日志包的依赖!
yml文件的配置:
server:
port: 8090 #provider模块的启动端口
dubbo:
application:
name: dubbo-provider #项目名称
registry:
address: 127.0.0.1:2181 #注册中心地址 在不同的机器时,需要做相应的修改
protocol: zookeeper
protocol:
name: dubbo
port: 20880 #提供者的服务端口,默认为20880
monitor:
protocol: registry #监控中心配置
provider:
host: 192.168.107.100 #提供者服务地址
上述配置完成后,我们在两个接口的实现类中,声明服务,使用@Service注解来声明,这是一个提供者服务!由于两个实现类的相似度很高,所以这里只展示一个,如下图所示:
这里需要注意的是:使用的@Service注解不是SpringBoot包的,而是Dubbo包中的!
最后,我们启动provider模块,进入注册中心页面,就可以看到我们新增的两个提供者服务!如下图所示:
至此,提供者服务就配置完成!
第二步:添加消费者服务(Consumer)
在consumer模块中,只需要配置yml文件即可,为什么不需要配置pom文件?还记得我们之前的模块的依赖关系么,consumer模块依赖于provider模块,所以,在依赖上也存在相应的依赖传递关系,不需要重复引入依赖了!这也是多模块的一个好处!
yml配置:
server:
port: 8081 #为了不和提供者端口冲突,一定要保证端口不冲突
dubbo:
application:
name: dubbo-consumer
#配置的是注册中心的地址
registry:
address: zookeeper://127.0.0.1:2181 #注册中心地址
monitor:
protocol: registry #监控中心
这里,我们也可以重新实现IDubboService接口,在这里我们可以使用 @Reference代替@Autowired注解 用于注入其他服务类,来实现相关相关逻辑处理,如下面代码所示:
package com.soyuan.dubboconsumer.impl;
import com.alibaba.dubbo.config.annotation.Reference;
import com.soyuan.dubbointerface.service.IDubboService;
import com.soyuan.dubbointerface.service.IDubboTestService;
import org.springframework.stereotype.Service;
@Service
public class DubboServiceImpl implements IDubboService {
/**
* 使用 @Reference代替@Autowired注解 用于注入其他服务类
*/
@Reference
private IDubboTestService dubboService;
@Override
public String sayHello(String name) {
String test = dubboService.sayTest("test");
return "这是在DubboService中引入了DubboTestService服务!"+test;
}
}
在这里,我们重写了IDubboService的sayHello方法,并且,在其中引入了IDubboTestService服务!
接下来,我们定义一个控制器,设计一个简单的接口用于测试,如下面代码所示:
package com.soyuan.dubboconsumer.controller;
import com.soyuan.dubbointerface.service.IDubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DubboController {
@Autowired
IDubboService dubboService;
@RequestMapping("/say")
public String sayHello(@RequestParam String name){
return dubboService.sayHello(name);
}
}
上面的配置都完成之后,我们启动consumer模块,并且到监控中心中查看,就可以看到我们新增的消费者,如下图所示:
最后,我们访问刚才我们定义的接口:http://localhost:8081/say?name=fuxy 出现下图所示,就表示消费者服务已经成功!
总结:
好好撸码,永不脱发!最后,分享一下我最近一直在听的一首歌:Your Man - - Josh Turner