首页 > 代码库 > RPC实践(四)Dubbo实践
RPC实践(四)Dubbo实践
Dubbo是一款重要的RPC框架,它是Alibaba开源的分布式服务框架。它主要特点:提供了注册中心来进行服务的管理,支持zookeeper、redis等方式来实现注册中心;Dubbo按照分层的方式来架构,使用这种方式可以使各个层之间解耦合或者最大限度地松耦合;采用的是服务提供者Provider和消费者Consumer这样模型。
一、Dubbo简单介绍
Dubbo是什么?Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。
Dubbo有何特点?
远程通讯:基于长连接的NIO框架抽象封装
集群容错:提供多协议支持,以及软负载均衡,失败容错,地址路由,动态配置等集群支持。
自动发现:基于注册中心目录服务,使服务消费方能动态的查找服务提供方,支持平滑减少或增加机器
二、Dubbo架构
Provider: 暴露服务的服务提供方。
Consumer: 调用远程服务的服务消费方。
Registry: 服务注册与发现的注册中心。
Container: 服务运行容器。(e.g.)Spring
Monitor: 统计服务的调用次调和 调用时间的监控中心
三、Dubbo实现原理
四、Dubbo实践目标
1、搭建基于zookeeper的Dubbo环境( 管理中心,客户端,服务端)
2、实践客户端和服务端的开发过程
3、客户端和服务端的调用
4、总结应用场景
五、Dubbo实践操作
1、环境搭建
1) 首先准备zookeeper(本实践采用伪分布式部署,在centos65的虚拟机192.168.136.144上,部署3个zookeeper,客户端端口分别为 2181,2182,2183),启动zookeeper后,可以看到上述端口都处于监听状态
2)下载Dubbo的管理web war包,我下载的版本是dubbo-admin-2.5.3.war,大家也可以下载源码自己打包编译。需要war包的可以从下面网址下载
3) 准备一个tomcat环境,本次实践使用的是tomcat 6,java版本为1.7 ,注意不要用1.8,用java 1.8 会报异常,解决比较麻烦
4) 将war包上传到tomcat的webapps目录下,先启动一下tomcat,让tomcat解压war包。
我们需要修改一下解压后的dubbo-admin-2.5.3/WEB-INF 目录下的配置文件dubbo.properties, 修改的目的是配置正确的注册中心zookeeper的地址
修改完成并保存。有两种方式访问部署的dubbo,一种是通过url: http://192.168.136.144:8080/dubbo-admin-2.5.3 方式来访问,一种是通过 http://192.168.136.144:8080/ 方式来访问, 如果采用第一种,直接启动就可以,如果采用第二种(本次实践也是采用这种),需要进行如下操作: 在webapps目录下执行
mv dubbo-admin-2.5.3 ROOT, rm dubbo-admin-2.5.3.war这么做的是将 dubbo解压后的目录设定为ROOT目录,这样tomcat启动就用确省地址访问dubbo工程,删除war包,是不让tomcat后续自动解压war包,否则启动了两个dubbo会有干涉。
5)上述操作有,启动tomcat,这样就可以通过缺省url访问dubbo,打开http://192.168.136.144:8080/后,输入账号和密码: root、root,如果正常会出现如下目录
好了,环境搭建告一段落,下面将进行客户端和服务端例子开发。由于服务端和客户端都用到接口api,所以整个项目工程有三个部分,分别是
1)工程-接口jar包
2)工程-服务端
3)工程-客户端
下面就三个工程来描述如何创建和使用
2、工程-接口jar包的创建
接口比较简单,就是一个interface,里面有2个方法。
首先我们在myeclipse里面,new-》other-》maven
输入要创建的工程后,点击finish。工程创建后,很不幸碰到了2个问题,如果没有碰到同样的问题,可以跳过阅读
1) 创建类或者接口时,提示java not visible in src folder in Package Explorer
解决的办法是:项目上右键-》属性,然后在下面界面上选择,可以选java,或者Dynamic Web Module(web工程要选此项)
2)问题2: 执行maven install时报告:
maven build异常 -Dmaven.multiModuleProjectDirectory system property is not set
解决: windwos-》profrencens-》java
点击edit 后,在Default VM Arguments 这个项目,填入-Dmaven.multiModuleProjectDirectory=$M2_HOME
好了,现在创建interface 后,可以执行maven build了。 在项目上,右键-》runas-》 maven clean,执行完后,再执行 run as -》maven install
可以在控制台提示的安装目录,发现安装到本地库的接口jar包。
觉得版本号太长挺烦的,因为在后面还需要引用这个接口包,可以修改一下pom.xml:
<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>
<groupId>com.study</groupId>
<artifactId>StudyDubboApi</artifactId>
<version>0.1</version>
<build/>
</project>
重新update 工程,并执行maven install 后,可以在本地库看到生成打包后的api jar包3、工程-服务端开发
建立一个maven工程取名为 StudyDubboServer,在这个工程里面,需要引入刚才生成的接口jar包,引入dubbo。
服务端开发的步骤:
1) 创建maven工程,修改pom.xml,引入相关的接口和依赖包
2)生成一个接口实现类,一个服务端应用程序类
3)编写applicationProvider.xml ,配置各种服务和暴露的接口
下面就这些步骤做具体的说明
3.1 创建maven工程,修改pom.xml
创建maven工程比较简单,主要是几个id的输入,创建好的工程如下所示:
pom.xml的内容如下所示,添加了dubbo,接口api,zookeeper,sping的依赖
<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> <groupId>com.study</groupId> <artifactId>StudyDubboServer</artifactId> <version>0.1</version> <build/> <dependencies> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.5.3</version> </dependency> <dependency> <groupId>com.study</groupId> <artifactId>StudyDubboApi</artifactId> <version>0.1</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring</artifactId> <version>2.5.6.SEC03</version> </dependency> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.6</version> <type>pom</type> </dependency> <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>0.4</version> </dependency> </dependencies> </project>
其中StudyDubboApi是服务端和客户端都需要用到的接口api jar包。 pom文件编写完成后,在项目工程上右键-》Maven4MyEclipse-》update projects 这样可以通过maven自动的下载依赖包到工程的maven lib。
3.2 下面要编写2个类,一个是接口的实现类,一个是服务端主程序
接口的实现类代码如下:HelloServiceApiImpl.java
package com.study.dubbo.demo;
import com.study.dubbo.demo.HelloServiceApi;
public class HelloServiceApiImpl implements HelloServiceApi {
String myName="";
public String sayHello(String name){
myName = name;
String ret="Hello, "+name+"!";
System.out.println( ret );
return ret;
}
public String getName ( ){
System.out.println( "Now name is:"+ myName+";" );
return myName;
}
}
要让服务程序跑起来,还需要一个服务端的应用程序主类:ProviderMain.java
package com.study.app;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class ProviderMain {
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
new String[] { "applicationProvider.xml" });
context.start();
System.out.println("按任意键退出");
System.in.read();
}
}
3)编写applicationProvider.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:application name="Provider_DubboHelloService" />
<!-- 使用zookeeper注册中心暴露服务地址 -->
<dubbo:registry address="zookeeper://192.168.136.144:2181" ></dubbo:registry>
<dubbo:protocol name="dubbo" port="20880"></dubbo:protocol>
<!-- 要暴露的服务API接口 -->
<dubbo:service interface="com.study.dubbo.demo.HelloServiceApi" ref="HelloService" />
<!-- 接口的实现,注意beanid 需要和服务接口的ref 一致 -->
<bean id="HelloService" class="com.study.dubbo.demo.HelloServiceApiImpl" />
</beans>
好了,服务端这样就可以跑起来了,右键,run as-》java application运行
4 工程-客户端开发
客户端的开发步骤更加简单一些,步骤如下:
1) 创建一个maven工程,在pom文件中引入接口api和其他相关的包
2)编写客户端程序
3)编写客户端spring文件
4.1 创建maven工程
创建客户端工程后,工程如下图所示:
pom.xml文件的内容如下:
<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>
<groupId>com.study</groupId>
<artifactId>StudyDubboCli</artifactId>
<version>0.1</version>
<build/>
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.5.3</version>
</dependency>
<dependency>
<groupId>com.study</groupId>
<artifactId>StudyDubboApi</artifactId>
<version>0.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>2.5.6.SEC03</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.6</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.4</version>
</dependency>
</dependencies>
</project>
4.2 客户端程序
客户端程序也分2个部分,一个是对于接口的调用类,一个是客户端程序的main入口
客户端的调用类如下:HelloServiceComsumer.java
package com.study.dubbo.demo;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.study.dubbo.demo.HelloServiceApi;
public class HelloServiceComsumer {
HelloServiceApi demoService;
/*
* 获取服务的Provider对象
*/
public void getServiceObj(){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
new String[] { "applicationConsumer.xml" });
context.start();
demoService = (HelloServiceApi) context
.getBean("HelloService");
}
/*
* 调用对象的sayHello 方法
*/
public void sayHello( String name) {
System.out.println(demoService.sayHello( name ));
}
/*
* 调用对象的getName 方法
*/
public String getName(){
String ret=demoService.getName( );
System.out.println("Now Provider Name is:"+ ret);
return ret;
}
}
客户端的主程序入口:ConsumerMain.java
package com.study.app;
import com.study.dubbo.demo.HelloServiceComsumer;
public class ConsumerMain {
public static void main(String[] args) throws Exception{
HelloServiceComsumer consumerService = new HelloServiceComsumer();
consumerService.getServiceObj();
String myFamily[]={ "Mom","Daddy","Honey","Pretty Girl"};
for(int i=0;i<myFamily.length;i++){
consumerService.sayHello(myFamily[i] );
consumerService.getName();
}
System.out.println("按任意键退出");
System.in.read();
}
}
4.3 spring 配置如下:applicationConsumer.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 ">
<!-- consumer application name -->
<dubbo:application name="Consumer_DubboHelloService" />
<!-- registry address, used for consumer to discover services -->
<dubbo:registry address="zookeeper://192.168.136.144:2181" ></dubbo:registry>
<dubbo:consumer timeout="5000" />
<!-- 引用服务接口 -->
<dubbo:reference id="HelloService" interface="com.study.dubbo.demo.HelloServiceApi"/>
</beans>
注意一下上面dubbo的配置,以及引用的服务配置,与provider的配置进行对照。
5、dubbo服务调用效果
dubbo应用,首先开启zookeeper服务,接着开启dubbo admin 应用,可以在web上看到 dubbo服务的相关情况。然后开启dubbo 服务端程序(Provider),最后运行dubbo 客户端(Consumer),客户端运行结果如下:
因为dubbo admin 有前台界面可以对服务和消费者进行监控,我们可以看一下 web界面的呈现内容:
RPC实践(四)Dubbo实践