DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Related

  • Simplify Java Persistence Using Quarkus and Hibernate Reactive
  • Evolution of the Quarkus Developer Experience
  • Building a Simple RAG Application With Java and Quarkus
  • Node.js: Architectural Gems and Best Practices for Developers to Excel

Trending

  • Building Custom Tools With Model Context Protocol
  • The Human Side of Logs: What Unstructured Data Is Trying to Tell You
  • Build Your First AI Model in Python: A Beginner's Guide (1 of 3)
  • Non-Project Backlog Management for Software Engineering Teams
  1. DZone
  2. Coding
  3. Java
  4. Boost throughput with RESTEasy Reactive in Quarkus 2.2

Boost throughput with RESTEasy Reactive in Quarkus 2.2

With the new 2.2 release, Quarkus continues to improve in terms of network-related features, reactive programming, and integration with the Eclipse Vert.x event bus.

By 
Daniel Oh user avatar
Daniel Oh
DZone Core CORE ·
Nov. 09, 21 · Tutorial
Likes (1)
Comment
Save
Tweet
Share
6.0K Views

Join the DZone community and get the full member experience.

Join For Free

Quarkus has, from its beginning, provided core features for coding Java programs in both imperative and reactive styles. With the new 2.2 release, Quarkus continues to improve in terms of network-related features, reactive programming, and integration with the Eclipse Vert.x event bus. For example, RESTEasy Reactive in Quarkus is a new JAX-RS implementation based on the Vert.x layer that achieves much higher throughput by handling reactive events on the non-blocking I/O thread.

The Red Hat build of Quarkus 2.2 provides production support for the RestEasy Reactive extensions, with additional features:

  • Multipart/form-data request handling
  • Executing a non-blocking method by default
  • Determining the dispatch strategy by method signatures
  • Providing a performance score dashboard for reactive endpoints

These new features deliver improved performance improvements when developing reactive applications.

This article demonstrates how you can improve the performance of a Quarkus reactive application by using RESTEasy Reactive features and the Quarkus Dev UI. Download the repository from GitHub to follow along with this tutorial.

Check REST reactive endpoints in the Quarkus Dev UI

First things first: Run Quarkus Dev Mode using the following Maven command in your project directory where you cloned the example:

$ ./mvnw quarkus:dev

Press d after the example application starts and displays the following messages:

--
Tests paused
Press [r] to resume testing, [o] Toggle test output, [h] for more options>

A new web browser will open to access the Quarkus Dev UI, shown in Figure 1. In the RESTEasy Reactive box, click Endpoint scores.

Figure 1. In the Quarkus Dev UI, the RESTEasy Reactive tile offers an "Endpoint scores" link.

You will then be taken to the Quarkus REST scores console, which shows the behavior of four REST reactive endpoints with scores and colors (see Figure 2).

Figure 2. The REST scores console shows the performance of endpoints through scores and colors.

Note that two endpoints have a score of 100 with the color green, but the /hello() endpoint has a score of only 33 in red and the /hello/stream/{count}/{name} endpoint has a score of 66 in yellow. Before we investigate why two endpoints are not performing well, let's do a local test to see whether they work properly.

Execute the following curl commands to invoke the two REST reactive endpoints. For the /hello endpoint, enter:

$ curl localhost:8080/hello
hello 

For the /hello/stream/{count}/{name} endpoint, enter:

$ curl localhost:8080/hello/stream/3/daniel 
data:hello daniel - 0 
data:hello daniel - 1 
data:hello daniel - 2

These commands should be complete without errors. Go back to the scores dashboard in the Quarkus Dev UI and click GET /hello. The detail scores will appear as shown in Figure 3.

Figure 3. The detailed view of an endpoint breaks scores down into Resource, Writer, and Execution.

Three measurements show whether a REST reactive application can be optimized further. For example, the hello endpoint is optimized only for resource measurement. This means the endpoint is accessible and returns a successful output, which you already tested locally. In contrast, the Writer and Execution measurements show failures with 0% scores.

Tune the slow endpoints to optimize performance

Open the ReactiveGreetingResource.java file in the src/main/java/org/acme/getting/started directory and take a look at the hello() method:

@GET
@Produces(MediaType.TEXT_PLAIN)
public Object hello() {
return "hello";
}

The return type of the method is currently defined with a type of Object. It needs to be specified as a String to avoid unnecessary object conversion during reactive application execution. Therefore, update the return type as shown in the following snippet (the change is highlighted in bold):

@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "hello";
}

Save the ReactiveGreetingResource.java file, then reload the scoreboard page in the Dev UI. You should find that the performance has improved because the Writer measurement has been fixed and the score has increased to 66 as shown in Figure 4.

Figure 4. The Writer's score is now 100%.

Non-blocking I/O

Let's fix the remaining performance issue in the hello() method, shown by the Execution measurement. RESTEasy Reactive, in the Red Hat build of Quarkus 2.2, automatically determines whether a particular method runs on a non-blocking I/O thread asynchronously or on a worker thread synchronously, based on the method's signature. The hello() method returns a String signature that dispatches a blocking worker thread. The blocking thread reduces reactive processing performance compared to the non-blocking I/O thread.

Therefore, you need to override the default dispatch strategy to make it use a non-blocking I/O thread, using the @NonBlocking annotation. Go back to the ReactiveGreetingResource.java file and add an @NonBlocking annotation as follows:

@GET
@Produces(MediaType.TEXT_PLAIN)
@NonBlocking
public String hello() {
return "hello";
}

Save the ReactiveGreetingResource.java file, then reload the scoreboard page in the Dev UI. You should now have 100 scores everywhere, thanks to optimizing the hello() method's performance (Figure 5).

Figure 5. All three scores are now 100%.

Now let's fix the other endpoint, /hello/stream/{count}/{name}. Move to the greetingsAsStream() method in the ReactiveGreetingResource.java file:

@GET
@Produces(MediaType.SERVER_SENT_EVENTS)
@RestSseElementType(MediaType.TEXT_PLAIN)
@Path("/stream/{count}/{name}")
@Blocking
public Multi<String> greetingsAsStream(int count, String name) {
return service.greetings(count, name);
}

The method signature is already specified Multi to dispatch a non-blocking I/O thread. However, an unnecessary @Blocking annotation appears in the method, overriding the default dispatch strategy. Therefore, you need to remove that annotation or comment it out. Update the greetingsAsStream method as shown in the following example:

@GET
@Produces(MediaType.SERVER_SENT_EVENTS)
@RestSseElementType(MediaType.TEXT_PLAIN)
@Path("/stream/{count}/{name}")
// @Blocking
public Multi<String> greetingsAsStream(int count, String name) {
return service.greetings(count, name);
}

Save the file and reload the scores page in the Dev UI. You should now have 100% scores everywhere because the greetingsAsStream() method has been optimized, as shown in Figure 6.

Figure 6. The second endpoint now has three 100% scores.

Figure 7 shows that you have optimized the performance of all endpoints.

Figure 7. The REST scores console shows 100% scores for all endpoints.

How to get started with Quarkus

This article has shown how developers optimize reactive applications with Quarkus in the inner-loop development phase. Release 2.2 also provides awesome features to improve developers' productivity, including continuous testing, improvements in the Quarkus command-line interface (CLI) and the Dev UI, and Dev Services.

Subscribe to bit.ly/danielohtv for learning cloud-native application development with Kubernetes.

Quarkus dev application Throughput (business) Boost (C++ libraries)

Opinions expressed by DZone contributors are their own.

Related

  • Simplify Java Persistence Using Quarkus and Hibernate Reactive
  • Evolution of the Quarkus Developer Experience
  • Building a Simple RAG Application With Java and Quarkus
  • Node.js: Architectural Gems and Best Practices for Developers to Excel

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!