Skip to content

Commit

Permalink
Merge pull request #6670 from pcasaes/master
Browse files Browse the repository at this point in the history
Add configuration for vert.x with native transport #6669
  • Loading branch information
cescoffier authored Feb 27, 2020
2 parents 58268ae + bdb1e7c commit d07fd1e
Show file tree
Hide file tree
Showing 7 changed files with 333 additions and 64 deletions.
101 changes: 101 additions & 0 deletions docs/src/main/asciidoc/vertx.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,80 @@ Otherwise, you can manually add this to the dependencies section of your `pom.xm
</dependency>
----

== Native Transport

Vert.x is capable of using https://netty.io/wiki/native-transports.html[Netty's native transports] which offers
performance improvements on certain platforms. To enable them you must include the appropriate dependency for your
platform. It's usually a good idea to include both to keep your application platform agnostic. Netty is smart enough
to use the correct one, that includes none at all on unsupported platforms:

[source,xml]
----
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-transport-native-epoll</artifactId>
<classifier>linux-x86_64</classifier>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-transport-native-kqueue</artifactId>
<classifier>osx-x86_64</classifier>
</dependency>
----

You will also have to explicitly configure Vert.x to use the native transport. In `application.properties` add:

[source]
----
quarkus.vertx.prefer-native-transport=true
----

Or in `application.yml`:

[source,yml]
----
quarkus:
vertx:
prefer-native-transport: true
----

If all is well quarkus will log:

----
[io.qua.ver.cor.run.VertxCoreRecorder] (main) Vertx has Native Transport Enabled: true
----

=== Native Linux Transport

On Linux you can enable the following socket options:

* SO_REUSEPORT
----
quarkus.http.so-reuse-port=true
----
* TCP_QUICKACK
----
quarkus.http.tcp-quick-ack=true
----
* TCP_CORK
----
quarkus.http.tcp-cork=true
----
* TCP_FASTOPEN
----
quarkus.http.tcp-fast-open=true
----

=== Native MacOS Transport

On MacOS Sierra and above you can enable the following socket options:

* SO_REUSEPORT
----
quarkus.http.so-reuse-port=true
----

== Accessing Vert.x

Once the extension has been added, you can access the _managed_ Vert.x instance using `@Inject`:
Expand Down Expand Up @@ -584,6 +658,33 @@ public void init(@Observes StartupEvent e, Vertx vertx, Instance<AbstractVerticl
}
----

== Listening to a Unix Domain Socket

Listening on a unix domain socket allows us to dispense with the overhead of TCP
if the connection to the quarkus service is established from the same host. This can happen
if access to the service goes through a proxy which is often the case
if you're setting up a service mesh with a proxy like Envoy.

IMPORTANT: This will only work on platforms that support <<native-transport>>.

To setup please enable the appropriate <<native-transport>> and set the following
environment property:

----
quarkus.http.domain-socket=/var/run/io.quarkus.app.socket
quarkus.http.domain-socket-enabled=true
----

By itself this will not disable the tcp socket which by default will open on
`0.0.0.0:8080`. It can be explicitly disabled:

----
quarkus.http.host-enabled=false
----

These properties can be set through Java's `-D` command line parameter or
on `application.properties`.

== Read only deployment environments

In environments with read only file systems you may receive errors of the form:
Expand Down
13 changes: 13 additions & 0 deletions extensions/netty/runtime/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,19 @@
<groupId>org.graalvm.nativeimage</groupId>
<artifactId>svm</artifactId>
</dependency>

<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-transport-native-epoll</artifactId>
<classifier>linux-x86_64</classifier>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-transport-native-kqueue</artifactId>
<classifier>osx-x86_64</classifier>
<optional>true</optional>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -43,6 +44,8 @@
@Recorder
public class VertxCoreRecorder {

private static final Logger LOGGER = Logger.getLogger(VertxCoreRecorder.class.getName());

private static final Pattern COMMA_PATTERN = Pattern.compile(",");

static volatile VertxSupplier vertx;
Expand Down Expand Up @@ -100,20 +103,21 @@ public void run() {
public static void initializeWeb(VertxConfiguration conf) {
if (webVertx != null) {
} else if (conf == null) {
webVertx = Vertx.vertx();
webVertx = logVertxInitialization(Vertx.vertx());
} else {
VertxOptions options = convertToVertxOptions(conf, false);
webVertx = Vertx.vertx(options);
webVertx = logVertxInitialization(Vertx.vertx(options));
}
}

public static Vertx initialize(VertxConfiguration conf) {
if (conf == null) {
return Vertx.vertx();
return logVertxInitialization(Vertx.vertx());
}

VertxOptions options = convertToVertxOptions(conf, true);

Vertx vertx;
if (options.getEventBusOptions().isClustered()) {
CompletableFuture<Vertx> latch = new CompletableFuture<>();
Vertx.clusteredVertx(options, ar -> {
Expand All @@ -123,10 +127,16 @@ public static Vertx initialize(VertxConfiguration conf) {
latch.complete(ar.result());
}
});
return latch.join();
vertx = latch.join();
} else {
return Vertx.vertx(options);
vertx = Vertx.vertx(options);
}
return logVertxInitialization(vertx);
}

private static Vertx logVertxInitialization(Vertx vertx) {
LOGGER.info(() -> String.format("Vertx has Native Transport Enabled: %s", vertx.isNativeTransportEnabled()));
return vertx;
}

private static VertxOptions convertToVertxOptions(VertxConfiguration conf, boolean allowClustering) {
Expand Down Expand Up @@ -173,6 +183,8 @@ private static VertxOptions convertToVertxOptions(VertxConfiguration conf, boole

options.setWarningExceptionTime(conf.warningExceptionTime.toNanos());

options.setPreferNativeTransport(conf.preferNativeTransport);

return options;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,10 @@ public class VertxConfiguration {
@ConfigItem
public ClusterConfiguration cluster;

/**
* Enable or disable native transport
*/
@ConfigItem
public boolean preferNativeTransport;

}
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ private VertxConfiguration createDefaultConfiguration() {
vc.maxWorkerExecuteTime = Optional.of(Duration.ofSeconds(1));
vc.internalBlockingPoolSize = 20;
vc.useAsyncDNS = false;
vc.preferNativeTransport = false;
vc.eventbus = new EventBusConfiguration();
vc.eventbus.keyCertificatePem = new PemKeyCertConfiguration();
vc.eventbus.keyCertificatePem.keys = Optional.empty();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ public class HttpConfiguration {
@ConfigItem(defaultValue = "0.0.0.0")
public String host;

/**
* Enable listening to host:port
*/
@ConfigItem(defaultValue = "true")
public boolean hostEnabled;

/**
* The HTTPS port
*/
Expand Down Expand Up @@ -110,6 +116,42 @@ public class HttpConfiguration {
@ConfigItem(name = "auth.session.encryption-key")
public Optional<String> encryptionKey;

/**
* Enable socket reuse port (linux/macOs native transport only)
*/
@ConfigItem(defaultValue = "false")
public boolean soReusePort;

/**
* Enable tcp quick ack (linux native transport only)
*/
@ConfigItem(defaultValue = "false")
public boolean tcpQuickAck;

/**
* Enable tcp cork (linux native transport only)
*/
@ConfigItem(defaultValue = "false")
public boolean tcpCork;

/**
* Enable tcp fast open (linux native transport only)
*/
@ConfigItem(defaultValue = "false")
public boolean tcpFastOpen;

/**
* Path to a unix domain socket
*/
@ConfigItem(defaultValue = "/var/run/io.quarkus.app.socket")
public String domainSocket;

/**
* Enable listening to host:port
*/
@ConfigItem(defaultValue = "false")
public boolean domainSocketEnabled;

public int determinePort(LaunchMode launchMode) {
return launchMode == LaunchMode.TEST ? testPort : port;
}
Expand Down
Loading

0 comments on commit d07fd1e

Please sign in to comment.