1. Dubbo是什么?
Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。简单的说,dubbo就是个服务框架,如果没有分布式的需求,其实是不需要用的,只有在分布式的时候,才有dubbo这样的分布式服务框架的需求,并且本质上是个服务调用的东东,说白了就是个远程服务调用的分布式框架(告别Web Service模式中的WSdl,以服务者与消费者的方式在dubbo上注册)
其核心部分包含:1. 远程通讯: 提供对多种基于长连接的NIO框架抽象封装,包括多种线程模型,序列化,以及“请求-响应”模式的信息交换方式。2. 集群容错: 提供基于接口方法的透明远程过程调用,包括多协议支持,以及软负载均衡,失败容错,地址路由,动态配置等集群支持。3. 自动发现: 基于注册中心目录服务,使服务消费方能动态的查找服务提供方,使地址透明,使服务提供方可以平滑增加或减少机器。
2. Dubbo能做什么?
1.透明化的远程方法调用,就像调用本地方法一样调用远程方法,只需简单配置,没有任何API侵入。 2.软负载均衡及容错机制,可在内网替代F5等硬件负载均衡器,降低成本,减少单点。3. 服务自动注册与发现,不再需要写死服务提供方地址,注册中心基于接口名查询服务提供者的IP地址,并且能够平滑添加或删除服务提供者。Dubbo采用全Spring配置方式,透明化接入应用,对应用没有任何API侵入,只需用Spring加载Dubbo的配置即可,Dubbo基于Spring的Schema扩展进行加载。
3. dubbo的架构
dubbo架构图如下所示:
[img]http://dl2.iteye.com/upload/attachment/0119/3214/ac7f0528-a4ae-3c5b-9bab-2b7c5c4216ef.jpg" alt="[/img]
节点说明:
Consumer: 调用远程服务的服务消费方。
Monitor: 统计服务的调用次调和调用时间的监控中心。
调用关系说明:
0. 服务容器负责启动,加载,运行服务提供者。
1. 服务提供者在启动时,向注册中心注册自己提供的服务。
2. 服务消费者在启动时,向注册中心订阅自己所需的服务。
3. 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
4. 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
5. 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
4. dubbo使用
spring配置方式的写法:
服务提供者:
1.下载zookeeper注册中心,下载地址:http://www.apache.org/dyn/closer.cgi/zookeeper/ 下载后解压即可,进入D:\zookeeper\bin,双击zkServer.cmd启动注册中心服务。
2.定义服务接口:
package com.test.dubbo.service;
import java.util.List;
public interface DemoService {
String sayHello(String name);
public List getUsers();
}
在服务提供方实现接口:
package com.test.dubbo.service.impl; import com.test.dubbo.entity.User; import com.test.dubbo.service.DemoService; import java.util.ArrayList; import java.util.List; public class DemoServiceImpl implements DemoService { @Override public String sayHello(String name) { return "Hello " + name; } @Override public List getUsers() { List list = new ArrayList(); User u1 = new User(); u1.setName("siheyuan"); u1.setAge(20); u1.setSex("f"); User u2 = new User(); u2.setName("batasi"); u2.setAge(21); u2.setSex("m"); list.add(u1); list.add(u2); return list; } }
3.spring服务配置
>dubbo-provider.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 "> <!-- 具体的实现bean --> <bean id="demoService" class="com.test.dubbo.service.impl.DemoServiceImpl" /> <!-- 提供方应用信息,用于计算依赖关系 --> <dubbo:application name="demo_provider" /> <!-- 使用multicast广播注册中心暴露服务地址 --> <!--<dubbo:registry address="multicast://224.5.6.7:1234" /> --> <!-- 使用zookeeper注册中心暴露服务地址 即zookeeper的所在服务器ip地址和端口号 --> <dubbo:registry address="zookeeper://192.168.1.83:2181" /> <!-- 用dubbo协议在20880端口暴露服务 --> <dubbo:protocol name="dubbo" port="20880" /> <!-- 声明需要暴露的服务接口 --> <dubbo:service interface="com.test.dubbo.service.DemoService" ref="demoService" /> </beans>
>applicationContext.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:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd"> <!-- 引入属性文件 --> <context:property-placeholder location="classpath:config.properties" /> <!-- 自动扫描(自动注入) --> <context:component-scan base-package="com.test.dubbo" /> </beans>
>spring-mvc.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:task="http://www.springframework.org/schema/task" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.1.xsd"> <task:annotation-driven/> <!-- 引入属性文件 --> <context:property-placeholder location="classpath:config.properties"/> <!-- 自动扫描controller包下的所有类,使其认为spring mvc的控制器 --> <context:component-scan base-package="com.test.dubbo" /> <!-- 配置页面跳转 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/default/" /> <property name="suffix" value=".jsp" /> </bean> <!-- 避免IE执行AJAX时,返回JSON出现下载文件 --> <bean id="mappingJackson2HttpMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>text/plain;charset=UTF-8</value> </list> </property> </bean> <!-- 启动Spring MVC的注解功能,完成请求和注解POJO的映射 --> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="messageConverters"> <list> <ref bean="mappingJackson2HttpMessageConverter" /><!-- json转换器 --> </list> </property> </bean> <mvc:annotation-driven conversion-service="conversionService" /> <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> </bean> <!-- 对模型视图名称的解析,即在模型视图名称添加前后缀 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/" p:suffix=".jsp" /> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="defaultEncoding"> <value>UTF-8</value> </property> <property name="maxUploadSize"> <value>32505856</value><!-- 上传文件大小限制为31M,31*1024*1024 --> </property> <property name="maxInMemorySize"> <value>4096</value> </property> </bean> </beans>
>User.java
package com.test.dubbo.entity; import java.io.Serializable; public class User implements Serializable { private String name; private int age; private String sex; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } }
>config.properties这个可以创建空文件即可
启动服务
package com.test.dubbo.provider; import org.springframework.context.support.ClassPathXmlApplicationContext; public class ProviderTest { public static void main(String[] args) throws Exception { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( new String[] { "applicationContext.xml","dubbo-provider.xml" }); context.start(); System.in.read(); // 为保证服务一直开着,利用输入流的阻塞来模拟 } }
3.服务消费者
1.配置远程服务的引用
>dubbo-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/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="test_consumer" /> <!-- 使用zookeeper注册中心暴露服务地址 --> <!-- <dubbo:registry address="multicast://224.5.6.7:1234" /> --> <dubbo:registry address="zookeeper://192.168.1.83:2181" /> <!-- 生成远程服务代理,可以像使用本地bean一样使用demoService --> <dubbo:reference id="demoService" interface="com.test.dubbo.service.DemoService" /> </beans>
2.调用远程服务
package com.test.dubbo.consumer; import com.test.dubbo.service.DemoService; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.io.IOException; import java.util.List; public class ConsumerTest { public static void main(String[] args) throws IOException { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( new String[] { "applicationContext.xml","dubbo-consumer.xml" }); context.start(); DemoService demoService = (DemoService) context.getBean("demoService"); String hello = demoService.sayHello("Beijing"); System.out.println(hello); List list = demoService.getUsers(); if (list != null && list.size() > 0) { for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); } } System.in.read(); } }
以上为主要代码,直接运行两个test即可。代码请下载附件。