Dubbo + Zookeeper entry (Part I)

1 Introduction

Four questions do micro-service architecture of distributed systems development at:
how a client access to so many services

  • API, Gateway

How to communicate between services and service 2
synchronous communication:

  • HTTP(Apache Http Client)
  • RPC (Dubbo, only supports Java)

Asynchronous communication:

  • Message queue (kafka RabbitMQ RocketMQ)

3 How much service management (management is essentially micro address management services)
Service Management: Service registration and discovery

  • Based service registration and discovery (Dubbo + Zookeeper) client
  • Based service registration and discovery (Eureka Spring Cloud in) the service side

4 Services hang of how to do

  • Retry mechanism
  • Service fuse
  • Service downgraded
  • Limiting service

Micro-service architecture will need to be addressed more than four big problems, the biggest problem is the root cause of these networks are not reliable.
There are two commonly used micro-service solutions:

  • Spring Boot + Spring Cloud
    -based HTTP
    completion of service registration and discovery using Eureka (Netflix's)
    components and more, full-featured
  • Spring Boot + Dubbo + Zookeeper (Apache s)
    based on the RPC communication framework
    using Dubbo + Zookeeper complete service registration and discovery
    fewer components, the first set of program function is not complete

2. RPC

2.1 Concepts

RPC (Remote Procedure Call) refers to the Remote Procedure Call, is an interprocess communication, it is a technology idea, rather than the norm.
It allows a program to call another address space (typically another machine sharing network) procedure or function, rather than coding the detail display programmer remote calls. That programmer whether to call a local or remote function, essentially calling code written in basically the same.

Distributed Services Framework Dubbo communications service architecture and micro-differences between the individual services SpringCloud: Dubbo based on the RPC protocol communication, and micro employed Cloud service is HTTP-based RESTful API. <// font>

2.2 RPC basic principles

A program on the server is assumed to be invoked on the server B program code execution on A, B as the server, calling the server A hi on server B () method, hi () method returns a string A to the server:
the client program A:

hello(){
   String msg = B.hi(new User(“张三”));
   System.out.println(msg);
}

Server program B:

String hi(user){
   return “你好:+user.getName();
}

The following figure shows the basic principle of RPC. A server and B, respectively, using the RPC server framework, when it finds a server A server call interface B, and B will establish a server connection. And the client need to carry parameters, then the parameters of the processing sequence.
Here Insert Picture Description
RPC can be seen that the two core modules: communication (data transmission via a network communication) and a sequence of (parameters and results serialization and deserialization).
RPC framework there are many, such as Dubbo , GRPC, Thrift, HSF (High Speed Service Framework)

Here again with a distributed service architecture diagram learn more about the RPC:
Here Insert Picture Description
In a distributed service framework (between back-office services, between foreground and background services) between each service will call interface with each other, these call interface management pay frame to the RPC process.

3. Zookeeper

Zookeeper is a distributed coordination service . Distributed Coordination Service is mainly used to solve the synchronization control between multiple processes in a distributed environment, so they ordered access to certain critical resources, prevent the consequences of "dirty data".

By drawing below to help understand this concept, multiple orders to deploy services on multiple servers ( multiple processes ), when there are 15 concurrent arrival Nginx server, Nginx forwarded to the service orders, service orders were assigned to three 5 a request to access goods and services, merchandise only five ( critical resource ), if not three orders service organization to manage access to goods and services, may occur deduction of commodity stocks is greater than 5, this is caused " dirty data . "

This problem does not exist in monomer applications, since a single application JVM is a process, a process there are several threads, the next single application, multiple threads can lead to critical resource access issues, by way synchronization code ensure orderly access to resources.

Here Insert Picture Description
分布式协调服务Zookeeper就是为了解决这一问题。协调的本质为“分布式锁”,当第一个服务请求到临界资源的时候,就给临界资源上锁,其他服务就无法再请求得到临界资源。

3.1 Zookeeper的数据模型

Zookeeper的数据模型像树结构,也像文件系统目录。树由节点组成,Zookeeper的数据存储也同样是基于节点,这种节点称为Znode。
但是不同于树的节点,Zonde的引用方式是路径引用,类似于文件路径:/用户服务/用户登录/订单服务/处理订单
Here Insert Picture Description

每个Znode节点存储的数据不能超过1MB

Zonde节点包含的元素

  • data:存储数据信息(比如服务ip、服务名称)
  • ACL:记录Znode的访问权限,即哪些用户或哪些IP可以访问本节点
  • child:记录子节点的地址
  • stat:包含Zonde的各种元数据,比如事务ID、版本号、时间抽、大小等等

3.2 Zookeeper的事件通知

当Znode发送改变,也就是调用了create(创建节点)、delete(删除节点)、setData(设置节点数据)方法的时候,将会触发Znode上注册的对应事件,请求Watch的客户端会接收到异步通知。

具体交互过程如下:
Here Insert Picture Description

  • 客户端调用 getData 方法,watch 参数是 true。服务端接到请求,返回节点数据,并且在对应的哈希表里插入被 Watch 的 Znode 路径,以及 Watcher 列表。
  • 当被 Watch 的 Znode 已删除,服务端会查找哈希表,找到该 Znode 对应的所有 Watcher,异步通知客户端,并且删除哈希表中对应的 Key-Value。

3.3 服务注册与发现

前言中提到常用的有两套微服务解决方案,解决了服务注册与发现,下面通过一张图来理解服务注册与发现的概念:
Here Insert Picture Description

  • 开启Zookeeper服务注册与发现中心
  • 各个微服务向服务中心注册信息(ip、服务名称等)
  • 用户请求订单服务,并设置watch为true,假设此时返回给服务注册与发现服务的微服务ip是192.168.0.1
  • API Geteway(API网关)中由zkClient(Zookeeper客户端)维护了一个列表,列表中存储了订单服务服务的地址为192.168.0.1,当用户下次再请求订单服务时,就可以直接拿到这个ip
  • 如果192.168.0.1宕机了,Zookeeper的服务发现功能能够发送异步通知给API网关通知该192.168.0.1服务已下线,然后zkClient从列表中删除这个服务ip
  • 当用户再次访问订单服务时,返回的服务ip就是192.168.0.4或者192.168.0.5

事件通知机制就是帮助Zookeeper完成服务注册与发现

3.4 Zookeeper一致性问题

如果只部署一台Zookeeper服务中心(单机),那么Zookeeper服务中心挂掉之后,整个服务就无法使用了。这时候就可以部署多个服务中心(集群),微服务可以连接任意一个服务中心,那么新的问题又产生了,就是数据如何同步。
Zookeeper服务是一主多从结构,在更新数据时,首先更新到Zookeeper服务集群的主节点(Leader),再同步到从节点(Follower)。读取数据时,直接读取任意节点。【读取分离】。
当主节点崩溃时,会从从节点中重新选举新的主节点。

数据写入流程保证数据一致性:

  • 客户端发出写入数据请求给任意Follower
  • Follower把写入数据请求转发给Leader
  • Leader采用二阶段提交方式,先发送Propose广播给Follower
  • Follower接收到Propose消息,写入日志成功后,返回ACK消息给Leader
  • Leader接到半数以上ACK消息,返回成功给客户端,并且广播Commit请求给Follower

3.5 Zookeeper的基本使用

Zookeeper是一个服务,需要被单独启动,有服务端和客户端,客户端可用命令行工具,Zookeeper的安装和基本使用见下面的Dubbo环境搭建小节。

4. 分布式锁

为了防止分布式系统中的多个进程之间相互干扰,我们需要一种分布式协调技术来对这些进程进行调度,而这个分布式协调技术的核心就是来实现这个分布式锁。

4.1 分布式锁应该具备的条件

  • 在分布式系统环境下,一个方法在同一时间只能被一个机器的一个线程执行
  • 高可用的获取锁与释放锁
    保证锁能正常获取和释放(比如获取到锁的程序在未释放锁之前就挂掉,导致锁不能正常释放,其他程序就一直无法获取锁)
  • 高性能的获取锁和释放锁
    获取锁和释放锁的时间快
  • 具备可重入特性
    可由多个任务并发使用,不会造成数据错误
  • 具备锁失效机制,防止死锁
  • 具备非阻塞锁特性,即没有获取到锁将直接返回获取锁失效

4.2 现有分布式锁的实现

  • Memcached
    利用Memcache的add命令,此命令是原子性操作,只有在key不存在的情况下,才能add成功
  • Redis
    利用Redis的setnx命令,此命令是原子性操作,只有在key不存在的情况下,才能set成功
  • Zookeeper
    利用Zookeeper的顺序临时节点,来实现分布式锁和等待队列。Zookeeper的设计初衷就是为了实现分布式锁服务。
  • Chubby
    利用了Paxos一致性算法

4.3 分布式锁的三大问题及解决

1 非原子性操作
设置锁的键值对和键值对的过期时间必须是一个原子操作,利用redis的set(key, value, expire)保证原子操作
2 误删锁

  • 假设JVM1设置锁的过期时间为30s
  • JVM1执行程序的时间超过了30s,这时JVM2便可获得锁
  • JVM1执行完程序后去删除锁,这时候删除的实际上是JVM2的锁

解决:
删除锁之前先判断是不是自己线程设置的锁
3 锁过期时间小于程序执行时间
也就是说程序还未执行完成,锁就过期了。
解决:利用守护线程,当检测到程序持有的锁块过期了,但是程序还未执行完,则增加锁的过期时间

4.4 Zookeeper如何实现分布式锁

利用Zookeeper的顺序临时节点,来实现分布式锁和等待队列。Zookeeper 的数据存储结构就像一棵树,这棵树由节点组成,这种节点叫做 Znode。

Znode 分为四种类型

  • 持久节点:默认的节点类型。创建节点的客户端与 Zookeeper 断开连接后,该节点依旧存在。
  • 持久节点顺序节点:顺序节点,就是在创建节点时,Zookeeper 根据创建的时间顺序给该节点名称进行编号。
  • 临时节点:当创建节点的客户端与 Zookeeper 断开连接后,临时节点会被删除。
  • 临时顺序节点::在创建节点时,Zookeeper 根据创建的时间顺序给该节点名称进行编号;当创建节点的客户端与 Zookeeper 断开连接后,临时节点会被删除。

Zookeeper应用了临时顺序节点实现分布式锁,步骤如下:

  • 获取锁:在 Zookeeper 当中创建一个持久节点 ParentLock。当第一个客户端想要获得锁时,需要在 ParentLock 这个节点下面创建一个临时顺序节点 Lock1。之后,客户端遍历ParentLock 下的所有锁,判断自己的锁是不是最靠前的(锁编号最小),如果是,则获取锁成功,否则向它的前一个锁注册Watcher,用于监听前一个锁是否存在,直到前一个锁释放之后(由于是临时顺序节点,因此锁释放之后,锁就删除了),该监听该锁的客户端获取锁成功。
  • Here Insert Picture Description
    Here Insert Picture Description
  • 释放锁,释放锁分两种情况:任务完成,客户端显示释放;执行任务过程中,客户端崩溃。这两种情况都会导致相关联的锁删除。

4.5 Zookeeper和Redis分布式锁的比较

Zookeeper分布式锁的优点:

  • 有封装好的框架,容易实现
  • 有等待锁的队列,大大提升抢锁效率。因为Zookeeper中利用顺序锁,后一个锁的客户端监听前一个客户端的锁即可,监听的锁一旦释放,则该客户端即可获得锁。而Redis中没有等待锁的队列,假设此时创建了三个锁,其中一个客户端获取锁成功,则另外两个客户端要不断地去竞争锁,没有向Zookeeper一样的Watcher机制和队列机制。

Zookeeper的缺点:

  • 添加和删除节点性能较低

Redis分布式锁的优点:

  • Set和Del指令的性能较高

Redis分布式锁的缺点:

  • 实现复杂,需要考虑超时、原子性、误删等情况
  • 没有等待锁的队列,只能在客户端自旋来等锁(没有获取到锁的客户端都不停地去看有没有可用锁),效率低下

5. Dubbo

5.1 简介

Dubbo是一款高性能、轻量级的开源Java RPC分布式服务框架,特性如下【来自dubbo官网】:

  • 面向接口代理的高性能RPC调用
    即当A服务器调用B服务器中的方法时,A服务把B服务的方法接口拿过来,A服务只需要调用接口的方法即可,Dubbo会自动去B服务器上找到相应的方法并执行,为开发者屏蔽了远程调用的底层细节。
  • 智能负载均衡
    比如当“用户业务”服务器访问量很大,增加“用户业务”服务器后,Dubbo管理具体调用哪台服务器。
  • 自动服务注册和发现
    Dubbo支持多个服务注册中心(其中一个就是Zookeeper),可以立即在线/离线检测服务。
  • 高扩展性
    Dubbo的微内核和插件设计确保了它可以通过第三方实现轻松地跨核心功能(如协议、传输和序列化)进行扩展。
  • 运行时流量路由
    Dubbo可以在运行时进行配置,以便流量可以根据不同的规则进行路由,这使得它很容易支持如灰度发布、数据中心感知路由等功能。
  • 可视化服务治理
    Dubbo为服务治理和维护提供了丰富的工具,如查询服务元数据、运行状况和统计信息

5.2 Dubbo核心功能

  • Remoting:远程通讯,提供对多种 NIO(Dubbo使用了著名的通信框架:Netty) 框架抽象封装,包括“同步转异步”和“请求-响应”模式的信息交换方式。
    通讯模型BIO:同步并阻塞;NID:异步并阻塞;AIO:异步非阻塞
  • Cluster:服务框架,提供基于接口方法的透明远程过程调用,包括多协议支持,以及软负载均衡,失败容错,地址路由,动态配置等集群支持。
  • Registry:服务注册中心,服务自动发现: 基于注册中心目录服务,使服务消费方能动态的查找服务提供方,使地址透明,使服务提供方可以平滑增加或减少机器。

5.3 Dubbo组件角色

Here Insert Picture Description
Dubbo的五个角色

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

上图中的调用关系说明

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

5.4 Dubbo环境搭建

【参考官方文档:http://dubbo.apache.org/zh-cn/docs/user/quick-start.html】
1 配置注册中心使用官方推荐的zookeeper

  • 到zookeeper官网下载,我这里下载的版本是3.4.11
  • zookeeper-3.4.11\conf下的zoo_sample.cfg文件复制一份改名为zoo.cfg
  • 新建文件夹zookeeper-3.4.11\data
  • 修改zoo.cfg配置项 dataDir=../data
  • 进入zookeeper-3.4.11\bin目录,在Windows上的命令窗口中运行zkServer.cmd打开注册中心服务
  • 运行zkCli.cmd进入zookeeper客户端管理终端
    Here Insert Picture Description

2 安装dubbo的管理控制台
dubbo的管理控制台提供了可视化web界面供我们管理各个服务

  • 到GitHub上下载安装包(https://github.com/locationbai/incubator-dubbo-ops-master)
  • 打开incubator-dubbo-ops-master\dubbo-admin\src\main\resources\application.properties文件,修改配置项 dubbo.registry.address=zookeeper://127.0.0.1:2181
  • 保证maven环境搭配好
  • 在incubator-dubbo-ops-master\dubbo-admin\下打开命令窗口,运行命令mvn clean package,意思是将dubbo-admin程序打成一个jar包(application.properties默认配置是jar包)
    Here Insert Picture Description
  • 将incubator-dubbo-ops-master\dubbo-admin\target下的dubbo-admin-0.0.1-SNAPSHOT.jar文件包放到incubator-dubbo-ops-master的同级目录下
  • 在命令终端中执行java -jar dubbo-admin-0.0.1-SNAPSHOT.jar,即以SpringBoot的方式启动dubbo-admin程序(保证在第一步zookeeper注册中心服务已开启)
    Here Insert Picture Description
  • 浏览器方法http://localhost:7001/,用户名和密码都是rootHere Insert Picture Description

3 配置控制中心

  • incubator-dubbo-ops-master\dubbo-monitor-simple目录下打开控制台,执行命令mvn package
  • 将dubbo-monitor-simple-2.0.0-assembly.tar.gz文件放到incubator-dubbo-ops-master的同级目录下并解压
  • 打开dubbo-monitor-simple-2.0.0\conf\dubbo.properties做如下配置:
dubbo.container=log4j,spring,registry,jetty-monitor
dubbo.application.name=simple-monitor
dubbo.application.owner=dubbo
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.protocol.port=7070
dubbo.jetty.port=8080
dubbo.jetty.directory=${user.home}/monitor
dubbo.charts.directory=${user.home}/monitor/charts
dubbo.statistics.directory=${user.home}/monitor/statistics
dubbo.log4j.file=logs/dubbo-monitor-simple.log
dubbo.log4j.level=WARN
  • 双击dubbo-monitor-simple-2.0.0\assembly.bin\start.bat
    Here Insert Picture Description
  • 浏览器访问http://localhost:8080
    Here Insert Picture Description

5.5 在SSM中使用Dubbo

下面模拟一个用户-订单地址管理服务

  • user-service-provider是生产者服务,提供查询用户订单的服务
  • order-service-consumer消费者服务,调用生产者服务中的接口
  • gmall-interface是将生产者服务和消费者服务中的接口提取出来,接口的具体实现在user-service-provider或order-service-consumer中
  • provider.xml中配置dubbo服务中心的相关信息(服务中心的ip和端口,申明暴露的服务接口等)
  • consumer.xml中配置dubbo消费者相关信息(申明需要调用的远程服务的接口等)

Here Insert Picture Description

源码
链接:https://pan.baidu.com/s/1TRyjIVErV1GwTtYyza2fvQ
提取码:0lsd

5.6 在Spring Boot中使用Dubbo

Here Insert Picture Description
hello-dubbo-service-user-api为服务暴露的接口
hello-dubbo-service-user-provider为服务提供者
hello-dubbo-service-user-consumer为服务消费者

使用:

  • 启动dubbo
  • 启动hello-dubbo-service-user-provider
  • 启动hello-dubbo-service-user-consumer
  • 浏览器访问:http://localhost:9000/hi
  • 使用incubator-dubbo-ops管理控制台查看:
    Here Insert Picture Description

源码:
链接:https://pan.baidu.com/s/1ZIYVJKY-5PjGbH3ZwjF8zA
提取码:bafg

6 附录

Reference:
https://www.funtl.com/zh/guide/Apache-Dubbo.html
http://dubbo.apache.org/en-us/

"Dubbo entry (novella)"

Published 243 original articles · 87 won praise · views 70000 +

Guess you like

Origin blog.csdn.net/IT_10/article/details/104085203