美文网首页
探索分布式框架dubbo

探索分布式框架dubbo

作者: 楚_kw | 来源:发表于2019-05-21 19:30 被阅读0次

    最近在研究阿里开源的分布式 RPC 框架 dubbo

    快速开始

    等等,在开始之前,先来读两篇短文,看看别人是怎么讲故事的,学习学习

    1、那些年,我们追过的RPC


    2、从SOA到微服务的演化 (原创:老刘 码农翻身 2017-05-22)

    小明毕业后为了户口,进入了一家大型国企的信息部门工作, 这个国企不差钱, 几十年来随着IT系统的发展, 也与时俱进地兴建了多个信息系统,只不过自家开发的极少, 从外边购买的极多, 虽然信息部也有开发能力, 但是当甲方的感觉是最妙的, 何况出了问题还可以把责任推出去。

    在这些系统当中, 小一点儿的有自动化办公系统(OA) , 休假系统,车辆管理系统, 薪水支付系统, 大点儿的有客户关系管理系统, ERP系统 ..... 等等, 可以说是琳琅满目,让人目不暇接,几十年来IT发展的技术,几乎都能在公司的IT环境中找到。

    小明的工作之一就是维护现在的IT系统博物馆, 博物馆中大部分都是遗留系统, 能工作,但是非常的老旧。硬件平台, 软件环境,开发语言各部相同,都是异构的。

    就说那个休假系统吧,还是用上个世纪流行的Delphi 写的。 还有那个OA系统, 也是上个世纪的ASP,运行在IIS上。 虽然界面丑陋,勉强能用。

    也有一点新东西,比如上周上线的那个维修系统不就用了最新的前端技术嘛, 小明也着实激动了一阵,看了两天的React。

    有一天有个著名外企的销售来到了小明的公司,请信息部门的老大吃了饭,K了歌。。。好像还搞了些小明这些小兵不知道的秘密活动。

    第二天老大给国企老总做了汇报, 过了一段时间, 公司发文了:

    为了提升IT效率,打破各个信息孤岛,实现各个信息系统之间的互联互通, 让业务和IT进行对齐, 达到业务敏捷性, 公司经慎重研究决定,邀请xxx公司作为咨询顾问, 从即日起开始实施SOA战略。

    小明看了一遍,愣住了,上面的字全都认识, 但连起来就不知道是什么意思, 虚头巴脑的, 唯一确定的是,咨询顾问要来了,要开始什么SOA了。

    顾问果然来了, 先给小明他们的信息部门洗了一次脑, 小明的脑海中被各种新式的名词所充斥: SOA, ESB, SCA, BEPL.... 下了课, 小明和同事们讨论了很久, 模模糊糊的明白了要做什么事情。

    好像是把这些遗留的异构系统包装成粗粒度的服务, 还是 Web 服务,可以通过Http来访问, 然后呢, 让大家互相调用, 甚至可以把这些服务进行编排,形成一个大的业务流程, 完成更高层次的业务, 听起来挺有意思的。

    外企的销售非常精明, 趁势卖了一大批硬件和软件, 他们的技术团队还确实帮着做了一个小的验证系统, 实现了一个业务场景,展示给公司老总看, 老总非常满意: 不错, 我们公司又一次站到了IT技术的前沿!

    然后就没有下文了, 领导们似乎忘记了, SOA似乎没有发生过,互联互通呢? 业务敏捷呢?

    小明很困惑,周末约着同学张大胖去吃饭。

    张大胖在一个互联网公司工作, 主要是做网上约车系统, 用的都是最前沿的技术, 他说: 听起来你们要把这些遗留的异构系统做数据/信息的集成啊, 只是没有做下去而已, 国企嘛可以理解。 你知道我们公司在干什么事儿吗?

    小明说:“不会和我们一样吧?”

    “完全不同! 我们公司才成立几年啊, 最重要的就是这个约车系统, 当然我们现在发展的很快,这三年以来系统已经快变成一个巨无霸了, 代码已经达到百万行级别, 没人能搞明白了, 代码库非常难于管理, 冲突不断。 系统部署也非常困难, 一点点小改动都需要巨无霸式的整体部署, 你能想象得到吗, 我们系统重启一次得15分钟!”

    “卧槽, 这么慢? 不可思议,我用过你们的打车软件, 用起来还可以啊?”

    “唉, 金玉其外,败絮其中, 你不知道我们每次发布有多痛苦, 但是竞争激烈, 我们还得频繁发布。 所以我们做的事情和你们相反, 不是集成, 而是拆分! 把一个巨无霸变成一些小的组件, 让这些小组件能完全独立的开发, 测试和部署。”

    “那你们的开发团队怎么办?” 小明问。

    “我们的组织结构也要随着这些小组件来重构啊,你看我们分成了“乘客管理”,“司机管理”,“旅程管理”,“支付管理”等好多组, 每个组只负责他们特定的一块儿功能, 并且每个组里边都有设计,开发,测试,部署等人员,一应俱全, 他们从头到尾全程负责。”

    “有意思啊,这些小组件都是独立的,每个组件实例都是一个进程吧, 那这些小组件怎么交互? 难道也是通过我们公司所用的Web service ?”

    “不不, 我们不用那重量级的Web service , 什么WSDL, 什么SOAP, 我们统统不用, 我们只用最轻量级的、基于Http 的Restful 来对外提供接口”

    小明突然想到一个问题:“你们每个部门负责一个特定功能,那数据怎么办?还用统一的数据库吗?”

    “这是个老大难问题,我们得做数据库的拆分啊,唉, 一言难尽。”

    小明说 :“可以理解,不过这样以来确实是更加敏捷了。”

    大胖说:“这还不是最厉害的,最厉害的是我们能快速的自动化的部署这些小组件,并且能为他们创建很多实例来运行,有一个挂掉了也没关系,别人可以调用那些还在运行的。”

    “所以关键点就是这些小组件对外提供的服务是无状态的,对吧?”

    “没错”  大胖说, “这一点和你们的SOA是一样的, 对了, 告诉你一个小秘密,我们在生产环境会做一些‘猴子测试’,通过写脚本随机的停掉一些实例,看看我们的系统运行的怎么样”

    小明说:“厉害啊,你们都玩的可都是心跳啊。”

    “木有办法,只有在生产环境才能发现真正的问题啊”

    “难道你们的这种方式没有缺点吗?”

    “当然有了, 就拿数据库来说吧, 数据做了分区, 一致性怎么保证啊? 选择分布式事务非常麻烦, 有时候不得不选择最终一致性来妥协; 还有服务多了, 客户调用起来非常的麻烦, 所以经常得把多个接口API封装,对外提供一个简单的接口 ; 当然这种基于HTTP的调用远没有原来的在一个进程内的方式效率高。 还有一个要命的问题就是监控,你想想这么多运行的实例, 互相之间有调用关系,一个地方出错了, 怎么追踪啊,很麻烦。”

    “不管如何, 你们这种把系统拆分,让一个独立的组织负责独立的部分还是很敏捷啊, 对了,你说的小组件,难道没有一个像SOA这样的高大上名称吗?”

    “当然有了, 业界把这种方式叫做微服务! 虽然这个词不能完整的表达我们做的事情。 我现在很期望Martin Flower 给它起个更贴切的名称,就像Dependency Injection 那样, 比之前的IoC强多了。 ”

    吃过饭回去的路上,小明心想:天下大势,真是分久必合,合久必分啊, 我们在零散系统的集成, 大胖他们又在搞巨无霸应用的拆分。

    相比而言,小明还是羡慕大胖,羡慕他们公司的朝气蓬勃。 他虽然明白自己所在国企的信息系统和大胖做的不一样, 但是暮气沉沉的感觉让人看不到希望, 再这么混下去, 热爱的技术可就真的废了。

    过了年,小明已经在国企服务了3年了,顺利的拿到了帝都的户口, 然后毫不迟疑的跳槽到了大胖的公司,去搞微服务去了。


    直接上 GitHub 找到 dubbo 项目 Apache Dubbo (incubating) Project

    git clone https://github.com/apache/incubator-dubbo.git
    

    进入 dubbo-demo 模块,如下


    dubbo-demo.PNG

    demo下面的几个模块的后缀就是表示其配置(注解配置,api配置,xml配置)
    interface只是一个接口模块

    正准备跃跃欲试,结果发现好像少了点什么,咋没有可视化界面dubbo-admin,看看文档发现,admin 已经被单独分离出来了

    下载运行dubbo-admin

    git clone https://github.com/apache/incubator-dubbo-admin
    # 直接在 dubbo-admin-server\src\main\java\org\apache\dubbo\admin启动DubboAdminApplication也可以
    mvn --projects dubbo-admin-server spring-boot:run
    
    cd dubbo-admin-ui
    npm install
    npm run dev
    
    dubbo-admin.PNG

    admin准备好了,但在demo里面发现默认注册中心用的都是多播:multicast://224.5.6.7:1234
    这里dubbo推荐使用 zookeeper

    安装 zookeeper

    下载地址:http://www.apache.org/dyn/closer.cgi/zookeeper/
    zookeeper 分为单机模式和集群模式,因为这里只是为了运行dubbo,这里只介绍Windows下装单机版(集群版,讲道理这种分布式的东西应该在Linux下折腾嘛)

    解压后进入conf目录,修改zoo_sample.cfg文件名为:zoo.cfg,这是因为zookeeper启动时默认加载zoo.cfg配置文件。修改zoo.cfg文件内容如下:

    # The number of milliseconds of each tick  
    # tickTime:这个时间是作为 Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个 tickTime 时间就会发送一个心跳。  
    # 默认情况下最小的会话超时时间为两倍的tickTime  
    tickTime=2000  
    # The number of ticks that the initial   
    # synchronization phase can take  
    # zookeeper集群中的包含多台server, 其中一台为leader, 集群中其余的server为follower. initLimit参数配置初始化连接时,   
    # follower和leader之间的最长心跳时间. 此时该参数设置为5, 说明时间限制为5倍tickTime, 即5*2000=10000ms=10s.  
    initLimit=5  
    # The number of ticks that can pass between   
    # sending a request and getting an acknowledgement  
    # 该参数配置leader和follower之间发送消息, 请求和应答的最大时间长度. 此时该参数设置为2, 说明时间限制为2倍tickTime, 即4000ms.  
    syncLimit=2  
    # the directory where the snapshot is stored.  
    # do not use /tmp for storage, /tmp here is just   
    # example sakes.  
    # dataDir:顾名思义就是 Zookeeper 保存数据的目录,默认情况下,Zookeeper 将写数据的日志文件也保存在这个目录里。  
    dataDir=D:\\zookeeper-3.4.8\\data  
    # dataLogDir:顾名思义就是 Zookeeper 保存日志文件的目录  
    dataLogDir=D:\\zookeeper-3.4.8\\log  
    # the port at which the clients will connect  
    # clientPort:这个端口就是客户端连接 Zookeeper 服务器的端口,Zookeeper 会监听这个端口,接受客户端的访问请求。  
    clientPort=2181  
    # the maximum number of client connections.  
    # increase this if you need to handle more clients  
    # maxClientCnxns:限制连接到 ZooKeeper 的客户端的数量  
    # maxClientCnxns=60  
    #  
    # Be sure to read the maintenance section of the   
    # administrator guide before turning on autopurge.  
    #  
    # http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance  
    #  
    # The number of snapshots to retain in dataDir  
    # autopurge.snapRetainCount=3  
    # Purge task interval in hours  
    # Set to "0" to disable auto purge feature  
    # autopurge.purgeInterval=1  
    

    需要在zookeeper-x.x.x文件夹下新建data和log文件夹

    启动 zookeeper

    cmd命令进入 zookeeper-3.4.8\bin 目录,启动 zkServer.cmd
    或者直接双击zkServer.cmd启动,双击后窗口不会关闭,如果关闭了表示未启动成功
    如果jdk环境变量设置了,但是提示JAVA_HOME找不到,则需要修改该目录下的 zkEnv.cmd 关于 JAVA_HOME 的一部分

    zookeeper.PNG

    启动 zookeeper 成功,下一步修改demo里面的注册中心的addresszookeeper://127.0.0.1:2181

    demo-api-consumer:

    public static void main(String[] args) {
            ReferenceConfig<DemoService> reference = new ReferenceConfig<>();
            reference.setApplication(new ApplicationConfig("dubbo-demo-api-consumer"));
            //reference.setRegistry(new RegistryConfig("multicast://224.5.6.7:1234"));
            reference.setRegistry(new RegistryConfig("zookeeper://127.0.0.1:2181"));
            reference.setInterface(DemoService.class);
            DemoService service = reference.get();
            String message = service.sayHello("dubbo");
            System.out.println(message);
        }
    

    demp-api-provider:

    public static void main(String[] args) throws Exception {
            ServiceConfig<DemoServiceImpl> service = new ServiceConfig<>();
            service.setApplication(new ApplicationConfig("dubbo-demo-api-provider"));      
            //service.setRegistry(new RegistryConfig("multicast://224.5.6.7:1234"));
            service.setRegistry(new RegistryConfig("zookeeper://127.0.0.1:2181"));
            System.out.println("provider启动了");
            service.setInterface(DemoService.class);
            service.setRef(new DemoServiceImpl());
            service.export();
            System.in.read();
        }
    

    万事俱备,首先启动 provider

    [21/05/19 17:15:36:347 CST] main  INFO logger.LoggerFactory: using logger: org.apache.dubbo.common.logger.log4j.Log4jLoggerAdapter
    provider启动了
    [21/05/19 17:15:42:375 CST] main  INFO utils.Compatibility: Running in ZooKeeper 3.4.x compatibility mode
    [21/05/19 17:15:43:093 CST] main  INFO imps.CuratorFrameworkImpl: Starting
    

    zookeeper 命令行

    2019-05-21 17:15:52,601 [myid:] - INFO  [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxnFactory@222] - Accepted socket connection from /127.0.0.1:55960
    2019-05-21 17:15:52,601 [myid:] - INFO  [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:ZooKeeperServer@949] - Client attempting to establish new session at /127.0.0.1:55960
    2019-05-21 17:15:52,632 [myid:] - INFO  [SyncThread:0:ZooKeeperServer@694] - Established session 0x10001863bea0003 with negotiated timeout 40000 for client /127.0.0.1:55960
    

    admin-ui 显示

    provider.PNG

    启动 consumer

    [21/05/19 17:38:20:068 CST] main  INFO config.AbstractConfig:  [DUBBO] Refer dubbo service org.apache.dubbo.demo.DemoService from url zookeeper://127.0.0.1:2181/org.apache.dubbo.registry.RegistryService?anyhost=true&application=dubbo-demo-api-consumer&check=false&default.deprecated=false&default.dynamic=true&default.lazy=false&default.register=true&default.sticky=false&deprecated=false&dubbo=2.0.2&dynamic=true&generic=false&interface=org.apache.dubbo.demo.DemoService&lazy=false&methods=sayHello&pid=13352&register=true&register.ip=192.168.10.1&remote.application=dubbo-demo-api-provider&remote.timestamp=1558430153116&side=consumer&sticky=false&timestamp=1558431487233, dubbo version: , current host: 192.168.10.1
    Hello dubbo, response from provider: 192.168.10.1:20880
    [21/05/19 17:38:20:967 CST] DubboShutdownHook  INFO config.DubboShutdownHook:  [DUBBO] Run shutdown hook now., dubbo version: , current host: 192.168.10.1
    

    zookeeper 命令行:

    2019-05-21 17:38:17,489 [myid:] - INFO  [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxnFactory@222] - Accepted socket connection from /127.0.0.1:56156
    2019-05-21 17:38:17,493 [myid:] - INFO  [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:ZooKeeperServer@949] - Client attempting to establish new session at /127.0.0.1:56156
    2019-05-21 17:38:17,528 [myid:] - INFO  [SyncThread:0:ZooKeeperServer@694] - Established session 0x10001863bea0004 with negotiated timeout 40000 for client /127.0.0.1:56156
    2019-05-21 17:38:21,045 [myid:] - INFO  [ProcessThread(sid:0 cport:2181)::PrepRequestProcessor@487] - Processed session termination for sessionid: 0x10001863bea0004
    2019-05-21 17:38:21,077 [myid:] - INFO  [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxn@1056] - Closed socket connection for client /127.0.0.1:56156 which had sessionid 0x10001863bea0004
    

    可以看到输出成功
    dubbo 的目的,即做到调用远程接口方法和调用本地接口方法一样透明简单,从这个demo中就可以看出来。

    相关文章

      网友评论

          本文标题:探索分布式框架dubbo

          本文链接:https://www.haomeiwen.com/subject/zzvdzqtx.html