dubbo中的各种协议
在Dubbo中使用Kryo序列化协议
在Dubbo中使⽤Kryo序列化协议Kryo是什么?Kryo是⽤于Java的快速⾼效的⼆进制对象图序列化框架。
该项⽬的⽬标是⾼速,⼩尺⼨和易于使⽤的API。
不管是将对象持久保存到⽂件、数据库还是通过⽹络传输时,都可以尝试Kryo。
Kryo还可以执⾏⾃动的深浅复制/克隆。
这是从对象到对象的直接复制,⽽不是从对象到字节的复制。
具体可以参考在Dubbo中使⽤Kryo本⽂基于Dubbo版本2.7.8Dubbo⽀持⾮常多的序列化⽅式,如hession2、avro、FST等等,其中Dubbo官⽹推荐的序列化⽅式是Kryo,因为Kryo是⼀种⾮常成熟的序列化实现,已经在Twitter、Groupon、Yahoo以及多个著名开源项⽬(如Hive、Storm)中⼴泛的使⽤。
开始在Dubbo中使⽤Kryo⾮常⽅便,⾸先引⼊依赖// 解决⼀些Kryo特殊序列化,https:///magro/kryo-serializersimplementation 'de.javakaffee:kryo-serializers:0.43'// ⾼性能序列化框架, https:///EsotericSoftware/kryoimplementation 'com.esotericsoftware:kryo:4.0.2'如果只是简单使⽤,引⼊即可,如果要⽀持⼀些例如List接⼝,则需要引⼊,它针对⼀些特殊类为Kryo做了适配。
配置在Dubbo中启⽤Kryo序列化⽅式,这⾥使⽤SpringBoot YML配置⽅式protocol:serialization: kryooptimizer: org.hmwebframework.microservice.dubbo.serialize.SerializationOptimizerImpl其中org.hmwebframework.microservice.dubbo.serialize.SerializationOptimizerImpl是指定Kryo序列化类,例如public class SerializationOptimizerImpl implements SerializationOptimizer {public Collection<Class> getSerializableClasses() {List<Class> classes = new LinkedList<Class>();classes.add(BidRequest.class);classes.add(BidResponse.class);classes.add(Device.class);classes.add(Geo.class);classes.add(Impression.class);classes.add(SeatBid.class);return classes;}}到这,Dubbo使⽤Kryo就已经OK了。
dubbo 的rpc 调用原理
dubbo 的rpc 调用原理Dubbo是一种高性能、轻量级的远程过程调用(RPC)框架,由阿里巴巴集团开发并开源。
它基于Java语言,提供了分布式应用的服务治理和调用功能,可以实现不同应用之间的远程通信。
Dubbo的RPC调用原理主要包括服务注册与发现、负载均衡、远程通信和序列化等几个关键步骤。
Dubbo通过服务注册与发现来管理服务的提供者和消费者。
服务提供者在启动时,会将自己提供的服务注册到注册中心,包括服务的名称、版本、地址等信息。
消费者在启动时,会从注册中心获取可用的服务提供者列表。
这样,消费者就可以根据服务名称和版本,选择合适的服务提供者进行调用。
Dubbo通过负载均衡来选择合适的服务提供者。
当消费者需要调用某个服务时,Dubbo会根据负载均衡算法选择一个服务提供者进行调用。
常见的负载均衡算法有随机、轮询、加权随机等。
负载均衡的目的是为了保证服务提供者之间的负载均衡,避免某个服务提供者过载或负载不均衡。
接下来,Dubbo通过远程通信来实现服务的调用。
Dubbo支持多种远程通信协议,包括Dubbo协议、HTTP协议、RMI协议等。
服务提供者和消费者之间通过网络进行通信,使用相应的协议进行数据传输。
Dubbo提供了连接管理、请求响应、心跳检测等功能,保证了远程通信的可靠性和稳定性。
Dubbo通过序列化来实现参数的传输。
在服务调用过程中,消费者需要将参数序列化为字节流进行传输,而服务提供者需要将字节流反序列化为参数进行处理。
Dubbo支持多种序列化协议,包括Hessian、Java原生序列化、JSON等。
序列化协议的选择需要考虑性能、安全性和兼容性等因素。
总的来说,Dubbo的RPC调用原理是通过服务注册与发现、负载均衡、远程通信和序列化等步骤实现的。
通过这些步骤,Dubbo可以实现服务的自动发现和调用,提供了高性能和可靠性的远程通信能力。
Dubbo在大规模分布式系统中得到了广泛应用,成为了构建微服务架构的重要基础设施之一。
dubbo调用原理
dubbo调用原理
Dubbo是一种高性能的RPC(Remote Procedure Call)框架,用
于简化分布式系统中的远程调用。
Dubbo主要解决了分布式应用中服务治理、远程调用、负载均衡、服务路由、容错处理、协议透明等问题,使得调用者可以像调用本地服务一样调用远程服务,并实现高效、可靠、透明的远程服务调用。
在Dubbo中,服务提供者将自己的服务发布到注册中心,消费者
从注册中心订阅服务,客户端通过负载均衡算法选择一个服务提供者
节点,并将远程调用请求发送到服务提供者节点。
在服务提供者节点
接收请求后,Dubbo框架会根据服务协议、序列化方式、负载均衡策略、容错策略等多个因素,将请求分发到具体的服务实现类中,并将执行
结果返回给消费方。
Dubbo框架通过代码嵌入式(AOP)和API两种方式实现服务远程调用。
在AOP方式下,Dubbo在服务提供方和消费方之间对应用进行透明代理,从而实现远程调用;而在API方式下,Dubbo提供了一系列
API接口,方便应用程序通过调用Dubbo提供的API实现服务的远程调用。
总之,Dubbo通过注册中心、负载均衡、容错处理等机制,实现
了服务治理,同时支持多种协议、序列化方式、负载均衡策略、容错
策略等,可以保证服务调用的高效、可靠、透明。
java分布式技术方案
Java分布式技术方案引言随着互联网的快速发展,大规模分布式系统的需求越来越多。
分布式系统能够提供高可用性、横向扩展和容错性等优势,使得系统能够应对高并发、海量数据的处理需求。
Java作为一种高效、可靠的编程语言,在构建分布式系统方面具有广泛的应用。
本文将介绍一些常见的Java分布式技术方案,包括Dubbo、Spring Cloud和Apache Kafka等。
1. DubboDubbo是阿里巴巴开源的一款高性能、轻量级分布式服务框架。
它具有简单易用、可扩展性强的特点,可以帮助开发者快速构建分布式系统。
Dubbo提供了丰富的特性,包括服务治理、负载均衡、集群容错、动态配置等,可以满足不同规模的分布式系统需求。
Dubbo的架构包括服务提供者、服务消费者和注册中心三个角色。
服务提供者将服务注册到注册中心,服务消费者从注册中心获取服务地址,然后通过远程调用实现服务通信。
Dubbo支持多种通信协议,包括Dubbo协议、REST协议和Hessian协议等。
此外,在高并发场景下,Dubbo还支持多种负载均衡策略和集群容错机制,保证系统的稳定性和性能。
2. Spring CloudSpring Cloud是一套快速构建分布式系统的工具集合,基于Spring框架。
它提供了一系列的解决方案,帮助开发者实现服务注册与发现、负载均衡、断路器、网关等功能。
Spring Cloud利用Netflix开源的组件构建分布式系统。
其中,Eureka是用于服务注册与发现的组件,可以使服务提供者和消费者自动实现发现和通信。
Ribbon是一种客户端负载均衡的组件,可以根据配置和负载算法,将请求分发到不同的服务实例。
Hystrix是一种断路器模式的实现,可以保护整个系统免受故障服务的影响。
Zuul是一种服务网关,可以提供动态路由和过滤器等功能。
Spring Cloud通过使用这些组件,可以极大地简化分布式系统的开发和部署。
它提供了一致的开发模型和配置方式,使得开发者可以专注于业务逻辑的实现。
dubbo的执行流程
dubbo的执行流程Dubbo的执行流程1. 介绍Dubbo是一种高性能的Java RPC框架,主要用于大规模分布式应用的服务化治理。
在使用Dubbo时,了解其执行流程是非常重要的。
2. 执行流程概述Dubbo的执行流程可以概括为以下几个步骤:1.服务的暴露:提供者将自己的服务接口发布到注册中心。
通过配置文件或注解,Dubbo会将服务发布到注册中心,让消费者能够发现和调用该服务。
2.服务的引用:消费者通过从注册中心获取提供者的地址信息,创建一个服务代理对象。
这个服务代理对象可以像调用本地方法一样调用远程服务。
3.通信过程:当消费者需要调用远程方法时,Dubbo使用底层的通信协议进行远程调用。
Dubbo支持多种通信协议,包括Dubbo协议、HTTP协议和RMI协议等。
4.负载均衡:如果一个服务有多个提供者,Dubbo会根据负载均衡策略选择其中一个提供者进行调用。
这样可以提高系统的并发能力和性能。
5.集群容错:如果某个提供者出现故障或网络异常,Dubbo会根据配置的容错策略进行处理。
例如,可以选择忽略异常、返回默认值或重试等。
3. 服务的暴露在Dubbo中,服务的暴露是通过配置文件或注解来完成的。
以下是服务暴露的一些关键步骤:•配置服务的接口和实现类。
•配置服务的协议和端口号。
•配置注册中心的地址和信息。
•使用Dubbo容器加载上述配置,并生成代理对象。
•将代理对象发布到注册中心。
4. 服务的引用服务的引用是消费者使用远程服务的过程。
以下是服务引用的一些关键步骤:•配置消费者要引用的服务接口和版本号。
•从注册中心获取提供者的地址信息,并创建代理对象。
•使用代理对象调用远程服务。
5. 通信过程Dubbo使用底层的通信协议进行远程调用。
以下是通信过程的一些关键步骤:•封装调用请求:Dubbo将用户的调用请求封装成一个调用对象,并序列化成二进制数据。
•选择通信协议:Dubbo支持多种通信协议,根据配置选择其中一种协议。
dubbo,hessian协议
dubbo,hessian协议竭诚为您提供优质文档/双击可除dubbo,hessian协议篇一:dubbo官方配置指南configurationReferenceconfigurationRelation:sla配置在此完成!servicelayeragreementapplicationconfig应用配置,用于配置当前应用信息,不管该应用是提供者还是消费者。
Registryconfig注册中心配置,用于配置连接注册中心相关信息。
protocolconfig协议配置,用于配置提供服务的协议信息,协议由提供方指定,消费方被动接受。
serviceconfig服务配置,用于暴露一个服务,定义服务的元信息,一个服务可以用多个协议暴露,一个服务也可以注册到多个注册中心。
providerconfig提供方的缺省值,当protocolconfig 和serviceconfig某属性没有配置时,采用此缺省值。
Referenceconfig引用配置,用于创建一个远程服务代理,一个引用可以指向多个注册中心。
consumerconfig消费方缺省配置,当Referenceconfig 某属性没有配置时,采用此缺省值。
methodconfig方法配置,用于serviceconfig和Referenceconfig指定方法级的配置信息。
argumentconfig用于指定方法参数配置。
configurationoverride:上图中以timeout为例,显示了配置的查找顺序,其它retries,loadbalance,actives等类似。
方法级优先,接口级次之,全局配置再次之。
如果级别一样,则消费方优先,提供方次之。
其中,服务提供方配置,通过uRl经由注册中心传递给消费方。
建议由服务提供方设置超时,因为一个方法需要执行多长时间,服务提供方更清楚,如果一个消费方同时引用多个服务,就不需要关心每个服务的超时设置。
理论上Referenceconfig的非服务标识配置,在consumerconfig,serviceconfig,providerconfig均可以缺省配置。
dubbo系列六、dubbo路由规则以及tag路由
dubbo系列六、dubbo路由规则以及tag路由dubbo路由1.dubbo路由简介dubbo路由的作⽤是在RegistryDirectory获取到Invoker集合后,先根据路由集合进⾏路由过滤,路由集合即RegistryDirectory.routers,默认是[TagRouter,MockInvokersSelector],如果使⽤了条件路由则是[ConditionRouter, TagRouter,MockInvokersSelector],其中ConditionRouter是条件路由,由ConditionRouterFactory创建,TagRouter是标签路由,dubbo2.6.5新增,MockInvokersSelector是mock路由,⽤于mock降级。
此外还有个脚本路由ScriptRouter,由ScriptRouterFactory创建。
RouterFactory是个SPI扩展,可以使⽤它扩展新的路由规则。
TagRouter和MockInvokersSelector是在RegistryDirectory创建时候通过setRouters⾃动增加,没有对应的XXXRouterFactory,那么ConditionRouter在哪⾥创建的呢?2.dubbo路由的创建路由的创建在com.alibaba.dubbo.registry.integration.RegistryDirectory.notify(List<URL>)内,该⽅法在dubbo consumer启动时候调⽤和zk节点providers、configurators、routers发⽣变化时候,zk触发consumer端执⾏。
@Overridepublic synchronized void notify(List<URL> urls) {List<URL> invokerUrls = new ArrayList<URL>();List<URL> routerUrls = new ArrayList<URL>();List<URL> configuratorUrls = new ArrayList<URL>();for (URL url : urls) {String protocol = url.getProtocol();String category = url.getParameter(Constants.CATEGORY_KEY, Constants.DEFAULT_CATEGORY);if (Constants.ROUTERS_CATEGORY.equals(category)|| Constants.ROUTE_PROTOCOL.equals(protocol)) {routerUrls.add(url);//把routers节点下的url保存到routerUrls集合} else if (Constants.CONFIGURATORS_CATEGORY.equals(category)|| Constants.OVERRIDE_PROTOCOL.equals(protocol)) {configuratorUrls.add(url);} else if (Constants.PROVIDERS_CATEGORY.equals(category)) {invokerUrls.add(url);} else {logger.warn("Unsupported category " + category + " in notified url: " + url + " from registry " + getUrl().getAddress() + " to consumer " + NetUtils.getLocalHost());}}//其它省略// routersif (routerUrls != null && !routerUrls.isEmpty()) {List<Router> routers = toRouters(routerUrls);//toRouters是把zk上routers节点转换为路由集合if (routers != null) { // null - do nothingsetRouters(routers);}}//其它省略}接着看toRouters,代码如下private List<Router> toRouters(List<URL> urls) {List<Router> routers = new ArrayList<Router>();if (urls == null || urls.isEmpty()) {return routers;}if (urls != null && !urls.isEmpty()) {for (URL url : urls) {if (Constants.EMPTY_PROTOCOL.equals(url.getProtocol())) {//routers节点下的url是empty协议,忽略,继续遍历continue;}String routerType = url.getParameter(Constants.ROUTER_KEY);//获取router url上的router节点值if (routerType != null && routerType.length() > 0) {url = url.setProtocol(routerType);//路由协议router://转换为具体的协议,⽐如condition://协议}try {Router router = routerFactory.getRouter(url);//dubbo spi机制获取对应的路由if (!routers.contains(router))routers.add(router);} catch (Throwable t) {logger.error("convert router url to router error, url: " + url, t);}}}return routers;}toRouters逻辑也简单,如果是router url是empty协议,忽略,继续遍历,接着获取router url上的router节点值,然后根据spi机制获取对应的路由对象,最后返回获取的路由集合。
dubbo支持的协议
dubbo支持的协议Dubbo支持的协议。
Dubbo是一款高性能的Java RPC框架,可以帮助用户快速构建分布式服务。
在Dubbo中,协议是非常重要的一部分,它定义了服务之间通信的规则和方式。
Dubbo支持多种协议,包括Dubbo协议、RMI协议、Hessian协议、HTTP协议、WebService协议等。
每种协议都有其特点和适用场景,下面我们来详细了解一下Dubbo支持的各种协议。
1. Dubbo协议。
Dubbo协议是Dubbo框架自己定义的一种RPC协议,它基于Netty实现,采用单一长连接和NIO异步通讯,适合于服务消费方数量多、服务提供方数量少的情况。
Dubbo协议的优点是在低延迟和高吞吐量方面表现优异,适合内部服务调用。
2. RMI协议。
RMI(Remote Method Invocation)是Java远程方法调用的一种方式,Dubbo框架对RMI进行了封装,使得RMI协议可以适用于Dubbo框架。
RMI协议的优点是使用简单,适合Java语言开发的服务之间通讯。
3. Hessian协议。
Hessian是一种基于HTTP的轻量级的远程调用协议,Dubbo框架支持Hessian 协议作为服务提供方和消费方之间的通讯协议。
Hessian协议的优点是跨语言支持好,适合异构系统的集成。
4. HTTP协议。
Dubbo框架支持基于HTTP的远程调用协议,这种协议可以通过HTTP的方式进行服务的调用和暴露。
HTTP协议的优点是与现有的基础设施兼容性好,适合在互联网环境下使用。
5. WebService协议。
Dubbo框架也支持基于WebService的远程调用协议,WebService是一种跨平台的、基于XML的标准协议,可以实现不同系统之间的互操作。
WebService协议的优点是与现有的企业服务集成好,适合企业内部系统集成。
在实际使用Dubbo框架时,我们可以根据具体的业务场景和需求选择合适的协议。
dubbo rpc调用流程及原理
dubbo rpc调用流程及原理Dubbo是一款高性能、轻量级的RPC框架,广泛应用于分布式系统中的服务调用。
本篇文章将详细介绍DubboRPC的调用流程及原理。
一、Dubbo框架概述Dubbo是一个基于Java开发的RPC框架,它提供了服务暴露、服务消费、负载均衡、监控等功能,旨在构建一个高可用、高性能的分布式系统。
Dubbo框架的特点包括:高性能、轻量级、灵活的扩展性、完善的监控机制等。
DubboRPC调用流程可以分为以下几个步骤:1.服务提供者注册:服务提供者在启动时,将自己暴露为远程服务,并将相关信息注册到注册中心。
注册中心负责管理服务提供者的信息,以便服务消费者可以方便地找到可用的服务。
2.服务消费者配置:服务消费者在启动时,从注册中心获取服务提供者的信息,并在本地进行配置。
这样,服务消费者就可以通过RPC 协议连接到服务提供者。
3.远程调用:服务消费者通过RPC协议向服务提供者发起调用请求,包括方法名、参数等信息。
服务提供者接收到请求后,执行相应的方法,并将结果返回给服务消费者。
4.结果返回:服务消费者接收到结果后,进行相应的处理,并将结果返回给调用方。
整个流程中,Dubbo框架提供了多种负载均衡策略,如随机、轮询、最少活跃调用等,以确保服务调用的公平性和高效性。
同时,Dubbo还支持多种通信协议,如HTTP、gRPC等,以满足不同场景下的需求。
三、DubboRPC原理DubboRPC原理主要包括以下几个部分:1.序列化与反序列化:Dubbo支持多种序列化协议,如Hessian2、Kryo、FST等。
服务提供者和消费者在通信时,采用适当的序列化协议进行数据交换,以确保数据传输的可靠性和效率。
2.通信协议:Dubbo支持多种通信协议,如Dubbo内置的HTTP、gRPC等。
在远程调用过程中,服务提供者和消费者通过通信协议进行数据交互,实现服务的远程调用。
3.线程模型:Dubbo采用多线程模型来处理服务调用请求。
微服务、dubbo、SpringCloud全部面试题-带答案解析
1.Dubbo推荐使用哪种协议(A)A.dubbo://B.rmi://C.rest://D.webservice://解析: Dubbo支持dubbo、rmi、hessian、http、webservice、thrift、redis等多种协议,但是Dubbo官网是推荐我们使用Dubbo协议的。
1、dubbo 协议采用单一长连接和NIO异步通讯,适合于小数据量大并发的服务调用,以及服务消费者机器数远大于服务提供者机器数的情况2、不适合传送大数据量的服务,比如传文件,传视频等,除非请求量很低。
针对每种协议的取舍,可以参考https:///xiaojin21cen/article/details/79834222。
2.Dubbo里面的非必备的节点角色是(D)A.Provider(服务提供者)B.Consumer(服务消费者)C.Registry(注册中心)D.Monitor(监控中心)解析:一个微服务中,必备的角色是Provider,Consumer,Registry3.Dubbo默认使用哪个注册中心(A)A.ZookeeperB.RedisC.MulticastD.Simple解析: Dubbo推荐使用 Zookeeper 作为注册中心,还有 Redis、Multicast、Simple 注册中心,但不推荐。
4.Dubbo中,在Provider(提供者)上可以配置Consumer(消费者)的属性有哪些(D)A.timeout:方法调用超时B.retries:失败重试次数,默认重试 2 次C.loadbalance:负载均衡算法,默认随机D.上述全部解析:在 Provider 上可以配置的 Consumer 端的属性有以下四种:(1)timeout:方法调用超时(2)retries:失败重试次数,默认重试 2 次(3)loadbalance:负载均衡算法,默认随机(4)actives 消费者端,最大并发调用限制5.Dubbo默认使用哪个容错方案(A)A.Failover Cluster (失败自动切换,自动重试其他服务器)B.Failfast Cluster (快速失败,立即报错,只发起一次调用)C.Failsafe Cluster (失败安全,出现异常时,直接忽略)D.Failback Cluster (失败自动恢复,记录失败请求,定时重发)解析:6.Dubbo默认用哪种负载均衡策略(A)A.Random LoadBalance (随机)B.RoundRobin LoadBalance (轮询)C.LeastActice LoadBalance (最少活跃)D.ConsistenHash LoadBalance (一致性Hash)解析: dubbo有以下四种负载均衡策略,默认使用随机策略。
Dubbo源码分析(六)Dubbo通信的编码解码机制
Dubbo源码分析(六)Dubbo通信的编码解码机制TCP的粘包拆包问题我们知道Dubbo的⽹络通信框架Netty是基于TCP协议的,TCP协议的⽹络通信会存在粘包和拆包的问题,先看下为什么会出现粘包和拆包当要发送的数据⼤于TCP发送缓冲区剩余空间⼤⼩,将会发⽣拆包待发送数据⼤于MSS(最⼤报⽂长度),TCP在传输前将进⾏拆包要发送的数据⼩于TCP发送缓冲区的⼤⼩,TCP将多次写⼊缓冲区的数据⼀次发送出去,将会发⽣粘包接收数据端的应⽤层没有及时读取接收缓冲区中的数据,将发⽣粘包以上四点基本上是出现粘包和拆包的原因,业界的解决⽅法⼀般有以下⼏种:将每个数据包分为消息头和消息体,消息头中应该⾄少包含数据包的长度,这样接收端在接收到数据后,就知道每⼀个数据包的实际长度了(Dubbo就是这种⽅案)消息定长,每个数据包的封装为固定长度,不够补0在数据包的尾部设置特殊字符,⽐如FTP协议Dubbo消息协议头规范在dubbo.io官⽹上找到⼀张图,协议头约定dubbo的消息头是⼀个定长的 16个字节的数据包:magic High & Magic Low:2byte:0-7位 8-15位:类似java字节码⽂件⾥的魔数,⽤来判断是不是dubbo协议的数据包,就是⼀个固定的数字Serialization id:1byte:16-20位:序列id,21 event,22 two way ⼀个标志位,是单向的还是双向的,23 请求或响应标识,status:1byte: 24-31位:状态位,设置请求响应状态,request为空,response才有值Id(long):8byte:32-95位:每⼀个请求的唯⼀识别id(由于采⽤异步通讯的⽅式,⽤来把请求request和返回的response对应上)data length:4byte:96-127位:消息体长度,int 类型看完这张图,⼤致可以理解Dubbo通信协议解决的问题,Dubbo采⽤消息头和消息体的⽅式来解决粘包拆包,并在消息头中放⼊了⼀个唯⼀Id来解决异步通信关联request和response的问题,下⾯以⼀次调⽤为⼊⼝分为四个部分来看下源码具体实现Comsumer端请求编码private class InternalEncoder extends OneToOneEncoder {@Overrideprotected Object encode(ChannelHandlerContext ctx, Channel ch, Object msg) throws Exception {com.alibaba.dubbo.remoting.buffer.ChannelBuffer buffer =com.alibaba.dubbo.remoting.buffer.ChannelBuffers.dynamicBuffer(1024);NettyChannel channel = NettyChannel.getOrAddChannel(ch, url, handler);try {codec.encode(channel, buffer, msg);} finally {NettyChannel.removeChannelIfDisconnected(ch);}return ChannelBuffers.wrappedBuffer(buffer.toByteBuffer());}}这个InternalEncoder是⼀个NettyCodecAdapter的内部类,我们看到codec.encode(channel, buffer, msg)这⾥,这个时候codec=DubboCountCodec,这个是在构造⽅法中传⼊的,DubboCountCodec.encode-->ExchangeCodec.encode-->ExchangeCodec.encodeRequestprotected void encodeRequest(Channel channel, ChannelBuffer buffer, Request req) throws IOException {//获取序列化⽅式,默认是Hessian序列化Serialization serialization = getSerialization(channel);// new了⼀个16位的byte数组,就是request的消息头byte[] header = new byte[HEADER_LENGTH];// 往消息头中set magic数字,这个时候header中前2个byte已经填充Bytes.short2bytes(MAGIC, header);// set request and serialization flag.第三个byte已经填充header[2] = (byte) (FLAG_REQUEST | serialization.getContentTypeId());if (req.isTwoWay()) header[2] |= FLAG_TWOWAY;if (req.isEvent()) header[2] |= FLAG_EVENT;// set request id.这个时候是0Bytes.long2bytes(req.getId(), header, 4);// 编码 request data.int savedWriteIndex = buffer.writerIndex();buffer.writerIndex(savedWriteIndex + HEADER_LENGTH);ChannelBufferOutputStream bos = new ChannelBufferOutputStream(buffer);//序列化ObjectOutput out = serialization.serialize(channel.getUrl(), bos);if (req.isEvent()) {encodeEventData(channel, out, req.getData());} else {//编码消息体数据encodeRequestData(channel, out, req.getData());}out.flushBuffer();bos.flush();bos.close();int len = bos.writtenBytes();checkPayload(channel, len);//在消息头中设置消息体长度Bytes.int2bytes(len, header, 12);// writebuffer.writerIndex(savedWriteIndex);buffer.writeBytes(header); // write header.buffer.writerIndex(savedWriteIndex + HEADER_LENGTH + len);}就是这⽅法,对request请求进⾏了编码操作,具体操作我写在代码的注释中,就是刚刚我们分析的消息头的代码实现Provider端请求解码看到NettyCodecAdapter中的InternalDecoder这个类的messageReceived⽅法,这⾥就是Provider端对于Consumer端的request请求的解码public void messageReceived(ChannelHandlerContext ctx, MessageEvent event) throws Exception {···try {// decode object.do {saveReaderIndex = message.readerIndex();try {msg = codec.decode(channel, message);} catch (IOException e) {buffer = com.alibaba.dubbo.remoting.buffer.ChannelBuffers.EMPTY_BUFFER;throw e;}···进⼊DubboCountCodec.decode--ExchangeCodec.decode// 检查 magic number.if (readable > 0 && header[0] != MAGIC_HIGH···}// check 长度如果⼩于16位继续等待if (readable < HEADER_LENGTH) {return DecodeResult.NEED_MORE_INPUT;}// get 消息体长度int len = Bytes.bytes2int(header, 12);checkPayload(channel, len);//消息体长度+消息头的长度int tt = len + HEADER_LENGTH;//如果总长度⼩于tt,那么返回继续等待if (readable < tt) {return DecodeResult.NEED_MORE_INPUT;}// limit input stream.ChannelBufferInputStream is = new ChannelBufferInputStream(buffer, len);try {//解析消息体内容return decodeBody(channel, is, header);} finally {···}这⾥对于刚刚的request进⾏解码操作,具体操作步骤写在注释中了Provider端响应编码当服务端执⾏完接⼝调⽤,看下服务端的响应编码,和消费端不⼀样的地⽅是,服务端进⼊的是ExchangeCodec.encodeResponse⽅法try {//获取序列化⽅式默认Hession协议Serialization serialization = getSerialization(channel);// 初始化⼀个16位的headerbyte[] header = new byte[HEADER_LENGTH];// set magic 数字Bytes.short2bytes(MAGIC, header);// set request and serialization flag.header[2] = serialization.getContentTypeId();if (res.isHeartbeat()) header[2] |= FLAG_EVENT;// set response status.这⾥返回的是OKbyte status = res.getStatus();header[3] = status;// set request id.Bytes.long2bytes(res.getId(), header, 4);int savedWriteIndex = buffer.writerIndex();buffer.writerIndex(savedWriteIndex + HEADER_LENGTH);ChannelBufferOutputStream bos = new ChannelBufferOutputStream(buffer);ObjectOutput out = serialization.serialize(channel.getUrl(), bos);// 编码返回消息体数据或者错误数据if (status == Response.OK) {if (res.isHeartbeat()) {encodeHeartbeatData(channel, out, res.getResult());} else {encodeResponseData(channel, out, res.getResult());}} else out.writeUTF(res.getErrorMessage());out.flushBuffer();bos.flush();bos.close();int len = bos.writtenBytes();checkPayload(channel, len);Bytes.int2bytes(len, header, 12);// writebuffer.writerIndex(savedWriteIndex);buffer.writeBytes(header); // write header.buffer.writerIndex(savedWriteIndex + HEADER_LENGTH + len);} catch (Throwable t) {// 发送失败信息给Consumer,否则Consumer只能等超时了if (!res.isEvent() && res.getStatus() != Response.BAD_RESPONSE) {try {// FIXME 在Codec中打印出错⽇志?在IoHanndler的caught中统⼀处理?logger.warn("Fail to encode response: " + res + ", send bad_response info instead, cause: " + t.getMessage(), t);Response r = new Response(res.getId(), res.getVersion());r.setStatus(Response.BAD_RESPONSE);r.setErrorMessage("Failed to send response: " + res + ", cause: " + StringUtils.toString(t));channel.send(r);return;} catch (RemotingException e) {logger.warn("Failed to send bad_response info back: " + res + ", cause: " + e.getMessage(), e);}}// 重新抛出收到的异常···}基本上和消费⽅请求编码⼀样,多了⼀个步骤,⼀个是在消息头中加⼊了⼀个状态位,第⼆个是如果发送有异常,则继续发送失败信息给Consumer,否则Consumer只能等超时了Conmsuer端响应解码和上⾯的解码⼀样,具体操作是在ExchangeCodec.decode--DubboCodec.decodeBody中。
dubbo rpc的原理
Dubbo RPC的原理1. 什么是Dubbo RPCDubbo是阿里巴巴开源的一款高性能、轻量级的Java RPC框架,提供了服务化治理、服务调用、负载均衡等特性,广泛应用于分布式系统的开发中。
Dubbo的核心原理之一就是RPC(Remote Procedure Call,远程过程调用)。
2. RPC概述RPC是一种分布式系统中不同节点之间通信的方式,可以使得节点之间的调用就像调用本地方法一样简单。
RPC的基本原理是将调用端发起的请求封装成消息,通过序列化和网络传输到服务端,服务端接收到消息后进行解析和处理,并将结果返回给调用端。
3. Dubbo的RPC原理Dubbo的RPC原理如下:3.1 服务暴露服务提供者将自己的服务暴露给注册中心,注册中心将其注册并通知消费者。
3.2 服务发现消费者从注册中心订阅服务列表,获取到可用的服务提供者信息。
3.3 负载均衡Dubbo使用负载均衡算法在多个服务提供者中选择一个进行调用,以实现对服务调用的分发和均衡。
3.4 远程通信Dubbo使用Netty等网络通信框架提供高性能的远程通信能力,消费者通过网络将请求发送到服务提供者。
3.5 序列化Dubbo支持多种序列化协议,如Hessian、Java序列化等,将对象序列化为字节流进行传输。
3.6 调用过程调用过程包括编码、解码、路由、集群容错等,Dubbo通过动态代理将接口调用转化为具体的方法调用,同时在调用过程中处理异常和容错机制。
3.7 结果返回服务提供者将处理结果序列化并返回给消费者,消费者将结果反序列化为对象。
4. Dubbo的基础组件Dubbo的RPC原理离不开以下几个基础组件的支持:4.1 注册中心Dubbo的注册中心负责服务的注册和发现,目前支持Zookeeper、Redis等多种注册中心。
4.2 远程通信Dubbo使用Netty等网络通信框架实现了高性能的异步通信模型,支持长连接和心跳检测。
4.3 序列化Dubbo支持多种序列化协议,如Hessian、Java序列化等,通过序列化将对象转换为字节流进行传输。
Dubbo服务发现源码解析
Dubbo服务发现源码解析模块源码模块⼀、⼀、源码1.1 源码模块组织Dubbo⼯程是⼀个Maven多Module的项⽬,以包结构来组织各个模块。
核⼼模块及其关系,如图所⽰:1.2 模块说明dubbo-common 公共逻辑模块,包括Util类和通⽤模型。
dubbo-remoting 远程通讯模块,相当于Dubbo协议的实现,如果RPC⽤RMI协议则不需要使⽤此包。
dubbo-rpc 远程调⽤模块,抽象各种协议,以及动态代理,只包含⼀对⼀的调⽤,不关⼼集群的管理。
dubbo-cluster 集群模块,将多个服务提供⽅伪装为⼀个提供⽅,包括:负载均衡、容错、路由等,集群的地址列表可以是静态配置的,也可以是由注册中⼼下发。
dubbo-registry 注册中⼼模块,基于注册中⼼下发地址的集群⽅式,以及对各种注册中⼼的抽象。
dubbo-monitor 监控模块,统计服务调⽤次数,调⽤时间的,调⽤链跟踪的服务。
dubbo-config 配置模块,是Dubbo对外的API,⽤户通过Config使⽤Dubbo,隐藏Dubbo所有细节。
dubbo-container 容器模块,是⼀个Standalone的容器,以简单的Main类加载Spring启动,因为服务通常不需要Tomcat/JBoss等Web容器的特性,没必要⽤Web容器去加载服务。
因为服务通常不需要 Tomcat/JBoss 等 Web 容器的特性,没必要⽤ Web 容器去加载服务。
⼆、服务发现Dubbo的应⽤会在启动时完成服务注册或订阅(不论是⽣产者,还是消费者)如下图所⽰。
图中⼩⽅块Protocol, Cluster, Proxy, Service, Container, Registry, Monitor代表层或模块,蓝⾊的表⽰与业务有交互,绿⾊的表⽰只对Dubbo内部交互。
图中背景⽅块Consumer, Provider, Registry, Monitor代表部署逻辑拓普节点。
Dubble入门
Dubble⼊门Dubbo 01架构模型传统架构 All in One测试⿇烦,微⼩修改全都得重新测单体架构也称之为单体系统或者是单体应⽤。
就是⼀种把系统中所有的功能、模块耦合在⼀个应⽤中的架构⽅式。
其优点为:项⽬易于管理、部署简单。
缺点:测试成本⾼、可伸缩性差、可靠性差、迭代困难、跨语⾔程度差、团队协作难聚合项⽬划分单项⽬容易因为某个功能导致整体oom拆分完咋实现SOA 架构: Service-Oriented Architecture⾯向服务的架构(SOA)是⼀个组件模型,它将应⽤程序拆分成不同功能单元(称为服务)通过这些服务之间定义良好的接⼝和契约联系起来。
接⼝是采⽤中⽴的⽅式进⾏定义的,它应该独⽴于实现服务的硬件平台、操作系统和编程语⾔。
这使得构建在各种各样的系统中的服务可以以⼀种统⼀和通⽤的⽅式进⾏交互。
在没有实施SOA的年代,从我们研发的⾓度来看,只能在代码级别复⽤,即Ctrl +V。
SOA出现,我们开始⾛向了模块、业务线的复⽤。
SOA年代的典型实现: SOAP协议,CXF框架,XML传输xsd,数据校验SOA架构伴随着软件研发⾏业20年的发展,在最初的时候,⼤型it公司内部系统规模越来越⼤,IT系统越来越复杂,All in One单体架构的思想导致公司内项⽬业务和数据相互隔离,形成了孤岛。
最初,我们使⽤数据库作为项⽬之间数据交互和中转的平台,现在我们有了消息中间件。
最初,我们使⽤XML完成系统之间解耦与相互关联,现在我们有了RPC,Restful最初,我们使⽤业务维度划分整体项⽬结构,最初,我们多项⽬节点维护⼀个共享数据中⼼,现在我们做冗余存储,闭环数据,保证⾼效运⾏及数据最终⼀致性最初,SOA思想指导指导我们把所有的IT系统汇总成⼀个⼤的整体,按照业务维度划分服务,集中化管理现在我们拆分抽象服务使其可以多系统复⽤相同的功能模块。
基于dubbo RPC的微服务式架构RPC远程过程调⽤ : Remote Procedure Call Protocol远程过程调⽤协议,它是⼀种通过⽹络从远程计算机程序上请求服务,⽽不需要了解底层⽹络技术的协议。
dubbo支持的7种协议
dubbo支持的7种协议建议看原文转自:https:///xiaojin21cen/article/details/798342221、dubbo 协议 (默认)2、rmi 协议3、hessian 协议4、http 协议5、webservice 协议6、thrift 协议7、memcached 协议8、redis 协议面试题:Dubbo支持dubbo、rmi、hessian、http、webservice、thrift、redis等多种协议,但是Dubbo官网是推荐我们使用Dubbo协议的。
下面我们就针对Dubbo的每种协议详解讲解,以便我们在实际应用中能够正确取舍。
1、dubbo 协议 (默认)缺省协议,使用基于mina1.1.7+hessian3.2.1的tbremoting交互。
连接个数:单连接连接方式:长连接传输协议:TCP传输方式:NIO异步传输序列化:Hessian 二进制序列化适用范围:传入传出参数数据包较小(建议小于100K),消费者比提供者个数多,单一消费者无法压满提供者,尽量不要用dubbo协议传输大文件或超大字符串。
适用场景:常规远程服务方法调用1、dubbo默认采用dubbo协议,dubbo协议采用单一长连接和NIO异步通讯,适合于小数据量大并发的服务调用,以及服务消费者机器数远大于服务提供者机器数的情况2、他不适合传送大数据量的服务,比如传文件,传视频等,除非请求量很低。
配置如下:<dubbo:protocol name="dubbo" port="20880" /><!-- Set default protocol: --><dubbo:provider protocol="dubbo" /><~-- Set service protocol --><dubbo:service protocol="dubbo" /><!-- Multi port --><dubbo:protocol id="dubbo1" name="dubbo" port="20880" /><dubbo:protocol id="dubbo2" name="dubbo" port="20881" />.<!-- Dubbo protocol options: --><dubbo:protocol name="dubbo" port="9090" server="netty" client="netty" codec=“dubbo”serialization=“hessian2” charset=“UTF-8” threadpool=“fixed” threads=“100” queues=“0” iothreads=“9”buffer=“8192” accepts=“1000” payload=“8388608” />3、Dubbo协议缺省每服务每提供者每消费者使用单一长连接,如果数据量较大,可以使用多个连接。
Dubbo架构设计详解
Dubbo架构设计详解Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合(或者最大限度地松耦合)。
从服务模型的角度来看,Dubbo采用的是一种非常简单的模型,要么是提供方提供服务,要么是消费方消费服务,所以基于这一点可以抽象出服务提供方(Provider)和服务消费方(Consumer)两个角色。
关于注册中心、协议支持、服务监控等内容,详见后面描述。
总体架构Dubbo的总体架构,如图所示:欢迎下载 2Dubbo框架设计一共划分了10个层,而最上面的Service层是留给实际想要使用Dubbo开发分布式服务的开发者实现业务逻辑的接口层。
图中左边淡蓝背景的为服务消费方使用的接口,右边淡绿色背景的为服务提供方使用的接口,位于中轴线上的为双方都用到的接口。
下面,结合Dubbo官方文档,我们分别理解一下框架分层架构中,各个层次的设计要点:1.服务接口层(Service):该层是与实际业务逻辑相关的,根据服务提供方和服务消费方的业务设计对应的接口和实现。
2.配置层(Config):对外配置接口,以ServiceConfig和ReferenceConfig为中心,可以直接new配置类,也可以通过spring解析配置生成配置类。
3.服务代理层(Proxy):服务接口透明代理,生成服务的客户端Stub和服务器端Skeleton,以ServiceProxy为中心,扩展接口为ProxyFactory。
4.服务注册层(Registry):封装服务地址的注册与发现,以服务URL为中心,扩展接口为RegistryFactory、Registry和RegistryService。
可能没有服务注册中心,此时服务提供方直接暴露服务。
5.集群层(Cluster):封装多个提供者的路由及负载均衡,并桥接注册中心,以Invoker为中心,扩展接口为Cluster、Directory、Router和LoadBalance。
java中dubbo的用法
Dubbo在Java中的用法什么是Dubbo?Dubbo是一种高性能、轻量级的开源分布式服务框架,由阿里巴巴集团开发并开源。
它主要用于解决分布式系统中的服务治理问题,提供了服务注册、发现、负载均衡、远程调用等核心功能。
Dubbo的设计目标是提供简单、高效、可扩展的分布式服务框架,使开发者可以专注于业务逻辑的实现,而无需关注底层的网络通信和分布式调用细节。
Dubbo的核心概念在使用Dubbo之前,我们需要了解一些Dubbo的核心概念:1.服务提供者(Provider):提供具体的服务实现。
2.服务消费者(Consumer):调用服务提供者的接口进行远程调用。
3.注册中心(Registry):用于服务的注册与发现,负责将服务提供者的信息注册到注册中心,并将服务消费者的请求路由到合适的服务提供者。
4.监控中心(Monitor):用于监控服务的调用次数、调用时间等指标,可以对服务进行性能分析和优化。
5.代理层(Proxy):用于将服务提供者的接口代理为本地接口,使得调用者可以像调用本地方法一样调用远程方法。
Dubbo的使用步骤下面是使用Dubbo的一般步骤:1.定义服务接口:首先需要定义服务接口,服务提供者和服务消费者都需要依赖该接口。
2.实现服务接口:服务提供者需要实现服务接口,并将其注册到注册中心。
3.配置Dubbo:在服务提供者和服务消费者的配置文件中,需要配置Dubbo相关的参数,如注册中心的地址、端口等。
4.启动注册中心:启动注册中心,使得服务提供者可以将自己的信息注册到注册中心。
5.启动服务提供者:启动服务提供者,使其可以提供具体的服务。
6.启动服务消费者:启动服务消费者,使其可以调用远程服务。
7.监控服务调用:启动监控中心,对服务调用进行监控和统计。
Dubbo的配置Dubbo支持多种配置方式,如XML配置、注解配置和API配置。
下面以XML配置为例进行说明。
服务提供者配置在服务提供者的配置文件(如dubbo-provider.xml)中,需要配置以下参数:<dubbo:application name="provider" /><dubbo:registry address="zookeeper://localhost:2181" /><dubbo:protocol name="dubbo" port="20880" /><dubbo:service interface="erService" ref="userService" />•dubbo:application:配置应用信息,name为应用名称。
Dubbo的负载均衡
Dubbo的负载均衡1.集群,分布式,负载均衡概念集群:⼀个内容,部署多次,形成的整体称为集群。
集群中每个个体应该部署到不同的服务器上。
伪集群:集群中内容部署到同⼀台服务器上,通过不同端⼝区分不同个体。
负载均衡:在集群前提下,当访问整个集群时,集群中每个节点被访问次数或频率的规则。
分布式:⼀个整体把拆分成不同的独⽴模块功能分开部署,这些独⽴模块部署的时候也可以⽤集群⽅式部署2.Dubbo的负载均衡策略Random:默认策略,随机。
随机访问集群中节点。
访问概率和权重有关。
RoundRobin:轮询。
访问频率和权重有关。
权重(weight):占有⽐例。
集群中每个项⽬部署的服务器的性能可能是不同,性能好的服务器权重应该⾼⼀些。
LeastActive:活跃数相同的随机,不同的活跃数⾼的放前⾯。
基本不⽤ConsistentHash:⼀致性Hash。
相同参数请求总是发到⼀个提供者。
基本不⽤在调⽤⽅设置@Reference@Reference(loadbalance = "roundrobin")private DemoDubboService demoDubboService;在服务提供⽅设置@Service@Service(loadbalance = "random")//@Service(weight = 4)public class DemoDubboServiceImpl implements DemoDubboService {}配置⽂件中全局设置所有provider和consumer的负载均衡效果dubbo:application:name: dubbo-providerregistry:address: zookeeper://127.0.0.1:2181protocol:port: 20884provider:loadbalance: randomconsumer:loadbalance: random。
dubbo rpc的原理
dubbo rpc的原理Dubbo RPC的原理Dubbo是一款高性能的分布式服务框架,它提供了一种基于RPC (Remote Procedure Call)的服务调用方式。
Dubbo RPC的原理是将服务提供者和服务消费者解耦,使它们可以独立部署和扩展,同时提供了负载均衡、容错、路由等功能,保证了服务的高可用性和可靠性。
Dubbo RPC的核心组件包括服务提供者、服务消费者、注册中心和协议栈。
服务提供者将服务注册到注册中心,服务消费者从注册中心获取服务提供者的地址,然后通过协议栈进行远程调用。
在Dubbo RPC中,服务提供者和服务消费者之间的通信是通过协议栈实现的。
Dubbo支持多种协议,包括Dubbo协议、HTTP协议、Hessian协议、Thrift协议等。
Dubbo协议是Dubbo RPC的默认协议,它基于Netty实现,支持异步、长连接、心跳等特性,具有较高的性能和可靠性。
Dubbo RPC的负载均衡功能是通过集群实现的。
Dubbo支持多种集群模式,包括Failover集群、Failfast集群、Failsafe集群、Failback集群、Forking集群等。
Failover集群是Dubbo RPC的默认集群模式,它会在服务提供者出现异常时自动切换到其他可用的服务提供者,保证了服务的高可用性。
Dubbo RPC的容错功能是通过重试机制实现的。
Dubbo支持多种重试策略,包括重试次数、重试间隔、重试异常等。
Dubbo还支持熔断器功能,当服务提供者出现异常时,熔断器会自动断开与该服务提供者的连接,避免服务消费者的请求继续流向该服务提供者,从而保证了服务的可靠性。
总之,Dubbo RPC是一款高性能、可靠性强的分布式服务框架,它提供了一种基于RPC的服务调用方式,使服务提供者和服务消费者可以独立部署和扩展,同时提供了负载均衡、容错、路由等功能,保证了服务的高可用性和可靠性。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Dubbo各种协议协议参考手册dubbo://1.<dubbo:protocol name="dubbo" port="20880"/> Set default protocol:1.<dubbo:provider protocol="dubbo"/>Set service protocol:1.<dubbo:service protocol="dubbo"/>Multi port:1.<dubbo:protocol id="dubbo1" name="dubbo" port="20880"/>2.<dubbo:protocol id="dubbo2" name="dubbo" port="20881"/>Dubbo protocol options:1.<dubbo:protocol name=“dubbo”port=“9090”server=“netty”client=“netty” codec=“dubbo”serialization=“hessian2”charset=“UTF-8”threadpool=“fixed” threads =“100”queues=“0”iothreads=“9”buffer=“8192”accepts=“1000”payload=“838860 8” />∙Transportero mina, netty, grizzy∙Serializationo dubbo, hessian2, java, json∙Dispatchero all, direct, message, execution, connection∙ThreadPoolo fixed, cached∙<dubbo:protocol name="dubbo"connections="2"/><dubbo:service connections=”0”>或<dubbo:reference connections=”0”>表示该服务使用JVM共享长连接。
(缺省)<dubbo:service connections=”1”>或<dubbo:reference connections=”1”>表示该服务使用独立长连接。
<dubbo:service connections=”2”>或<dubbo:reference connections=”2”>表示该服务使用独立两条长连接。
1.<dubbo:protocol name="dubbo" accepts="1000"/>缺省协议,使用基于mina1.1.7+hessian3.2.1的tbremoting交互。
∙连接个数:单连接∙连接方式:长连接∙传输协议:TCP∙传输方式:NIO异步传输∙序列化:Hessian二进制序列化∙适用范围:传入传出参数数据包较小(建议小于100K),消费者比提供者个数多,单一消费者无法压满提供者,尽量不要用dubbo协议传输大文件或超大字符串。
∙适用场景:常规远程服务方法调用为什么要消费者比提供者个数多:因dubbo协议采用单一长连接,假设网络为千兆网卡(1024Mbit=128MByte),根据测试经验数据每条连接最多只能压满7MByte(不同的环境可能不一样,供参考),理论上1个服务提供者需要20个服务消费者才能压满网卡。
为什么不能传大包:因dubbo协议采用单一长连接,如果每次请求的数据包大小为500KByte,假设网络为千兆网卡(1024Mbit=128MByte),每条连接最大7MByte(不同的环境可能不一样,供参考),单个服务提供者的TPS(每秒处理事务数)最大为:128MByte / 500KByte = 262。
单个消费者调用单个服务提供者的TPS(每秒处理事务数)最大为:7MByte / 500KByte = 14。
如果能接受,可以考虑使用,否则网络将成为瓶颈。
为什么采用异步单一长连接:因为服务的现状大都是服务提供者少,通常只有几台机器,而服务的消费者多,可能整个网站都在访问该服务,比如Morgan的提供者只有6台提供者,却有上百台消费者,每天有1.5亿次调用,如果采用常规的hessian服务,服务提供者很容易就被压跨,通过单一连接,保证单一消费者不会压死提供者,长连接,减少连接握手验证等,并使用异步IO,复用线程池,防止C10K问题。
(1) 约束:∙参数及返回值需实现Serializable接口∙参数及返回值不能自定义实现List, Map, Number, Date, Calendar等接口,只能用JDK自带的实现,因为hessian会做特殊处理,自定义实现类中的属性值都会丢失。
()∙Hessian序列化,只传成员属性值和值的类型,不传方法或静态变量,兼容情况:(由吴亚军提供)∙总结:会抛异常的情况:枚举值一边多一种,一边少一种,正好使用了差别的那种,或者属性名相同,类型不同接口增加方法,对客户端无影响,如果该方法不是客户端需要的,客户端不需要重新部署;输入参数和结果集中增加属性,对客户端无影响,如果客户端并不需要新属性,不用重新部署;输入参数和结果集属性名变化,对客户端序列化无影响,但是如果客户端不重新部署,不管输入还是输出,属性名变化的属性值是获取不到的。
总结:服务器端和客户端对领域对象并不需要完全一致,而是按照最大匹配原则。
(2) 配置:dubbo.properties:1.dubbo.service.protocol=dubbormi://∙如果服务接口继承了java.rmi.Remote接口,可以和原生RMI互操作,即:o提供者用Dubbo的RMI协议暴露服务,消费者直接用标准RMI接口调用,o或者提供方用标准RMI暴露服务,消费方用Dubbo的RMI协议调用。
∙如果服务接口没有继承java.rmi.Remote接口,o缺省Dubbo将自动生成一个com.xxx.XxxService$Remote的接口,并继承java.rmi.Remote接口,并以此接口暴露服务,o但如果设置了<dubbo:protocol name="rmi" codec="spring" />,将不生成$Remote接口,而使用Spring的RmiInvocationHandler接口暴露服务,和Spring兼容。
Define rmi protocol:1.<dubbo:protocol name="rmi"port="1099"/>Set default protocol:1.<dubbo:provider protocol="rmi"/>Set service protocol:1.<dubbo:service protocol="rmi"/>Multi port:1.<dubbo:protocol id="rmi1" name="rmi" port="1099"/>2.<dubbo:protocol id="rmi2" name="rmi" port="2099"/>3.4.<dubbo:service protocol="rmi1"/>Spring compatible:1.<dubbo:protocol name="rmi" codec="spring"/>Java标准的远程调用协议。
∙连接个数:多连接∙连接方式:短连接∙传输协议:TCP∙传输方式:同步传输∙序列化:Java标准二进制序列化∙适用范围:传入传出参数数据包大小混合,消费者与提供者个数差不多,可传文件。
∙适用场景:常规远程服务方法调用,与原生RMI服务互操作(1) 约束:∙参数及返回值需实现Serializable接口∙dubbo配置中的超时时间对rmi无效,需使用java启动参数设置:-Dsun.rmi.transport.tcp.responseTimeout=3000,参见下面的RMI配置。
(2) 配置:dubbo.properties:1.dubbo.service.protocol=rmi(3) RMI配置:1.java -Dsun.rmi.transport.tcp.responseTimeout=3000更多RMI优化参数请查看:/docs/cd/E17409_01/javase/6/docs/technotes/guides /rmi/sunrmiproperties.htmlhessian://依赖:1.<dependency>2.<groupId>com.caucho</groupId>3.<artifactId>hessian</artifactId>4.<version>4.0.7</version>5.</dependency>可以和原生Hessian服务互操作,即:∙提供者用Dubbo的Hessian协议暴露服务,消费者直接用标准Hessian接口调用,∙或者提供方用标准Hessian暴露服务,消费方用Dubbo的Hessian协议调用。
基于Hessian的远程调用协议。
∙连接个数:多连接∙连接方式:短连接∙传输协议:HTTP∙传输方式:同步传输∙序列化:Hessian二进制序列化∙适用范围:传入传出参数数据包较大,提供者比消费者个数多,提供者压力较大,可传文件。
∙适用场景:页面传输,文件传输,或与原生hessian服务互操作(1) 约束:∙参数及返回值需实现Serializable接口∙参数及返回值不能自定义实现List, Map, Number, Date, Calendar等接口,只能用JDK自带的实现,因为hessian会做特殊处理,自定义实现类中的属性值都会丢失。