react api_使用Java EE 8中的React式API加速服务

react api

服务通常可以通过异步处理进行优化,即使不改变其对外界的行为。

某些服务效率不高的原因是,它们需要等待其他服务提供结果才能继续下去。

让我们看一下如何在不等待外部REST服务的情况下调用它们,并独立进行多个并行调用,然后将其结果与Java EE 8中的响应管道结合起来。

如果我们的服务调用了多个微服务,并等待每个调用完成并返回结果,然后再执行另一个调用,那么使用响应式API进行重构是一个不错的选择。 为了提高服务效率,如果它们彼此不依赖,则可以并行执行对外部服务的所有调用。 这将减少等待所花费的时间,从而加快微服务的速度。

为了并行调用REST服务,我们将在JAX-RS中使用新的React式客户端API。 我们将其与RxJava库结合起来,以在可用时结合其结果。 这种结合将使我们能够编写简洁高效的代码。 另一个好处是,可以释放当前线程以进行进一步处理,同时等待远程调用的结果。

我们将建立一个管道,在结果到达时对其进行处理,最后将其合并为单个响应。 管道的第一部分将调用每个远程服务。 除了等待结果以外,我们将指定处理每个收到的结果并继续调用其他服务。 在JAX-RS客户端请求构建器上使用rx()方法可以使我们调用get()方法的版本,该版本将立即返回而不是等待结果。 为了处理结果到达时的结果,我们可以将方法处理程序链接到从get()方法的rx版本返回的CompletionStage上:

CompletionStage stage = temperatureServiceTarget.request().rx().get(Temperature.class).thenApply(temperature -> new Forecast(temperature));

上面的代码将调用温度服务,然后注册一个lambda表达式,以在到达温度时对其进行处理。 这会将温度映射到预测对象,稍后可以使用stage变量进行访问。

但是,我们希望使用的另一种变体get()方法连同RxJava可流动祈求从泽西岛项目获得Flowable的RxJava而不是CompletionStage 。 与CompletionStage相比, Flowable接口可以更轻松地将多个异步结果与更简单的代码组合在一起,并且效率更高。

使用以下代码,我们将调用外部服务并返回Flowable:

Flowable flowable = temperatureServiceTarget.register(RxFlowableInvokerProvider.class).request().rx(RxFlowableInvoker.class).get(Temperature.class).map(temperature -> new Forecast(temperature);

我们注册了其他RxFlowableInvokerProvider ,它允许以后请求RxFlowableInvoker 。 此调用然后给了我们Flowable从RxJava返回类型。 这些类不在JAX-RS API中,我们必须将它们与Jersey RxJava2库一起添加:

<dependency><groupId>org.glassfish.jersey.ext.rx</groupId><artifactId>jersey-rx-client-rxjava2</artifactId><version>2.26</version>
</dependency>

乍一看,我们似乎在做同一件事的同时使代码变得更加复杂。 但是, Flowable实例使我们能够轻松组合多个调用:

Flowable.concat(flowable1, flowable2).doOnNext(forecast -> {forecasts.add(forecast);}).doOnComplete(() -> {asyncResponse.resume(Response.ok(forecasts).build());}).doOnError(asyncResponse::resume).subscribe();
}

对于从任何流通量收到的每个预测,我们将其添加到预测列表中。 最后,我们发送预测列表作为响应或发送错误响应。 要注册侦听器,必须对subscribe()最后一次调用,否则将忽略它们。

您可能还已经注意到asyncResponse变量用于发送最终响应或发出错误信号。 这是一个JAX-RS异步响应实例,用于在数据可用时在以后的时间完成REST响应,而不会阻塞初始处理线程。 使用异步响应有助于在等待外部REST服务的结果时节省线程资源。 为了在REST端点中打开异步处理,我们将注入javax.ws.rs.container.AsyncResponse作为REST方法参数,以及@Suspended批注。 我们还将返回类型更改为void,因为我们将使用AsyncResponse实例构建响应:

@GET
@Produces(MediaType.APPLICATION_JSON)
public void getForecasts(@Suspended AsyncResponse asyncResponse) {...here come some asynchronous calls to REST services...asyncResponse.resume(...)
}

最终代码示例

以下代码将:

  • 在getForecasts方法中打开REST请求的异步处理
  • 在异步响应上设置5分钟超时
  • 对伦敦和北京执行两次温度服务,而无需等待结果
  • 将结果合并为一系列预测
  • 将序列中的每个预测添加到列表中
  • 处理完所有结果后发送完整列表
  • 发生异常时发送错误结果
  • 使用subscribe方法注册处理程序
private Flowable getTemperature(String location) {return temperatureTarget.register(RxFlowableInvokerProvider.class).resolveTemplate("city", location).request().rx(RxFlowableInvoker.class).get(Temperature.class).map(temperature -> new Forecast(location, temperature));
}@GET
@Produces(MediaType.APPLICATION_JSON)
public void getForecasts(@Suspended AsyncResponse asyncResponse) {List forecasts = new ArrayList<>();asyncResponse.setTimeout(5, TimeUnit.MINUTES);Flowable.concat(getTemperature("London"), getTemperature("Beijing")).doOnNext(forecast -> {forecasts.add(forecast);}).doOnComplete(() -> {asyncResponse.resume(Response.ok(forecasts).build());}).doOnError(asyncResponse::resume).subscribe();
}

翻译自: https://www.javacodegeeks.com/2018/06/speed-services-reactive-api.html

react api

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/333379.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

android申请权限一次性申请多个,android 6.0以上动态一次申请多个权限-最美解决方案...

目录背景危险权限申请权限思路申请权限流程干货后续一.背景android23 API新增危险权限校验&#xff0c;需要手动获取&#xff1a;二.危险权限&#xff1a;日历数据android.permission-group.CALENDARandroid.permission.READ_CALENDARandroid.permission.WRITE_CALENDAR相机and…

IntelliJ IDEA for Mac 直接将模块硬盘上的根目录删除会怎么样

不通过 IDEA 删除模块文件&#xff0c;而是直接手动从硬盘删除模块文件&#xff0c;造成的结果如下图所示&#xff1a; 【模块内容导航窗格】的内容是根据以下两个配置文件的信息从硬盘中加载进来的&#xff1a; 项目根目录/.idea/modules.xml 这个文件记载了配置文件【模块名…

java 谓词_谓词::不适合Java

java 谓词Jim Laskey在OpenJDK core-libs-dev邮件列表上最近的消息“ RFR&#xff1a;CSR – JDK-8203428 Predicate :: not ”指出了JDK Bug JDK-8203428 [“ Predicate :: not”]。 JDK-8203428的“摘要”指出&#xff1a;“引入新的静态方法Predicate :: not&#xff0c;这将…

android root权限函数,android 4.4下app永久获取root权限的方法

本帖最后由 jackson 于 2017-4-16 20:55 编辑通过参照[FAQ11414]android KK 4.4 版本后&#xff0c;user 版本su 权限严重被限制问题说明http://www.voidcn.com/blog/wds1181977/article/p-6157006.html明确要修改三个地方&#xff1a;(1)把dalvik/vm/native/dalvik_system_Zyg…

IntelliJ IDEA 项目开发中各个目录的关系

项目根目录&#xff08;Project Root&#xff09;&#xff1a;本地硬盘中存放项目内容的根目录 项目名称&#xff08;Project Name&#xff09;&#xff1a;IDEA 保存的项目名称&#xff0c;默认和项目根目录的名称相同&#xff0c;可以修改。有啥作用&#xff1f;通过 IDEA 部…

apache spark_Apache Spark中的自定义日志

apache spark您是否曾经对运行了几个小时的Spark作业感到沮丧&#xff0c;但由于基础设施问题而失败了。 您会很晚才知道此故障&#xff0c;并浪费了数小时的时间&#xff0c;当Spark UI日志也无法进行事后检查时&#xff0c;它会更加痛苦。 你不是一个人&#xff01; 在本文…

android中暂停服务,Android 装逼技术之暗码启动应用

前言喜欢的小伙伴欢迎关注&#xff0c;我会定期分享Android知识点及解析&#xff0c;还会不断更新的BATJ面试专题&#xff0c;欢迎大家前来探讨交流&#xff0c;如有好的文章也欢迎投稿。什么是暗码&#xff1f;在拨号盘中输入*#*##*#*后&#xff0c;APP 可以监控到这些输入&am…

JShell 详解

文章目录一、简介二、为什么使用 JShell三、参考示例启动 JShell退出 JShell声明定义基本类型的变量声明定义一个方法覆盖已存在的变量、方法、类的定义查看 JShell 默认导入的包自动补全功能列出所有键入的源列出已声明方法及其签名加载外部的源代码查看 JShell 提供的所有指令…

graphql_GraphQL在Wildfly群上

graphql“ GraphQL是API的查询语言&#xff0c;是用于使用现有数据完成这些查询的运行时。 GraphQL为您的API中的数据提供了完整且易于理解的描述&#xff0c;使客户能够准确地询问他们所需的内容&#xff0c;仅此而已&#xff0c;使随着时间的推移更容易开发API并启用强大的开…

android中有哪些utils的作用,AndroidUtils

多年开发Android积攒下来好多常用的工具方法&#xff0c;保存在随笔中&#xff0c;持续更新。TimeUtil/*** 获取距当前时刻的时间戳** param createTime* return*/public static String getTimestamp(long createTime) {long currrentMillis System.currentTimeMillis();// if…

Java中的关键字this_super

文章目录要点错误的理解正确的理解演示代码要点 1.在类的构造器中&#xff0c;可以使用 this() 调用本类的其它构造器&#xff0c;调用的时候根据构造器声明的参数列表传递参数值 2.super() 调用父类的无参构造器 3.super.method() 调用父类的 method() 方法 4.super.name …

Spring Hibernate教程

1.简介 在本文中&#xff0c;我们将演示如何利用最流行的ORM&#xff08;对象关系映射&#xff09;工具之一的Hibernate的功能 &#xff0c;该工具可将面向对象的域模型转换为传统的关系数据库。 Hibernate是目前最流行的Java框架之一。 由于这个原因&#xff0c;我们在Java Co…

百度地图瓦片 android,百度地图自定义瓦片图获取

nodejs代码const request require(request);const fs require(fs);const bagpipe require(bagpipe);const TileLnglatTransform require(tile-lnglat-transform);let [x1, y1] [72.26, 54.57]; // 起始点坐标(左上角)let [x2, y2] [137.31, 17.8]; // 终点坐标(右下角)le…

IntelliJ IDEA for Mac 如何自定义快捷键_设置快捷键

文章目录设置代码补全快捷键设置展开全部的快捷键折叠全部快捷键设置代码补全快捷键 代码自动补全&#xff0c;即智能提示。 打开【系统偏好设置】如下图所示&#xff1a; 在左侧的菜单栏中找到 Keymap → Main Menu → Code → Code Completion → Basic&#xff1a; 设…

android8 老手机,华为多款老旧手机获升安卓8.0,流畅度飙升!

原标题&#xff1a;华为多款老旧手机获升安卓8.0&#xff0c;流畅度飙升&#xff01;一直以来&#xff0c;在手机用户圈都有这么一个共识&#xff0c;那就是安卓手机不如iPhone流畅&#xff0c;之前安卓手机给人的印象就是容易卡顿&#xff0c;而谷歌则一直在为此事苦恼&#x…

java12关键字var_Java 10:“ var”关键字

java12关键字varJava 10使用关键字var引入了局部变量类型推断 。 这意味着无需编写&#xff1a; Map<Department, List<Employee>> map new HashMap<>(); // ... for (Entry<Department, List<Employee>> dept : map.entrySet()) {List<Emp…

IntelliJ IDEA for Mac自定义动态代码模板快捷键(Live Templates Shortcut)

文章目录查看更多的快捷键常用的代码模板自定义代码模板快捷键格式化等号文档注释代码模板快捷键应用示例声明定义引用类型变量数组的 for 循环指定循环次数的 for 循环增强 for 循环倒序 for 循环自动生成普通 for 循环语句自动生成main 方法自动生成输出语句自动生成增强for循…

android udp 设备发现,两台Android设备之间进行UDP连接(使用多播地址)~~求大神指点...

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼首先 发送端&#xff1a;package com.example.multicastclient;import android.support.v7.app.ActionBarActivity;import java.io.IOException;import java.net.DatagramPacket;import java.net.InetAddress;import java.net.Mult…

java serial_Java的@Serial批注

java serialJDK可能正在使用JDK 11 &#xff1a; Serial获得另一个标准&#xff08;预定义&#xff09;注释 。 JDK-8202385 [“标记与序列相关的字段和方法的注释”]的目的是添加“某种“ SerialRelated”注释&#xff0c;以促进对序列字段和方法的声明的自动检查。” 这种想法…

IntelliJ IDEA 选中变量名,高亮显示其它地方的这个变量名,高亮颜色如何设置呢?

选中了一个变量名&#xff0c;会高亮显示位于别的地方的这个变量名&#xff0c;那么怎么修改其他地方的高亮颜色&#xff1f; 按下 Command , 打开偏好设置窗口&#xff0c;接着看下图&#xff1a;