Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set useOpenSsl in Flags lazily to reduce server startup time #2184

Merged
merged 12 commits into from
Oct 25, 2019
Merged
66 changes: 37 additions & 29 deletions core/src/main/java/com/linecorp/armeria/common/Flags.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import com.linecorp.armeria.client.retry.RetryingRpcClient;
import com.linecorp.armeria.common.util.Exceptions;
import com.linecorp.armeria.common.util.Sampler;
import com.linecorp.armeria.common.util.SystemInfo;
import com.linecorp.armeria.internal.SslContextUtil;
import com.linecorp.armeria.server.RoutingContext;
import com.linecorp.armeria.server.ServerBuilder;
Expand Down Expand Up @@ -117,9 +118,8 @@ public final class Flags {
private static final boolean HAS_WSLENV = System.getenv("WSLENV") != null;
private static final boolean USE_EPOLL = getBoolean("useEpoll", isEpollAvailable(),
trustin marked this conversation as resolved.
Show resolved Hide resolved
value -> isEpollAvailable() || !value);

private static final boolean USE_OPENSSL = getBoolean("useOpenSsl", OpenSsl.isAvailable(),
value -> OpenSsl.isAvailable() || !value);
@Nullable
private static Boolean useOpenSsl;
ikhoon marked this conversation as resolved.
Show resolved Hide resolved

private static final boolean DUMP_OPENSSL_INFO = getBoolean("dumpOpenSslInfo", false);

Expand Down Expand Up @@ -312,34 +312,15 @@ public final class Flags {
} else if (USE_EPOLL) {
logger.info("Using /dev/epoll");
}

if (!OpenSsl.isAvailable()) {
final Throwable cause = Exceptions.peel(OpenSsl.unavailabilityCause());
logger.info("OpenSSL not available: {}", cause.toString());
} else if (USE_OPENSSL) {
logger.info("Using OpenSSL: {}, 0x{}",
OpenSsl.versionString(),
Long.toHexString(OpenSsl.version() & 0xFFFFFFFFL));

if (dumpOpenSslInfo()) {
final SSLEngine engine = SslContextUtil.createSslContext(
SslContextBuilder::forClient,
false,
unused -> {}).newEngine(ByteBufAllocator.DEFAULT);
logger.info("All available SSL protocols: {}",
ImmutableList.copyOf(engine.getSupportedProtocols()));
logger.info("Default enabled SSL protocols: {}", SslContextUtil.DEFAULT_PROTOCOLS);
ReferenceCountUtil.release(engine);
logger.info("All available SSL ciphers: {}", OpenSsl.availableJavaCipherSuites());
logger.info("Default enabled SSL ciphers: {}", SslContextUtil.DEFAULT_CIPHERS);
}
}
}

private static boolean isEpollAvailable() {
// Netty epoll transport does not work with WSL (Windows Sybsystem for Linux) yet.
// TODO(trustin): Re-enable on WSL if https://github.com/Microsoft/WSL/issues/1982 is resolved.
return Epoll.isAvailable() && !HAS_WSLENV;
if (SystemInfo.isLinux()) {
// Netty epoll transport does not work with WSL (Windows Sybsystem for Linux) yet.
// TODO(trustin): Re-enable on WSL if https://github.com/Microsoft/WSL/issues/1982 is resolved.
return Epoll.isAvailable() && !HAS_WSLENV;
}
return false;
}

/**
Expand Down Expand Up @@ -426,7 +407,34 @@ public static boolean useEpoll() {
* {@code -Dcom.linecorp.armeria.useOpenSsl=false} JVM option to disable it.
*/
public static boolean useOpenSsl() {
return USE_OPENSSL;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we still need the null check that returns the value after we set it once like we had before (can use a different name for the local variable if it makes it confusing).

if (useOpenSsl != null) {
return useOpenSsl;
}
final boolean useOpenSsl = getBoolean("useOpenSsl", true);
if (!useOpenSsl) {
// OpenSSL explicitly disabled
return Flags.useOpenSsl = false;
}
if (!OpenSsl.isAvailable()) {
final Throwable cause = Exceptions.peel(OpenSsl.unavailabilityCause());
logger.info("OpenSSL not available: {}", cause.toString());
mumgmangmange marked this conversation as resolved.
Show resolved Hide resolved
return Flags.useOpenSsl = false;
}
logger.info("Using OpenSSL: {}, 0x{}", OpenSsl.versionString(),
Long.toHexString(OpenSsl.version() & 0xFFFFFFFFL));
if (dumpOpenSslInfo()) {
final SSLEngine engine = SslContextUtil.createSslContext(
SslContextBuilder::forClient,
false,
unused -> {}).newEngine(ByteBufAllocator.DEFAULT);
logger.info("All available SSL protocols: {}",
ImmutableList.copyOf(engine.getSupportedProtocols()));
logger.info("Default enabled SSL protocols: {}", SslContextUtil.DEFAULT_PROTOCOLS);
ReferenceCountUtil.release(engine);
logger.info("All available SSL ciphers: {}", OpenSsl.availableJavaCipherSuites());
logger.info("Default enabled SSL ciphers: {}", SslContextUtil.DEFAULT_CIPHERS);
}
return Flags.useOpenSsl = true;
}

/**
Expand Down
27 changes: 27 additions & 0 deletions core/src/main/java/com/linecorp/armeria/common/util/OsType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright 2019 LINE Corporation
*
* LINE Corporation licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/

package com.linecorp.armeria.common.util;

/**
* Operating system.
*/
public enum OsType {
WINDOWS,
LINUX,
MAC,
OTHERS
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ public final class SystemInfo {

private static boolean JETTY_ALPN_OPTIONAL_OR_AVAILABLE;

private static final OsType osType;

static {
int javaVersion = -1;
try {
Expand Down Expand Up @@ -109,6 +111,17 @@ public final class SystemInfo {
JETTY_ALPN_OPTIONAL_OR_AVAILABLE = false;
}
}

final String osName = Ascii.toUpperCase(System.getProperty("os.name", ""));
if (osName.startsWith("WINDOWS")) {
osType = OsType.WINDOWS;
} else if (osName.startsWith("LINUX")) {
osType = OsType.LINUX;
} else if (osName.startsWith("MAC")) {
osType = OsType.MAC;
} else {
osType = OsType.OTHERS;
}
}

/**
Expand Down Expand Up @@ -154,8 +167,18 @@ public static long currentTimeMicros() {
return JavaVersionSpecific.get().currentTimeMicros();
}

private static boolean isLinux() {
return Ascii.toLowerCase(System.getProperty("os.name", "")).startsWith("linux");
ikhoon marked this conversation as resolved.
Show resolved Hide resolved
/**
* Returns the operating system for the currently running process.
*/
public static OsType osType() {
return osType;
}

/**
* Returns {@code true} if the operating system is Linux.
*/
public static boolean isLinux() {
return osType == OsType.LINUX;
}

private SystemInfo() {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.epoll.EpollChannelOption;
import io.netty.handler.ssl.OpenSsl;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.util.DomainNameMapping;
Expand Down Expand Up @@ -1576,7 +1575,7 @@ public Server build() {
ports = ImmutableList.of(new ServerPort(0, HTTP));
}
} else {
if ((!OpenSsl.isAvailable() || !Flags.useOpenSsl()) && !SystemInfo.jettyAlpnOptionalOrAvailable()) {
if (!Flags.useOpenSsl() && !SystemInfo.jettyAlpnOptionalOrAvailable()) {
throw new IllegalStateException(
"TLS configured but this is Java 8 and neither OpenSSL nor Jetty ALPN could be " +
"detected. To use TLS with Armeria, you must either use Java 9+, enable OpenSSL, " +
Expand Down