Dubbo 是什么
- 一款分布式服务框架
- 高性能和透明化的RPC远程服务调用方案
- SOA服务治理方案
Dubbo 架构流程图
Provider:服务提供方
Consumer:服务消费者
Registry:注册中心
Monitor:统计服务调用次数和调用时间的监控中心
调用流程
0.启动服务提供者。
1.服务提供者在启动时,向注册中心注册自己提供的服务。
2.服务消费者在启动时,向注册中心订阅自己所需的服务。
3.注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
4.服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
5.服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
注册中心
服务提供方:针对所提供的服务到注册中心发布。
服务消费方:到服务中心订阅所需的服务。
对于任何一方,不论服务提供方或者服务消费方都有可能同时兼具两种角色,即需要提供服务也需要消费服务。
架构搭建案例开始
第一步:Zookeeper下载,安装,配置
1.1:下载:http://apache.fayea.com/zookeeper/ 一般选择稳定版本,我选的是3.4.9
1.2:然后解压到一个目录,打开conf目录copy一份zoo_sample.cfg文件,并重命名为zoo.cfg(必须是这个名字)
1.3:打开zoo.cfg,入手阶段基本不用做什么修改,唯一需要注意的是端口号,后面的dubbo 管理配置需要和这个保持一致(后面说)
1.4:找到bin目录下的 zKserver.cmd 启动zookeeper
这里zookeeper就OK了
第二步:下载,配置dubbo的管理项目
2.4 删除 tomcat webapp 目录下面的文件,将dubbo admin 包解压内容放到root目录中,修改classpath 目录下的dubbo.properties, 将这个监测中心注册到zookeeper,即将dubbo.registry.address改成你安装zookeeper的机子IP+zookeeper配置的端口。我这里是一台机子演示,默认端口与zookeeper是一致的所以不用修改。用户名密码就没有改动的必要了。
这里可以看到,提供者为0,消费者为0
第三步:创建提供者
3.1:创建两个maven项目,一个提供者,一个消费者 (dubbo_provider,dubbo_consuner)
service包,公用接口,很简单,就是个maven基础java包,不需要加入任何依赖,也不需要加入任何配置文件
<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.test</groupId>
<artifactId>service</artifactId>
<version>0.0.1-SNAPSHOT</version>
</project>
2个项目dubbo_provider包引入service依赖,且需要引入dubbo,zookeeper,log4依赖,这里不需要引入Spring,dubbo自带依赖,不过版本很旧,也可以自己手动移除然后引入新版本Spring。下面给出其中一个的pom实例,copy请自行修改artifactId
pom.xml:
<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.test</groupId>
<artifactId>dubbo_consumer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<spring.version>3.2.8.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<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>
package com.dubbo.service;
/**
* 功能概要:提供者service接口层
*
* @author zsq
* @since 2018年9月29日
*/
public interface HelloService {
public String sayHello(String name);
public String testDubbo(String name);
}
package com.dubbo.service.impl;
import com.dubbo.service.HelloService;
/**
* 功能概要:提供者service实现层
*
* @author zsq
* @since 2018年9月29日
*/
public class HelloServiceImpl implements HelloService {
public String sayHello(String name) {
return name + ", Hello dubbo provider111!";
}
public String testDubbo(String name) {
return name + ", test dubbo provider222!";
}
}
3.4:在resource资源包下创建相应的资源配置文件applicationProvider.xml和日志配置文件log4j.properties
applicationProvider.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="hello-provider" />
<!-- 使用zookeeper注册中心暴露服务地址,多个地址中间用,号隔开 ?backup=192.168.137.131:2181,192.168.137.132:2181 -->
<dubbo:registry address="zookeeper://127.0.0.1:2181" />
<!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="20881" />
<!-- 具体的实现bean -->
<bean id="helloservice" class="com.dubbo.service.impl.HelloServiceImpl" />
<bean id="helloDubbo" class="com.dubbo.service.impl.HelloDubboImpl" />
<!-- 声明需要暴露的服务接口 -->
<dubbo:service timeout="3000" interface="com.dubbo.service.HelloService" ref="helloservice"
cluster="failover" />
<dubbo:service timeout="3000" interface="com.dubbo.service.HelloDubbo" ref="helloDubbo"
retries="2" cluster="forking" />
<!--失败自动切换,当出现失败,重试其它服务器,通常用于读操作,但重试会带来更长延迟 ,可通过retries="2"来设置重试次数(不含第一次)。
默认就是failover,可以不写 ,包括(failfast/failback/forking) ,forks="2",并行调用多个服务器,只要一个成功即返回。
通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过它来设置最大并行数。 -->
<dubbo:reference interface=""></dubbo:reference>
</beans>
日志配置文件log4j.properties
# Global logging configuration\uff0c\u5efa\u8bae\u5f00\u53d1\u73af\u5883\u4e2d\u8981\u7528debug
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
注意:在创建applicationProvider.xml时,可能会出现dubbo.xsd不匹配报错的问题,需要手动引入外部的xsd文件
步骤:window-->preperence-->xml-->xml Catalog-->Add-->dubbo.xsd
3.5:在test包下创建HelloServiceTest.java类进行测试
package com.dubbo.service;
import java.io.IOException;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class HelloServiceTest {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
new String[]{"applicationProvider.xml"});
context.start();
System.out.println("服务注册成功");
try {
System.in.read();//让此程序一直跑,表示一直提供服务
} catch (IOException e) {
e.printStackTrace();
}
}
}
至此:服务提供者创建完成
成功启动之后,显示注册到了zookeeper。
这个时候我们刷新下dubbo.admin页面看看效果,显示提供者为2,说明一切正常
第四步:创建消费者
4.1:创建两个maven项目,一个提供者,一个消费者 (dubbo_provider,dubbo_consuner)
4.2:在dubbo_consumer项目中,引入项目的相关依赖,pom.xml
<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.test</groupId>
<artifactId>dubbo_consumer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<spring.version>3.2.8.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<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>
4.3:在service公共接口包下新建HelloService.java接口
package com.dubbo.service;
/**
* 功能概要:消费者service接口
*
* @author zsq
* @since 2018年9月29日
*/
public interface HelloService {
public String sayHello(String name);
public String testDubbo(String name);
}
4.4:在resouce资源包下创建相应的资源文件applicationConsumer.xml和日志文件log4j.properties
applicationConsumer.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="hello-consumer" />
<!-- 使用zookeeper注册中心暴露服务地址 -->
<dubbo:registry address="zookeeper://127.0.0.1:2181" />
<!-- 生成远程服务代理,可以和本地bean一样使用HelloService -->
<dubbo:reference id="helloService" interface="com.dubbo.service.HelloService" />
<dubbo:reference id="helloDubbo" interface="com.dubbo.service.HelloDubbo" />
</beans>
日志文件log4j.properties
# Global logging configuration\uff0c\u5efa\u8bae\u5f00\u53d1\u73af\u5883\u4e2d\u8981\u7528debug
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
4.5:在test测试包下创建HelloServiceConsumerTest.java测试文件
package com.dubbo.service;
import java.io.IOException;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class HelloServiceConsumerTest {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
new String[] { "applicationConsumer.xml" });
context.start();
HelloService providerService = (HelloService) context.getBean("helloService");
HelloDubbo providerDubbo=(HelloDubbo) context.getBean("helloDubbo");
System.out.println(providerService.sayHello("Tom"));
System.out.println(providerDubbo.sayDubbo("zookeeper+dubbo"));
try {
System.in.read();//让此程序一直跑
} catch (IOException e) {
e.printStackTrace();
}
}
}
至此,消费者的代码也书写完毕
成功启动测试文件后,
这个时候我们刷新下dubbo.admin页面看看效果,显示消费者为2,说明一切正常