如何快速开发一个 Dubbo 应用

转载自   如何快速开发一个 Dubbo 应用

导读:在分布式系统中,远程调用是最基础也是最重要的基石。历史上,曾经先后出现过 CORBA、RMI、EJB、WebService 等技术和规范,在服务化以及微服务日趋流行的今天,更多的被广泛使用的是包括 gRPC、Finagle、以及国内的 Dubbo 为代表的轻量级框架。

由于这些框架多半与服务注册中心、配置中心等配套设施结合使用,用来作为系统分布式服务化的场景,因此这类框架又被统称为服务框架。本文将以 Dubbo 为例,介绍如何快速开发一个 Dubbo 应用。

 

背景

本文将以 Dubbo 为例,介绍如何快速开发一个 Dubbo 应用。为了便于读者理解:

  • 首先会介绍一下传统的 RMI 的基本概念

  • 然后比较下现代的 RPC 框架与 RMI 的区别

  • 再基于 Dubbo 提供的 API 展示最基本的 Dubbo 应用如何开发

  • 最后介绍如何通过 start.dubbo.io 快速搭建 Dubbo 的脚手架工程

 

Java RMI 简介

Java RMI (Remote Method Invocation) 远程方法调用,能够让客户端像使用本地调用一样调用服务端 Java 虚拟机中的对象方法。RMI 是面向对象语言领域对 RPC (Remote Procedure Call)的完善,用户无需依靠 IDL 的帮助来完成分布式调用,而是通过依赖接口这种更简单自然的方式。

Java RMI 工作原理

一个典型的 RMI 调用如下图所示:

  1. 服务端向 RMI 注册服务绑定自己的地址;

  2. 客户端通过 RMI 注册服务获取目标地址;

  3. 客户端调用本地的 Stub 对象上的方法,和调用本地对象上的方法一致;

  4. 本地存根对象将调用信息打包,通过网络发送到服务端;

  5. 服务端的 Skeleton 对象收到网络请求之后,将调用信息解包;

  6. 然后找到真正的服务对象发起调用,并将返回结果打包通过网络发送回客户端。

 

(来源:https://www.cs.rutgers.edu/~pxk/417/notes/images/rpc-rmi_flow.png)

 

Java RMI 基本概念

Java RMI 是 Java 领域创建分布式应用的技术基石。后续的 EJB 技术,以及现代的分布式服务框架,其中的基本理念依旧是 Java RMI 的延续。在 RMI 调用中,有以下几个核心的概念:

  1. 通过接口进行远程调用

  2. 通过客户端的 Stub 对象和服务端的 Skeleton 对象的帮助将远程调用伪装成本地调用

  3. 通过 RMI 注册服务完成服务的注册和发现

对于第一点,客户端需要依赖接口,而服务端需要提供该接口的实现。对于第二点,在 J2SE 1.5 版本之前需要通过 rmic 预先编译好客户端的 Stub 对象和服务端的 Skeleton 对象。在之后的版本中,不再需要事先生成 Stub 和 Skeleton 对象。

下面通过示例代码简单的展示 RMI 中的服务注册和发现:

服务端的服务注册

 

说明:

  1. 初始化服务对象实例;

  2. 通过 UnicastRemoteObject.exportObject 生成可以与服务端通讯的 Stub 对象;

  3. 创建一个本地的 RMI 注册服务,监听端口为 1099。该注册服务运行在服务端,也可以单独启动一个注册服务的进程;

  4. 将 Stub 对象绑定到注册服务上,这样,客户端可以通过 Hello 这个名字查找到该远程对象。

客户端的服务发现

 

说明:

  1. 获取注册服务实例,在本例中,由于没有传入任何参数,假定要获取的注册服务实例部署在本机,并监听在 1099 端口上;

  2. 从注册服务中查找服务名为 Hello 的远程对象;

  3. 通过获取的 Stub 对象发起一次 RMI 调用并获得结果。

理解 RMI 的工作原理和基本概念,对掌握现代分布式服务框架很有帮助,建议进一步的阅读 RMI 官方教材 [1]。

 

Dubbo 基本概念

现代的分布式服务框架的基本概念与 RMI 是类似的,同样是使用 Java 的 Interface 作为服务契约,通过注册中心来完成服务的注册和发现,远程通讯的细节也是通过代理类来屏蔽。具体来说,Dubbo 在工作时有以下四个角色参与:

  1. 服务提供者:启动时在指定端口上暴露服务,并将服务地址和端口注册到注册中心上。

  2. 服务消费者:启动时向注册中心订阅自己感兴趣的服务,以便获得服务提供方的地址列表。

  3. 注册中心 :负责服务的注册和发现,负责保存服务提供方上报的地址信息,并向服务消费方推送。

  4. 监控中心:负责收集服务提供方和消费方的运行状态,比如服务调用次数、延迟等,用于监控。

  5. 运行容器:负责服务提供方的初始化、加载以及运行的生命周期管理。

 

部署阶段

  • 服务提供者在指定端口暴露服务,并向注册中心注册服务信息。

  • 服务消费者向注册中心发起服务地址列表的订阅。

 

运行阶段

  • 注册中心向服务消费者推送地址列表信息。

  • 服务消费者收到地址列表后,从其中选取一个向目标服务发起调用。

  • 调用过程服务消费者和服务提供者的运行状态上报给监控中心。

 

基于 API 的 Dubbo 应用

Dubbo 的应用一般都是通过 Spring 来组装的。为了快速获得一个可以工作的 Dubbo 应用,这里的示例摒弃了复杂的配置,而改用面向 Dubbo API 的方式来构建服务提供者和消费者,另外,注册中心和监控中心在本示例中也不需要安装和配置。

在生产环境,Dubbo 的服务需要一个分布式的服务注册中心与之配合,比如,ZooKeeper。为了方便开发,Dubbo 提供了直连[2]以及组播[3]两种方式,从而避免额外搭建注册中心的工作。在本例中,将使用组播的方式来完成服务的注册和发现。

 

定义服务契约

 

说明:

  1. 定义了一个简单的服务契约 GreetingsService,其中只有一个方法 sayHi 可供调用,入参是 String 类型,返回值也是 String 类型。

 

提供契约的实现

 

说明:

  1. 服务提供者需要实现服务契约 GreetingsService 接口。

  2. 该实现简单的返回一个欢迎信息,如果入参是 dubbo,则返回 hi, dubbo。

 

实现 Dubbo 服务提供方

 

说明:

  1. 创建一个 ServiceConfig 的实例,泛型参数信息是服务接口类型,即 GreetingsService。

  2. 生成一个 AplicatonConfig 的实例,并将其装配进 ServiceConfig。

  3. 生成一个 RegistryConfig 实例,并将其装配进 ServiceConfig,这里使用的是组播方式,参数是 multicast://224.5.6.7:1234。合法的组播地址范围为:224.0.0.0 - 239.255.255.255

  4. 将服务契约 GreetingsService 装配进 ServiceConfig。

  5. 将服务提供者提供的实现 GreetingsServiceImpl 的实例装配进 ServiceConfig。

  6. ServiceConfig 已经具备足够的信息,开始对外暴露服务,默认监听端口是 20880。

  7. 为了防止服务端退出,按任意键或者 ctrl-c 退出。

 

实现 Dubbo 服务调用方

 

说明:

  1. 创建一个 ReferenceConfig 的实例,同样,泛型参数信息是服务接口类型,即 GreetingService。

  2. 生成一个 AplicatonConfig 的实例,并将其装配进 ReferenceConfig。

  3. 生成一个 RegistryConfig 实例,并将其装配进 ReferenceConfig,注意这里的组播地址信息需要与服务提供方的相同。

  4. 将服务契约 GreetingsService 装配进 ReferenceConfig。

  5. 从 ReferenceConfig 中获取到 GreetingService 的代理。

  6. 通过 GreetingService 的代理发起远程调用,传入的参数为 dubbo。

  7. 打印返回结果 hi, dubbo。

 

运行

完整的示例:

https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-api 

在完整的示例中,由于配置了 exec-maven-plugin,可以很方便的在命令行下通过 maven 的方式执行。当然,您也可以在 IDE 里直接执行,但是需要注意的是,由于使用了组播的方式来发现服务,运行时需要指定:

 -Djava.net.preferIPv4Stack=true。

 

★ 构建示例

通过以下的命令来同步示例代码并完成构建:

  1. 同步代码:git clone https://github.com/dubbo/dubbo-samples.git

  2. 构建:mvn clean package

 

当看到 BUILD SUCCESS 的时候表明构建完成,下面就可以开始进入运行阶段了。

 

★ 运行服务端

通过运行以下的 maven 命令来启动服务提供者:

 

当 first-dubbo-provider is running. 出现时,代表服务提供者已经启动就绪,等待客户端的调用。

 

★ 运行客户端

通过运行以下的 maven 命令来调用服务:

 

可以看到, hi, dubbo 是从服务提供者返回的执行结果。

 

快速生成 Dubbo 应用

Dubbo 还提供了一个公共服务快速搭建基于 Spring Boot 的 Dubbo 应用。访问 http://start.dubbo.io 并按照下图所示来生成示例工程:

 

说明:

  1. 在 Group 中提供 maven groupId,默认值是 com.example。

  2. 在 Artifact 中提供 maven artifactId,默认值是 demo。

  3. 在 DubboServiceName 中提供服务名,默认值是 com.example.HelloService。

  4. 在 DubboServiceVersion 中提供服务的版本,默认值是 1.0.0。

  5. 在 Client/Server 中选取本次构建的工程是服务提供者 (Server) 还是服务消费者 (Client),默认值是 server。

  6. 使用 embeddedZookeeper 作为服务注册发现,默认为勾选。

  7. 是否激活 qos 端口,默认为不勾选,如果勾选可以通过 22222 端口访问。

  8. 点击 Generate Project 即可下载生成好的工程。

在本例中展示的是服务提供者,同样的,通过在生成界面选取 client 来生成对应的服务消费者。

 

★ 运行

用 IDE 打开生成好的工程,可以发现应用是一个典型的 Spring Boot 应用。程序的入口如下所示:

 

说明:

  1. 在 2181 端口上启动嵌入式 ZooKeeper。

  2. 启动 Spring Boot 上下文。

可以直接在 IDE 中运行,输出结果如下:

2018-05-28 16:59:38.072  INFO 59943 --- [           main] a.b.d.c.e.WelcomeLogoApplicationListener : 

 :: Dubbo Spring Boot (v0.1.0) : https://github.com/dubbo/dubbo-spring-boot-project

 :: Dubbo (v2.0.1) : https://github.com/alibaba/dubbo

 :: Google group : http://groups.google.com/group/dubbo

...

2018-05-28 16:59:39.624  INFO 59943 --- [           main] com.example.demo.DemoApplication         : Started DemoApplication in 1.746 seconds (JVM running for 2.963)

说明:

  1. 输出中打印的以 dubbo. 开头的配置信息,定义在 main/resources/application.properties 中。

 

★ 通过 Telnet 管理服务

生成工程的时候如果选择了激活 qos 的话,就可以通过 telnet 或者 nc 来管理服务、查看服务状态。

目前 qos 支持以下几个命令,更详细的信息请查阅官方文档[4]:

  • ls:列出消费者、提供者信息

  • online:上线服务

  • offline:下线服务

  • help:联机帮助

 

总结

在本文中,从 RMI 开始,介绍了 Java 领域分布式调用的基本概念,也就是基于接口编程、通过代理将远程调用伪装成本地、通过注册中心完成服务的注册和发现。

然后为了简单起见,使用简单的组播注册方式和直接面向 Dubbo API 编程的方式介绍了如何开发一个 Dubbo 的完整应用。深入的了解 ServiceConfig 和 ReferenceConfig 的用法,对于进一步的使用 Spring XML 配置、乃至 Spring Boot 的编程方式有这很大的帮助。

最后,简单的介绍了如何通过 Dubbo 团队提供的公共服务 start.dubbo.io 快速搭建基于 Spring Boot 的 Dubbo 应用,并通过 qos 来做 Dubbo 服务的简单运维。

【注解】

Getting Started Using JavaTM RMI :

https://docs.oracle.com/javase/6/docs/technotes/guides/rmi/hello/hello-world.html

直连提供者 :

http://dubbo.apache.org/books/dubbo-user-book/demos/explicit-target.html

Multicast 

注册中心 :

http://dubbo.apache.org/books/dubbo-user-book/references/registry/multicast.html

在线运维命令 :

http://dubbo.apache.org/books/dubbo-user-book/references/qos.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/324644.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

‘小会计’的转行之旅

本文原创:王哈哈1大学学习的专业是会计学,目前社会上来说很普遍的工作,都说会计是越老越吃香,所以一毕业就先找了一份和专业相关的工作,然后就开始了抱着公司的大腿努力工作。毕业三年期间也换了几份工作,本…

【2018.3.17】模拟赛之三-ssl1863jzoj1367 俄罗斯方块【模拟】

正题 链接 需要纪中OJ账号 有7种方块 有n列,给出每列的方块高度,求一种方块所有方面都落地的方案数 输入输出(需要自取) Input 第一行为二个整数C和P,1 ≤ C ≤ 100, 1 ≤ P ≤ 7,表示列数和下落方…

Python缩进的几个原则

Python的缩进有以下几个原则 顶级代码必须顶行写,即如果一行代码本身不依赖于任何条件,那它必须不能进行任何缩进 同一级别的代码,缩进必须一致 官方建议缩进用4个空格

应用程序的8个关键性能指标以及测量方法

前言 高性能一直是我们作为程序员..孜孜不倦的追求.. 有的时候甚至会为了一句代码吵上几天.. 那么到底应该如何评估我们的性能指标来判断是否需要优化呢? 今天就来讲一下这个.. 说明一下,本篇是译文. 原文地址:https://stackify.com/application-performance-metrics/ …

MyBatis Plus

文章目录第一节 MyBatis Plus 的简介第二节 MyBatis Plus 的框架搭建[1] 第一步:导包[2] 搭建SSM开发环境[3] 在数据库中创建测试表[4] 在pojo层下创建Student表的实体类[5] 在mapper层创建StudentMapper接口并继承BaseMapper接口[6] 创建测试类,并从Spr…

班级日常分享,一天一瞬间

119级日常分享经过两周左右的KTV项目终于要告一段落了,上午先让各个小组在班内试讲了下自己小组所做的KTV点歌系统,整体上做的还可以,有些小组还存在一些细节问题,在试讲的时候也都给他们指了指,相信下来会有所改进的。…

DDOS 攻击的防范教程

转载自 DDOS 攻击的防范教程 一个多月前,阮一峰的个人网站遭受 DDOS 攻击,下线了50多个小时。这篇文章就是他总结的,教大家如何应对这种攻击。 需要说明的是,我对 DDOS 并不精通,从没想过自己会成为攻击目标。攻击…

【2018.3.17】模拟赛之四-ssl1864jzoj1368 燃烧木棒【最短路,Floyd】

正题 链接 需要纪中OJ账号 有n条木棒,长度为1或根号2,给出每根木棒两头的坐标,和燃烧需要的时间。只能从一个木棒的一头开始点火,求燃烧完所有木棒所需要的最短时间。 输入输出(需要自取) Input 输入…

python变量的创建过程(内存地址变化)

​ name “Alex” 原因 python 解释器有自动垃圾回收机制,自动隔一段时间把没有跟变量名关联的内存数据回收。

推荐一份基于Docker的DevOps实战培训教程

01. 基于Docker的DevOps实战培训 微软工具链 基于Azure和Team Foundation Server 微软DevOps工具链是基于Visual Studio 应用生命周期管理(VSALM - Visual Studio Application Lifecycle Managemnet)的软件管理平台,本动手实验希望通过模拟一…

所有和Java中代理有关的知识点都在这了

转载自 所有和Java中代理有关的知识点都在这了 对于每一个Java开发来说,代理这个词或多或少都会听说过。你可能听到过的有代理模式、动态代理、反向代理等。那么,到底什么是代理,这么多代理又有什么区别呢。本文就来简要分析一下。 代理技…

神奇!一行代码实现删除某集合下标20-30的元素

大家好,我是雄雄。今天我们还是分享关于集合的内容。假如有这样的需求,已知集合的长度为100,也就是集合中有100个元素,现需要删除索引20-30之间的元素,我们应该怎么实现呢?我们先初始化集合,代码…

ssl初一组周六模拟赛【2018.3.17】

前言 先说一下成绩: 姓名成绩xjq(没错又是他)310hjq200hzb150wyc(本人)130lrz130xxy100lw30zyc缺考 正题 题目1:ssl2574 & jzoj1368 无限序列【斐波那契数列】 刚开始想用分治,结果做不出来,然后想到了更好的方法&#xff…

注意!在subList生成子列表之后,一定不要随便更改原列表

大家好,我是雄雄。前几期我们说过,subList方法是返回原列表的子列表,并且我们还说过,在subList返回的子列表上操作时,会直接影响着原列表,原文在这里:subList?? subString???子列表只是原列…

DotNetCore跨平台~Dockerfile的解释

大叔感觉网上对Dockerfile的说明不是很清楚,或者说怎么去用说的不清楚,在vs2017里我们可以去建立自己的Dockerfile文件,然后你的项目可以被生成一个镜像,把它推到仓库之后,你可以在linux,mac上去run你的项目了&#xf…

当你「ping 一下」的时候,你知道它背后的逻辑吗

转载自 当你「ping 一下」的时候,你知道它背后的逻辑吗 我们在遇到网络不通的情况,大家都知道去 ping 一下,看一下网络状况。 那你知道「ping」命令后背的逻辑是什么吗?知道它是如何实现的吗? 一、「ping」命令的作…

POJ1611-嫌犯【图论,并查集】

正题 题目链接: http://poj.org/problem?id1611 大意 有n个人,m个组,有一个流感嫌犯,流感嫌犯会将所在的组的所有人变成流感嫌犯,求流感嫌犯的数量。 解题思路 并查集将各个组合并,然后看看那些人是和…

python的三元运算

a 10 b 5if a > 15 :c a else:c bd a if a > 15 else bd 值1 if 条件A else 值2如果条件A成立,就取左边的 值1,则 取 值2

​凌云KTV点歌系统功能简介

19级青鸟三班 凌云小组指导老师:穆雄雄老师 班主任:王欣欣老师小组成员:组长:李磊 副组长:杨云浩组员:高启航 朱齐 李欣然 高松 张方仪 王浩如 苏荟旭 贾增伟制作周期:2020年9月25日-10月…

REST参考手册

总说接口定义要遵守 RESTful,那么什么是REST呢,今天跟小编一起来了解一下这个规范吧~! 原文作者简介: BRIAN SLETTEN是一个关注前沿技术的软件工程师,现居于加州奥本。他的职业生涯横跨了各个行业,包括零售…