【问题标题】:how do I migrate a Java interface to a microservice?如何将 Java 接口迁移到微服务?
【发布时间】:2016-01-07 03:22:41
【问题描述】:

我正在研究微服务,以及将我们的一些代码迁移到这种架构的可能性。我了解一般概念,但很难了解它如何适用于我们的示例。

假设我有一个名为RatingEngine 的接口和一个名为RatingEngineImpl 的实现,它们都在我的单体应用程序中运行。原理很简单——RatingEngineImpl 可以在不同的机器上运行,并由单体应用程序通过(比如)REST API 访问,通过 http 使用 json 序列化 DTO。我们甚至有一个接口来帮助解耦。

但实际上我该怎么做呢?据我所知,我需要为臀部单体(即现在的客户端)创建一个新的接口实现,它调用接口方法,将它们转换为 REST 调用,并通过网络将它们发送到新的“评级引擎服务”。然后我还需要实现一个新的 http 服务器,每个接口方法都有一个端点,然后它反序列化 DTO(方法参数)并将调用路由到我们原来的 RatingEngineImpl,它位于服务器内部。然后它将响应序列化并将其发送回客户端。

所以这看起来像是大量的管道代码。它还增加了维护开销,因为如果您在界面中调整一个方法,您需要在另外两个地方进行更改。

我错过了什么吗?有什么聪明的方法可以让我们自动构建样板代码吗?

【问题讨论】:

    标签: java rest microservices


    【解决方案1】:

    微服务模式并不建议您将拥有的每一项服务都迁移到它自己的可部署环境中。只移动将受益于它自己的发布周期的自我维持的逻辑。 IE。如果您的 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 服务的调用可能需要几秒钟或几分钟,具体取决于多种因素。只要应用程序是“反应性的”并且可以在没有“评级”的情况下继续工作 - 并在可用时向用户显示评级 - 就可以了。如果您正在等待对评级服务的阻塞调用,则超过几毫秒。 - 响应时间成为障碍。在 Java 中制作反应式应用程序不像在 node.js 中那样方便/常见。被动的方法很可能会触发整个系统的改造。

    • 容错客户端 对单个项目进行单元/集成测试很容易。测试复杂的微服务网络不是。你能做的最好的事情就是让你的客户不那么挑剔。模式验证等实际上是坏事。在 XML 中,使用单个 XPath 从响应中获取所需的数据,不多不少。这样,微服务响应的更改将不需要更新所有客户端。在这方面,JSON 比 XML 更容易处理。

    【讨论】:

    • Tak Petter 了解详细回复。我现有的 java 接口在哪里适合?示例类是否也实现了RatingEngine?还是计算方法只是委托给RatingEngineImpl
    • 嗯.. 好吧,我不会真正尝试适应界面。客户端甚至可能没有 Java 接口的符号,因为微服务架构建议您可以混合和匹配任何语言/平台。 “接口”将是一些 json 或 XML 消息。但当然,您可以直接在服务中实现该接口。我已经更新了这个例子。在许多框架中,有一些简单的方法可以使 java 中的调用“透明”。 IE。客户端在普通接口中调用一个方法并将其代理到一些 HTTP 休息调用。有点过时了,不过看看 vert.x 等吧
    【解决方案2】:

    有一些框架可以减少这样的样板代码。我在当前项目中使用 Spring Boot(尽管不是用于微服务)。如果您已经有基于 Spring 的项目,那么它确实简化了微服务(或任何其他基于 Spring 的非微服务应用程序)的开发。查看一些示例:https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples

    【讨论】:

    • 我们的代码目前没有弹簧。但是如果我理解正确的话,你可以注释接口、实现,或者两者都注释,spring boot 会神奇地监听 http,反序列化 DTO,并将调用路由到实现中的正确方法。你能给我举个例子吗?
    • "[,..] 和 spring boot 会神奇地监听 http,反序列化 DTO,并将调用路由到 [...]" - 我们应该把这在 Java 开发者的圣诞愿望清单上:javalobby.org/java/forums/t84854.html
    【解决方案3】:

    不,很遗憾,您不会错过任何实质性的东西。微服务架构有其自身的成本。引起您注意的一个(样板代码)是列表中的一个众所周知的项目。 This 是 Martin Fowler 的一篇非常好的文章,解释了这个想法的各种优点和缺点。它包括以下主题:

    • 增加了复杂性
    • 增加运营维护成本
    • 努力保持一致性(同时允许以特殊方式处理特殊情况)

    ...还有更多。

    【讨论】:

    • 我听说您可以使用 spring 和/或 RESTeasy 的巧妙功能为您神奇地处理其中的一些...
    • 有许多工具旨在让您的生活更轻松(用于部署、监控、通信等),但它们不会为您做难的部分。为了有效地采用这种技术,主要的先决条件是你的工具有一定的成熟度。从平台虚拟化到 REST 服务体验。如果您正在寻找特定工具,则需要对您的要求进行深入调查。
    猜你喜欢
    • 1970-01-01
    • 2018-01-06
    • 1970-01-01
    • 2017-01-06
    • 2019-11-06
    • 2019-05-21
    • 2021-12-11
    • 2019-04-16
    • 2016-09-09
    相关资源
    最近更新 更多