Dubbo+Zookeeper实现简单的远程方法调用示例
1. Dubbo介绍
示例代码:Github
1.1 RPC
Remote Procedure Call:远程过程调用

1.2 Dubbo架构

Subscribe 订阅;签署;赞成
Monitor 监听器;监控器
1.3 Dubbo在Zookeeper中注册信息的结构

2. Dubbo使用
2.1 创建Common工程
group id:com.joker.dubbo
artifact id:dubbo-common
package:jar
创建实体类
com.joker.dubbo.entity.Employee.java
package com.joker.dubbo.entity;
import java.io.Serializable;
public class Employee implements Serializable {
    private static final long serialVersionUID = 1L;
    private Integer empId;
    private String empName;
    private Double salary;
    public Employee() {
    }
    public Employee(Integer empId, String empName, Double salary) {
        this.empId = empId;
        this.empName = empName;
        this.salary = salary;
    }
    // getter、setter略
}
创建远程调用的接口
package com.joker.dubbo.service.EmployeeRemoteService.java
package com.joker.dubbo.service;
import com.joker.dubbo.entity.Employee;
import java.util.List;
public interface EmployeeRemoteService {
    List<Employee> getEmployeeByConditionRemote(Employee employee);
}
2.2 创建Provider工程
group id:com.joker.dubbo
artifact id:dubbo-provider
package:war
依赖于:Common工程,使用其中的实体类和接口
依赖信息
pom.xml
<dependencies>
    <!-- 依赖于dubbo-common -->
    <dependency>
        <groupId>com.joker.dubbo</groupId>
        <artifactId>dubbo-common</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
        <version>2.2</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.6.8</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>dubbo</artifactId>
        <version>2.5.5</version>
    </dependency>
    <dependency>
        <groupId>com.github.sgroschupf</groupId>
        <artifactId>zkclient</artifactId>
        <version>0.1</version>
    </dependency>
</dependencies>
配置log4j日志文件
log4j.properties
log4j.rootLogger=DEBUG,myConsole
log4j.appender.myConsole=org.apache.log4j.ConsoleAppender
log4j.appender.myConsole.Target=System.out
log4j.appender.myConsole.layout=org.apache.log4j.PatternLayout
log4j.appender.myConsole.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n
配置web.xml
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
		  http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-dubbo.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
</web-app>
Spring配置文件中Dubbo的配置
spring-dubbo.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配置:指定当前Web应用名称,便于在注册中心中注册 -->
    <dubbo:application name="dubbo-provider"/>
    <!-- Dubbo配置:指定注册中心的种类以及位置 -->
    <dubbo:registry protocol="zookeeper" address="192.168.252.128" port="2181"/>
    <!-- Dubbo配置:指定Dubbo的Provider本身监听的端口号 consumer访问时要使用这个端口号-->
    <dubbo:protocol name="dubbo" port="20880"/>
    <!-- 配置接口实现类的bean -->
    <bean id="employeeRemoteServiceImpl" class="com.joker.dubbo.service.impl.EmployeeRemoteServiceImpl"/>
    <!-- Dubbo配置:给远程方法接口指定实现类 -->
    <dubbo:service interface="com.joker.dubbo.service.EmployeeRemoteService" ref="employeeRemoteServiceImpl"/>
</beans>
创建远程调用接口的实现类
com.joker.dubbo.service.impl.EmployeeRemoteServiceImpl.java
package com.joker.dubbo.service.impl;
import com.joker.dubbo.entity.Employee;
import com.joker.dubbo.service.EmployeeRemoteService;
import java.util.ArrayList;
import java.util.List;
/**
 * @PackageName:com.joker.dubbo.service.impl
 * @Date:2019/10/18 14:02
 * @Author: zsy
 */
public class EmployeeRemoteServiceImpl implements EmployeeRemoteService {
    @Override
    public List<Employee> getEmployeeByConditionRemote(Employee employee) {
        System.out.println("***provider***:" + employee);
        // 假数据用于数据测试
        List<Employee> empList = new ArrayList<>();
        empList.add(new Employee(111, "empName111", 111.11));
        empList.add(new Employee(222, "empName222", 222.22));
        empList.add(new Employee(333, "empName333", 333.33));
        return empList;
    }
}
注册简单测试
运行web项目,启动tomcat服务器,尝试连接Zookeeper,此时要确保服务器Zookeeper已启动
启动成功可以看到控制台日志打印心跳检查信息:
[2019-10-18 02:19:51,355] Artifact dubbo-provider:war exploded: Artifact is deployed successfully
[2019-10-18 02:19:51,355] Artifact dubbo-provider:war exploded: Deploy took 24,538 milliseconds
[DEBUG] 2019-10-18 14:20:01,235(31554) --> [RMI TCP Connection(192.168.252.128:2181)] org.apache.zookeeper.ClientCnxn$SendThread.readResponse(ClientCnxn.java:758): Got ping response for sessionid: 0x16ddd844d9a0000 after 2ms
[DEBUG] 2019-10-18 14:20:11,241(41560) --> [RMI TCP Connection(192.168.252.128:2181)] org.apache.zookeeper.ClientCnxn$SendThread.readResponse(ClientCnxn.java:758): Got ping response for sessionid: 0x16ddd844d9a0000 after 2ms
此时到服务器端启动Zookeeper客户端:
/opt/zookeeper3.4.9/bin/zkCli.sh
#启动后查看是否已经注册上provider的信息
[zk: localhost:2181(CONNECTED) 0] ls /
[animal, dubbo, zookeeper, fruits]
[zk: localhost:2181(CONNECTED) 1] ls /dubbo
[com.joker.dubbo.service.EmployeeRemoteService]
[zk: localhost:2181(CONNECTED) 2] ls /dubbo/com.joker.dubbo.service.EmployeeRemoteService
[configurators, providers]
[zk: localhost:2181(CONNECTED) 3] ls /dubbo/com.joker.dubbo.service.EmployeeRemoteService/providers
[dubbo%3A%2F%2F192.168.252.1%3A20880%2Fcom.joker.dubbo.service.EmployeeRemoteService%3Fanyhost%3Dtrue%26application%3Ddubbo-provider%26dubbo%3D2.5.5%26generic%3Dfalse%26interface%3Dcom.joker.dubbo.service.EmployeeRemoteService%26methods%3DgetEmployeeByConditionRemote%26pid%3D6364%26revision%3D1.0-SNAPSHOT%26side%3Dprovider%26timestamp%3D1571379571726]
[zk: localhost:2181(CONNECTED) 4]
通过ls /dubbo/com.joker.dubbo.service.EmployeeRemoteService/providers我们看到下面注册的provider,通过Url解码得到内容:
dubbo://192.168.252.1:20880/com.joker.dubbo.service.EmployeeRemoteService?anyhost=true&application=dubbo-provider&dubbo=2.5.5&generic=false&interface=com.joker.dubbo.service.EmployeeRemoteService&methods=getEmployeeByConditionRemote&pid=6364&revision=1.0-SNAPSHOT&side=provider×tamp=1571379571726
至此,证明Provider配置成功!
2.3 创建Consumer工程
group id:com.joker.dubbo
artifact id:dubbo-consumer
package:war
依赖信息
pom.xml
<dependencies>
    <!-- 依赖于dubbo-common -->
    <dependency>
        <groupId>com.joker.dubbo</groupId>
        <artifactId>dubbo-common</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
        <version>2.2</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.6.8</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>dubbo</artifactId>
        <version>2.5.5</version>
    </dependency>
    <dependency>
        <groupId>com.github.sgroschupf</groupId>
        <artifactId>zkclient</artifactId>
        <version>0.1</version>
    </dependency>
    <!-- spring-mvc -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>4.3.10.RELEASE</version>
    </dependency>
    <!-- jsp -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.1.3-b06</version>
        <scope>provided</scope>
    </dependency>
</dependencies>
配置log4j日志配置文件
log4j.properties
log4j.rootLogger=DEBUG,myConsole
log4j.appender.myConsole=org.apache.log4j.ConsoleAppender
log4j.appender.myConsole.Target=System.out
log4j.appender.myConsole.layout=org.apache.log4j.PatternLayout
log4j.appender.myConsole.layout.ConversionPattern=[%-5p] %d(%r) --> [%t] %l: %m %x %n
配置web.xml
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
		  http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">
    <servlet>
        <servlet-name>springDispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springDispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>
配置SpringMVC
spring-mvc.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"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       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://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    <!-- SpringMVC相关配置 -->
    <context:component-scan base-package="com.joker.dubbo.handler"/>
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    <mvc:annotation-driven/>
    <mvc:default-servlet-handler/>
    <!-- Dubbo配置:当前应用名称 -->
    <dubbo:application name="dubbo-consumer"/>
    <!-- Dubbo配置:指定Dubbo注册中心类型和位置 -->
    <dubbo:registry protocol="zookeeper" address="192.168.252.128" port="2181"/>
    <!-- Dubbo配置:引用Provider提供的可以远程调用的服务 -->
    <dubbo:reference id="employeeRemoteService" interface="com.joker.dubbo.service.EmployeeRemoteService"/>
</beans>
创建Handler类映射远程接口请求
com.joker.dubbo.handler.EmployeeHandler.java
package com.joker.dubbo.handler;
import com.joker.dubbo.entity.Employee;
import com.joker.dubbo.service.EmployeeRemoteService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
/**
 * @PackageName:com.joker.dubbo.handler
 * @Date:2019/10/18 14:51
 * @Author: zsy
 */
@Controller
public class EmployeeHandler {
    @Autowired
    EmployeeRemoteService employeeRemoteService;
    @RequestMapping("/get/emp/list")
    public String getEmpList() {
        Employee employee = new Employee(666, "empName666", 666.66);
        List<Employee> empList = employeeRemoteService.getEmployeeByConditionRemote(employee);
        for (Employee emp : empList) {
            System.out.println(emp);
        }
        return "success";
    }
}
创建返回成功页面
success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
	<h1> Success !</h1>
</body>
</html>
注册简单测试
运行consumer的web项目,启动一个新的tomcat服务器,并设置不同的端口号;
同provider,启动完成后可以看到控制台日志打印心跳检查信息:
[DEBUG] 2019-10-18 16:21:14,947(31499) --> [RMI TCP Connection(192.168.252.128:2181)] org.apache.zookeeper.ClientCnxn$SendThread.readResponse(ClientCnxn.java:758): Got ping response for sessionid: 0x16ddd844d9a000b after 3ms
[DEBUG] 2019-10-18 16:21:24,947(41499) --> [RMI TCP Connection(192.168.252.128:2181)] org.apache.zookeeper.ClientCnxn$SendThread.readResponse(ClientCnxn.java:758): Got ping response for sessionid: 0x16ddd844d9a000b after 1ms
[DEBUG] 2019-10-18 16:21:34,949(51501) --> [RMI TCP Connection(192.168.252.128:2181)] org.apache.zookeeper.ClientCnxn$SendThread.readResponse(ClientCnxn.java:758): Got ping response for sessionid: 0x16ddd844d9a000b after 1ms
此时到Zookeeper服务端查看服务注册信息:
[zk: localhost:2181(CONNECTED) 21] ls /dubbo/com.joker.dubbo.service.EmployeeRemoteService
[consumers, configurators, routers, providers]
[zk: localhost:2181(CONNECTED) 22]
这是可以看到Zookeeper注册中心不仅有providers,还有了新注册的consumers;
这时执行命令:ls /dubbo/com.joker.dubbo.service.EmployeeRemoteService/consumers
可以看到我们注册的consumer信息
[consumer%3A%2F%2F192.168.252.1%2Fcom.joker.dubbo.service.EmployeeRemoteService%3Fapplication%3Ddubbo-consumer%26category%3Dconsumers%26check%3Dfalse%26dubbo%3D2.5.5%26interface%3Dcom.joker.dubbo.service.EmployeeRemoteService%26methods%3DgetEmployeeByConditionRemote%26pid%3D13468%26revision%3D1.0-SNAPSHOT%26side%3Dconsumer%26timestamp%3D1571386846115]
通过URL解码可以看到:
consumer://192.168.252.1/com.joker.dubbo.service.EmployeeRemoteService?application=dubbo-consumer&category=consumers&check=false&dubbo=2.5.5&interface=com.joker.dubbo.service.EmployeeRemoteService&methods=getEmployeeByConditionRemote&pid=13468&revision=1.0-SNAPSHOT&side=consumer×tamp=1571386846115
这里显示的是调用接口的消费者信息。
这时打开浏览器输出http://localhost:8081/consumer/get/emp/list
注意:本项目中配置consumer的tomcat端口号为8081
可以看到成功页面返回!
同时看到tomcat运行控制台打印信息:
consumer端:
Employee{empId=111, empName='empName111', salary=111.11}
Employee{empId=222, empName='empName222', salary=222.22}
Employee{empId=333, empName='empName333', salary=333.33}
provider端
***provider***:Employee{empId=666, empName='empName666', salary=666.66}
证明远程方法调用成功,consumer调用了远程方法,并传递给provider一个Employee对象。
provider成功接收,并执行getEmployeeByConditionRemote()方法,返回一个Employee的List。
至此,consumer配置成功!
Dubbo+Zookeeper实现远程调用成功!
返回!
同时看到tomcat运行控制台打印信息:
consumer端:
Employee{empId=111, empName='empName111', salary=111.11}
Employee{empId=222, empName='empName222', salary=222.22}
Employee{empId=333, empName='empName333', salary=333.33}
provider端
***provider***:Employee{empId=666, empName='empName666', salary=666.66}
证明远程方法调用成功,consumer调用了远程方法,并传递给provider一个Employee对象。
provider成功接收,并执行getEmployeeByConditionRemote()方法,返回一个Employee的List。
至此,consumer配置成功!
Dubbo+Zookeeper实现远程调用成功!
Dubbo+Zookeeper实现简单的远程方法调用示例的更多相关文章
- dubbo+zookeeper+springboot简单示例
		目录 dubbo+zookeeper+springboot简单示例 zookeeper安装使用 api子模块 生产者producer 消费者consumer @(目录) dubbo+zookeeper ... 
- SpringBoot + Dubbo + zookeeper 搭建简单分布式服务
		SpringBoot + Dubbo + zookeeper 搭建简单分布式服务 详细操作及源码见: https://github.com/BillyYangOne/dubbo-springboot 
- Dubbo+Zookeeper的简单入门案例
		1.1 Dubbo简介 Apache Dubbo是一款高性能的Java RPC框架.其前身是阿里巴巴公司开源的一个高性能.轻量级的开源Java RPC框架,可以和Spring框架无缝集成. 什么是R ... 
- spring Boot环境下dubbo+zookeeper的一个基础讲解与示例
		一,学习背景 1. 前言 对于我们不管工作还是生活中,需要或者想去学习一些东西的时候,大致都考虑几点: a) 我们为什么需要学习这个东西? b) 这个东西是什么? c) ... 
- MAC环境下idea:maven+Spring+Dubbo+Zookeeper简单工程搭建
		: 一:安装软件:tomcatZookeeperDubbo+admin 二:工程: 总工程 API Pom.xml:不用引用任何东西 Provider Pom.xml:要denpend ... 
- 用dubbo+zookeeper+spring搭建一个简单的http接口程序
		dubbo是一个分布式服务框架,是阿里巴巴开发的一个解决RPC远程调用优化的核心框架,包含负载均衡算法,能提高分布式系统的性能. zookeeper是hadoop的一个子项目,主要用来解决分布式系统的 ... 
- Dubbo + Zookeeper 简单配置
		Dubbo + Zookeeper Zookeeper 下载及配置 下载到本机/usr/local目录 wget https://mirrors.tuna.tsinghua.edu.cn/apache ... 
- dubbo+zookeeper示例记录
		提示:要直接看搭建例子的可以跳到 三 一.项目架构的发展 传统的mvc架构项目将整个系统功能实现全部写在一个项目中,部署在一个机器上,随着用户量的增涨,单个项目服务器无法承受暴增的用户请求时需要增加服 ... 
- Java代码搭建Dubbo+ZooKeeper 的示例
		.personSunflowerP { background: rgba(51, 153, 0, 0.66); border-bottom: 1px solid rgba(0, 102, 0, 1); ... 
随机推荐
- io流追加到一个文件中信息比如日志
			package com.yh.day02.arrays; import java.io.File;import java.io.FileInputStream;import java.io.FileN ... 
- Samba安装及配置
			samba 可以实现Windows对Windows . Windows对Linux.Linux对Linux的文件传输 在centos7安装samba yum install samba 启动samba ... 
- kettle抽取数据发送邮件Linux调度
			kettle抽取数据发送邮件Linux调度 #1.进入kettle安装目录 然后执行sqoop.sh文件启动kettlecd /app/pdi-ce-7.1.0.0-12/data-integrati ... 
- redis缓存穿透,缓存击穿,缓存雪崩
			概念解释 redis 缓存穿透 key对应的数据在数据源并不存在,每次针对此key的请求从缓存获取不到,请求都会到数据源,从而可能压垮数据源.比如用一个不存在的用户id获取用户信息,不论缓存还是数据库 ... 
- IDEA乱码Tomcat控制台乱码输出乱码报文乱码
			电脑重装系统后,重新安装了最新版的IDEA 2019.2.2,出现乱码.百度了很多,慢慢的解决了乱码的问题,现记录如下.方法因人而异,不同的问题不一样的方法. 第一 修改IDEA文件编码格式 设置id ... 
- SpringBoot2.0 基础案例(15):配置MongoDB数据库,实现增删改查逻辑
			本文源码:GitHub·点这里 || GitEE·点这里 一.NoSQL简介 1.NoSQL 概念 NoSQL( Not Only SQL ),意即"不仅仅是SQL".对不同于传统 ... 
- React躬行记(12)——Redux中间件
			Redux的中间件(Middleware)遵循了即插即用的设计思想,出现在Action到达Reducer之前(如图10所示)的位置.中间件是一个固定模式的独立函数,当把多个中间件像管道那样串联在一起时 ... 
- 【xmind】 使用 Java 生成思维导图
			前言 在日常的工作与学习中,我们经常会使用思维导图这个工具,来把抽象而又无形的思考转换成有形并且具体的图像,是理清思路,梳理逻辑的一大神器. 准确的说,思维导图并不是一个具体的工具,而是一种方法.是道 ... 
- 一篇文章,彻底理解ReentrantLock
			本人免费整理了Java高级资料,涵盖了Java.Redis.MongoDB.MySQL.Zookeeper.Spring Cloud.Dubbo高并发分布式等教程,一共30G,需要自己领取.传送门:h ... 
- PlayJava Day021
			容器: Collection接口:定义了存取一组对象的方法,其子接口Set和List分别定义了存储方式 List:存储数据有序且可重复 ----> ArrayList Set:存储数据无序且不可 ... 
