尝试搭建以zookeeper为注册中心是dubbo远程服务调用框架,同时解释一下常用的配置。
建立以下三个项目
api:提供公共的接口定义
cdemo:客户端demo
sdemo:服务端demo
下面是服务端和客户端都需要的一些依赖:
<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>
<dependency>
<groupId>com.garine</groupId>
<artifactId>garine-learn-dubbo-api</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/dubbo -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.1</version>
<!-- <exclusions>
<exclusion>
<artifactId>spring</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
</exclusions>-->
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.9</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.10</version>
</dependency>
<dependency>
<groupId>com.caucho</groupId>
<artifactId>hessian</artifactId>
<version>4.0.38</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty</artifactId>
<version>6.1.26</version>
</dependency>
</dependencies>
项目基于spring boot开发,采用基于xml的配置方式,使用@ImportResource注解导入配置xml文件
api定义一个接口Helloservice,sdemo编写实现类HelloServiceImpl
首先是sdemo的配置文件:
<?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:application name="dubbo-server" owner="garine"/>
<dubbo:registry id="zk1" address="zookeeper://192.168.0.15:2181"/>
<!--<dubbo:registry id="zk1" address="N/A"/>-->
<!-- 支持配置多协议服务 -->
<dubbo:protocol port="20880" name="dubbo"/>
<dubbo:protocol port="8081" name="hessian"/>
<dubbo:service interface= "com.garine.dubbo.api.HelloService" registry="zk1" protocol="dubbo" ref="helloService"/>
<bean id="helloService" class="com.garine.learn.dubbo.impl.HelloServiceImpl"/>
<dubbo:service interface= "com.garine.dubbo.api.HessianService" registry="zk1" protocol="hessian,dubbo" ref="hessianService"/>
<bean id="hessianService" class="com.garine.learn.dubbo.impl.HessianServiceImpl"/>
</beans>
需要注意的配置:
dubbo:registry是配置服务的注册中心地址,如果不注册服务到注册中心,可以这样配置
<dubbo:registry id="zk1" address="N/A"/>
dubbo:protocol配置服务接口支持的协议,可以配置多个,一个接口暴露服务时也支持多协议例如这里的hessianService
dubbo:service暴露服务的定义,其中有些配置需要注意:
1.timeout 服务端设置连接超时时间
配置好之后,在spring boot application启动点上使用注解导入xml文件@ImportResource(locations={“classpath:dubbo-server.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:application name="dubbo-client" owner="garine"/>
<!--注册中心集群,可用逗号分隔-->
<dubbo:registry address="zookeeper://192.168.0.15:2181?register=false" check="false" file="d:/dubbo-server-cache"/>
<!-- <dubbo:reference id="helloService"
interface="com.garine.dubbo.api.HelloService"
protocol="dubbo" url="dubbo://192.168.0.109:20880/com.garine.dubbo.api.HelloService"/>-->
<dubbo:reference id="helloService"
interface="com.garine.dubbo.api.HelloService"
protocol="dubbo" mock="com.garine.mock.TestMock" timeout="2" cluster="failsafe"/>
<dubbo:reference id="HessianService"
interface="com.garine.dubbo.api.HessianService"
protocol="hessian" cluster="failover"/>
</beans>
dubbo:registry中多了个配置check=”false”,这个配置表示客户端启动时不检查引用的服务是否可用。这样做的好处是当客户端也提供服务给sdemo引用时,如果启动检查服务是否可用,那么相互依赖必定有一方失败,所以false可以避免这种情况。
file=”d:/dubbo-server-cache”表示服务列表的地址信息缓存输出位置,对服务地址进行缓存可以避免每次服务调用都向注册中心获取服务地址信息。这里也可以不配置注册中心,只要我们知道服务的地址所在,一样可以访问服务
<dubbo:registry address="N/A"/>
<dubbo:reference id="helloService"
interface="com.garine.dubbo.api.HelloService"
protocol="dubbo" url="dubbo://192.168.0.109:20880/com.garine.dubbo.api.HelloService"/>
dubbo:reference 定义引用了哪个服务,这里需要注意的配置有
1.timeout客户端定义连接超时的时间
2.cluster定义服务调用失败的容错策略,例如超时时候怎么处理,共有六种策略
默认failover 自动重试其他服务2次
failsafe 吞掉异常
failfast 快速失败,调用失败就跑出异常
failback 失败后自动恢复,记录失败调用,然后定时重试
forking 并行调用服务,以成功调用的服务为准,forks设置并行数目
broadcast 广播,任意一个报错则报错
3.mock服务降级策略,保证核心服务可用,自定义写一个类实现当前的服务接口,当mock定义之后,服务调用失败,会自动mock中的对应方法,需要注意的是cluster的优先级高于mock,例如cluster可以用failsafe吞掉异常,导致mock不用执行。
配置的级别大概如下
1.一般是方法级别优先,然后是接口最后是全局配置
2.级别一样,那么就客户端配置优先
3.timeout 一般两边都可以配,但是谁来主控一般都是服务端
retries 重试是客户端关注的配置
loadblance 负载是客户端配置
cluster是客户端的配置
配置完成之后,引入xml文件@ImportResource(locations={“classpath:dubbo-client.xml”}),要使用helloService只需要从spring 容器获取即可。
搭建过程遇到的问题:
1.maven编译依赖子模块问题,编译过程一直报错,找不到api模块的HelloService,是pom.xml配置引起的
处理如下
1)中加入