zoukankan      html  css  js  c++  java
  • JAVA总结--dubbo与zookeeper

    读累了就看看实操https://www.cnblogs.com/huasky/p/10214642.html 

    一、SOA

    概念:SOA:Service-Oriented Architecture,面向服务的架构,将应用程序的不同功能(服务)通过定义的接口来实现数据通信;服务治理;服务调度中心和治理中心;

    架构演变:单一应用架构ORM  |  垂直应用架构MVC  |  分布式服务架构RPC  |  流动计算架构SOA

    ORM :流量小,单一应用,部署一起;关注于简化增删改查的对象关系映射,

    MVC :流量增加,应用拆分;关注于提高前端开发速度;

    RPC :远程过程调用;通过网络进行远程计算机服务的请求;核心业务抽取;关注于业务的复用和整合;

    由统一到分布式:

    使用场景由混乱到统一:

     SOA又叫服务治理,SOA就是帮助我们把服务之间调用的乱七八糟的关系给治理起来,然后提供一个统一的标准;

    统一标准:各系统的协议、地址、交互方式。

    新的交互方式:各个系统分别根据统一标准向数据总线进行注册,各子系统调用其他子系统时,我们并不关心如果找到其他子系统,我们只招数据总线,数据总线再根据统一标准找其他子系统,所以数据总线在这里充当一个只路人的作用。

    数据总线是起到调度服务的作用,数据总线不是集成服务,数据总线更新一个调度框架,每个服务需要根据约定向数据总线注册服务;服务不是经过总线的,是直接向client响应;

     二、dubbo

    概念:dubbo:一个解决大规模服务治理的高性能分布式服务框架;分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,是阿里巴巴SOA服务化治理方案的核心框架;

    流程与说明: 

    dubbo的架构图如下:

    其中,

    · Provider: 暴露服务的服务提供方。

    · Consumer: 调用远程服务的服务消费方。

    · Registry: 服务注册与发现的注册中心。

    · Monitor: 统计服务的调用次调和调用时间的监控中心。

    · Container: 服务运行容器。

    调用关系说明:

    1. 服务容器负责启动,加载,运行服务提供者。

    2. 服务提供者在启动时,向注册中心注册自己提供的服务。

    3. 服务消费者在启动时,向注册中心订阅自己所需的服务。

    4. 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。

    5. 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。

    6. 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。

      Dubbo提供了很多协议,Dubbo协议、RMI协议、Hessian协议,Dubbo源代码有各种协议的实现,我们之前没用Dubbo之前时,大部分都用Hessian来使用我们服务的暴露和调用,利用HessianProxyFactory调用远程接口。

    原理:

    初始化过程细节:

         第一步,就是将服务装载容器中,然后准备注册服务。和spring中启动过程类似,spring启动时,将bean装载进容器中的时候,首先要解析bean。所以dubbo也是先读配置文件解析服务。

    解析服务:

        1)、基于dubbo.jar内的Meta-inf/spring.handlers配置,spring在遇到dubbo名称空间时,会回调DubboNamespaceHandler类。

        2)、所有的dubbo标签,都统一用DubboBeanDefinitionParser进行解析,基于一对一属性映射,将XML标签解析为Bean对象。生产者或者消费者初始化的时候,会将Bean对象转会为url格式,将所有Bean属性转成url的参数。 然后将URL传给Protocol扩展点,基于扩展点的Adaptive机制,根据URL的协议头,进行不同协议的服务暴露和引用。

    暴露服务:

        a、 直接暴露服务端口

        在没有使用注册中心的情况,这种情况一般适用在开发环境下,服务的调用这和提供在同一个IP上,只需要打开服务的端口即可。 即,当配置 or ServiceConfig解析出的URL的格式为: Dubbo://service-host/com.xxx.TxxService?version=1.0.0 基于扩展点的Adaptiver机制,通过URL的“dubbo://”协议头识别,直接调用DubboProtocol的export()方法,打开服务端口。

        b、向注册中心暴露服务:

        和上一种的区别:需要将服务的IP和端口一同暴露给注册中心。 ServiceConfig解析出的url格式为: registry://registry-host/com.alibaba.dubbo.registry.RegistryService?export=URL.encode(“dubbo://service-host/com.xxx.TxxService?version=1.0.0”)

    基于扩展点的Adaptive机制,通过URL的“registry://”协议头识别,调用RegistryProtocol的export方法,将export参数中的提供者URL先注册到注册中心,再重新传给Protocol扩展点进行暴露: Dubbo://service-host/com.xxx.TxxService?version=1.0.0

    引用服务:

        a、直接引用服务:

        在没有注册中心的,直连提供者情况下, ReferenceConfig解析出的URL格式为: Dubbo://service-host/com.xxx.TxxService?version=1.0.0

    基于扩展点的Adaptive机制,通过url的“dubbo://”协议头识别,直接调用DubboProtocol的refer方法,返回提供者引用。

        b、从注册中心发现引用服务:

        此时,ReferenceConfig解析出的URL的格式为: registry://registry-host/com.alibaba.dubbo.registry.RegistryService?refer=URL.encode(“consumer://consumer-host/com.foo.FooService?version=1.0.0”)

        基于扩展点的Apaptive机制,通过URL的“registry://”协议头识别,就会调用RegistryProtocol的refer方法,基于refer参数总的条件,查询提供者URL,如: Dubbo://service-host/com.xxx.TxxService?version=1.0.0

        基于扩展点的Adaptive机制,通过提供者URL的“dubbo://”协议头识别,就会调用DubboProtocol的refer()方法,得到提供者引用。 然后RegistryProtocol将多个提供者引用,通过Cluster扩展点,伪装成单个提供这引用返回。

    暴露服务的主过程:

        首先ServiceConfig类拿到对外提供服务的实际类ref,然后将ProxyFactory类的getInvoker方法使用ref生成一个AbstractProxyInvoker实例,到这一步就完成具体服务到invoker的转化。接下来就是Invoker转换到Exporter的过程。 Dubbo处理服务暴露的关键就在Invoker转换到Exporter的过程,下面我们以Dubbo和rmi这两种典型协议的实现来进行说明: Dubbo的实现: Dubbo协议的Invoker转为Exporter发生在DubboProtocol类的export方法,它主要是打开socket侦听服务,并接收客户端发来的各种请求,通讯细节由dubbo自己实现。 Rmi的实现: RMI协议的Invoker转为Exporter发生在RmiProtocol类的export方法,他通过Spring或Dubbo或JDK来实现服务,通讯细节由JDK底层来实现。

    服务消费的主过程:

        首先ReferenceConfig类的init方法调用Protocol的refer方法生成Invoker实例。接下来把Invoker转为客户端需要的接口

     三、zookeeper(可作为Dubbo的注册中心使用)

    概念zookeeper:为分布式应用程序提供协调服务;为其他分布式程序提供协调服务;本身也是分布式程序;

    zookeeper提供的服务:配置维护、域名服务、分布式同步、组服务;其实只提供了两个功能(管理数据和监听数据): 管理(存储,读取)用户程序提交的数据; 并为用户程序提供数据节点监听服务;

    应用场景:

    Zookeeper主要是做注册中心用;基于Dubbo框架开发的提供者、消费者都向Zookeeper注册自己的URL,消费者还能拿到并订阅提供者的注册URL,以便在后续程序的执行中去调用提供者。而提供者发生了变动,也会通过Zookeeper向订阅的消费者发送通知;

    用于担任服务生产者和服务消费者的注册中心,服务生产者将自己提供的服务注册到Zookeeper中心,服务的消费者在进行服务调用的时候先到Zookeeper中查找服务,获取到服务生产者的详细信息之后,再去调用服务生产者的内容与数据;

    zookeeper数据模型

    Znode:目录结构;节点;

    数据模型是一棵树(ZNode Tree),由斜杠(/)进行分割的路径,就是一个ZNode,如/hbase/master,其中hbase和master都是ZNode;

    每个Znode节点都包含了该节点的数据、状态信息、子节点。状态信息用来记录每次节点变更后的时间戳、版本等信息。因此,当版本发生变更的时候,ZooKeeper会同步修改该节点的状态信息。

    Znode有如下特征:

    1. 监视(Watch)

      客户端可以在Znode上面增加监视事件,当Znode发生变化的时候,ZooKeeper就会触发watch,并向客户端发送且仅通知一次,watch只能被触发一次。

    2. 数据访问

      节点数据访问是原子性,每个节点都有ACL(权限列表),规定了用户的权限,可以划分权限设定。

    3. 节点类型

      节点类型分为两种,永久性和临时性。临时性节点在每次会话结束的时候,自动删除。也可以手动删除临时节点,而且临时节点没法建立子节点。

    4. 顺序节点

      每个节点创建的时候,都会给新创建的节点增加1个身份数字,从1开始。它的格式“%10d”,计数超过2^32-1时,会有溢出风险。

      Znode类型有4种:永久性节点、临时性节点、永久性有序节点、临时性有序节点

    ZooKeeper采用ACL(Access Control Lists)策略来进行权限控制;

    zookeeper的5种权限:

    ·CREATE: 创建子节点的权限。

    ·READ: 获取节点数据和子节点列表的权限。

    ·WRITE:更新节点数据的权限。

    ·DELETE: 删除子节点的权限。

    ·ADMIN: 设置节点ACL的权限。

    注意:CREATE 和 DELETE 都是针对子节点的权限控制。

    zookeeper原理:

    (1)ZooKeeper分为服务器端(Server) 和客户端(Client),客户端可以连接到整个 ZooKeeper服务的任意服务器上(除非 leaderServes 参数被显式设置, leader 不允许接受客户端连接)。

    (2)客户端使用并维护一个 TCP 连接,通过这个连接发送请求、接受响应、获取观察的事件以及发送心跳。如果这个 TCP 连接中断,客户端将自动尝试连接到另外的 ZooKeeper服务器。客户端第一次连接到 ZooKeeper服务时,接受这个连接的 ZooKeeper服务器会为这个客户端建立一个会话。当这个客户端连接到另外的服务器时,这个会话会被新的服务器重新建立。

    (3)上图中每一个Server代表一个安装Zookeeper服务的机器,即是整个提供Zookeeper服务的集群(或者是由伪集群组成);

    (4)组成ZooKeeper服务的服务器必须彼此了解。 它们维护一个内存中的状态图像,以及持久存储中的事务日志和快照, 只要大多数服务器可用,ZooKeeper服务就可用;

    (5)ZooKeeper 启动时,将从实例中选举一个 leader,Leader 负责处理数据更新等操作,一个更新操作成功的标志是当且仅当大多数Server在内存中成功修改数据。每个Server 在内存中存储了一份数据。

    (6)Zookeeper是可以集群复制的,集群间通过Zab协议(Zookeeper Atomic Broadcast)来保持数据的一致性;

    (7)Zab协议包含两个阶段:leader election阶段和Atomic Brodcast阶段。

    • a) 集群中将选举出一个leader,其他的机器则称为follower,所有的写操作都被传送给leader,并通过brodcast将所有的更新告诉给follower。

    • b) 当leader崩溃或者leader失去大多数的follower时,需要重新选举出一个新的leader,让所有的服务器都恢复到一个正确的状态。

    • c) 当leader被选举出来,且大多数服务器完成了 和leader的状态同步后,leadder election 的过程就结束了,就将会进入到Atomic brodcast的过程。

    • d) Atomic Brodcast同步leader和follower之间的信息,保证leader和follower具有形同的系统状态。

    Leader算法:以Fast Paxos算法为基础的

    zookeeper角色:Leader、learner或follower、ObServer 

    领导者(Leader):负责进行投票的发起和决议,更新系统状态;

    学习者(Learner)或跟随者(Follower):接收客户端请求,并向客户端返回结果,在选主过程中参与投票;如果接收到的客户端请求为写请求,将转发给Leader来完成系统状态的更新;

    观察者(ObServer):接收客户端的连接,将写请求转发给Leader;不参与选主过程的投票,仅同步Leader状态;扩展系统,提高读写速度;

    应用场景

    1 统一命名服务(如Dubbo服务注册中心)

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

    在Dubbo实现中:

    服务提供者在启动的时候,向ZK上的指定节点/dubbo/${serviceName}/providers目录下写入自己的URL地址,这个操作就完成了服务的发布。

    服务消费者启动的时候,订阅/dubbo/${serviceName}/providers目录下的提供者URL地址, 并向/dubbo/${serviceName} /consumers目录下写入自己的URL地址。

    注意,所有向ZK上注册的地址都是临时节点,这样就能够保证服务提供者和消费者能够自动感应资源的变化。 另外,Dubbo还有针对服务粒度的监控,方法是订阅/dubbo/${serviceName}目录下所有提供者和消费者的信息。

    2 配置管理 (如淘宝开源配置管理框架Diamond)

    在大型的分布式系统中,为了服务海量的请求,同一个应用常常需要多个实例。如果存在配置更新的需求,常常需要逐台更新,给运维增加了很大的负担同时带来一定的风险(配置会存在不一致的窗口期,或者个别节点忘记更新)。zookeeper可以用来做集中的配置管理,存储在zookeeper鸡群中的配置,如果发生变更会主动推送到连接配置中心的应用节点,实现一处更新处处更新的效果。

    3 分布式集群管理 (Hadoop分布式集群管理)

    这通常用于那种对集群中机器状态,机器在线率有较高要求的场景,能够快速对集群中机器变化作出响应。这样的场景中,往往有一个监控系统,实时检测集群机器是否存活。过去的做法通常是:监控系统通过某种手段(比如ping)定时检测每个机器,或者每个机器自己定时向监控系统汇报“我还活着”。 这种做法可行,但是存在两个比较明显的问题:

    (1) 集群中机器有变动的时候,牵连修改的东西比较多。

    (2) 有一定的延时。

    利用ZooKeeper有两个特性,就可以实现另一种集群机器存活性监控系统:

    (1) 客户端在节点 x 上注册一个Watcher,那么如果 x?的子节点变化了,会通知该客户端。

    (2) 创建EPHEMERAL类型的节点,一旦客户端和服务器的会话结束或过期,那么该节点就会消失。

    例如,监控系统在 /clusterServers 节点上注册一个Watcher,以后每动态加机器,那么就往 /clusterServers 下创建一个 EPHEMERAL类型的节点:/clusterServers/{hostname}. 这样,监控系统就能够实时知道机器的增减情况,至于后续处理就是监控系统的业务了。

    4 分布式锁(强一致性)

    这个主要得益于ZooKeeper为我们保证了数据的强一致性。锁服务可以分为两类,一个是 保持独占,另一个是 控制时序。

    (1) 所谓保持独占,就是所有试图来获取这个锁的客户端,最终只有一个可以成功获得这把锁。通常的做法是把zk上的一个znode看作是一把锁,通过create znode的方式来实现。所有客户端都去创建 /distribute_lock 节点,最终成功创建的那个客户端也即拥有了这把锁。

    (2) 控制时序,就是所有视图来获取这个锁的客户端,最终都是会被安排执行,只是有个全局时序了。做法和上面基本类似,只是这里 /distribute_lock 已经预先存在,客户端在它下面创建临时有序节点(这个可以通过节点的属性控制:CreateMode.EPHEMERAL_SEQUENTIAL来指定)。Zk的父节点(/distribute_lock)维持一份sequence,保证子节点创建的时序性,从而也形成了每个客户端的全局时序。

  • 相关阅读:
    61. 最长不含重复字符的子字符串
    60. 礼物的最大价值 (未理解)
    59. 把数字翻译成字符串
    58. 把数组排成最小的数
    57. 数字序列中某一位的数字 (不懂)
    spring data jpa 官方文档
    idea 编译报错 源发行版 1.8 需要目标发行版 1.8
    idea maven 依赖报错 invalid classes root
    solr
    spring boot 官方文档
  • 原文地址:https://www.cnblogs.com/huasky/p/8268568.html
Copyright © 2011-2022 走看看