2019独角兽企业重金招聘Python工程师标准>>>

dubbo + (点对点型、zookeeper)整合,理解其思想,熟悉其基本流程

2017-06-25

(github地址:https://github.com/jiangcaijun/dubbo)

1、dubbo的设计思想

这里输入引用文本Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以服务者与消费者的方式在dubbo上注册

dubbo的架构图,如下(图片来源于internet)

Provider: 暴露服务的服务提供方。 Consumer: 调用远程服务的服务消费方。 Registry: 服务注册与发现的注册中心。 Monitor: 统计服务的调用次调和调用时间的监控中心。 Container: 服务运行容器。

调用关系说明:

  1. 服务容器负责启动,加载,运行服务提供者。
  2. 服务提供者在启动时,向注册中心注册自己提供的服务。
  3. 服务消费者在启动时,向注册中心订阅自己所需的服务。
  4. 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
  5. 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
  6. 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。

参考自:Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错) - 好库文摘

2、自定义实现注册中心

新建三个项目,均用maven进行管理,基于JDK1.7。实现点对点的生产与消费。

  • dubbo-api (注册中心:服务注册与发现的注册中心)
  • dubbo-provider(生产者:暴露服务的服务提供方)
  • dubbo-consumer(消费者:调用远程服务的服务消费方)

2.1 dubbo-api (注册中心)

新建该项目,其pom如下

<groupId>com.dubbo.demo</groupId>
<artifactId>dubbo-api</artifactId>
<version>1.0-SNAPSHOT</version>

新建一个接口,生产者将会负责该接口的实现,消费者将会调用该接口

package com.dubbo.demo;public interface IHelloWorld {public String sayHello(String name);public Object doSomeThing();
}

接着,利用maven install将其发布至本地仓库中,生产者与消费者将均会在pom.xml中引入该依赖。

其项目结构如图:

2.2 dubbo-provider (生产者)

新建该项目,其pom如下。

<groupId>com.dubbo.demo.provider</groupId>
<artifactId>dubbo-provider</artifactId>
<version>1.0-SNAPSHOT</version>
<properties><slf4j.version>1.7.21</slf4j.version>
</properties>
<dependencies><dependency><groupId>com.dubbo.demo</groupId><artifactId>dubbo-api</artifactId><version>1.0-SNAPSHOT</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>dubbo</artifactId><version>2.5.3</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>${slf4j.version}</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>${slf4j.version}</version></dependency>
</dependencies>

该生产者引入了dubbo-api (注册中心)和dubbo的依赖,同时为了方便调试,还添加了日志相关依赖。

实现dubbo-api (注册中心)的接口

package com.dubbo.demo.provider;import com.dubbo.demo.IHelloWorld;public class HelloWorldServiceImpl implements IHelloWorld {public String sayHello(String name) {return "Hello World  " + name + ", I come from dubbo-api " ;}public Object doSomeThing() {return "i am doSomeThing, I come from dubbo-api " ;}
}

在resource目录下新建配p2p_provider.xml,暴露IHelloWorld接口

<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://code.alibabatech.com/schema/dubbohttp://code.alibabatech.com/schema/dubbo/dubbo.xsd"><!-- 提供方应用信息,用于计算依赖关系 --><dubbo:application name="hello_world_provider" owner="jcj" /><!--表示我们的服务注册到哪个位置--><dubbo:registry address="N/A"></dubbo:registry><!-- 用dubbo协议在20880端口暴露服务 --><dubbo:protocol name="dubbo" port="20880"></dubbo:protocol><!-- 具体的实现bean --><bean id="helloService" class="com.dubbo.demo.provider.HelloWorldServiceImpl" /><!-- 声明需要暴露的服务接口 --><dubbo:service interface="com.dubbo.demo.IHelloWorld" ref="helloService" /></beans>

同时新建一个dubboTest方法,用来启动dubbo-provider (生产者)。

public class dubboTest {public static void main(String []args) throws IOException {ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext(new String("provider.xml"));classPathXmlApplicationContext.start();System.in.read();}
}

其项目结构如图(图中红圈代表其引入了dubbo-api(注册中心)的依赖):

2.3 dubbo-consumer (消费者)

其pom和dubbo-provider (生产者)类似,均需要引入dubbo-api (注册中心)和dubbo的依赖。

在resource目录下新建p2p_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://code.alibabatech.com/schema/dubbo"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://code.alibabatech.com/schema/dubbohttp://code.alibabatech.com/schema/dubbo/dubbo.xsd"><!-- 提供方应用信息,用于计算依赖关系 --><dubbo:application name="hello_world_provider" owner="jcj" /><!--表示我们的服务注册到哪个位置--><dubbo:registry address="N/A"></dubbo:registry><!-- 声明需要暴露的服务接口 --><dubbo:reference interface="com.dubbo.demo.IHelloWorld"url="dubbo://127.0.0.1:20880/com.dubbo.demo.IHelloWorld"id="helloService"></dubbo:reference></beans>

与dubbo-provider (生产者)的p2p_provider.xml比较,均声明需要暴露的服务接口,即暴露了dubbo-api(注册中心)的接口方法。

新建一个测试方法dubboConsumerTest

import com.dubbo.demo.IHelloWorld;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException;public class dubboConsumerTest {public static void main(String []args) throws IOException {ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext(new String("p2p_consumer.xml"));IHelloWorld iHelloWorld = (IHelloWorld)classPathXmlApplicationContext.getBean("helloService");String result = iHelloWorld.sayHello("哈哈哈");System.out.println("dubboConsumerTest.main: " + result);Object object = iHelloWorld.doSomeThing();System.out.println("dubboConsumerTest.main: " + object.toString());}
}

其项目结构如图(图中红圈代表其引入了dubbo-api(注册中心)的依赖):

2.4 点对点型dubbo测试

先启动dubbo-provider (生产者)的dubboTest方法,此时服务开始提供; 此时生产者控制台输出如下:

[ com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol ] - [ INFO ]
[DUBBO] disconected from /192.168.58.1:54584,url:dubbo://192.168.58.1:20880/com.dubbo.demo.IHelloWorld?anyhost=true&application=hello_world_provider&channel.readonly.sent=true&codec=dubbo&dubbo=2.5.3&heartbeat=60000&interface=com.dubbo.demo.IHelloWorld&methods=doSomeThing,sayHello&owner=jcj&pid=15740&revision=1.0-SNAPSHOT&side=provider&timestamp=1498555464131, dubbo version: 2.5.3, current host: 127.0.0.1

再启动dubbo-consumer (消费者)的dubboConsumerTest,尝试调用该方法。 此时消费者控制台输出:

Refer dubbo service com.dubbo.demo.IHelloWorld from url
dubbo://127.0.0.1:20880/com.dubbo.demo.IHelloWorld?application=hello_world_provider&dubbo=2.5.3&interface=com.dubbo.demo.IHelloWorld&methods=doSomeThing,sayHello&owner=jcj&pid=8296&revision=1.0-SNAPSHOT&side=consumer&timestamp=1498555502597, dubbo version: 2.5.3, current host: 192.168.58.1
dubboConsumerTest.main: Hello World  哈哈哈, I come from dubbo-api
dubboConsumerTest.main: i am doSomeThing, I come from dubbo-api

证明测试通过。

3、利用zookeeper实现注册中心

3.1 zookeeper安装

  • 安装zookeeper前,务必已经安装好Java环境
  • 下载地址:http://www.apache.org/dyn/closer.cgi/zookeeper/ ,我下载的是zookeeper-3.4.5.tar.gz版本的
  • tar -zxvf zookeeper-3.4.5.tar.gz解压后,复制conf目录下的zoo_sample.cfg ,即 cp zoo_sample.cfg zoo.cfg,(原因:Zookeeper在启动时会找这个文件作为默认配置文件)
  • 启动zookeeper
    • ./zkServer.sh start-foreground (可以查看启动日志)
    • ./zkServer.sh start
  • 测试启动结果
    • ./zkServer.sh status
    • zookeeper默认使用的TCP连接端口是2181
      • 查看61616端口是否打开: netstat -an | grep 2181
      • 通过 netstat -tlnp 查找占用pid号
      • 查找到zookeeper对应的进程: ps -ef | grep zookeeper
  • 关闭zookkeeper
    • ./zkServer.sh stop

3.2 dubbo-provider (生产者)

在pom.xml中添加zookeeper相关依赖,dubbo-consumer (消费者)也需要添加

<!--zookeeper apache-->
<dependency><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId><version>3.4.6</version>
</dependency>
<!--zkclient-->
<dependency><groupId>com.github.sgroschupf</groupId><artifactId>zkclient</artifactId><version>0.1</version>
</dependency>

在resource目录下新建zk_provider.xml,连接zookeeper

<!-- 提供方应用信息,用于计算依赖关系 -->
<dubbo:application name="hello_world_provider" owner="jcj" /><!-- 使用zookeeper注册中心暴露服务地址-->
<dubbo:registry address="zookeeper://182.254.xx.xx:2181" check="false" subscribe="false" register="" /><!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="20880"></dubbo:protocol><!-- 声明需要暴露的服务接口 -->
<dubbo:service interface="com.dubbo.demo.IHelloWorld" ref="helloService" /><!-- 具体的实现bean -->
<bean id="helloService" class="com.dubbo.demo.provider.HelloWorldServiceImpl" />

dubbo:registry 标签一些属性的说明:

  • 1)register是否向此注册中心注册服务,如果设为false,将只订阅,不注册。
  • 2)check注册中心不存在时,是否报错。
  • 3)subscribe是否向此注册中心订阅服务,如果设为false,将只注册,不订阅。
  • 4)timeout注册中心请求超时时间(毫秒)。
  • 5)address可以Zookeeper集群配置,地址可以多个以逗号隔开等。

dubbo:service标签的一些属性说明:

  • 1)interface服务接口的路径
  • 2)ref引用对应的实现类的Bean的ID
  • 3)registry向指定注册中心注册,在多个注册中心时使用,值为dubbo:registry的id属性,多个注册中心ID用逗号分隔,如果不想将该服务注册到任何registry,可将值设为N/A
  • 4)register 默认true ,该协议的服务是否注册到注册中心。

以上,引用自:Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错) - 好库文摘

3.3 dubbo-consumer (消费者)

在resource目录下新建zk_consumer.xml,连接zookeeper

<!-- 提供方应用信息,用于计算依赖关系 -->
<dubbo:application name="hello_world_provider" owner="jcj" /><dubbo:registry address="zookeeper://182.254.xx.xx:2181" /><!-- 生成远程服务代理,可以和本地bean一样使用其接口 -->
<dubbo:reference id="helloService" interface="com.dubbo.demo.IHelloWorld" />

3.4 dubbo_ZK (测试)

运行各相应的xml文件,注意生产者与消费者的先后启动顺序,可以在消费者的控制台看到相应的预期输出,测试通过。

4 FAQ

4.1 zookeeper没有设置超时时间

当zookeeper注册中心连不上时dubbo的线程时,由于ZKClient默认的超时时间是Integer.MAX_VALUE,几乎等于无限等待。因为系统有一些定时任务会比较频繁地开启新线程连接dubbo,所以导致的结果是tomcat一会儿线程池就满了,其它的不依赖dubbo的功能也被阻塞无法使用。

解决方案:dubbo连接zookeeper注册中心因为断网导致线程无限等待问题

4.2dubbo与zookeeper的关系

dubbo:是管理中间层的工具,在业务层到数据仓库间有非常多服务的接入和服务提供者需要调度,dubbo提供一个框架解决这个问题。

注意这里的dubbo只是一个框架,至于你架子上放什么是完全取决于你的,就像一个汽车骨架,你需要配你的轮子引擎。这个框架中要完成调度必须要有一个分布式的注册中心,储存所有服务的元数据,你可以用zk,也可以用别的,例如:

  • Multicast注册中心
  • Zookeeper注册中心
  • Redis注册中心
  • Simple注册中心

5 参考链接

  • DUBBO
  • Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错) - 好库文摘
  • 从头开始搭建一个dubbo+zookeeper平台 - min.jiang - 博客园
  • dubbo连接zookeeper注册中心因为断网导致线程无限等待问题
  • ZooKeeper学习第一期---Zookeeper简单介绍 - 邬兴亮 - 博客园
  • 简单之美 | 基于Dubbo框架构建分布式服务> 这里输入引用文本

转载于:https://my.oschina.net/u/3136014/blog/1036912

dubbo简易实现_分别利用自定义的注册中心和zookeeper相关推荐

  1. 微服务笔记:第一章_微服务简介|Eureka注册中心|Nacos注册中心|Nacos配置管理|Feign|Gateway服务网关

    微服务笔记:第一章_微服务简介|Eureka注册中心|Nacos注册中心|Nacos配置管理|Feign|Gateway服务网关 1. 微服务简介 1.1 服务架构演变 1.2 SpringCloud ...

  2. nacos 下线接口_微服务架构nacos注册中心为什么那么火

    最近nacos非常火,很多使用eureka的都替换成nacos,既可以做注册中心也可以做配置中心,除此之外还有更好用的功能,今天说一下nacos和gateway做动态路由. 动态路由网上一搜一大堆,真 ...

  3. Dubbo 注册中心 之 Zookeeper

    2-6 注册中心概述

  4. eureka 集群失败的原因_对于注册中心,ZooKeeper、Eureka哪个更合适?

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 来源:http://h5ip.cn/Kr8D 简介 Eureka本 ...

  5. dubbo yml配置_利用springboot+dubbo,构建分布式微服务,全程注解开发(一)

    随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进. 一.先来一张图 说起 Dubbo,相信大家都不 ...

  6. Dubbo系列(1)_背景介绍和基本情况

    一.本文目的 主要介绍Dubbo的产生背景和需要解决的问题 二.产生背景 随着大数据量.高并发的互联网应用越来越多,单机系统已经无法满足系统的需要.通过SOA搭建一个分布式服务框架,用于分担压力,提高 ...

  7. dubbo在idea下的使用创建 服务者,消费者 注册中心

    一.基础知识 1.分布式基础理论 1.1).什么是分布式系统? <分布式系统原理与范型>定义: "分布式系统是若干独立计算机的集合,这些计算机对于用户来说就像单个相关系统&quo ...

  8. Dubbo环境搭建-ZooKeeper注册中心

    场景 Dubbo简介与基本概念: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/103555224 注: 博客: https:// ...

  9. Dubbo 融合 Nacos 成为注册中心

    Nacos 作为 Dubbo 生态系统中重要的注册中心实现,其中 dubbo-registry-nacos 则是 Dubbo 融合 Nacos 注册中心的实现. 预备工作 当您将 dubbo-regi ...

最新文章

  1. 【飘移】仅需7个动作完成“斯堪的纳维亚钟摆”飘移过弯教程
  2. 为什么下载源码包需要到官网上去下载?
  3. 一些非常有用的备忘录文档
  4. mysql for update 锁_MySql FOR UPDATE 锁的一点问题……
  5. 如何更合理地选择图表形式
  6. sql server 复制_SQL Server复制配置:点对点和合并复制
  7. canvas 从入门到入坟
  8. Matlab Tricks(十三)—— 提取矩阵的对角线元素
  9. FTP文件服务搭建与同步传输
  10. nodejs后端接入阿里云《天眼数聚》银行卡四要素验证
  11. 照片如何换背景?分享两个快速换背景的方法
  12. python实现匿名发邮件_python 发送匿名邮件或无发件人
  13. 51单片机DHT11温湿度ESP8266WiFi手机APP显示设计
  14. 安徽省大数据与人工智能竞赛经验分享-3【从赛题中分析比赛需要的技能】
  15. 2022开源社区app源码多端圈子社区论坛系统
  16. 自动化运维工具ansible(安装与模块介绍)
  17. GNSS和GPS的区别
  18. GMSSL :SM2椭圆曲线公钥密码算法-密钥交换协议
  19. 【愚公系列】2021年11月 攻防世界-进阶题-MISC-025(Miscellaneous-200)
  20. linux 下写不了文件,linux下用root为什么写不了windows下的文件

热门文章

  1. building tool
  2. WdatePicker日历控件使用方法(转)
  3. JavaScript技巧[转载]
  4. background-position 用法介绍
  5. 重拾Javascript(四) 运动 图片的淡入淡出
  6. 试解释如下两个概念:CLR和CTS
  7. 红帽子RedHat Linux 9.0
  8. JVM垃圾回收,面试问到的都有了
  9. 一个基于 SpringBoot 开源的小说和漫画在线阅读网站,简洁大方 !强烈推荐 !
  10. java多线程基础概念