浅析Dubbo服务

浅析Dubbo服务

Dubbo是阿里开源的一个分布式服务框架,致力于提供高性能和透明化的RPC远程调用方案,以及SOA服务治理方案。
Dubbo是阿里巴巴SOA服务化治理方案的核心框架,每天为2,000+个服务提供3,000,000,000+次访问量支持,并被广泛应用于阿里巴巴集团的各成员站点。Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。

转变的历程

  1. 单一应用框架(ORM)

当网站流量小时,只需一个应用,可以将所有功能都部署在一起,这样可以减少部署的节点和成本。

缺点:单一的系统架构,使得在开发过程中,占用的资源越来越多,随着流量的增加,将会越来越难维护。

Dubbo采用微内核+插件话体系,设计十分优雅,扩展性强。

单一应用架构
  1. 垂直应用架构(MVC)

垂直应用架构解决了单一应用架构所面临的扩容问题,容量能够分散到各个子系统当中,且系统的体积可控,一定程度上降低了开发人员协同以及维护的成本,提升了开发效率。

缺点:在垂直架构中相同逻辑代码需要不断复制,不能复用。

垂直应用架构
  1. 分布式应用架构(RPC)

当垂直应用越来越多的时候,应用之间的交互是不可避免的,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心。

分布式应用架构
  1. 流动计算架构(SOA)

随着服务化的进一步服务,服务越来越多,服务之间的调用和依赖关系也越来越复杂,诞生了面向服务的架构体系(SOA),也因此衍生了一系列相应的结束,如对服务提供,链接处理,通信协议,序列化方式,服务发现,服务路由,日志输出等行为进行封装的服务框架

比较图
  • 单一应用架构

当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。
此时,用于简化增删改查工作量的 数据访问框架(ORM) 是关键。

  • 垂直应用架构

当访问量逐渐增大,单一应用增加机器带来的加速度越来越小,将应用拆成互不相干的几个应用,以提升效率。
此时,用于加速前端页面开发的 Web框架(MVC) 是关键。

  • 分布式服务架构

当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。
此时,用于提高业务复用及整合的 分布式服务框架(RPC) 是关键。

  • 流动计算架构

当服务越来越多,容量的评估,小服务资源的浪费等问题逐渐显现,此时需增加一个调度中心基于访问压力实时管理集群容量,提高集群利用率。
此时,用于提高机器利用率的 资源调度和治理中心(SOA) 是关键。

RPC(Remote Procedure Call Protocol)(远程过程调用协议)

当我们有两台服务器A、B,分别部署了不同的应用a,b,当服务器A 想调用服务器B上面提供的方法的时候,这个是不能够直接调用的,这个时候就需要通过网络来表达调用的语义和调用的数据,这个时候远程调用服务的概念就产生了。

RPC是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。
RPC采用客户机/服务器模式。请求程序就是一个客户机,而服务提供程序就是一个服务器。首先,客户机调用进程发送一个有进程参数的调用信息到服务进程,然后等待应答信息。在服务器端,进程保持睡眠状态直到调用信息到达为止。当一个调用信息到达,服务器获得进程参数,计算结果,发送答复信息,然后等待下一个调用信息,最后,客户端调用进程接收答复信息,获得进程结果,然后调用执行继续进行。

Dubbo的概念

Dubbo概念

  • 一款分布式服务框架
  • 高性能和透明化的RPC远程服务调用方案
  • SOA服务治理方案

Dubbo是一个分布式服务框架,以及SOA治理方案。其功能主要包括:高性能NIO通讯及多协议集成,服务动态寻址与路由,软负载均衡与容错,依赖分析与降级等。

Dubbo适用于哪些场景

当网站变大后,不可避免的需要拆分应用进行服务化,以提高开发效率,调优性能,节省关键竞争资源等。

当服务越来越多时,服务的URL地址信息就会爆炸式增长,配置管理变得非常困难,F5硬件负载均衡器的单点压力也越来越大。

当进一步发展,服务间依赖关系变得错踪复杂,甚至分不清哪个应用要在哪个应用之前启动,架构师都不能完整的描述应用的架构关系。

接着,服务的调用量越来越大,服务的容量问题就暴露出来,这个服务需要多少机器支撑?什么时候该加机器?等等……

在遇到这些问题时,都可以用Dubbo来解决。

Dubbo的设计思路

该框架具有极高的扩展性,采用微核+插件体系,并且文档齐全,很方便二次开发,适应性极强。

Dubbo架构

Provider:暴露服务的服务提供方
Consumer:调用远程服务的服务消费方
Registry:服务注册与发现注册中心
Monitor:统计服务的调用次数和调用时间的监控中心

调用流程:
0.服务容器负责启动,加载,运行服务提供者。
1.服务提供者在启动时,向注册中心注册自己提供的服务。
2.服务消费者在启动时,向注册中心订阅自己所需的服务。
3.注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
4.服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
5.服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心

Dubbo注册中心

对于服务提供方,它需要发布服务。
对于消费方,它需要获取提供方提供的服务。
当然,也可以即是提供方也是消费方。
通过服务统一管理起来,可以有效地优化内部应用对服务发布/使用的管理。服务注册中心可以通过特定协议来完成对外的统一。

Dubbo提供的注册中心有如下几种类型可供选择:

  • Multicast注册中心
  • Zookeeper注册中心
  • Redis注册中心
  • Simple注册中心

Dubbo优点

优点:

  1. 透明化的远程方法调用
  • 像调用本地方法一样调用远程方法;只需简单配置,没有任何API侵入。
  1. 软负载均衡及容错机制
  • 可在内网替代nginx lvs等硬件负载均衡器。
  1. 服务注册中心自动注册 & 配置管理
    -不需要写死服务提供者地址,注册中心基于接口名自动查询提供者ip。
    使用类似zookeeper等分布式协调服务作为服务注册中心,可以将绝大部分项目配置移入zookeeper集群。
  2. 服务接口监控与治理
    -Dubbo-admin与Dubbo-monitor提供了完善的服务接口管理与监控功能,针对不同应用的不同接口,可以进行 多版本,多协议,多注册中心管理。

Dubbo序列化协议

Hessian协议

Hessian是一个轻量级的RPC服务,它是基于Binary-RPC协议实现的,他会序列化反序列化你的实例,它的传输协议时Http协议,在dubbo中,主要应用到了它的序列化的协议。

hessian适合发送二进制数据,通过hessian序列化后的包,包的体积会比java自带的小一些。

和java自带的序列化做一个对比


public class Main {

    private static long time1;
    private static long time2;

    public static byte[] hessianSerialize(Object obj) throws IOException {
        long nowTime = System.currentTimeMillis();
        if (obj == null)
            throw new NullPointerException();

        ByteArrayOutputStream os = new ByteArrayOutputStream();
        HessianOutput ho = new HessianOutput(os);
        ho.writeObject(obj);
        time1 = System.currentTimeMillis() - nowTime;
        return os.toByteArray();
    }

    public Object hessianDeserialize(byte[] by) throws IOException {
        if (by == null)
            throw new NullPointerException();

        ByteArrayInputStream is = new ByteArrayInputStream(by);
        HessianInput hi = new HessianInput(is);
        return hi.readObject();
    }

    public static byte[] javaSerialize(Object obj) throws Exception {
        long noewTime = System.currentTimeMillis();
        if (obj == null)
            throw new NullPointerException();

        ByteArrayOutputStream os = new ByteArrayOutputStream();
        ObjectOutputStream out = new ObjectOutputStream(os);
        out.writeObject(obj);
        time2 = System.currentTimeMillis() - noewTime;
        return os.toByteArray();
    }

    public Object javaDeserialize(byte[] by) throws Exception {

        if (by == null)
            throw new NullPointerException();

        ByteArrayInputStream is = new ByteArrayInputStream(by);
        ObjectInputStream in = new ObjectInputStream(is);
        return in.readObject();
    }

    public static void main(String[] args) throws Exception {

        People people = new People(19, "222333222233332222", "关玮琳", "健康");
        People people2 = new People(21, "555333222233332222", "张三", "不健康");
        byte[] hessianByte = hessianSerialize(people);
        byte[] javaByte = javaSerialize(people2);

        System.out.println("hessianByte 序列化后的长度   " + hessianByte.length);
        System.out.println("javaSerialize 序列化后的长度   " + javaByte.length);

        System.out.println("hessianByte 序列化时常  " + time1);
        System.out.println("javaSerialize 序列化时常  " + time2);

    }

}


结果:

hessianByte 序列化后的长度   86
javaSerialize 序列化后的长度   132
hessianByte 序列化时常  51
javaSerialize 序列化时常  16

Hessian语法

        #starting production
top     ::=value

        #分割成64k每chunk的8-bit二进制数据
binary  ::= 'b' b1 b0 <binary-data> binary  #不是最后一个chunk
        ::= 'B' b1 b0 <binary-data>         #最后一个chunk
        ::= [x20-x2f] <binary-data>         #长度范围为 0-15

        #boolean true/false
boolean ::= 'T'
        ::= 'F'

        #对象的定义(compact map)
class-def ::= 'O' type int string*

        #time in UTC encoded as 64-bit long milliseconds since epoch
date    ::= 'd' b7 b6 b5 b4 b3 b2 b1 b0

        #64-bit IEEE double
double  ::= 'D' b7 b6 b5 b4 b3 b2 b1 b0
        ::= x67                         #0.0
        ::= x68                         #1.0
        ::= x69 b0                      #byte表示的double(-128.0 to 127.0)
        ::= x6a b1 b0                   #short表示的double
        ::= x6b b3 b2 b1 b0             #32-bit float表示的double

        #32-bit 有符号整型
int     ::= 'I' b3 b2 b1 b0
        ::= [x80-xbf]                   #-x10 to x3f
        ::= [xc0-xcf] b0                #-x800 to x7ff
        ::= [xd0-xd7] b1 b0             #-x40000 to x3ffff

        # list/vector length
length  ::= 'l' b3 b2 b1 b0
        ::= x6e int

        # list/vector
list    ::= 'V' type? length? value* 'z'
        ::= 'v' int int value*          #第一个int表示类型引用, 第二个int表示长度

        #64-bit有符号long
long    ::= 'L' b7 b6 b5 b4 b3 b2 b1 0
        ::= [xd8-xef]                   #-x08 to x0f
        ::= [xf0-xff] b0                #-x800 to x7ff
        ::= [x38-x3f] b1 b0             #-x40000 to x3ffff
        ::= x77 b3 b2 b1 b0             #32-bit 整型表示的long

        #map/object
map     ::= 'M' type? (value value)* 'z'    #key, value map pairs

        # null value
null    ::= 'N'

        #对象实例
object  ::= 'o' int value*

        #值引用
ref     ::= 'R' b3 b2 b1 b0 # 对流中第n个map/list/object的引用

        ::= x4a b0          # 对map/list/object的引用,范围为1-255th
        ::= x4b b1 b0       # 对map/list/object 的引用,范围为1-65535th

        #UTF-8 编码的字符串,分割成64k大小的chunks
string  ::= 's' b1 b0 <utf8-data> string    #非末尾chunk
        ::= 'S' b1 b0 <utf8-data>           #长度范围为(0-65535)的字符串
        ::=[x00-x1f] <utf8-data>            #长度范围为(0-31) 的字符串

        #map/list 的类型(针对面向对象语言)
type    ::= 't' b1 b0 <type-string>     #类型名称
        ::= x75 int                     #类型引用值(用整数表示)

        #main production
value   ::=null
        ::= binary
        ::= boolean
        ::= date
        ::= double
        ::= int
        ::= list
        ::= long
        ::= map
        ::= class-def value
        ::= ref
        ::= string

可序列化的类型

  1. 原始二进制数据
  2. boolean
  3. 64-bit date
  4. 64-bit double
  5. 32-bit int
  6. 64-bit long
  7. null
  8. UTF8编码的string

另外包括3种递归类型:

  1. list for lists and arrays
  2. map for maps and dictionaries
  3. object for objects

最后,它还包含一个特殊的类型:

  1. ref 用来表示对共享对象的引用.

Hessian 2.0有3个内部的引用表:

  1. 一个object/list 引用表.
  2. 一个类型定义(class definition)引用表.
  3. 一个type(class name)引用表.

参考文献

什么是Hessian协议呢?

hessian学习基础篇——序列化和反序列化

Dubbo原理解析

Dubbo入门基础与实例讲解

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,980评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,422评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,130评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,553评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,408评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,326评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,720评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,373评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,678评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,722评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,486评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,335评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,738评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,283评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,692评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,893评论 2 335

推荐阅读更多精彩内容

  • 种一棵树最好的时间是十年前,其次是现在。在决心去做一件事时越早开始越好,更好的是现在就开始。所谓做事拖延,不是拖延...
    ICE蝈蝈阅读 1,552评论 0 1
  • 清明早,小满迟,谷雨立夏正相宜。 清明高粱谷雨花,立夏谷子小满薯。 清明高粱接种谷,谷雨棉花再种薯。 清明麻,谷...
    井小亮阅读 326评论 0 1
  • 是谁坐在菩提树下,细数着轮回了一季又一季的满帘落花。柔柔的呢喃,瑟瑟的叹息,潺潺的相思,妩媚了胭脂妖冶的芳华。听,...
    一朝相伴一夕相牵阅读 377评论 0 0