Skip to content

Commit

Permalink
Upgrade to Netty 4.1.0.CR5 / Use epoll and BoringSSL when running on …
Browse files Browse the repository at this point in the history
…linux-x86_64

- Upgrade to Netty 4.1.0.CR5
- Use epoll when running on linux-x86_64
- Use BoringSSL for SSL when running on linux-x86_64
- Use different event loop names for different transport types
- Use different event loop names for bosses and workers
- Log the availability of epoll and BoringSSL
  • Loading branch information
trustin committed Mar 30, 2016
1 parent 8ade192 commit a8ffa67
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 18 deletions.
10 changes: 9 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
<jackson.version>2.6.5</jackson.version>
<logback.version>1.1.5</logback.version>
<metrics.version>3.1.2</metrics.version>
<netty.version>4.1.0.CR3</netty.version>
<netty.version>4.1.0.CR5</netty.version>
<slf4j.version>1.7.16</slf4j.version>
<tomcat.version>8.0.30</tomcat.version>
<jetty.alpnAgent.version>1.0.1.Final</jetty.alpnAgent.version>
Expand All @@ -110,6 +110,7 @@
<groupId>io.netty</groupId>
<artifactId>netty-transport-native-epoll</artifactId>
<version>${netty.version}</version>
<classifier>linux-x86_64</classifier>
</dependency>
<dependency>
<groupId>io.netty</groupId>
Expand All @@ -128,6 +129,13 @@
<version>3.20.0-GA</version>
<scope>runtime</scope>
</dependency>
<!-- epoll and BoringSSL support -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-tcnative-boringssl-static</artifactId>
<version>1.1.33.Fork15</version>
<classifier>linux-x86_64</classifier>
</dependency>

<!-- ALPN -->
<dependency>
Expand Down
52 changes: 40 additions & 12 deletions src/main/java/com/linecorp/armeria/client/RemoteInvokerFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ThreadFactory;
import java.util.function.Function;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -67,12 +68,25 @@ public final class RemoteInvokerFactory implements AutoCloseable {

private static final Logger logger = LoggerFactory.getLogger(RemoteInvokerFactory.class);

private enum TransportType {
NIO, EPOLL;
}

/**
* The default {@link RemoteInvokerFactory} implementation.
*/
public static final RemoteInvokerFactory DEFAULT =
new RemoteInvokerFactory(RemoteInvokerOptions.DEFAULT,
new DefaultThreadFactory("defaultArmeriaClient", true));
public static final RemoteInvokerFactory DEFAULT = new RemoteInvokerFactory(
RemoteInvokerOptions.DEFAULT,
type -> {
switch (type) {
case NIO:
return new DefaultThreadFactory("default-armeria-client-nio", true);
case EPOLL:
return new DefaultThreadFactory("default-armeria-client-epoll", true);
default:
throw new Error();
}
});

/**
* Closes the default {@link RemoteInvokerFactory}.
Expand All @@ -88,8 +102,11 @@ public static void closeDefault() {
}
}

private static final ThreadFactory DEFAULT_THREAD_FACTORY =
new DefaultThreadFactory("armeriaClient", false);
private static final ThreadFactory DEFAULT_THREAD_FACTORY_NIO =
new DefaultThreadFactory("armeria-client-nio", false);

private static final ThreadFactory DEFAULT_THREAD_FACTORY_EPOLL =
new DefaultThreadFactory("armeria-client-epoll", false);

private final EventLoopGroup eventLoopGroup;
private final boolean closeEventLoopGroup;
Expand All @@ -99,12 +116,23 @@ public static void closeDefault() {
* Creates a new instance with the specified {@link RemoteInvokerOptions}.
*/
public RemoteInvokerFactory(RemoteInvokerOptions options) {
this(options, DEFAULT_THREAD_FACTORY);
this(options, type -> {
switch (type) {
case NIO:
return DEFAULT_THREAD_FACTORY_NIO;
case EPOLL:
return DEFAULT_THREAD_FACTORY_EPOLL;
default:
throw new Error();
}
});
}

private RemoteInvokerFactory(RemoteInvokerOptions options, ThreadFactory threadFactory) {
private RemoteInvokerFactory(RemoteInvokerOptions options,
Function<TransportType, ThreadFactory> threadFactoryFactory) {

requireNonNull(options, "options");
requireNonNull(threadFactory, "threadFactory");
requireNonNull(threadFactoryFactory, "threadFactoryFactory");

final Bootstrap baseBootstrap = new Bootstrap();

Expand All @@ -121,7 +149,7 @@ private RemoteInvokerFactory(RemoteInvokerOptions options, ThreadFactory threadF
eventLoopGroup = eventLoopOption.get();
closeEventLoopGroup = false;
} else {
eventLoopGroup = createGroup(threadFactory);
eventLoopGroup = createGroup(threadFactoryFactory);
closeEventLoopGroup = true;
}

Expand All @@ -142,9 +170,9 @@ private static Class<? extends DatagramChannel> datagramChannelType() {
return Epoll.isAvailable() ? EpollDatagramChannel.class : NioDatagramChannel.class;
}

private static EventLoopGroup createGroup(ThreadFactory threadFactory) {
return Epoll.isAvailable() ? new EpollEventLoopGroup(0, threadFactory)
: new NioEventLoopGroup(0, threadFactory);
private static EventLoopGroup createGroup(Function<TransportType, ThreadFactory> threadFactoryFactory) {
return Epoll.isAvailable() ? new EpollEventLoopGroup(0, threadFactoryFactory.apply(TransportType.EPOLL))
: new NioEventLoopGroup(0, threadFactoryFactory.apply(TransportType.NIO));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ public Future<T> removeListener(
}

@Override
public Future<T> removeListeners(
@SafeVarargs
public final Future<T> removeListeners(
GenericFutureListener<? extends Future<? super T>>... listeners) {
return delegate.removeListeners(listeners);
}
Expand Down
35 changes: 31 additions & 4 deletions src/main/java/com/linecorp/armeria/server/Server.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
Expand All @@ -44,9 +45,11 @@
import io.netty.channel.epoll.EpollServerSocketChannel;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.ssl.OpenSsl;
import io.netty.handler.ssl.SslContext;
import io.netty.util.DomainMappingBuilder;
import io.netty.util.DomainNameMapping;
import io.netty.util.concurrent.DefaultThreadFactory;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GlobalEventExecutor;
import io.netty.util.concurrent.ImmediateEventExecutor;
Expand All @@ -61,6 +64,30 @@ public final class Server implements AutoCloseable {

private static final Logger logger = LoggerFactory.getLogger(Server.class);

private static final ThreadFactory DEFAULT_THREAD_FACTORY_BOSS_NIO =
new DefaultThreadFactory("armeria-server-boss-nio", false);

private static final ThreadFactory DEFAULT_THREAD_FACTORY_WORKER_NIO =
new DefaultThreadFactory("armeria-server-worker-nio", false);

private static final ThreadFactory DEFAULT_THREAD_FACTORY_BOSS_EPOLL =
new DefaultThreadFactory("armeria-server-boss-epoll", false);

private static final ThreadFactory DEFAULT_THREAD_FACTORY_WORKER_EPOLL =
new DefaultThreadFactory("armeria-server-worker-epoll", false);

static {
logger.info("/dev/epoll: " +
(Epoll.isAvailable() ? "available"
: "unavailable (" + Epoll.unavailabilityCause() + ')'));

if (OpenSsl.isAvailable()) {
logger.info("OpenSSL: " +
(OpenSsl.isAvailable() ? "available (" + OpenSsl.versionString() + ')'
: "unavailable (" + OpenSsl.unavailabilityCause() + ')'));
}
}

private final ServerConfig config;
private final DomainNameMapping<SslContext> sslContexts;

Expand Down Expand Up @@ -236,11 +263,11 @@ public Future<Void> start(Promise<Void> promise) {
try {
// Initialize the event loop groups.
if (Epoll.isAvailable()) {
bossGroup = new EpollEventLoopGroup(1);
workerGroup = new EpollEventLoopGroup(config.numWorkers());
bossGroup = new EpollEventLoopGroup(1, DEFAULT_THREAD_FACTORY_BOSS_EPOLL);
workerGroup = new EpollEventLoopGroup(config.numWorkers(), DEFAULT_THREAD_FACTORY_WORKER_EPOLL);
} else {
bossGroup = new NioEventLoopGroup(1);
workerGroup = new NioEventLoopGroup(config.numWorkers());
bossGroup = new NioEventLoopGroup(1, DEFAULT_THREAD_FACTORY_BOSS_NIO);
workerGroup = new NioEventLoopGroup(config.numWorkers(), DEFAULT_THREAD_FACTORY_WORKER_NIO);
}

// Initialize the server sockets asynchronously.
Expand Down

0 comments on commit a8ffa67

Please sign in to comment.