Przeglądaj źródła

Default to server VM and add client VM check

Today we softly warn about running with the client VM. However, we
should really refuse to start in production mode if running with the
client VM as the performance of the client VM is too devastating for a
server application. This commit adds an option to jvm.options to ensure
that we are starting with the server VM (on all 32-bit non-Windows
platforms on server-class machines (2+ CPUs, 2+ GB physical RAM) this is
the default and on all 64-bit platforms this is the only option) and
adds a bootstrap check for the client VM.

Relates #18155
Jason Tedor 9 lat temu
rodzic
commit
e11b96ca9c

+ 0 - 6
core/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java

@@ -246,12 +246,6 @@ final class Bootstrap {
             PidFile.create(environment.pidFile(), true);
         }
 
-        // warn if running using the client VM
-        if (JvmInfo.jvmInfo().getVmName().toLowerCase(Locale.ROOT).contains("client")) {
-            ESLogger logger = Loggers.getLogger(Bootstrap.class);
-            logger.warn("jvm uses the client vm, make sure to run `java` with the server vm for best performance by adding `-server` to the command line");
-        }
-
         try {
             if (!foreground) {
                 Loggers.disableConsoleLogging();

+ 28 - 0
core/src/main/java/org/elasticsearch/bootstrap/BootstrapCheck.java

@@ -163,6 +163,7 @@ final class BootstrapCheck {
         if (Constants.LINUX) {
             checks.add(new MaxMapCountCheck());
         }
+        checks.add(new ClientJvmCheck());
         return Collections.unmodifiableList(checks);
     }
 
@@ -476,4 +477,31 @@ final class BootstrapCheck {
 
     }
 
+    static class ClientJvmCheck implements BootstrapCheck.Check {
+
+        @Override
+        public boolean check() {
+            return getVmName().toLowerCase(Locale.ROOT).contains("client");
+        }
+
+        // visible for testing
+        String getVmName() {
+            return JvmInfo.jvmInfo().getVmName();
+        }
+
+        @Override
+        public String errorMessage() {
+            return String.format(
+                    Locale.ROOT,
+                    "JVM is using the client VM [%s] but should be using a server VM for the best performance",
+                    getVmName());
+        }
+
+        @Override
+        public final boolean isSystemCheck() {
+            return false;
+        }
+
+    }
+
 }

+ 22 - 0
core/src/test/java/org/elasticsearch/bootstrap/BootstrapCheckTests.java

@@ -31,6 +31,7 @@ import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.AtomicReference;
 
 import static org.hamcrest.CoreMatchers.allOf;
 import static org.hamcrest.CoreMatchers.containsString;
@@ -373,6 +374,27 @@ public class BootstrapCheckTests extends ESTestCase {
         expectThrows(RuntimeException.class, () -> BootstrapCheck.check(true, false, defaultChecks, "testMinMasterNodes"));
     }
 
+    public void testClientJvmCheck() {
+        final AtomicReference<String> vmName = new AtomicReference<>("Java HotSpot(TM) 32-Bit Client VM");
+        final BootstrapCheck.Check check = new BootstrapCheck.ClientJvmCheck() {
+            @Override
+            String getVmName() {
+                return vmName.get();
+            }
+        };
+
+        RuntimeException e = expectThrows(
+                RuntimeException.class,
+                () -> BootstrapCheck.check(true, false, Collections.singletonList(check), "testClientJvmCheck"));
+        assertThat(
+                e.getMessage(),
+                containsString("JVM is using the client VM [Java HotSpot(TM) 32-Bit Client VM] " +
+                        "but should be using a server VM for the best performance"));
+
+        vmName.set("Java HotSpot(TM) 32-Bit Server VM");
+        BootstrapCheck.check(true, false, Collections.singletonList(check), "testClientJvmCheck");
+    }
+
     public void testIgnoringSystemChecks() {
         BootstrapCheck.Check check = new BootstrapCheck.Check() {
             @Override

+ 3 - 0
distribution/src/main/resources/config/jvm.options

@@ -48,6 +48,9 @@
 
 ## basic
 
+# force the server VM
+-server
+
 # set to headless, just in case
 -Djava.awt.headless=true