简介
大规模服务化之前,应用可能只是通过RMI或Hessian等工具,简单的暴露和引用远程服务,通过配置服务的URL地址进行调用,通过F5等硬件进行负载均衡。
(1) 当服务越来越多时,服务URL配置管理变得非常困难,F5硬件负载均衡器的单点压力也越来越大。
此时需要一个服务注册中心,动态的注册和发现服务,使服务的位置透明。
并通过在消费方获取服务提供方地址列表,实现软负载均衡和Failover,降低对F5硬件负载均衡器的依赖,也能减少部分成本。
(2) 当进一步发展,服务间依赖关系变得错踪复杂,甚至分不清哪个应用要在哪个应用之前启动,架构师都不能完整的描述应用的架构关系。
这时,需要自动画出应用间的依赖关系图,以帮助架构师理清理关系。
(3) 接着,服务的调用量越来越大,服务的容量问题就暴露出来,这个服务需要多少机器支撑?什么时候该加机器?
为了解决这些问题,第一步,要将服务现在每天的调用量,响应时间,都统计出来,作为容量规划的参考指标。
其次,要可以动态调整权重,在线上,将某台机器的权重一直加大,并在加大的过程中记录响应时间的变化,直到响应时间到达阀值,记录此时的访问量,再以此访问量乘以机器数反推总容量。
Dubbo是一个分布式服务框架,解决了上面的所面对的问题,Dubbo的架构如图所示:
节点角色说明:
Provider: 暴露服务的服务提供方。
Consumer: 调用远程服务的服务消费方。
Registry: 服务注册与发现的注册中心。
Monitor: 统计服务的调用次调和调用时间的监控中心。
Container: 服务运行容器。
列子代码
服务端代码
package com.test; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Bootstrap { public static void main(String[] args) throws Exception { @SuppressWarnings("resource") ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( new String[] { "applicationProvider.xml" }); context.start(); System.out.println("???"); Thread.sleep(Long.MAX_VALUE); } }
接口和实现类
public interface IProcessData { public String hello(String name); } public class ProcessDataImpl implements IProcessData { public String hello(String name) { System.out.println(name); return "hello : " + name; } }
spring 配置文件
<?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="hello-world" /> <!-- 注册地址 --> <dubbo:registry address="zookeeper://192.168.0.100:2181" check="false"></dubbo:registry> <!-- Service interface Concurrent Control --> <dubbo:service interface="com.test.IProcessData" ref="demoService" executes="10" /> <!-- designate implementation --> <bean id="demoService" class="com.test.impl.ProcessDataImpl" /> </beans>
pom.xml文件
<?xml version="1.0"?> <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0</modelVersion> <groupId>com.michael</groupId> <artifactId>dubbo-server</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.1.1</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.5</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.6.1</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>3.2.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>3.2.5.RELEASE</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.5.3</version> <exclusions> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.6</version> </dependency> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> <version>0.1</version> </dependency> </dependencies> </project>
客户端代码
package com.test; import org.springframework.context.support.ClassPathXmlApplicationContext; public class ConsumerThd { public void sayHello() { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( new String[] { "applicationConsumer.xml" }); context.start(); IProcessData demoService = (IProcessData) context.getBean("demoService"); System.out.println(demoService.hello("world")); } } public class Test { public static void main(String[] args) { ConsumerThd thd = new ConsumerThd(); thd.sayHello(); } }
spring配置文件
<?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-of-helloworld-app" /> <!-- registry address, used for consumer to discover services --> <dubbo:registry address="zookeeper://192.168.1.100:2181" check="false"></dubbo:registry> <dubbo:consumer timeout="5000" /> <!-- which service to consume? --> <dubbo:reference id="demoService" interface="com.test.IProcessData"/> </beans>
pom.xml文件
<?xml version="1.0"?> <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0</modelVersion> <groupId>com.michael</groupId> <artifactId>dubbo-client</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.1.1</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.5</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.6.1</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>3.2.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>3.2.5.RELEASE</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.5.3</version> <exclusions> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.6</version> </dependency> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> <version>0.1</version> </dependency> <dependency> <groupId>com.michael</groupId> <artifactId>dubbo-server</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> </dependencies> </project>
一些配置信息介绍
集群容错模式:
可以自行扩展集群容错策略,参见:集群扩展
Failover Cluster
- 失败自动切换,当出现失败,重试其它服务器。(缺省)
- 通常用于读操作,但重试会带来更长延迟。
- 可通过retries="2"来设置重试次数(不含第一次)。
Failfast Cluster
- 快速失败,只发起一次调用,失败立即报错。
- 通常用于非幂等性的写操作,比如新增记录。
Failsafe Cluster
- 失败安全,出现异常时,直接忽略。
- 通常用于写入审计日志等操作。
Failback Cluster
- 失败自动恢复,后台记录失败请求,定时重发。
- 通常用于消息通知操作。
Forking Cluster
- 并行调用多个服务器,只要一个成功即返回。
- 通常用于实时性要求较高的读操作,但需要浪费更多服务资源。
- 可通过forks="2"来设置最大并行数。
Broadcast Cluster
- 广播调用所有提供者,逐个调用,任意一台报错则报错。(2.1.0开始支持)
- 通常用于通知所有提供者更新缓存或日志等本地资源信息。
负载均衡
Random LoadBalance
- 随机,按权重设置随机概率。
- 在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。
RoundRobin LoadBalance
- 轮循,按公约后的权重设置轮循比率。
- 存在慢的提供者累积请求问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。
LeastActive LoadBalance
- 最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。
- 使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。
ConsistentHash LoadBalance
- 一致性Hash,相同参数的请求总是发到同一提供者。
- 当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。
- 算法参见:http://en.wikipedia.org/wiki/Consistent_hashing。
- 缺省只对第一个参数Hash,如果要修改,请配置<dubbo:parameter key="hash.arguments" value="0,1" />
- 缺省用160份虚拟节点,如果要修改,请配置<dubbo:parameter key="hash.nodes" value="320" />
协议参考
dubbo://
Dubbo缺省协议采用单一长连接和NIO异步通讯,适合于小数据量大并发的服务调用,以及服务消费者机器数远大于服务提供者机器数的情况。Dubbo缺省协议不适合传送大数据量的服务,比如传文件,传视频等,除非请求量很低。
rmi://
RMI协议采用JDK标准的java.rmi.*实现,采用阻塞式短连接和JDK标准序列化方式。
hessian://
Hessian协议用于集成Hessian的服务,Hessian底层采用Http通讯,采用Servlet暴露服务,Dubbo缺省内嵌Jetty作为服务器实现。
Hessian是Caucho开源的一个RPC框架:http://hessian.caucho.com,其通讯效率高于WebService和Java自带的序列化。
http://
采用Spring的HttpInvoker实现
webservice://
基于CXF的frontend-simple和transports-http实现。
CXF是Apache开源的一个RPC框架:http://cxf.apache.org,由Xfire和Celtix合并而来 。
thrift://
当前 dubbo 支持的 thrift 协议是对 thrift 原生协议的扩展,在原生协议的基础上添加了一些额外的头信息,比如service name,magic number等。使用dubbo thrift协议同样需要使用thrift的idl compiler编译生成相应的java代码,后续版本中会在这方面做一些增强。
memcached://
redis://
注册中心参考
Multicast注册中心
不需要启动任何中心节点,只要广播地址一样,就可以互相发现
组播受网络结构限制,只适合小规模应用或开发阶段使用。
组播地址段: 224.0.0.0 - 239.255.255.255
Zookeeper注册中心
流程说明:
- 服务提供者启动时
- 向/dubbo/com.foo.BarService/providers目录下写入自己的URL地址。
- 服务消费者启动时
- 订阅/dubbo/com.foo.BarService/providers目录下的提供者URL地址。
- 并向/dubbo/com.foo.BarService/consumers目录下写入自己的URL地址。
- 监控中心启动时
- 订阅/dubbo/com.foo.BarService目录下的所有提供者和消费者URL地址。
Redis注册中心
Redis过期数据
通过心跳的方式检测脏数据,服务器时间必须相同,并且对服务器有一定压力。
可靠性声明
阿里内部并没有采用Redis做为注册中心,而是使用自己实现的基于数据库的注册中心,即:Redis注册中心并没有在阿里内部长时间运行的可靠性保障,此Redis桥接实现只为开源版本提供,其可靠性依赖于Redis本身的可靠性。
Simple注册中心
Dogfooding
注册中心本身就是一个普通的Dubbo服务,可以减少第三方依赖,使整体通讯方式一致。
配置
<dubbo:service/> 服务配置,用于暴露一个服务,定义服务的元信息,一个服务可以用多个协议暴露,一个服务也可以注册到多个注册中心。
<dubbo:reference/> 引用配置,用于创建一个远程服务代理,一个引用可以指向多个注册中心。
<dubbo:protocol/> 协议配置,用于配置提供服务的协议信息,协议由提供方指定,消费方被动接受。
<dubbo:application/> 应用配置,用于配置当前应用信息,不管该应用是提供者还是消费者。
<dubbo:module/> 模块配置,用于配置当前模块信息,可选。
<dubbo:registry/> 注册中心配置,用于配置连接注册中心相关信息。
<dubbo:monitor/> 监控中心配置,用于配置连接监控中心相关信息,可选。
<dubbo:provider/> 提供方的缺省值,当ProtocolConfig和ServiceConfig某属性没有配置时,采用此缺省值,可选。
<dubbo:consumer/> 消费方缺省配置,当ReferenceConfig某属性没有配置时,采用此缺省值,可选。
<dubbo:method/> 方法配置,用于ServiceConfig和ReferenceConfig指定方法级的配置信息。
<dubbo:argument/> 用于指定方法参数配置。
还有支持令牌验证
路由规则包括路由规则脚本,黑名单,白名单
服务降级
路线图
参考
相关推荐
【Dubbo入门到精通架构高级课程】是一门深入解析Dubbo框架的全面教程,旨在帮助初学者和进阶者理解并掌握这个强大的Java分布式服务框架。该课程包含了视频讲解、课件资料以及配套的源码,确保学习者能理论与实践相...
【Dubbo入门教程+实例源码】是一份针对初学者设计的教程,旨在帮助开发者快速理解和掌握Apache Dubbo这一高性能、轻量级的服务治理框架。Dubbo是阿里巴巴开源的一个分布式服务框架,它提供了服务注册与发现、负载...
我感觉很不错的宝贝,现在和大家分享,希望能够帮到大家,如果你需要可以下载看看,很适合喜欢研究技术的人员
【Dubbo入门实例Demo】是针对初学者设计的一个实践教程,旨在帮助新手快速理解并掌握Apache Dubbo这一高性能、轻量级的Java RPC框架。在学习过程中,新手往往会在配置、依赖、通信等方面遇到诸多问题,这个Demo就是...
### Dubbo入门实战详解 #### 一、Dubbo概述与应用场景 ##### 1.1 什么是Dubbo? Dubbo是一款由阿里巴巴开发的分布式服务框架,它致力于提供高性能和透明化的RPC远程服务调用方案。该框架是阿里巴巴SOA服务化治理...
【Dubbo入门Demo详解】 Dubbo是一款高性能、轻量级的Java开源服务框架,由阿里巴巴开发并维护,它主要提供了服务治理、远程调用、集群容错、监控等核心功能,是微服务架构中常见的服务治理组件。在这个“dubbo入门...
【Dubbo入门例子程序】是针对初学者设计的一个简单示例,旨在帮助理解并快速上手Apache Dubbo这一高性能、轻量级的Java远程服务框架。这个例子通过一个"Hello, World!"的应用来演示Dubbo的基本用法,采用Maven作为...
【标题】"Dubbo入门案例HelloWorld"是一个基础的学习教程,旨在帮助初学者理解并实践Dubbo框架的基本用法。Dubbo是阿里巴巴开源的一款高性能、轻量级的Java RPC(远程过程调用)框架,它提供了服务治理、负载均衡、...
本文将基于"Dubbo入门之HelloWorld"的主题,深入探讨如何从零开始学习并实践Dubbo的基本用法。 首先,我们需要了解什么是RPC(Remote Procedure Call)。RPC是一种使程序可以调用另一个系统中的函数或方法的技术,...
【标题】"dubbo入门的demo" Dubbo是一款高性能、轻量级的开源Java RPC框架,它提供了服务发现、服务治理、流量控制、熔断机制等功能,是阿里巴巴贡献给Apache基金会的重要项目。本Demo旨在帮助初学者理解并掌握...
【标题】"dubbo入门示例,zookeeper+dubbo-admin" 涉及到的核心技术是Dubbo和Zookeeper,这两个都是Java生态系统中的关键组件,主要用于构建分布式服务系统。 【Dubbo】是阿里巴巴开源的一款高性能、轻量级的Java...
【标题】"dubbo入门 dubbo_demo.zip" 提供了一个初学者接触和了解Apache Dubbo的起点。Dubbo是一款高性能、轻量级的开源Java RPC框架,它致力于提供面向服务的治理方案,使得分布式系统开发更为便捷。在这个压缩包中...
dubbo入门实例源码,直接解压后,分别将dubboprovider和dubboconsumer项目导入myeclipse中,先启动zookeeper注册中心(bin\zkServer.cmd或zkServer.sh),再启动provider中main…………
【标题】"新建文件夹 (6).rar_dubbo入门" 提供了我们即将探讨的主题——Dubbo入门。Dubbo是阿里巴巴开源的一款高性能、轻量级的Java服务治理框架,它致力于提供面向服务的RPC(远程过程调用)解决方案,帮助开发者...
1. **Dubbo入门** - **安装配置**:首先,你需要安装Java环境,并在项目中引入Dubbo依赖。通常,Dubbo项目基于Maven构建,因此你需要在`pom.xml`文件中添加Dubbo的依赖。 - **服务接口定义**:创建服务接口(API)...
这个"1-dubbo入门案例"文件应该包含了上述步骤的示例代码,你可以导入到IDE中运行,根据实际情况进行调整。这个案例是学习和理解Dubbo工作原理的一个很好的起点,通过实践,你可以深入理解Dubbo的特性,如动态配置、...
【Dubbo入门案例和项目源码】是一个针对初学者的教程资源,包含了使用Dubbo构建Web服务的基础示例和完整的项目源代码。Dubbo是阿里巴巴开源的一款高性能、轻量级的Java服务框架,广泛应用于分布式系统开发,尤其在...
在本篇中,我们将深入探讨Dubbo入门示例,特别是基于属性配置的方式。Dubbo是一个高性能、轻量级的开源Java RPC框架,旨在提供一种简单易用的服务治理方案。通过属性配置,我们可以更加灵活地控制服务的行为,实现...
【标题】"Dubbo入门搭建zookeeper集群+服务端消费端demo"主要涵盖了两个核心的分布式服务框架——Dubbo和Zookeeper,以及如何在实际环境中整合它们进行服务的注册与发现。 Dubbo是阿里巴巴开源的一款高性能、轻量级...