360SDN.COM

响应式Spring 5对应用设计的影响

来源:原力注入  2017-09-11 13:16:37    评论:0点击:

↑ 点击上方“原力注入”关注我们哦

响应式编程最近有点火,就连马上要推出的Spring 5 也集合了很多相应式的特性,今天我们来谈谈响应式 Spring 5 对应用设计会产生哪些影响。

原文地址:https://dzone.com/articles/reactive-spring-5-and-application-design-impact

Spring 5即将推出,其中包含了很多响应式的属性。前方高能 - 它不仅仅只是一组新的注解,而是用颠覆性的方式来编写应用。

Spring框架的第5版支持响应式编程,同时响应式编程也带来了一些新的挑战。 本文分享一下响应式设计的新规则是什么,以及它如何影响到基于Spring的应用程序开发。 这篇文章假设读者已经有了Spring 5和Reactor Project中新功能的知识。

函数编程

Spring 5的响应式编程带来一个不可避免的趋势 - 向函数式编程发展。当使用诸如Spring的WebClient或Spring Data的响应式仓库之类的非阻塞实现时,我们必须处理响应式数据类型:Mono和Flux。为了保持非阻塞,查询的结果只能通过功能转换进行访问。

这是我们使用阻止依赖关系编写命令式执行代码:

public Person addPerson(Person person) {
    IpAddressDetails ipDetails = ipService.getDetails(person.getIpAddress());
    person.setIpAddressDetails(ipDetails);
    return repository.save(person); 
}

而这是我们使用基于Reactor的实现:

private Mono<Person> addPerson(Mono<Person> mono) {
    return mono
        .flatMap(this::addIpAddressDetails)
        .flatMap(repository::save); 
}

现在,你没有选择 - iterate或flatMap。 平面映射是唯一的选择。 切换到命令式编程的唯一方法是使用block()方法。 但是阻塞正是我们想要避免的。 所以我们的代码变得更加函数式。 我们不必使用纯函数式编程,而函数编程的知识可以帮助您。 许多函数编程模式,如Free Monads或Monad Transformers,可以使响应式代码更好。

(不)可变性

局部变量由lambda表达式捕获,可能被不同的线程异步访问。 如果我们的对象是可变的,那么存在并发问题的危险,比如竞争条件。 解决方案可能是使所有的对象不可变。 听起来比实际上容易 在理论上,我们只是使对象属性最终化,并使嵌套对象也不可变:

public class Person { 
    private final String id; 
    private final String firstname; 
    private final String lastname;
    private final IpAddress ipAddress; // immutable inside
    public Person(String id, String firstname, String lastname, IpAddress ipAddress) {
        this.id = id;
        this.firstname = firstname;
        this.lastname = lastname;
        this.ipAddress = ipipAddress
    }
    // getters
}

但是在实践过程中,可能存在如下异常:

  • 响应式库的问题。 “找不到实体的默认构造函数”是我们从不同的序列化器(如Hibernate)看到的消息,如果我们不提供可变字段和默认构造函数。

  • 没有可互操作的不可变的集合接口。 vavr或Guava中有不可变的集合。路线图中有JDK9,带来更方便的不可变的集合创建。 但是我们依赖的大多数第三方代码都使用可变集合。

  • 只有一个构造函数是不够的。直接使用“所有args”构造函数,我们的代码将很快变得丑陋。 另一套模式来到这里拯救:建造者和镜头。 我们应该知道并使用它们。

  • 不用说,其他JVM语言,如Scala,Clojure或Kotlin,具有不可变的语言本土公民。

Spring 5带来了专门的Kotlin支持。 Kotlin绝对是考虑实施响应式Spring 5应用程序的好选择,它可以简化不可变对象的使用。 另一个选择可能只是适当地封装可变性。

反向压力

Spring 5框架的一些响应式特征也可用于非响应式应用程序。这样的一个特征是反向压力。不要以控制的方式丢弃消息和传达需求,响应式流引入了基于拉取方式的反向压力。

我们可以添加反向压力和并行性,甚至可以加入到非响应式阻塞应用程序,例如处理大数据集。 以下是我们如何可以实现并行处理和批量处理,同时正确地将需求与背压进行沟通:

public void refreshIpAddressDetails() {
    LocalDateTime dateTime = LocalDateTime.now().minusDays(90);
    repository.findByUpdatedAtLessThan(dateTime)
        .buffer(300)
        .parallel(2)
        .flatMap(this::updateIpAddressDetails)
        .subscribe(System.out::println, System.err::println);
}

当然,反向压力不会取代批量框架的功能,但在某些情况下,它可能是我们需要的唯一额外的工具。


阻塞式库

即使在异步环境中,有时使用阻塞实现是不可避免的,因为没有非阻塞替代方法可用。 一个典型的例子是JDBC。 它被设计为阻塞并消耗每个数据库调用的线程。 所以问题是我们如何在一个基于Spring的应用程序中使用阻塞库。

我们可以将隔离调度分派到隔离的调度程序中,以避免混合阻塞和非阻塞调用。 这将允许我们控制总线程数,并让CPU在主执行上下文中提供非阻塞任务,并应用各种优化。 反应器文档建议对这种类型的作业使用elastic()调度器。

弹性模式

响应式系统必须具有弹性。 响应式宣言本身并没有说明如何实现弹性。 许多其他来源。 弹性模式的一个很好的来源是Michael Nygard的“Release It!”一书,可以添加到响应式系统的一些有用的模式是Bulkheads和Circuit Breaker。

系统不会整体失败。 我们可以隔离系统的不同部分来隔离故障。 在这种情况下,隔板是故障单元。 Bulkheading可以在许多层面上发生:我们可以隔离网络,机器,应用程序或线程。

断路器的主要目标是快速提供故障响应。 而不是等待超时,您可以立即发出错误信号。

当涉及弹性模式实现时,有几个库存在。 除了知名的Netflix的Hystrix,还有resilience4j,对响应式和函数式编程非常友好。

验证响应式

测试是我们可以阻塞的唯一的地方。 当我们同时进行许多测试或尝试验证响应式时,阻塞的缺点将会来临。 Reactor工具,如StepVerifier,可以在这里帮助。

在代码级测试之后,非常希望验证部署中的响应式。 特殊工具,如Netflix的Chaos Monkey,简化了这个任务。 如果您不使用Chaos Monkey,您可以使用自己的脚本设备来重现各种故障情况,但在不考虑如何在类似生产环境中的实际故障情况下测试它是如何工作的,实施灵活性并不重要。

负载测试是另一个重要的方面。 实际上,响应式系统的目标解决了负载带来的挑战,因此负载测试应该是响应式测试的一个重要方面。 幸运的是,存在许多负载测试工具:JMeter,Tsung,LoadComplete等。

总体设计影响

为了实现响应式,应用程序必须具有responsive, resilient, elastic, 和message-driven。这个列表中的最后一个标准导致了异步的通信方式。这包括异步请求/回复和消息传递库,数据库驱动程序等。 为了完全不阻塞,我们必须将整个执行周期作为围绕并行结构的一组功能组合。 将一个现存的阻塞应用程序更改为非阻塞的,可能会导致重新设计。

WebFlux or MVC

Spring 5本身带来了WebFlux的响应式编程支持,但不会删除Spring MVC。 同时,WebFlux不可避免的并发功能编程可能会产生一个精神上的开销,并不是为了使代码更易于阅读。 我们需要保持务实,并根据软件需求选择一种抽象。 响应式系统解决了现代应用的挑战,与大量用户相关的挑战和高吞吐量。 非阻塞库不适用于每种技术。 Reactor目前支持的集成(如MongoDB,Cassandra或Kafka)依赖于非阻塞驱动程序,并且还解决了高吞吐量的挑战。 不是每个应用程序都具有足够高的吞吐量,从而从非阻塞设计得益。 强制阻塞式Spring MVC应用程序仍然可以快速,灵活和响应。

互联网技术社群,期待您的加入

长按二维码
加入我们

关注公众号获取更多资源!

阅读原文

为您推荐

友情链接 |九搜汽车网 |手机ok生活信息网|ok生活信息网|ok微生活
 Powered by www.360SDN.COM   京ICP备11022651号-4 © 2012-2016 版权