Many microservice-based applications have been developed using the popular RESTful
approach for communication between there microservices,often referred to as imperative
microservices. However, with the rise in popularity of reactive programming , many
developers are transforming their applications, moving away from the imperative logic
previously used to an asynchronous , non-blocking, functional style.
许多基于微服务的应用程序都是使用流行的RESTful方法开发的,用于在这些微服务(通常称为命令式微服务)之间进行通信。然而,随着响应式编程的流行,许多开发人员正在对他们的应用程序进行转换,从以前使用的命令式逻辑转向异步、非阻塞、函数式风格。
But it can be hard to know where to start to achieve this transformation and to enable
greater responsiveness and reactivity from your applications . This article will take you
through the journey from imperative to reactive and explain when you need to consider
writing reactive microservices.
但是,很难知道从哪里开始实现这种转换,并使应用程序具有更强的响应性和反应性。本文将带您经历从命令式到响应式的过程,并解释何时需要考虑编写响应式微服务。
Why reactive?
To explore reactive's growing popularity among developers and why so many applications
are making the move to reactive, let's take a look at a simple demo application.
为了探究reactive在开发人员中越来越受欢迎,以及为什么这么多应用程序都转向reactive,让我们看一个简单的演示应用程序。
This demo application consists of two microservices: service-a and service-b. Initially,
they are wired together through RESTful calls, enabling one service-a endpoint to be
exposed to the application's clients , as depicted in the following figure.
这个演示应用程序由两个微服务组成:service-a和service-b。最初,它们通过RESTful调用连接在一起,从而允许将一个服务——一个端点公开给应用程序的客户机,如下图所示。
So far, so good! However, one day service-b stops responding, blocking service-a. This
leaves your application blocked and unresponsive. To counteract this, the invocation of the
calls between service-a and service-b could be changed from synchronous to
asynchronous, allowing service-a to perform other tasks while waiting for service-b to
come back online.
到目前为止,一切顺利!但是,有一天service-b停止响应,阻塞service-a。这将导致应用程序被阻塞,无法响应。为了解决这个问题,可以将服务-a和服务-b之间调用的调用从同步更改为异步,从而允许服务-a在等待服务-b恢复联机状态的同时执行其他任务。
From Synchronous to Asynchronous calls
Changing from synchronous to asynchronous calls is fairly
straightforward. You can use CompletionStages in Java 8.
However, once you've entered an asynchronous world,
new headaches emerge. For example, Jave EE context now
needs to be managed. Any new threads in a thread pool
won't inherit any contexts from its parent . This is an issue
because a security context, JNDI (Java Naming and Directory Interface), and CDI
(Contexts and Dependency Injection) often need to be associated with any new threads
assigned(分配) to your method calls. So, how can this be achieved? Fortunately,Eclipse
MicroProfile has an answer to this too: MicroProfile Context Propagation(传播).
从同步调用切换到异步调用相当简单。您可以在Java 8中使用completionstage。然而,一旦你进入了一个异步的世界,新的问题就出现了。例如,现在需要管理Java EE上下文。线程池中的任何新线程都不会从其父线程继承任何上下文。这是一个问题,因为安全上下文、JNDI (Java命名和目录接口)和CDI(上下文和依赖注入)通常需要与分配给方法调用的任何新线程相关联。那么,如何才能实现这一点呢?幸运的是,Eclipse MicroProfile也有一个答案:MicroProfile上下文传播。
MicroProfile Context Propagation
MicroProfile Context Propagation introduces the ManagedExecutor and ThreadContext APIs to
manage the contexts of the threads, dispatched by the
thread pool, managed by your application runtime. Managed
executors in MicroProfile Context Propagation allow you to
use completion stages that run with predictable thread
contexts regardless of which therad the action ends up
running on. With MicroProfile Context Propagation,the
thread context is completely deterministic because context
is always captured from the thread that creates the completion state and applied when
running the action. The following code listing shows example of using MicroProfile Context
Propagation to propagate Security and Application Context.
微概要上下文传播引入了ManagedExecutor和ThreadContext api来管理线程的上下文,这些线程由线程池分派,由应用程序运行时管理。微概要上下文传播中的托管执行器允许您使用与可预测的线程上下文一起运行的完成阶段,而不管操作最终在哪个线程上运行。使用微概要上下文传播,线程上下文是完全确定的,因为上下文总是从创建完成阶段的线程捕获,并在运行操作时应用。下面的代码清单显示了使用微配置文件上下文传播来传播安全性和应用程序上下文的示例。