1、RPC简介
RPC【Remote Procedure Call】是指远程过程调用,是一种进程间通信方式,他是一种技术的思想,而不是规范。它允许程序调用另一个地址空间(通常是共享网络的另一台机器上)的过程或函数,而不用程序员显式编码这个远程调用的细节。即程序员无论是调用本地的还是远程的函数,本质上编写的调用代码基本相同。
2、Dubbo
Apache Dubbo (incubating) |ˈdʌbəʊ| 是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。
官网原理图:
Dubbo 中文官网:http://dubbo.apache.org/zh-cn/
3、Zookeeper
Zookeeper 是 Apacahe Hadoop 的子项目,是一个树型的目录服务,支持变更推送,适合作为 Dubbo 服务的注册中心,工业强度较高,可用于生产环境,并推荐使用 [1]。
4、安装Zookeeper 和 Dubbo控制台
1)、下载zookeeper
网址 https://archive.apache.org/dist/zookeeper/zookeeper-3.4.13/
2)、解压zookeeper
3)、将conf下的zoo_sample.cfg复制一份改名为zoo.cfg即可。
注意几个重要位置:
dataDir=./ 临时数据存储的目录(可写相对路径)
clientPort=2181 zookeeper的端口号
修改完成后cmd运行zkServer.cmd
4)、下载dubbo-admin:链接 https://github.com/apache/incubator-dubbo-ops
5)、解压进入dubbo-admin 项目,一个springboot 项目,修改配置文件中的zookeeper连接地址
6)、打包运行:进入项目目录 mvn clean package
7)、打包成jar后 进入target目录 java -jar dubbo-admin-0.0.1-SNAPSHOT.jar
8)、查看项目启动在什么端口,浏览器输入运行即可,账号和密码为root
注:zookeeper服务要先启动起来。
5、项目搭建
1)、创建公共接口项目:rpc-common
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>
<artifactId>rpc-common</artifactId>
</project>
实体类,注:实现远程调用要实现 Serializable 接口
package com.rpc.bean;
import java.io.Serializable;
import java.util.Date;
/**
* @author WDG
* @date 2019-2-14
*/
public class User implements Serializable {
private String userId;
private String address;
private Date birth;
private String username;
//setter and getter...
@Override
public String toString() {
return "User{" +
"userId='" + userId + '\'' +
", address='" + address + '\'' +
", birth=" + birth +
", username='" + username + '\'' +
'}';
}
}
服务提供者接口 UserService.java:
package com.rpc.service;
import com.rpc.bean.User;
/**
* @author WDG
* @date 2019-2-14
* 用户服务接口
*/
public interface UserService {
User getInfo(String userId);
}
服务消费者接口:
package com.rpc.service;
import com.rpc.bean.User;
/**
* @author WDG
* @date 2019-2-14
*/
public interface ConsumerService {
User getUser();
}
2)、创建服务提供者项目 rpc-provide:
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">
<parent>
<artifactId>rpcparent</artifactId>
<groupId>rpcdemo</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>rpc-provide</artifactId>
<dependencies>
<!--引入公共依赖-->
<dependency>
<groupId>rpcdemo</groupId>
<artifactId>rpc-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- 引入dubbo -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.2</version>
</dependency>
<!-- 由于我们使用zookeeper作为注册中心,所以需要操作zookeeper
dubbo 2.6以前的版本引入zkclient操作zookeeper
dubbo 2.6及以后的版本引入curator操作zookeeper
下面两个zk客户端根据dubbo版本2选1即可
-->
<!-- curator-framework -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.12.0</version>
</dependency>
</dependencies>
</project>
服务提供方实现类:UserServiceImpl.java
package com.rpc.service.impl;
import com.rpc.bean.User;
import com.rpc.service.UserService;
import java.util.Date;
/**
* @author WDG
* @date 2019-2-14
*/
public class UserServiceImpl implements UserService {
public User getInfo(String userId) {
System.out.println("获得参数:"+userId);
User user = new User();
user.setUserId(userId);
user.setAddress("中国大陆");
user.setUsername("jack");
user.setBirth(new Date());
return user;
}
}
classpath下创建配置文件:provide.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="rpc-provide" />
<!-- 使用zookeeper注册中心暴露服务地址 -->
<dubbo:registry address="zookeeper://127.0.0.1:2181" />
<!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="20880" />
<!-- 声明需要暴露的服务接口 -->
<dubbo:service interface="com.rpc.service.UserService" ref="userService" />
<!-- 和本地bean一样实现服务 -->
<bean id="userService" class="com.rpc.service.impl.UserServiceImpl" />
</beans>
创建启动入口测试服务注册 RunApplication.java:
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException;
/**
* @author WDG
* @date 2019-2-14
*/
public class RunApplication {
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("provide.xml");
applicationContext.start();
//阻塞进程
System.in.read();
}
}
运行程序后 在dubbo控制台查看服务表明注册成功:
3)、搭建服务消费者项目:
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">
<parent>
<artifactId>rpcparent</artifactId>
<groupId>rpcdemo</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>rpc-consumer</artifactId>
<dependencies>
<dependency>
<groupId>rpcdemo</groupId>
<artifactId>rpc-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- 引入dubbo -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.2</version>
</dependency>
<!-- 由于我们使用zookeeper作为注册中心,所以需要操作zookeeper
dubbo 2.6以前的版本引入zkclient操作zookeeper
dubbo 2.6及以后的版本引入curator操作zookeeper
下面两个zk客户端根据dubbo版本2选1即可
-->
<!-- curator-framework -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.12.0</version>
</dependency>
</dependencies>
</project>
服务消费者实现类:ConsumerServiceImpl.java
package com.rpc.service.impl;
import com.alibaba.dubbo.config.annotation.Reference;
import com.rpc.bean.User;
import com.rpc.service.ConsumerService;
import com.rpc.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author WDG
* @date 2019-2-14
* 服务消费者实现类
*/
@Service
public class ConsumerServiceImpl implements ConsumerService {
@Autowired
private UserService userService;
public User getUser() {
return userService.getInfo("123243");
}
}
classpath目录下配置消费者 consumer.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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<context:component-scan base-package="com.rpc.service.impl" ></context:component-scan>
<!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
<dubbo:application name="rpc-consumer" />
<!-- 使用zookeeper注册中心暴露发现服务地址 -->
<dubbo:registry address="zookeeper://127.0.0.1:2181" />
<!-- 生成远程服务代理,可以和本地bean一样使用userService -->
<dubbo:reference id="userService" interface="com.rpc.service.UserService" />
</beans>
创建项目入口启动类 RunApplication.java:
import com.rpc.bean.User;
import com.rpc.service.ConsumerService;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException;
/**
* @author WDG
* @date 2019-2-14
*/
public class RunApplication {
public static void main(String[] args) throws IOException {
//加载spring 容器
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("consumer.xml");
//获取远程实例
ConsumerService consumerService = context.getBean(ConsumerService.class);
User user = consumerService.getUser();
System.out.println(user);
System.out.println("远程调用完成");
System.in.read();
}
}
运行截图:
管理控制台截图:
Spring 项目中使用Dubbo + Zookeeper实现的简单RPC实现完成,下节记录Spring Boot中整合Dubbo使用。