Duboo文档阅读-用户指南(2)
来源:互联网 发布:云计算平台架构 编辑:程序博客网 时间:2024/05/16 17:49
作者:刘海龙
微博:[http://weibo.com/liuhailong2008]
博客:[http://blog.csdn.net/stationxp]2015-02-17 天园小区
计划是这样的:先把Duboo所有文档看一遍;然后启动起来,玩一把;然后看源码汲取营养;最后再把文档过一遍。
用户指南部分篇幅较长,本次涉及:协议参考、注册中心参考、Telnet命令参考、Maven、基准测试工具包
服务容器
服务容器是一个standalone的启动程序,因为后台服务不需要Tomcat或JBoss等Web容器的功能,如果硬要用Web容器去加载服务提供方,增加复杂性,也浪费资源。
服务容器只是一个简单的Main方法,并加载一个简单的Spring容器,用于暴露服务。
服务容器的加载内容可以扩展,内置了spring, jetty, log4j等加载,可通过Container扩展点进行扩展,参见:Container。
(缺省只加载spring)
java com.alibaba.dubbo.container.Main
(通过main函数参数传入要加载的容器)
java com.alibaba.dubbo.container.Main spring jetty log4j
java com.alibaba.dubbo.container.Main -Ddubbo.container=spring,jetty,log4j
Reference Config缓存
ReferenceConfig实例很重,封装了与注册中心的连接以及与提供者的连接,需要缓存,否则重复生成ReferenceConfig可能造成性能问题并且会有内存和连接泄漏。API方式编程时,容易忽略此问题。
Dubbo 2.4.0+版本,提供了简单的工具类ReferenceConfigCache用于缓存ReferenceConfig实例。
使用方式如下:
ReferenceConfig reference = new ReferenceConfig();
reference.setInterface(XxxService.class);
reference.setVersion(“1.0.0”);
……
ReferenceConfigCache cache = ReferenceConfigCache.getCache();
XxxService xxxService = cache.get(reference); // cache.get方法中会Cache Reference对象,并且调用ReferenceConfig.get方法启动ReferenceConfig
// 注意! Cache会持有ReferenceConfig,不要在外部再调用ReferenceConfig的destroy方法,导致Cache内的ReferenceConfig失效!
// 使用xxxService对象
xxxService.sayHello();
API参考手册
协议参考手册
注册中心
参数验证
基于JSR303实现的,用户只需标识JSR303标准的验证Annotation,并通过声明filter来实现验证。
import java.io.Serializable;import java.util.Date;import javax.validation.constraints.Future;import javax.validation.constraints.Max;import javax.validation.constraints.Min;import javax.validation.constraints.NotNull;import javax.validation.constraints.Past;import javax.validation.constraints.Pattern;import javax.validation.constraints.Size;public class ValidationParameter implements Serializable { private static final long serialVersionUID = 7158911668568000392L; @NotNull // 不允许为空 @Size(min = 1, max = 20) // 长度或大小范围 private String name; @NotNull(groups = ValidationService.Save.class) // 保存时不允许为空,更新时允许为空 ,表示不更新该字段 @Pattern(regexp = "^\\s*\\w+(?:\\.{0,1}[\\w-]+)*@[a-zA-Z0-9]+(?:[-.][a-zA-Z0-9]+)*\\.[a-zA-Z]+\\s*$") private String email; @Min(18) // 最小值 @Max(100) // 最大值 private int age; @Past // 必须为一个过去的时间 private Date loginDate; @Future // 必须为一个未来的时间 private Date expiryDate; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Date getLoginDate() { return loginDate; } public void setLoginDate(Date loginDate) { this.loginDate = loginDate; } public Date getExpiryDate() { return expiryDate; } public void setExpiryDate(Date expiryDate) { this.expiryDate = expiryDate; }}
验证异常信息的处理:
try { parameter = new ValidationParameter(); validationService.save(parameter); System.out.println("Validation ERROR"); } catch (RpcException e) { // 抛出的是RpcException ConstraintViolationException ve = (ConstraintViolationException) e.getCause(); // 里面嵌了一个ConstraintViolationException Set<ConstraintViolation<?>> violations = ve.getConstraintViolations(); // 可以拿到一个验证错误详细信息的集合 System.out.println(violations); }
需要封装一个工具方法,判断RpcException中是否包含 ConstraintViolationException和violation的个数。
结果缓存
lru 基于最近最少使用原则删除多余缓存,保持最热的数据被缓存。
threadlocal 当前线程缓存,比如一个页面渲染,用到很多portal,每个portal都要去查用户信息,通过线程缓存,可以减少这种多余访问。
jcache 与JSR107集成,可以桥接各种缓存实现。
缓存类型可扩展,参见:CacheFactory扩展点
泛化引用
泛接口调用方式主要用于客户端没有API接口及模型类元的情况,参数及返回值中的所有POJO均用Map表示,通常用于框架集成,比如:实现一个通用的服务测试框架,可通过GenericService调用所有服务实现。
GenericService barService = (GenericService) applicationContext.getBean(“barService”);
Object result = barService.$invoke(“sayHello”, new String[] { “java.lang.String” }, new Object[] { “World” });
回声测试
回声测试用于检测服务是否可用,回声测试按照正常请求流程执行,能够测试整个调用是否通畅,可用于监控。
所有服务自动实现EchoService接口,只需将任意服务引用强制转型为EchoService,即可使用。
String status = echoService.$echo(“OK”); // 回声测试可用性
assert(status.equals(“OK”))
上下文
boolean isProviderSide = RpcContext.getContext().isProviderSide(); // 本端是否为提供端,这里会返回true
String clientIP = RpcContext.getContext().getRemoteHost(); // 获取调用方IP地址
String application = RpcContext.getContext().getUrl().getParameter(“application”); // 获取当前服务配置信息,所有配置信息都将转换为URL的参数
// …
yyyService.yyy(); // 注意:每发起RPC调用,上下文状态会变化
boolean isProviderSide = RpcContext.getContext().isProviderSide(); // 此时本端变成消费端,这里会返回false
// …
隐式传参
path,group,version,dubbo,token,timeout几个key有特殊处理,请使用其它key值。
异步调用
适用于特别耗时的操作。
本地调用
本地调用,使用了Injvm协议,是一个伪协议,它不开启端口,不发起远程调用,只在JVM内直接关联,但执行Dubbo的Filter链。
好好考察一下效率。
协议参考
Simple监控中心
<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-2.5.xsdhttp://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <!-- 当前应用信息配置 --> <dubbo:application name="simple-monitor" /> <!-- 连接注册中心配置 --> <dubbo:registry address="127.0.0.1:9090" /> <!-- 暴露服务协议配置 --> <dubbo:protocol port="7070" /> <!-- 暴露服务配置 --> <dubbo:service interface="com.alibaba.dubbo.monitor.MonitorService" ref="monitorService" /> <bean id="monitorService" class="com.alibaba.dubbo.monitor.simple.SimpleMonitorService" /></beans>
暴露一个简单监控中心服务,但不注册到注册中心: (如果是用安装包,不需要自己写这个配置,如果是自己实现监控中心,则需要)
<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-2.5.xsdhttp://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <!-- 当前应用信息配置 --> <dubbo:application name="simple-monitor" /> <!-- 暴露服务协议配置 --> <dubbo:protocol port="7070" /> <!-- 暴露服务配置 --> <dubbo:service interface="com.alibaba.dubbo.monitor.MonitorService" ref="monitorService" registry="N/A" /> <bean id="monitorService" class="com.alibaba.dubbo.monitor.simple.SimpleMonitorService" /></beans>
直连监控中心服务:
注册中心参考
multicast注册中心
不需要启动任何中心节点,只需要广播地址一样,就可以互相发现。
组播地址段: 224.0.0.0 - 239.255.255.255
提供方启动时广播自己的地址。
消费方启动时广播订阅请求。
提供方收到订阅请求时,单播自己的地址给订阅者,如果设置了unicast=false,则广播给订阅者。
消费方收到提供方地址时,连接该地址进行RPC调用。
Zookeeper注册中心
安装方式参见: Zookeeper安装手册,只需搭一个原生的Zookeeper服务器,并将Quick Start中Provider和Consumer里的conf/dubbo.properties中的dubbo.registry.addrss的值改为zookeeper://127.0.0.1:2181即可使用。
zookeeper实现:https://github.com/sgroschupf/zkclient 。
http://repo1.maven.org/maven2/com/github/sgroschupf/zkclient
Redis注册中心
只需搭一个原生的Redis服务器,并将Quick Start中Provider和Consumer里的conf/dubbo.properties中的dubbo.registry.addrss的值改为redis://127.0.0.1:6379即可使用。
Redis过期数据
通过心跳的方式检测脏数据,服务器时间必须相同,并且对服务器有一定压力。
数据结构:
使用Redis的Key/Map结构存储数据。
主Key为服务名和类型。
Map中的Key为URL地址。
Map中的Value为过期时间,用于判断脏数据,脏数据由监控中心删除。(注意:服务器时间必需同步,否则过期检测会不准确)
使用Redis的Publish/Subscribe事件通知数据变更。
通过事件的值区分事件类型:register, unregister, subscribe, unsubscribe。
普通消费者直接订阅指定服务提供者的Key,只会收到指定服务的register, unregister事件。
监控中心通过psubscribe功能订阅/dubbo/*,会收到所有服务的所有变更事件。
调用过程:
服务提供方启动时,向Key:/dubbo/com.foo.BarService/providers下,添加当前提供者的地址。
并向Channel:/dubbo/com.foo.BarService/providers发送register事件。
服务消费方启动时,从Channel:/dubbo/com.foo.BarService/providers订阅register和unregister事件。
并向Key:/dubbo/com.foo.BarService/providers下,添加当前消费者的地址。
服务消费方收到register和unregister事件后,从Key:/dubbo/com.foo.BarService/providers下获取提供者地址列表。
服务监控中心启动时,从Channel:/dubbo/*订阅register和unregister,以及subscribe和unsubsribe事件。
服务监控中心收到register和unregister事件后,从Key:/dubbo/com.foo.BarService/providers下获取提供者地址列表。
服务监控中心收到subscribe和unsubsribe事件后,从Key:/dubbo/com.foo.BarService/consumers下获取消费者地址列表。
选项:
可通过设置redis中key的前缀,缺省为dubbo。
可通过设置redis集群策略,缺省为failover。
failover: 只写入和读取任意一台,失败时重试另一台,需要服务器端自行配置数据同步。
replicate: 在客户端同时写入所有服务器,只读取单台,服务器端不需要同步,注册中心集群增大,性能压力也会更大。
Simple注册中心
Dogfooding
注册中心本身就是一个普通的Dubbo服务,可以减少第三方依赖,使整体通讯方式一致。
适用性说明
此SimpleRegistryService只是简单实现,不支持集群,可作为自定义注册中心的参考,但不适合直接用于生产环境。
<?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-2.5.xsdhttp://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <!-- 当前应用信息配置 --> <dubbo:application name="simple-registry" /> <!-- 暴露服务协议配置 --> <dubbo:protocol port="9090" /> <!-- 暴露服务配置 --> <dubbo:service interface="com.alibaba.dubbo.registry.RegistryService" ref="registryService" registry="N/A" ondisconnect="disconnect" callbacks="1000"> <dubbo:method name="subscribe"><dubbo:argument index="1" callback="true" /></dubbo:method> <dubbo:method name="unsubscribe"><dubbo:argument index="1" callback="false" /></dubbo:method> </dubbo:service> <!-- 简单注册中心实现,可自行扩展实现集群和状态同步 --> <bean id="registryService" class="com.alibaba.dubbo.registry.simple.SimpleRegistryService" /></beans>
Telnet命令参考
支持telnet对服务进行调试、管理,还可以扩展。
Maven
mvn duboo:registry -Dport=x
基准测试包
benchmark-2..214.tar.gz
- Duboo文档阅读-用户指南(2)
- Duboo文档阅读-用户指南(1)
- duboo
- commons-fileupload用户指南(文档翻译)
- commons-fileupload用户指南(文档翻译)
- MonetDB用户指南0——Reader's guide文档阅读指导
- 构建jBPM用户指南文档
- srilm 阅读文档2
- Velocity用户指南(中文版)(2)
- Velocity用户指南(中文版)(2)
- commons-fileupload用户指南(文档翻译
- 《Apache Velocity用户指南》官方文档
- pyqt4文档阅读(2):QSlider
- duboo注解
- Struts 框架技术用户指南(一) (2)
- jBPM jPDL3.2用户指南(中文版)
- 【Flume NG用户指南】(2)配置
- 2、restlet 2.3 用户指南(二)初窥
- [ LeetCode] Remove Duplicates from Sorted Array
- Leetcode NO.118 Pascal's Triangle
- 自定义字符流缓冲区
- 5 intent
- 5 Your TabHost must have a TabWidget whose id attribute is ‘android.R.id.tabcontent’
- Duboo文档阅读-用户指南(2)
- day5代码积累
- 弹出蒙层
- php 对传递过来的变量判断是否存在
- (整理)非常全面的PNG开发资源
- ajax --- jquery + php 代码整理
- Java开发者易犯错误Top10
- 【java编程】Collection类之ArrayList去除自定义对象的重复元素
- 6 Resource