一、Dubbo概述:
Apache Dubbo |ˈdʌbəʊ| 是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。
节点角色说明
节点 | 角色说明 |
---|---|
Provider | 暴露服务的服务提供方 |
Consumer | 调用远程服务的服务消费方 |
Registry | 服务注册与发现的注册中心 |
Monitor | 统计服务的调用次数和调用时间的监控中心 |
Container | 服务运行容器 |
调用关系说明
0.服务容器负责启动,加载,运行服务提供者。
- 服务提供者在启动时,向注册中心注册自己提供的服务。
- 服务消费者在启动时,向注册中心订阅自己所需的服务。
- 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
- 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
- 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
二、HelloWord 示例(使用Xml配置方式实现消费者工程与提供者工程调用)
在示例中我们将创建一个用户服务提供者工程,暴露一个根据用户id查询用户所有收货地址的接口。在消费者工程中进行调用。
2.1 创建公共接口类maven工程service-interface
工程结构如下:
2.1.1 接口工程 pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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.xiaohui.serviceinterface</groupId>
<artifactId>service-interface</artifactId>
<version>1.0</version>
<properties>
<lombok.version>1.18.10</lombok.version>
</properties>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
</dependencies>
</project>
2.1.2 公共接口类 UserService & OrderService 以及实体类 UserAddress
package com.xiaohui.service;
import com.xiaohui.domain.UserAddress;
import java.util.List;
public interface UserService {
/**
* 查询某个用户的全部地址
* @param userId
* @return
*/
public List<UserAddress> queryAllUserAddress(String userId);
}
package com.xiaohui.service;
import com.xiaohui.domain.UserAddress;
import java.util.List;
public interface OrderService {
public List<UserAddress> initOrder(String userId);
}
package com.xiaohui.domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserAddress implements Serializable {
private Integer id;
private String userAddress;
private String userId;
}
UserAddress 需要在网络通讯中传输,所以需要支持序列化,所以需要实现 java.io.Serializable 接口。
2.2 创建服务提供者 maven工程user-service-provider
工程目录结构如下:
2.2.1 修改pom.xml 依赖文件
<?xml version="1.0" encoding="UTF-8"?>
<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.xiaohui.userserviceprovider</groupId>
<artifactId>user-service-provider</artifactId>
<version>1.0</version>
<dependencies>
<!-- 公共接口类依赖 -->
<dependency>
<groupId>com.xiaohui.serviceinterface</groupId>
<artifactId>service-interface</artifactId>
<version>1.0</version>
</dependency>
<!-- dubbo 依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.7</version>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.11</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.32.Final</version>
</dependency>
</dependencies>
</project>
其中公共接口类依赖为2.1 步骤中创建的maven 模块
2.2.2 编写远程接口实现类 com.xiaohui.servive.impl.UserServiceImpl
package com.xiaohui.servive.impl;
import com.xiaohui.domain.UserAddress;
import com.xiaohui.service.UserService;
import java.util.ArrayList;
import java.util.List;
public class UserServiceImpl implements UserService {
public static List<UserAddress> address = new ArrayList<UserAddress>();
static{
address.add(new UserAddress(1,"西安市未央区阿房一路","10001"));
address.add(new UserAddress(2,"郑州市中原区冬青街","10002"));
}
public List<UserAddress> queryAllUserAddress(String userId) {
return address;
}
}
2.2.3 创建Spring配置文件并声明暴露服务(重点)
src/main/resources/applicationContext.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://dubbo.apache.org/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<!-- 提供方应用信息,用于计算依赖关系 -->
<dubbo:application name="user-service-provider" />
<!-- 使用zookeeper广播注册中心暴露服务地址 -->
<dubbo:registry address="zookeeper://172.18.230.184:2181" />
<!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="20880" />
<!-- 和本地bean一样实现服务 -->
<bean id="userService" class="com.xiaohui.servive.impl.UserServiceImpl" />
<!-- 声明需要暴露的服务接口 -->
<dubbo:service interface="com.xiaohui.service.UserService" ref="userService" />
</beans>
<dubbo:application /> :应用信息配置,服务消费者和提供者两个工程都需要进行配置。name 属性声明工程应用名称。(两个工程都配)
<dubbo:registry /> : 注册中心配置,指明服务提供者和消费者用于注册获取服务地址的注册中心类型地址信息。指定zookeeper的服务地址端口。(两个工程都配置)
<dubbo:protocol /> : 协议配置,用于配置提供服务的协议信息,协议由提供方指定,消费方被动接受。(提供方配置)
<dubbo:service /> : 服务配置,声明需要暴露的服务接口 ,interface为接口全路径,ref为指定接口执行的实现类 (提供方配置)
2.2.4 服务提供者启动类
package com.xiaohui.main;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException;
public class TestProvider {
public static void main(String[] args) throws IOException {
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
System.out.println("provider 服务启动成功");
System.in.read();
}
}
改测试类中我们加载了spring 配置文件,为了让提供方应用不停掉,我么使用System.in.read() 让服务方一直保持运行中。
2.3 创建服务消费者 maven工程order-service-consumer
工程目录如下:
2.3.1 修改pom.xml 文件
<?xml version="1.0" encoding="UTF-8"?>
<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.xiaohui.orderserviceconsumer</groupId>
<artifactId>order-service-consumer</artifactId>
<version>1.0</version>
<dependencies>
<dependency>
<groupId>com.xiaohui.serviceinterface</groupId>
<artifactId>service-interface</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.7</version>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.11</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.32.Final</version>
</dependency>
</dependencies>
</project>
消费者工程与服务提供者工程依赖一致,引入了公共接口依赖,以及dubbo和zk相关依赖。
2.3.2 编写接口调用类
com.xiaohui.service.impl.OrderServiceImpl,其中属性UserService 编写了其setter方法,使用Spring xml方式进行依赖注入。
package com.xiaohui.service.impl;
import com.xiaohui.domain.UserAddress;
import com.xiaohui.service.OrderService;
import com.xiaohui.service.UserService;
import java.util.List;
public class OrderServiceImpl implements OrderService {
private UserService userService;
public void setUserService(UserService userService) {
this.userService = userService;
}
public List<UserAddress> initOrder(String userId) {
return userService.queryAllUserAddress(userId);
}
}
2.3.3 编写spring配置文件application.properties
<?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://dubbo.apache.org/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<!-- 提供方应用信息,用于计算依赖关系 -->
<dubbo:application name="order-service-consumer" />
<!-- 使用zookeeper广播注册中心暴露服务地址 -->
<dubbo:registry address="zookeeper://172.18.230.184:2181" />
<!-- 引用配置: 创建一个远程服务代理,一个引用可以指向多个注册中心 -->
<dubbo:reference id="userService" interface="com.xiaohui.service.UserService"></dubbo:reference>
<!-- orderService -->
<bean class="com.xiaohui.service.impl.OrderServiceImpl">
<property name="userService" ref="userService"></property>
</bean>
</beans>
application:配置应用相关信息
registry: 配置注册中心信息,指定zookeeper的服务地址端口
<dubbo:reference > :引用配置,用于创建一个远程服务代理,一个引用可以指向多个注册中心。
2.3.4 消费者测试类
package com.xiaohui.test;
import com.xiaohui.domain.UserAddress;
import com.xiaohui.service.OrderService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException;
import java.util.List;
public class TestConsumer {
public static void main(String[] args) throws IOException {
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
OrderService orderService = context.getBean(OrderService.class);
List<UserAddress> list = orderService.initOrder("zhang san");
for (UserAddress address : list) {
System.out.println(address.getUserId()+"---"+address.getUserAddress());
}
// System.in.read();
}
}
2.4 启动测试验证
zookeepe 服务验证
保证zookeeper服务启动正常,再启动服务提供者工程,待控制台打印出“provider 服务启动成功”。
我们登录 dubbo-admin 控制台(参考Dubbo(二) Dubbo管理控制台dubbo-admin搭建),查看服务提供者可以看到应用列表以及提供者信息。
接着我们再启动 消费者工程:
为了演示,在消费者测试类最后加上 System.in.read();让消费者工程继续保持运行中,我们在应用列表和服务消费者中可以看到消费者工程信息。