通信,高可用性和微服务

时间:2019-07-10 11:04:12

标签: microservices communication api-design high-availability

我对微服务的理解是,您可以根据需要“仅”旋转同一服务的多个实例。

那么我的问题是,如果您有x个微服务实例,分布在y台服务器上,那么微服务上调用API的任何人怎么知道在哪里找到它?

我见过的一种方法是拥有某种发现服务(可以路由到实例的固定IP地址,例如负载均衡器);但是可以肯定的是,这只是将问题推到了一层-然后发现服务需要知道一切在哪里/什么时候发生故障等等?那发现服务的高可用性又如何呢(如果您有多个实例,那么您将回到不知道什么又来了)

另一种方法可能是使用发布/订阅消息传递,但是同样,您仍然需要知道队列管理器在哪里(具有高可用性等);因此,您基本上仍然会遇到相同的问题-使用这种方法,对查询的响应会更加棘手。

另一个相关的问题是,如果您有一个从STOMP提要中提取的微服务,您将如何进行HA?您不能只拥有该服务的x个实例,否则您将要订阅和读取x次数据,这意味着当数据传递到下游系统时最终会重复。因此,您需要某种主动/被动的方法,对吗?这意味着您需要一些东西来管理该故障转移,从而再次给出单点故障?

2 个答案:

答案 0 :(得分:3)

您可以拥有一个服务注册表,服务在启动时在其中注册自己。注册表可能会监听其他服务针对注册事件的广播,因此无需在服务中的某个位置固定注册表的位置。

然后,所有其他服务可以使用此注册表通过查询注册表来查找可用实例。注册表也可以充当DNS解析器,因此您的服务可以使用DNS通过名称解析其他服务,还可以自动在多个主机之间进行负载平衡。

另一种方法可能是逆转责任,并且希望与其他服务联系的服务广播请求,该请求由其他服务用所需的信息回答(这基本上是DNS所做的)。

Consul by Hashi Corp是解决此问题的一种可行方法。看一下它提供的功能,这些功能可能另外有用,例如健康检查。

答案 1 :(得分:1)

我所做的是:

我让每个服务在启动时都生成一个目录,该目录可以作为根资源(.../{service}/)访问。 在此ToC中,所有端点都作为Map。

键是一个(众所周知的)EndpointId,值始终由

组成
  • title
  • href
  • type(mediaType)

所以,基本上是常规链接。

魔术位于href中,其中公共主机(DNS)可配置为环境变量(例如,Config Map)。由于使用了DNS,因此LoadBalancing等不合时宜。但是您也可以将这种方法用于内部IP。

here中提到的这是一种好习惯。

  

在输入REST API之前,除了初始URI(书签)和适用于目标受众的标准媒体类型集(即,可能会使用该API的任何客户端都希望理解)之外,都应该没有其他知识。从那时起,所有应用程序状态转换都必须由客户端选择服务器提供的选择来驱动,这些选择出现在接收到的表示形式中或由用户对这些表示形式的暗示来暗示。过渡可以由客户对媒体类型和资源通信机制的了解来确定(或受其限制),这两者都可以动态地(例如,按需编码)加以改进。 [这里的失败表示带外信息正在驱动交互,而不是超文本。]

因此,每个服务都有一个根资源,其中包含指向所有端点的链接(有时是模板化的)。

通过将其发布到称为“端点”的Kafka主题中,可以重复使用相同的ToC,其中key是(众所周知的)ServiceId(“ fooService”或“ fooService:1.2.3”), value是其目录。

每个服务还具有对主题(GlobalKTable)的读取访问权限,因此,当它想生成指向FooService的链接时,他在GlobalKTable中查找其ToC,在其ID中查找端点,将模板变量替换为real值并完成,它不会更改type,因为它被认为是正确的。

这里很酷的事情是(由于Kafkas GlobalKTable和QueryableKeyStores),当FooService更改其端点(仅以不间断的方式)时,所有其他服务都会自动生成新链接。 DNS更改或重命名路径段将起作用。重命名参数显然没有。