我正在研究微服务,以及将我们的一些代码迁移到此架构的可能性。我理解一般概念,但我很难看到它如何适用于我们的例子。
假设我有一个名为RatingEngine
的接口和一个名为RatingEngineImpl
的实现,它们都在我的单片应用程序中运行。原理很简单 - RatingEngineImpl
可以在不同的机器上运行,并通过(例如)REST API由单片应用程序访问,使用json通过http序列化DTO。我们甚至有一个界面来帮助解决这个问题。
但我该怎么做呢?据我所知,我需要为rump monolith(即现在的客户端)创建一个新的接口实现,它接受对接口方法的调用,将它们转换为REST调用,并通过网络将它们发送到新的“评级引擎服务”。然后我还需要实现一个新的http服务器,每个接口方法都有一个端点,然后反序列化DTO(方法参数)并将调用路由到位于服务器内部的原始RatingEngineImpl
。然后它将响应序列化并将其发送回客户端。
所以这看起来像是一大堆管道代码。它还增加了维护开销,因为如果你在界面中调整一个方法,你需要在另外两个地方进行更改。
我错过了什么吗?有没有一些聪明的方法可以自动化这个样板代码构建?
答案 0 :(得分:2)
微服务模式并不建议您将所拥有的每项服务移动到其自身的可部署性。只有移动自我维持的逻辑部分才能从它自己的发布周期中受益。即如果您的RatingEngine每周都需要更新逻辑更新,但系统的其余部分相当稳定 - 它可能会受益于它自己的服务。
是的 - 微服务增加了复杂性,但不是真正的HTTP服务器的锅炉板代码。有很多框架可以解决这个问题。 Vert.x是一件好事。其他的是Spring Boot,Apache Camel等。完整的微服务设置可能与Vert.x一样。
public class RatingService extends AbstractVerticle implements RatingEngine{
public void start() {
vertx.createHttpServer().requestHandler(req -> {
req.response()
.putHeader("content-type", "application/json")
.end(computeCurrentRating().encodePrettily());
}).listen(8080);
}
@Override
public int getRating(){
return 4; // or whatever.
}
protected JsonObject computeCurrentRating(){
return new JsonObject().put("rating", getRating());
}
}
即使是Java内置框架JAX-RS也有助于在不太多代码行中创建微服务。
微服务真正的努力是在客户端添加错误处理逻辑。一些常见的陷阱
微服务可能会停止如果调用RatingService会导致连接拒绝异常 - 您能处理它吗?你能评估一下"等级"在客户端,以防止进一步处理?您可以重复使用旧的回复来估算评级吗? ..或者至少 - 你需要发出错误信号以支持员工。
反应式应用?您还能等待多长时间?对内存方法的调用将在纳秒内返回,对外部HTTP服务的调用可能需要几秒或几分钟,具体取决于许多因素。只要应用程序是"反应性"并且可以在没有"评级的情况下继续工作。 - 并在用户可用时显示评级 - 这很好。如果您正在等待阻止呼叫评级服务,超过几毫秒。 - 响应时间成为障碍。在node.js中创建Java中的响应式应用程序并不方便/通用。反应式方法可能会触发整个系统的重制。
容忍客户单个项目的单元/集成测试很容易。测试复杂的微服务网络不是。你可以做的最好的事情是让你的客户电话不那么挑剔。模式验证等实际上是坏事。在XML中,使用单个XPath从响应中获取所需的数据,而不是更少。这样,微服务响应的改变不需要更新所有客户端。在这方面,JSON比XML更容易处理。
答案 1 :(得分:1)
不,不幸的是你不会遗漏任何重大内容。微服务架构有自己的成本。引起你注意的那个(样板代码)是列表中的一个众所周知的项目。 This是Martin Fowler的一篇非常好的文章,解释了这个想法的各种优缺点。它包括以下主题:
......还有更多。
答案 2 :(得分:0)
有一些框架可以减少这样的样板代码。我在当前项目中使用Spring Boot(虽然不适用于微服务)。如果您已经拥有基于Spring的项目,那么它确实简化了微服务(或任何其他基于Spring的微服务应用程序)的开发。查看一些示例:http://jsfiddle.net/nt87koye/4/