Are We Reactive Now?
我们之前写的这段代码和基于 HTTP 微服务非常接近,区别就是我们用了 event bus 取代了 HTTP,这个可以改变我的响应式服务吗?是的,我们来看看为什么。
Elasticity
弹性的分布式是之前的 HTTP 版本做不到的,因为 microservice 调用服务的时候用了一个固定的 URL,没有提供我们需要的分布式(当然改进通过其他技术还是可以的),但是现在我们使用消息发送到某个地址,改变了这个游戏,让我们看看这个微服务系统怎么行为吧。
你还记得之前执行的输出,返回的JSON 显示了 verticle 计算的输出,输出显示总是同一个 verticle,消息也是显示是同一个实例,因为我们只有一个实例在运行,然后我们运行两个实例会发生什么。
停止 Hello microservice 的执行,然后运行下面的命令:
然后,打开两个终端在 hello-microservice 消息目录,执行以下命令(在每一个终端):
这样启动了两个 hello microservice 的实例,回到浏览器,刷新页面,你可能看到如下的结果:
我们使用了来给你个 Hello 实例,Vert.x 集群连接了不同的节点,event bus 也是一个集群,得益于 event bus 的 round-robin ,Vert.x event bus 分发消息到不同的可执行的实例,而且做了负载均衡的事情。
因此用了 event bus ,我们有了需要的弹性分布式特性。
Resilience
关于快速恢复(失败)呢?在现在的节点里,如果hello microservice 失败了,我们得到一个 failure 和执行下面的代码:
即使用户获取到一个 error mesage,我们没有崩溃,也没有限制了拓展性,我们仍然可以处理这个请求。然后,为了改善我们的用户体验,我们应该总是及时回复给用户,即使我们没有从service获取响应,为了实现这个逻辑,我们可以使用超时的代码。
为了说明这一点,让我们修改hello microservice 注入故障和问题行为。这段代码在microservices/ hello-microservice-faulty 文件下。
这个start 方法随机从三种启动策略中选好一种:1.响应失败,2.忘记响应(调用方超时),3.发送正确的结果
重新打包和启动这两个 hello microservice 的实例。
因为注入了失败的情况,所以我们改进消费房错误的容忍度,实际上,消费方可能获取一个超时或者失败的情况,在 hello consumer microservice 中,我们改变代码调用方式:
代码位于microservices/hello-consumer- microservice-timeout 文件夹下,超时的方法在给定时间内没有获取服务的回应就会提出失败,重试的方法将会执行重试,在响应失败或者超时的情况下。subscribeon方法指出哪个线程调用需要做,我们使用event bus loop 调用 callbacks。如果没有这个,方法将会执行默认Rxjava 线程池,打破了 Vert.x 线程模型。Vert.x 提供的 RXHelper 类盲目尝试调用服务并不是一个很聪明的容错策略。它甚至可以是有害的,下一章详细介绍了不同的方法。
现在你可以重新载入这个页面,你总是会获取一个结果,即使是失败或者超时,当调用服务的时候线程没有被阻塞,因此你可以继续接收请求,并且即使响应,所以这里实现的超时重试造成的伤害大于好处,我们将在下一章接续讨论。
Summary
在这个章节中,我们先是用HTTP实现微服务,URL使用硬编码打破了响应式编程的其中一个特性,因此接下来我们使用了消息机制,看到 event bus 怎么帮助我们实现响应式服务。
我们构建了响应式服务,但是这里还有一些短板我们需要关注。如果我们仅仅使用HTTP 服务呢?我们怎么避免硬编码呢?关于快速恢复?我们在这里看到了超时和重试,但是断路器,失效备援,隔离呢?让我们继续之后的学习。
原文地址:
https://developers.redhat.com/promotions/building-reactive-microservices-in-java/
有什么讨论的内容,可以加我微信公众号: