当前位置: 首页 > 科技观察

如何快速开发一个Dubbo应用?

时间:2023-03-16 22:01:12 科技观察

在分布式系统中,远程调用是最基本也是最重要的基石。历史上曾出现过CORBA、RMI、EJB、WebService等技术和规范。在面向服务和微服务越来越流行的今天,以gRPC、Finagle、国内的Dubbo为代表的应用越来越广泛。轻量级框架。由于这些框架多与服务注册中心、配置中心等配套设施结合使用,作为系统分布式服务的场景,因此这类框架统称为服务框架。本文将以Dubbo为例,介绍如何快速开发一个Dubbo应用。背景本文将以Dubbo为例,介绍如何快速开发一个Dubbo应用。为了让读者更容易理解:首先会介绍传统RMI的基本概念,然后比较现代RPC框架和RMI的区别,然后展示如何基于Dubbo提供的API开发最基本的Dubbo应用多宝。最后会介绍如何快速启动dubbo.io搭建Dubbo的脚手架项目JavaRMI简介JavaRMI(RemoteMethodInvocation)远程方法调用使得客户端可以调用服务端Java虚拟机中的对象方法,就像使用一个本地调用。RMI是RPC(RemoteProcedureCall)在面向对象语言领域的完善。用户不需要依赖IDL的帮助来完成分布式调用,而是依赖更简单自然的接口方式。JavaRMI的工作原理一个典型的RMI调用如下图所示:服务器将自己的地址绑定到RMI注册服务;客户端通过RMI注册服务获取目标地址;客户端调用本地Stub对象上的方法,与调用本地对象上的方法一致;本地存根对象将调用信息打包,通过网络发送给服务器;服务器上的Skeleton对象接收到网络请求,解包调用信息;然后找到真正的服务对象发起调用,并将返回结果包通过网络发回给客户端。(来源:https://www.cs.rutgers.edu/~pxk/417/notes/images/rpc-rmi_flow.png)JavaRMI的基本概念JavaRMI是Java领域创建分布式应用程序的技术基石.后续的EJB技术和现代分布式服务框架的基本概念仍然是JavaRMI的延续。在RMI调用中,有以下几个核心概念:通过接口进行远程调用。借助客户端的Stub对象和服务器端的Skeleton对象,将远程调用伪装成本地调用。服务注册和发现是通过RMI注册服务完成的。对于第一个此时,客户端需要依赖接口,服务端需要提供接口的实现。对于第二点,在J2SE1.5版本之前,需要通过rmic预编译客户端Stub对象和服务器端Skeleton对象。在以后的版本中,不再需要提前生成Stub和Skeleton对象。下面通过示例代码简单展示RMI中的服务注册和发现:服务器的服务注册说明:初始化服务对象实例;通过UnicastRemoteObject.exportObject生成可以与服务器通信的Stub对象;创建本地RMI注册服务,监听1099端口,注册服务运行在服务器端,也可以单独启动一个注册服务进程;Stub对象与注册服务绑定,这样客户端就可以通过名字Hello找到远程对象。客户端服务发现说明:获取注册的服务实例。本例中,由于没有传入参数,假设要获取的注册服务实例部署在本机,监听1099端口;从已注册服务中查找服务名称Hello的远程对象;通过获得的Stub对象发起RMI调用并获得结果。了解RMI的工作原理和基本概念,对于掌握现代分布式服务框架非常有帮助。推荐阅读RMI官方教材[1]。Dubbo的基本概念现代分布式服务框架的基本概念类似于RMI。它还使用Java的Interface作为服务契约,通过注册中心完成服务注册和发现,通过代理类屏蔽远程通信的细节。具体来说,Dubbo有以下四种角色参与:服务提供者:启动时将服务暴露在指定端口,并将服务地址和端口注册到注册中心。服务消费者:启动时向注册中心订阅自己感兴趣的服务,从而获取服务提供者的地址列表。注册中心:负责服务注册和发现,负责保存服务提供者上报的地址信息,并推送给服务消费者。监控中心:负责收集服务提供者和消费者的运行状态,如服务调用次数、延迟等,进行监控。运行容器:负责服务提供者的初始化、加载和运行生命周期管理。部署阶段服务提供者在指定端口暴露服务,并向注册中心注册服务信息。服务消费者向注册中心发起订阅服务地址列表。在运行阶段,注册中心将地址列表信息推送给服务消费者。服务消费者收到地址列表后,选择其中之一发起对目标服务的调用。调用过程服务消费者和服务提供者的运行状态上报给监控中心。基于API的Dubbo应用Dubbo应用一般通过Spring进行组装。为了快速得到一个可以运行的Dubbo应用,这里的例子摒弃了繁琐的配置,采用面向DubboAPI的方式构建服务提供者和消费者。另外,注册中心和监控中心在本例中不需要安装和配置。在生产环境中,Dubbo的服务需要一个分布式的服务注册中心与之配合,比如ZooKeeper。为了方便开发,Dubbo提供了直连[2]和组播[3],免去了额外搭建注册中心的工作。本例中将使用组播来完成服务注册和发现。服务契约定义说明:定义了一个简单的服务契约GreetingsService,其中只有一个方法sayHi可以调用,入参为String类型,返回值也是String类型。提供合约的实现描述:服务提供者需要实现服务合约的GreetingsService接口。该实现只是简单的返回一个欢迎信息,如果入参是dubbo,则返回hi,dubbo。Dubbo服务提供者实现说明:创建一个ServiceConfig实例,泛型参数信息为服务接口类型,即GreetingsService。创建一个AplicatonConfig实例并将其组装到ServiceConfig中。生成一个RegistryConfig实例,组装成ServiceConfig。这里使用的是组播方式,参数为multicast://224.5.6.7:1234。有效的多播地址范围是:224.0.0.0-239.255.255.255将服务契约GreetingsService组装到ServiceConfig中。将服务提供者提供的GreetingsServiceImpl实例组装到ServiceConfig中。ServiceConfig已经有足够的信息开始向外界公开服务。默认监听端口为20880,要防止服务器退出,按任意键或ctrl-c退出即可。Dubbo服务调用者实现说明:创建一个ReferenceConfig实例。同理,泛型参数信息为服务接口类型,即GreetingService。创建一个AplicatonConfig的实例并将其组装到ReferenceConfig中。生成RegistryConfig实例,组装成ReferenceConfig。注意这里的组播地址信息需要和服务商的一致。将服务契约GreetingsService组装到ReferenceConfig中。从ReferenceConfig获取GreetingService代理。通过GreetingService的代理发起远程调用,传入参数为dubbo。打印返回结果hi,dubbo。完整样例运行:https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-api完整样例中,由于配置了exec-maven-plugin,运行起来非常方便命令行接下来,通过maven执行。当然也可以直接在IDE中执行,但是需要注意的是,由于是使用组播来发现服务,所以运行时需要指定:-Djava.net.preferIPv4Stack=true。构建示例,使用以下命令同步示例代码并完成构建:它表明构建已完成。下面就可以开始进入运行阶段了。通过运行以下maven命令运行服务器以启动服务提供者:当first-dubbo-provider正在运行时。出现,表示服务提供者准备启动,正在等待客户端的调用。运行客户端通过运行如下maven命令来调用服务:可以看到,hi,dubbo是服务提供者返回的执行结果。快速生成Dubbo应用Dubbo也提供了一个公共服务来快速构建基于SpringBoot的Dubbo应用。访问http://start.dubbo.io,生成示例工程如下图:注意:Group中提供mavengroupId,默认为com.example。在Artifact中提供mavenartifactId,默认值为demo。在DubboServiceName中提供服务名称,默认值为com.example.HelloService。DubboServiceVersion提供的服务版本,默认为1.0.0。在Client/Server中,选择本次构建的项目是服务提供者(Server)还是服务消费者(Client)。默认值为服务器。使用embeddedZookeeper作为服务注册发现,默认勾选。是否开启qos端口,默认不勾选,勾选则可以通过22222端口访问。点击GenerateProject下载生成的工程。在此示例中,显示了服务提供商。同样,在生成界面选择client,生成对应的服务消费者。运行IDE打开生成的工程,可以发现应用是一个典型的SpringBoot应用。程序入口如下:描述:在2181端口启动嵌入式ZooKeeper。启动SpringBoot上下文。可以直接在IDE中运行,输出结果如下:2018-05-2816:59:38.072INFO59943---[main]a.b.d.c.e.WelcomeLogoApplicationListener:::DubboSpringBoot(v0.1.0):https://github.com/dubbo/dubbo-spring-boot-project::Dubbo(v2.0.1):https://github.com/alibaba/dubbo::Googlegroup:http://groups.google.com/group/dubbo...2018-05-2816:59:39.624INFO59943---[main]com.example.demo.DemoApplication:StartedDemoApplicationin1.746seconds(JVMrunningfor2.963)说明:dubbo开头打印的配置信息。在输出中定义在main/resources/application.特性。如果通过Telnet管理服务生成项目时选择激活qos,则可以通过telnet或nc管理服务,查看服务状态。目前qos支持以下命令。更详细的信息可以参考官方文档[4]:ls:列出消费者和提供者信息online:在线服务offline:离线服务help:在线帮助是本文总结的,从RMI开始,基本的引入了Java领域分布式调用的概念,即基于接口编程,通过代理将远程调用伪装成本地,通过注册中心完成服务注册和发现。然后,为简单起见,介绍如何使用简单的组播注册方式,直接编程到DubboAPI,开发一个完整的Dubbo应用。深入了解ServiceConfig和ReferenceConfig的用法,对于进一步使用SpringXML配置乃至SpringBoot编程都有很大的帮助。最后简单介绍一下如何通过Dubbo团队提供的公共服务start.dubbo.io,快速构建一个基于SpringBoot的Dubbo应用,并使用qos对Dubbo服务进行简单的运维。【本文为专栏作者《阿里巴巴官方技术》原创稿件,转载请联系原作者】点此查看作者更多好文