Skip to content

Commit

Permalink
New round of Spring optimizations (#9288)
Browse files Browse the repository at this point in the history
* New round of spring optimizations

- Upgrade to Spring Boot 3.3.4
- Remove the JPA variant that is not competitive and
  introduces additional processing not needed in
  other variants
- Use batched update in the JDBC variant (compliant with
  the test requirements)
- Set Hikari maximum pool size to 256
- Switch to jstachio for view rendering

* New round of spring-webflux optimizations

- Upgrade to Spring Boot 3.3.4
- Disable Netty leak detection
- Turn a flapMap operation to a map
- Switch to jstachio for view rendering
- Remove unused JdbcDbRepository class
- Set R2DBC maximum pool size to 256
- Polishing
  • Loading branch information
sdeleuze authored Oct 1, 2024
1 parent 5b93494 commit b03e526
Show file tree
Hide file tree
Showing 35 changed files with 210 additions and 422 deletions.
28 changes: 22 additions & 6 deletions frameworks/Java/spring-webflux/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,12 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.3</version>
<version>3.3.4</version>
</parent>

<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>21</java.version>
<jstachio.version>1.3.6</jstachio.version>
</properties>

<dependencies>
Expand All @@ -36,8 +35,16 @@
<artifactId>r2dbc-postgresql</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mustache</artifactId>
<groupId>io.jstach</groupId>
<artifactId>jstachio</artifactId>
<version>${jstachio.version}</version>
</dependency>
<dependency>
<groupId>io.jstach</groupId>
<artifactId>jstachio-apt</artifactId>
<version>${jstachio.version}</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
Expand All @@ -55,6 +62,15 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>io.jstach</groupId>
<artifactId>jstachio-apt</artifactId>
<version>${jstachio.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ RUN java -Djarmode=tools -jar app.jar extract

EXPOSE 8080

CMD ["java", "-Dlogging.level.root=OFF", "-Dreactor.netty.http.server.lastFlushWhenNoRead=true", "-jar", "app/app.jar", "--spring.profiles.active=mongo"]
CMD ["java", "-Dlogging.level.root=OFF", "-Dio.netty.leakDetection.level=disabled", "-Dreactor.netty.http.server.lastFlushWhenNoRead=true", "-jar", "app/app.jar", "--spring.profiles.active=mongo"]
2 changes: 1 addition & 1 deletion frameworks/Java/spring-webflux/spring-webflux.dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ RUN java -Djarmode=tools -jar app.jar extract

EXPOSE 8080

CMD ["java", "-Dlogging.level.root=OFF", "-Dreactor.netty.http.server.lastFlushWhenNoRead=true", "-jar", "app/app.jar", "--spring.profiles.active=r2dbc"]
CMD ["java", "-Dlogging.level.root=OFF", "-Dio.netty.leakDetection.level=disabled", "-Dreactor.netty.http.server.lastFlushWhenNoRead=true", "-jar", "app/app.jar", "--spring.profiles.active=r2dbc"]
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;
import org.springframework.web.reactive.result.view.ViewResolver;
import org.springframework.web.server.WebHandler;
import org.springframework.web.server.adapter.WebHttpHandlerBuilder;

Expand All @@ -20,8 +19,8 @@
public class App {

@Bean
public HttpHandler httpHandler(RouterFunction<ServerResponse> route, ServerFilter serverFilter, ViewResolver viewResolver) {
WebHandler webHandler = RouterFunctions.toWebHandler(route, HandlerStrategies.builder().viewResolver(viewResolver).build());
public HttpHandler httpHandler(RouterFunction<ServerResponse> route, ServerFilter serverFilter) {
WebHandler webHandler = RouterFunctions.toWebHandler(route, HandlerStrategies.builder().build());
return WebHttpHandlerBuilder.webHandler(webHandler).filter(serverFilter).build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,20 @@
import org.springframework.data.mongodb.core.mapping.Document;

@Document
public final class Fortune {
public final class Fortune implements Comparable<Fortune> {

@Id
public int id;

public String message;

public Fortune(int id, String message) {
this.id = id;
this.message = message;
}

public int getId() {
return id;
}

public String getMessage() {
return message;
@Override
public int compareTo(final Fortune other) {
return message.compareTo(other.message);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ public final class World {

@Id
public int id;

@Field("randomNumber")
public int randomnumber;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import reactor.core.publisher.Mono;

public interface DbRepository {

Mono<World> getWorld(int id);

Mono<World> findAndUpdateWorld(int id, int randomNumber);
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
package benchmark.web;

import java.util.Collections;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

import benchmark.model.Fortune;
import benchmark.model.World;
import benchmark.repository.DbRepository;
import io.jstach.jstachio.JStachio;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;

import static java.util.Comparator.comparing;

@Component
public class DbHandler {

private static final String CONTENT_TYPE_VALUE = "text/html; charset=utf-8";

private final DbRepository dbRepository;

public DbHandler(DbRepository dbRepository) {
Expand All @@ -33,7 +34,7 @@ public Mono<ServerResponse> db(ServerRequest request) {
.switchIfEmpty(Mono.error(new Exception("No World found with Id: " + id)));

return ServerResponse.ok()
.contentType(MediaType.APPLICATION_JSON)
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.body(world, World.class);
}

Expand All @@ -45,7 +46,7 @@ public Mono<ServerResponse> queries(ServerRequest request) {
.collectList();

return ServerResponse.ok()
.contentType(MediaType.APPLICATION_JSON)
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.body(worlds, new ParameterizedTypeReference<List<World>>() {
});
}
Expand All @@ -71,20 +72,19 @@ public Mono<ServerResponse> updates(ServerRequest request) {
.collectList();

return ServerResponse.ok()
.contentType(MediaType.APPLICATION_JSON)
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.body(worlds, new ParameterizedTypeReference<List<World>>() {
});
}

public Mono<ServerResponse> fortunes(ServerRequest request) {
Mono<List<Fortune>> result = dbRepository.fortunes().collectList().flatMap(fortunes -> {
fortunes.add(new Fortune(0, "Additional fortune added at request time."));
fortunes.sort(comparing(fortune -> fortune.message));
return Mono.just(fortunes);
});

return ServerResponse.ok()
.render("fortunes", Collections.singletonMap("fortunes", result));
return dbRepository.fortunes()
.concatWith(Mono.just(new Fortune(0, "Additional fortune added at request time.")))
.collectSortedList()
.flatMap(fortunes ->
ServerResponse.ok()
.header(HttpHeaders.CONTENT_TYPE, CONTENT_TYPE_VALUE)
.bodyValue(JStachio.render(new Fortunes(fortunes))));
}

private static int randomWorldNumber() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package benchmark.web;

import java.util.List;

import benchmark.model.Fortune;
import io.jstach.jstache.JStache;

@JStache(path = "fortunes.mustache")
public record Fortunes(List<Fortune> fortunes) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ spring:
r2dbc:
username: ${database.username}
password: ${database.password}
url: r2dbc:postgresql://${database.host}:${database.port}/${database.name}
url: r2dbc:postgresql://${database.host}:${database.port}/${database.name}?loggerLevel=OFF&disableColumnSanitiser=true&assumeMinServerVersion=16&sslmode=disable
pool:
max-size: 256

---
spring:
Expand Down
4 changes: 1 addition & 3 deletions frameworks/Java/spring/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@

This is the Spring MVC portion of a [benchmarking test suite](../) comparing a variety of web development platforms.

An embedded undertow is used for the web server, with nearly everything configured with default settings.
The only thing changed is Hikari can use up to (2 * cores count) connections (the default is 10).
See [About-Pool-Sizing](https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing)
An embedded undertow is used for the web server.

There are two implementations :
* For postgresql access, JdbcTemplate is used. See [JdbcDbRepository](src/main/java/hello/JdbcDbRepository.java).
Expand Down
21 changes: 0 additions & 21 deletions frameworks/Java/spring/benchmark_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,27 +24,6 @@
"notes": "",
"versus": ""
},
"jpa": {
"db_url": "/db",
"query_url": "/queries?queries=",
"fortune_url": "/fortunes",
"update_url": "/updates?queries=",
"port": 8080,
"approach": "Realistic",
"classification": "Fullstack",
"database": "Postgres",
"framework": "spring",
"language": "Java",
"flavor": "None",
"orm": "Full",
"platform": "Servlet",
"webserver": "Undertow",
"os": "Linux",
"database_os": "Linux",
"display_name": "spring-jpa",
"notes": "",
"versus": "spring"
},
"mongo": {
"db_url": "/db",
"query_url": "/queries?queries=",
Expand Down
Loading

0 comments on commit b03e526

Please sign in to comment.