Zookeeper如何确保每位工人都能愉快地从工作委托经理那里得到一些工作。

Apache ZooKeeper是注册,管理和发现在不同计算机上运行的服务的工具。 当我们必须处理具有许多节点的分布式系统时,它是技术堆栈中必不可少的成员,这些节点需要知道其依赖关系从何处启动。

但是ZooKeeper的级别很低,即使标准用例也需要很多行代码。 这就是Apache Curator诞生的原因–一个比ZooKeeper更友好,更易于使用的包装器库。 使用Curator,我们可以用更少的代码和更简洁的方式交付更多内容。

“ Guava对于Java来说就像Curator对ZooKeeper一样” – ZooKeeper提交者Patrick Hunt

使用ZooKeeper负载均衡微服务

我们习惯于在应用程序前面部署负载均衡器的情况。 它的作用是确保每个单个节点获得或多或少相同的流量。

在微服务世界中,情况是相同的,但是与单片方法相比,我们具有显着的优势:当我们需要扩展应用程序时,我们不必复制整个系统并将其部署在功能强大的服务器上即可平稳运行。 我们只能将精力集中在需要扩展的小模块上,因此扩展成本要低得多(无论是在服务器成本还是在很多情况下为部署模块做准备所需的开发方面)。

但是随着我们系统的发展,我们最终会得到许多可扩展的模块,每个模块都需要单独的负载平衡器。 这似乎很麻烦,因为即使没有基础架构,我们的基础架构也非常复杂。 幸运的是,如果我们将ZooKeeper用作服务编排和发现工具,则可以使用内置的负载平衡功能,而不会在我们的微服务架构中引入任何其他复杂性。

为了展示ZooKeeper中开箱即用的负载平衡工作方式,我们需要两项服务:将多次部署的工作人员,以及将任务委派给已注册工作人员的经理。

简单工人

让我们从创建一个简单的工作程序开始,该工作程序将侦听给定的端口并在要求执行其工作时返回一些结果。 为了实现这个微小的微服务,我们将使用Groovy, Undertow轻量级servlet容器,当然还要使用ZooKeeper和Curator。

我们的工作人员将由一个小类组成,该小类的主要方法可以完成三件事:

class Main {static final void main(String[] args) {// Step 1: Extract name and port number to launch worker// Step 2: Configure and start Rest server on given port// Step 3: Register worker in ZooKeeper}
}

为简便起见,我将在此处省略步骤1和2,您可以在GitHub project上查看完整的源代码。 我们的工作人员只有一个端点GET / work,它会返回一个响应,并带有被叫工作人员的名字:

@Path("/")
class Main {@GET@Path("/work")public String work() {String response = "Work done by $workerName"println responsereturn response}}

步骤3: ZooKeeper中的注册工作人员是最有趣的地方,因此我将对其进行详细说明:

private static void registerInZookeeper(int port) {CuratorFramework curatorFramework = CuratorFrameworkFactory.newClient("localhost:2181", new RetryNTimes(5, 1000))curatorFramework.start()ServiceInstance<Void> serviceInstance = ServiceInstance.builder().uriSpec(new UriSpec("{scheme}://{address}:{port}")).address('localhost').port(port).name("worker").build()ServiceDiscoveryBuilder.builder(Void).basePath("load-balancing-example").client(curatorFramework).thisInstance(serviceInstance).build().start()
}
  • 第2-3行:我们创建并启动CuratorFramework客户端,该客户端包装了我们要在ZooKeeper实例上执行的所有操作。 为简单起见,我们将localhost与默认端口一起使用(通常,它应该是ZooKeeper的运行实例的URL)
  • 第4-9行创建了代表我们的工作人员的ServiceInstance。 我们传递了从其他微服务呼叫此工作人员所需的所有“联系方式”
  • 第11-16行在由CuratorFramework客户端表示的ZooKeeper中注册我们的实例。

出发工人

现在,Worker已经准备就绪,因此我们可以创建胖子罐(使用Gradle fatJar任务),然后使用以下命令启动它:

java -jar simple-worker/build/libs/simple-worker-1.0-shadow.jar Worker_1 18005

在启动worker之前,请记住您需要在默认2181端口上运行的ZooKeeper实例!

要检查worker是否正在运行,您应该在http:// localhost:18005 / work上打开浏览器,并在其中看到“ Worker_1完成的工作”文本。 要验证工作人员是否已在ZooKeeper中正确注册了自己,请启动命令行客户端:

cd/bin
./zkCli.sh

然后执行ls命令,查看在/ load-balancing-example / worker路径下注册的一个节点:

[zk: localhost:2181(CONNECTED) 1] ls /load-balancing-example/worker <enter>
[f69545e8-8466-40c0-93e9-f493eb7496b4]

简单的经理

现在,由于我们有工作人员在监听/ work的请求,因此我们可以创建简单的经理服务委托任务给其下属。 主要方法看上去与简单工作人员项目中的方法非常相似,主要区别在于我们没有在ZooKeeper中注册,我们仅创建角色(给惊喜)为我们提供工作人员实例的ServiceProvider 。 所以基本的工作流程是:

  1. 等待/ delegate上的请求
  2. 从ZooKeeper的ServiceProvider获取工作程序服务的实例
  3. 调用工作人员的/工作并返回其执行结果

要创建ServiceProvider,我们必须创建CuratorFramework客户端,连接到ZooKeeper,然后获取具有给定名称的服务的ServiceProvider,在本例中为worker

CuratorFramework curatorFramework = CuratorFrameworkFactory.newClient("localhost:2181", new RetryNTimes(5, 1000))
curatorFramework.start()ServiceDiscovery<Void> serviceDiscovery = ServiceDiscoveryBuilder.builder(Void).basePath("load-balancing-example").client(curatorFramework).build()
serviceDiscovery.start()serviceProvider = serviceDiscovery.serviceProviderBuilder().serviceName("worker").build()
serviceProvider.start()
  • 第1-2行,创建ZooKeeper客户端,方法与简单工作者相同
  • 第4-8行,创建ServiceDiscovery,它将能够为我们提供服务提供商。
  • 第10-11行。 创建并启动ServiceProvider,将用于获取工作程序节点的工作实例。

最后,我们需要一个Rest端点,管理器在其上等待任务委派:

@GET
@Path("/delegate")
public String delegate() {def instance = serviceProvider.getInstance()String address = instance.buildUriSpec()String response = (address + "/work").toURL().getText()println responsereturn response
}

起始经理

Manager已准备就绪,执行fatJar任务后,我们可以使用以下命令启动它:

java -jar simple-manager/build/libs/simple-manager-1.0-shadow.jar 18000

为了验证它是否正常工作,我们可以在浏览器中打开( http:// localhost:18000 / delegate )以查看消息“ Worker_1完成的工作”。

经理对其员工一无所知。 他唯一知道的是服务已在ZooKeeper中的特定路径下注册。 这很简单,无论我们是在本地启动多个工作人员还是在不同国家/地区的不同服务器上分布。

使用ZooKeeper开箱即用的负载平衡

想象一下这样的情况:经理从首席执行官那里获得了太多任务,以至于他需要多个工人来委派工作。 在标准情况下,我们将被迫扩大规模并在他们前面放置负载平衡器。 但是ZooKeeper无需任何其他工作即可为我们提供此功能。

让我们添加更多在不同端口上侦听的工作者:

java -jar simple-worker/build/libs/simple-worker-1.0-shadow.jar Worker_1 18005 &java -jar simple-worker/build/libs/simple-worker-1.0-shadow.jar Worker_2 18006 &java -jar simple-worker/build/libs/simple-worker-1.0-shadow.jar Worker_3 18007 &java -jar simple-worker/build/libs/simple-worker-1.0-shadow.jar Worker_4 18008 &

诀窍是所有工作程序都在ZooKeeper中的同一路径下注册,因此当我们在/ load-balancing-example / worker下列出节点时,将看到四个实例:

[zk: localhost:2181(CONNECTED) 0] ls /load-balancing-example/worker  <enter>
[d5bc4eb9-8ebb-4b7c-813e-966a25fdd843, 13de9196-bfeb-4c1a-b632-b8b9969b9c0b, 85cd1387-2be8-4c08-977a-0798017379b1, 9e07bd1d-c615-430c-8dcb-bf228e9b56fc]

这里最重要的是,要利用这四个新工作人员,经理不需要对代码进行任何更改。 我们可以在流量增加时启动新的工作程序实例,或者在无事可做时将其关闭。 Manager与这些操作脱钩,它仍然调用ServiceProvider来获取worker的实例并将工作传递给他。

所以现在当我们打开http:// localhost:18000 / delegate并按几次刷新时,我们将看到:

Work done by Worker_1
Work done by Worker_2
Work done by Worker_3
Work done by Worker_4
Work done by Worker_1
Work done by Worker_2
Work done by Worker_3

它是如何实现的? 默认情况下,ServiceProvider使用Rounded-robin ProviderStrategy实现,该实现旋转给定路径下可用的实例,从而使每个实例都有一些工作要做。 如果默认机制不符合我们的需求,我们当然可以实施自定义策略。

摘要

今天就这些。 如您所见,通过使用Apache ZooKeeper和Curator,我们可以在无需部署,监视和管理单独负载均衡器的情况下生存。 即使没有微服务架构,基础架构也非常复杂。

翻译自: https://www.javacodegeeks.com/2014/07/zookeeper-curator-and-how-microservices-load-balancing-works.html

ZooKeeper,策展人以及微服务负载平衡的工作方式相关推荐

  1. zookeeper 负载_ZooKeeper,策展人以及微服务负载平衡的工作方式

    zookeeper 负载 Zookeeper如何确保每个工人都能从工作委托经理那里愉快地完成工作. Apache ZooKeeper是注册,管理和发现在不同计算机上运行的服务的工具. 当我们必须处理具 ...

  2. 微服务负载均衡实现高可用_使用负载平衡实现大容量可用性

    微服务负载均衡实现高可用 Written by Yona Gidalevitz 由Yona Gidalevitz撰写 Most users of the web are blissfully unaw ...

  3. 微服务负载均衡 Ribbon

    微服务负载均衡 什么是Ribbon? 目前的主流负载方案分为以下两种: 1,集中式负载均衡,在消费者和服务提供方中间使用独立的代理方式进行负载,有硬件的(比如 F5),也有软件的(比如Nginx). ...

  4. 微服务之间的最佳调用方式

    上一篇:3600万中国人在抖音"上清华" 0.2T架构师学习资料干货分享 茉莉花,别名:茉莉,拉丁文名:Jasminum sambac (L.) Ait,木犀科.素馨属直立或攀援灌 ...

  5. 万字长文浅析SpringCould微服务负载均衡框架Ribbon源码(字多慎入)

    前言 版本 作者:韩数 Github:github.com/hanshuaikan- 完成日期:2019-06-16日 jdk:1.8 springboot版本:2.1.3.RELEASE Sprin ...

  6. 微服务升级_SpringCloud Alibaba工作笔记0017---Nacos之服务消费者注册和负载

    技术交流QQ群[JAVA,C++,Python,.NET,BigData,AI]:170933152 上面一节,咱们说了nacos的服务提供者,下面咱们说 nacos的服务消费者,就是咱们创建一个83 ...

  7. 微服务负载均衡小能手-Ribbon

    引言 书接上篇 微服务管家婆-Nacos Discovery 使用Nacos对微服务做了服务治理,通过Nacos维护的服务清单找到目标微服务,此时有个小问题,如果目标微服务是多个时,该怎么办,应该调用 ...

  8. 聊一聊微服务常见配置中心工作原理

    0. 环境 nacos版本:1.4.1 Spring Cloud : 2020.0.2 Spring Boot :2.4.4 Spring Cloud alibaba: 2.2.5.RELEASE S ...

  9. Sentinel服务熔断Ribbon环境预说_客户自定义限流处理_削峰填谷_流量控制_速率控制_服务熔断_服务降级---微服务升级_SpringCloud Alibaba工作笔记0048

    技术交流QQ群[JAVA,C++,Python,.NET,BigData,AI]:170933152 然后咱们看服务熔断功能 然后这里我们要说上面的内容 首先我们准备环境,服务提供者是,9003,90 ...

最新文章

  1. linux 文件查找与文件中注释去除
  2. Introduction to Django(The Definitive Guild to Django)
  3. 将线程pid转成16进制_如何使用jstack分析线程状态
  4. dataGridView1去掉第一列
  5. CSS3 box flex 布局
  6. P4245 【模板】任意模数多项式乘法(NTT)
  7. 【数据结构与算法】单链表的Java实现
  8. linux 网络命令 dns,[LN_03] Linux网络环境查看(网卡|路由|DNS|IP)、网络测试命令(端口探测|路由跟踪|抓包|ssh连接)...
  9. c语言strlren函数的原代码,VB常用函数
  10. 企业如何做好EDM-企业做EDM的方案设计
  11. 中挪动正请求第三方支出牌照竖立支出公司
  12. 互联网运营和传统运营,到底有什么区别
  13. WinHex数据恢复使用教程
  14. 阿米洛键盘失灵_机械键盘按键失灵维修,这里有个案例给你一些思路。
  15. 学北邮计算机未来四十岁,2020年北京邮电大学计算机研究生保研心得
  16. xp 计算机配置,xp怎么查看电脑配置
  17. 算法分析——算法的渐进效率分析 和 渐进符号大O、大Ω、大θ、小o、小ω
  18. 包饺子、看表演、逛庙会 中外居民北京“过大年”
  19. GLSL里的矩阵对向量的乘法与OpenGL里用数组生成矩阵进行向量乘法的非直觉不一致
  20. 小飞学习Docker之使用容器

热门文章

  1. SSM整合简单登录案例
  2. raid配置ssd为缓存_超融合硬件选配推荐指南 | 第三期:SSD 与 HDD
  3. java每个阶段的学习时间_每个Java学习者都会犯的10个最常见的1个错误
  4. neo4j导入两个文件_Neo4j:找到两个纬度/经度之间的中点
  5. oracle aq_通过Java 8流使用Oracle AQ
  6. 如何在Java JVM中处理图像和视频
  7. 维持硒测试自动化的完美方法
  8. OCA第1部分中的Java难题
  9. Project Reactor展开方法
  10. 鸡肉和鸡蛋–测试前解决Spring属性