1、生产者搭建html
新建一个maven工程,勾选Create a simple projectjava
Packaging方式选择jar包的方式。git
修改pom.xml文件:github
<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.shaw</groupId> <artifactId>provider</artifactId> <version>1.0.0</version> <properties> <spring.version>4.3.2.RELEASE</spring.version> </properties> <dependencies> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.5.3</version> <exclusions> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> <version>0.1</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> </dependencies> </project>
按照如图的方式,建立相关目录文件web
ProviderService.javaspring
package com.shaw.service; public interface ProviderService { public void sayHello(); }
ProviderServiceImpl.javaapache
package com.shaw.service.impl; import com.shaw.service.ProviderService; public class ProviderServiceImpl implements ProviderService{ @Override public void sayHello() { System.out.println("Hello!I am Provider!"); } }
TestProviderService.java编程
package com.shaw.service; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestProviderService { public static void main(String[] args) { ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext(new String[]{"application.xml"}); context.start(); System.out.println("生产者服务已经注册成功!"); try { System.in.read();//让此程序一直跑,表示一直提供服务 } catch (Exception e) { e.printStackTrace(); } } }
application.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 "> <!-- 具体的实现bean --> <bean id="providerService" class="com.shaw.service.impl.ProviderServiceImpl" /> <!-- 提供方应用信息,用于计算依赖关系 --> <dubbo:application name="provider" /> <!-- 使用zookeeper注册中心暴露服务地址 --> <dubbo:registry address="zookeeper://127.0.0.1:2181" /> <!-- 用dubbo协议在20880端口暴露服务 --> <dubbo:protocol name="dubbo" port="29014" /> <!-- 声明须要暴露的服务接口 --> <dubbo:service interface="com.shaw.service.ProviderService" ref="providerService" /> </beans>
按照以下步骤测试生产者:tomcat
一、启动zookeeper
二、启动tomcat 【一、2两点的相关搭建能够参考博主以前的博文《zookeeper环境及dubbo-admin管理平台搭建》】
三、右键TestProviderService类。
地址栏输入:http://localhost:8080/dubbo-admin-2.5.4/ 帐户密码为root/root。输入服务名称:com.shaw.service.ProviderService
至此,生产者搭建完成并提供服务了。
2、消费者搭建
按照搭建生产者的过程从新搭建一个consumer的工程:
工程目录以下:
TestConsumerService.java
package com.shaw.consumer; import java.io.IOException; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.shaw.service.ProviderService; public class TestConsumerService { public static void main(String[] args) { ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext(new String[]{"application.xml"}); context.start(); ProviderService testService = (ProviderService) context.getBean("testProviderService"); testService.sayHello(); try { System.in.read(); } catch (IOException e) { e.printStackTrace(); } } }
application.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="consumer" /> <!-- 使用multicast广播注册中心暴露发现服务地址 --> <dubbo:registry protocol="zookeeper" address="zookeeper://127.0.0.1:2181" /> <!-- 生成远程服务代理,能够和本地bean同样使用demoService --> <dubbo:reference id="testProviderService" interface="com.shaw.service.ProviderService" /> </beans>
消费者测试:
继续生产者的测试步骤不一样的是最后在TestConsumerService类右键。
控制台输入了生产者打印出来的信息:
同时登陆:http://localhost:8080/dubbo-admin-2.5.4/ 也能够查看相关消费者的服务信息如图:
3、相关dubbo配置信息
3.1 dubbo经常使用配置
<dubbo:service/> 服务配置,用于暴露一个服务,定义服务的元信息,一个服务能够用多个协议暴露,一个服务也能够注册到多个注册中心。 <dubbo:service ref="demoService" interface="com.unj.dubbotest.provider.DemoService" />
<dubbo:reference/> 引用服务配置,用于建立一个远程服务代理,一个引用能够指向多个注册中心。 <dubbo:reference id="demoService" interface="com.unj.dubbotest.provider.DemoService" />
<dubbo:protocol/> 协议配置,用于配置提供服务的协议信息,协议由提供方指定,消费方被动接受。 <dubbo:protocol name="dubbo" port="20880" />
<dubbo:application/> 应用配置,用于配置当前应用信息,无论该应用是提供者仍是消费者。 <dubbo:application name="xixi_provider" /> <dubbo:application name="hehe_consumer" />
<dubbo:registry/> 注册中心配置,用于配置链接注册中心相关信息。
<dubbo:registry address="zookeeper://127.0.0.1:2181" />
<dubbo:module/> 模块配置,用于配置当前模块信息,可选。 <dubbo:monitor/> 监控中心配置,用于配置链接监控中心相关信息,可选。 <dubbo:provider/> 提供方的缺省值,当ProtocolConfig和ServiceConfig某属性没有配置时,采用此缺省值,可选。 <dubbo:consumer/> 消费方缺省配置,当ReferenceConfig某属性没有配置时,采用此缺省值,可选。 <dubbo:method/> 方法配置,用于ServiceConfig和ReferenceConfig指定方法级的配置信息。 <dubbo:argument/> 用于指定方法参数配置。
3.2 服务调用超时设置
上图中以timeout为例,显示了配置的查找顺序,其它retries, loadbalance, actives也相似。
方法级优先,接口级次之,全局配置再次之。
若是级别同样,则消费方优先,提供方次之。
其中,服务提供方配置,经过URL经由注册中心传递给消费方。
建议由服务提供方设置超时,由于一个方法须要执行多长时间,服务提供方更清楚,若是一个消费方同时引用多个服务,就不须要关心每一个服务的超时设置。
理论上ReferenceConfig的非服务标识配置,在ConsumerConfig,ServiceConfig, ProviderConfig都可以缺省配置。
3.3 启动时检查
Dubbo缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止Spring初始化完成,以便上线时,能及早发现问题,默认check=true。
若是你的Spring容器是懒加载的,或者经过API编程延迟引用服务,请关闭check,不然服务临时不可用时,会抛出异常,拿到null引用,若是check=false,老是会返回引用,当服务恢复时,能自动连上。
能够经过check="false"关闭检查,好比,测试时,有些服务不关心,或者出现了循环依赖,必须有一方先启动。
1、关闭某个服务的启动时检查:(没有提供者时报错) <dubbo:reference interface="com.foo.BarService" check="false" /> 2、关闭全部服务的启动时检查:(没有提供者时报错) 写在定义服务消费者一方 <dubbo:consumer check="false" /> 3、关闭注册中心启动时检查:(注册订阅失败时报错) <dubbo:registry check="false" />
引用缺省是延迟初始化的,只有引用被注入到其它Bean,或被getBean()获取,才会初始化。
若是须要饥饿加载,即没有人引用也当即生成动态代理,能够配置:
<dubbo:reference interface="com.foo.BarService" init="true" />
3.4 订阅
一、问题
为方便开发测试,常常会在线下共用一个全部服务可用的注册中心,这时,若是一个正在开发中的服务提供者注册,可能会影响消费者不能正常运行。
二、解决方案
可让服务提供者开发方,只订阅服务(开发的服务可能依赖其它服务),而不注册正在开发的服务,经过直连测试正在开发的服务。
禁用注册配置: <dubbo:registry address="10.20.153.10:9090" register="false" /> 或者: <dubbo:registry address="10.20.153.10:9090?register=false" />
3.5 回声测试(测试服务是否可用)
回声测试用于检测服务是否可用,回声测试按照正常请求流程执行,可以测试整个调用是否通畅,可用于监控。
全部服务自动实现EchoService接口,只需将任意服务引用强制转型为EchoService,便可使用。
<dubbo:reference id="memberService" interface="com.xxx.MemberService" />
MemberService memberService = ctx.getBean("memberService"); // 远程服务引用 EchoService echoService = (EchoService) memberService; // 强制转型为EchoService String status = echoService.$echo("OK"); // 回声测试可用性 assert(status.equals("OK"))
3.6 延迟链接
延迟链接,用于减小长链接数,当有调用发起时,再建立长链接。
只对使用长链接的dubbo协议生效。
<dubbo:protocol name="dubbo" lazy="true" />
3.7 令牌验证
防止消费者绕过注册中心访问提供者,在注册中心控制权限,以决定要不要下发令牌给消费者,注册中心可灵活改变受权方式,而不需修改或升级提供者
1、全局设置开启令牌验证: <!--随机token令牌,使用UUID生成--> <dubbo:provider interface="com.foo.BarService" token="true" /> <!--固定token令牌,至关于密码--> <dubbo:provider interface="com.foo.BarService" token="123456" /> 2、服务级别设置开启令牌验证: <!--随机token令牌,使用UUID生成--> <dubbo:service interface="com.foo.BarService" token="true" /> <!--固定token令牌,至关于密码--> <dubbo:service interface="com.foo.BarService" token="123456" /> 3、协议级别设置开启令牌验证: <!--随机token令牌,使用UUID生成--> <dubbo:protocol name="dubbo" token="true" /> <!--固定token令牌,至关于密码--> <dubbo:protocol name="dubbo" token="123456" />
3.8 日志适配
缺省自动查找:log4j、slf4j、jcl、jdk
能够经过如下方式配置日志输出策略:dubbo:application logger="log4j"/>
访问日志:
若是你想记录每一次请求信息,可开启访问日志,相似于apache的访问日志。此日志量比较大,请注意磁盘容量。
将访问日志输出到当前应用的log4j日志: <dubbo:protocol accesslog="true" /> 将访问日志输出到指定文件: <dubbo:protocol accesslog="http://10.20.160.198/wiki/display/dubbo/foo/bar.log" />
3.9 配置Dubbo缓存文件
配置方法以下:
<dubbo:registryfile=”${user.home}/output/dubbo.cache” />
注意:
文件的路径,应用能够根据须要调整,保证这个文件不会在发布过程当中被清除。若是有多个应用进程注意不要使用同一个文件,避免内容被覆盖。
这个文件会缓存:
注册中心的列表
服务提供者列表
有了这项配置后,当应用重启过程当中,Dubbo注册中心不可用时则应用会从这个缓存文件读取服务提供者列表的信息,进一步保证应用可靠性。
本文代码下载:dubbo-provider-consumer