#2298 Override the processor number with an environment variable

Signed-off-by: olivier lamy <olamy@webtide.com>
This commit is contained in:
olivier lamy 2018-03-07 20:58:03 +10:00
parent 74055b9837
commit 7004aaa538
18 changed files with 119 additions and 19 deletions

View File

@ -47,6 +47,7 @@ import org.eclipse.jetty.annotations.AnnotationParser.Handler;
import org.eclipse.jetty.plus.annotation.ContainerInitializer;
import org.eclipse.jetty.util.JavaVersion;
import org.eclipse.jetty.util.MultiException;
import org.eclipse.jetty.util.ProcessorUtils;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.log.Log;
@ -453,7 +454,7 @@ public class AnnotationConfiguration extends AbstractConfiguration
start = System.nanoTime();
//execute scan, either effectively synchronously (1 thread only), or asynchronously (limited by number of processors available)
final Semaphore task_limit = (isUseMultiThreading(context)? new Semaphore(Runtime.getRuntime().availableProcessors()):new Semaphore(1));
final Semaphore task_limit = (isUseMultiThreading(context)? new Semaphore(ProcessorUtils.availableProcessors()):new Semaphore( 1));
final CountDownLatch latch = new CountDownLatch(_parserTasks.size());
final MultiException me = new MultiException();

View File

@ -64,6 +64,7 @@ import org.eclipse.jetty.io.MappedByteBufferPool;
import org.eclipse.jetty.io.ssl.SslClientConnectionFactory;
import org.eclipse.jetty.util.Fields;
import org.eclipse.jetty.util.Jetty;
import org.eclipse.jetty.util.ProcessorUtils;
import org.eclipse.jetty.util.Promise;
import org.eclipse.jetty.util.SocketAddressResolver;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
@ -213,7 +214,7 @@ public class HttpClient extends ContainerLifeCycle
byteBufferPool = new MappedByteBufferPool(2048,
executor instanceof ThreadPool.SizedThreadPool
? ((ThreadPool.SizedThreadPool)executor).getMaxThreads()/2
: Runtime.getRuntime().availableProcessors()*2);
: ProcessorUtils.availableProcessors()*2);
addBean(byteBufferPool);
if (scheduler == null)

View File

@ -27,6 +27,7 @@ import org.eclipse.jetty.client.HttpDestination;
import org.eclipse.jetty.client.Origin;
import org.eclipse.jetty.client.api.Connection;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.util.ProcessorUtils;
import org.eclipse.jetty.util.Promise;
import org.eclipse.jetty.util.annotation.ManagedObject;
@ -35,7 +36,7 @@ public class HttpClientTransportOverHTTP extends AbstractConnectorHttpClientTran
{
public HttpClientTransportOverHTTP()
{
this(Math.max(1, Runtime.getRuntime().availableProcessors() / 2));
this(Math.max( 1, ProcessorUtils.availableProcessors() / 2));
}
public HttpClientTransportOverHTTP(int selectors)

View File

@ -32,6 +32,7 @@ import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.fcgi.FCGI;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.util.ProcessorUtils;
import org.eclipse.jetty.util.Promise;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
@ -44,7 +45,7 @@ public class HttpClientTransportOverFCGI extends AbstractConnectorHttpClientTran
public HttpClientTransportOverFCGI(String scriptRoot)
{
this(Math.max(1, Runtime.getRuntime().availableProcessors() / 2), false, scriptRoot);
this( Math.max( 1, ProcessorUtils.availableProcessors() / 2), false, scriptRoot);
}
public HttpClientTransportOverFCGI(int selectors, boolean multiplexed, String scriptRoot)

View File

@ -40,6 +40,7 @@ import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpScheme;
import org.eclipse.jetty.proxy.AsyncProxyServlet;
import org.eclipse.jetty.util.ProcessorUtils;
/**
* Specific implementation of {@link org.eclipse.jetty.proxy.AsyncProxyServlet.Transparent} for FastCGI.
@ -111,7 +112,7 @@ public class FastCGIProxyServlet extends AsyncProxyServlet.Transparent
String scriptRoot = config.getInitParameter(SCRIPT_ROOT_INIT_PARAM);
if (scriptRoot == null)
throw new IllegalArgumentException("Mandatory parameter '" + SCRIPT_ROOT_INIT_PARAM + "' not configured");
int selectors = Math.max(1, Runtime.getRuntime().availableProcessors() / 2);
int selectors = Math.max( 1, ProcessorUtils.availableProcessors() / 2);
String value = config.getInitParameter("selectors");
if (value != null)
selectors = Integer.parseInt(value);

View File

@ -34,6 +34,7 @@ import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.toolchain.test.TestTracker;
import org.eclipse.jetty.util.LeakDetector;
import org.eclipse.jetty.util.ProcessorUtils;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.hamcrest.Matchers;
import org.junit.After;
@ -59,8 +60,8 @@ public abstract class AbstractHttpClientServerTest
ServerFCGIConnectionFactory fcgiConnectionFactory = new ServerFCGIConnectionFactory(new HttpConfiguration());
serverBufferPool = new LeakTrackingByteBufferPool(new MappedByteBufferPool.Tagged());
connector = new ServerConnector(server, null, null, serverBufferPool,
1, Math.max(1, Runtime.getRuntime().availableProcessors() / 2), fcgiConnectionFactory);
connector = new ServerConnector( server, null, null, serverBufferPool,
1, Math.max( 1, ProcessorUtils.availableProcessors() / 2), fcgiConnectionFactory);
// connector.setPort(9000);
server.addConnector(connector);

View File

@ -32,6 +32,7 @@ import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.IntUnaryOperator;
import org.eclipse.jetty.util.ProcessorUtils;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.component.ContainerLifeCycle;
@ -68,10 +69,10 @@ public abstract class SelectorManager extends ContainerLifeCycle implements Dump
if (executor instanceof ThreadPool.SizedThreadPool)
{
int threads = ((ThreadPool.SizedThreadPool)executor).getMaxThreads();
int cpus = Runtime.getRuntime().availableProcessors();
int cpus = ProcessorUtils.availableProcessors();
return Math.max(1,Math.min(cpus/2,threads/16));
}
return Math.max(1,Runtime.getRuntime().availableProcessors()/2);
return Math.max(1,ProcessorUtils.availableProcessors()/2);
}
protected SelectorManager(Executor executor, Scheduler scheduler)

View File

@ -50,6 +50,7 @@ import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpHeaderValue;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.util.HttpCookieStore;
import org.eclipse.jetty.util.ProcessorUtils;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
@ -352,7 +353,7 @@ public abstract class AbstractProxyServlet extends HttpServlet
*/
protected HttpClient newHttpClient()
{
int selectors = Math.max(1, Runtime.getRuntime().availableProcessors() / 2);
int selectors = Math.max(1,ProcessorUtils.availableProcessors()/2);
String value = getServletConfig().getInitParameter("selectors");
if (value != null)
selectors = Integer.parseInt(value);

View File

@ -42,6 +42,7 @@ import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.ProcessorUtils;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
@ -149,7 +150,7 @@ public class ProxyServletLoadTest
startClient();
// Number of clients to simulate
int clientCount = Runtime.getRuntime().availableProcessors();
int clientCount = ProcessorUtils.availableProcessors();
// Latch for number of clients still active (used to terminate test)
final CountDownLatch activeClientLatch = new CountDownLatch(clientCount);

View File

@ -42,6 +42,7 @@ import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.ssl.SslConnection;
import org.eclipse.jetty.util.FutureCallback;
import org.eclipse.jetty.util.ProcessorUtils;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
@ -196,7 +197,7 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
for (ConnectionFactory factory:factories)
addConnectionFactory(factory);
int cores = Runtime.getRuntime().availableProcessors();
int cores = ProcessorUtils.availableProcessors();
if (acceptors < 0)
acceptors=Math.max(1, Math.min(4,cores/8));
if (acceptors > cores)

View File

@ -37,6 +37,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.HttpOutput;
import org.eclipse.jetty.util.ProcessorUtils;
/**
* A servlet that uses the Servlet 3.1 asynchronous IO API to server
@ -78,7 +79,7 @@ public class DataRateLimitedServlet extends HttpServlet
if (tmp!=null)
pauseNS=TimeUnit.MILLISECONDS.toNanos(Integer.parseInt(tmp));
tmp = getInitParameter("pool");
int pool=tmp==null?Runtime.getRuntime().availableProcessors():Integer.parseInt(tmp);
int pool=tmp==null?ProcessorUtils.availableProcessors():Integer.parseInt(tmp);
// Create and start a shared scheduler.
scheduler=new ScheduledThreadPoolExecutor(pool);

View File

@ -0,0 +1,49 @@
//
// ========================================================================
// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.util;
/**
* ProcessorUtils return the default value for processor number fron {@link Runtime#getRuntime()#availableProcessors()}
* but in a virtual environment you can override it using env var <code>JETTY_AVAILABLE_PROCESSORS</code>
*/
public class ProcessorUtils
{
private static int AVAILABLE_PROCESSORS = Runtime.getRuntime().availableProcessors();
static
{
String avlProcEnv = System.getenv( "JETTY_AVAILABLE_PROCESSORS" );
if (avlProcEnv != null)
{
try
{
AVAILABLE_PROCESSORS = Integer.parseInt( avlProcEnv );
}
catch ( NumberFormatException e )
{
// ignore
}
}
}
public static int availableProcessors()
{
return AVAILABLE_PROCESSORS;
}
}

View File

@ -28,6 +28,7 @@ import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import org.eclipse.jetty.util.ProcessorUtils;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.component.ContainerLifeCycle;
@ -78,7 +79,7 @@ public class ExecutorThreadPool extends ContainerLifeCycle implements ThreadPool
public ExecutorThreadPool(ThreadPoolExecutor executor, int reservedThreads, ThreadGroup group)
{
this(executor, Math.min(Runtime.getRuntime().availableProcessors(), executor.getCorePoolSize()), reservedThreads, group);
this( executor, Math.min(ProcessorUtils.availableProcessors(),executor.getCorePoolSize()),reservedThreads,group);
}
private ExecutorThreadPool(ThreadPoolExecutor executor, int minThreads, int reservedThreads, ThreadGroup group)

View File

@ -25,6 +25,7 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import org.eclipse.jetty.util.ProcessorUtils;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
@ -96,7 +97,7 @@ public class ReservedThreadExecutor extends AbstractLifeCycle implements TryExec
{
if (capacity>=0)
return capacity;
int cpus = Runtime.getRuntime().availableProcessors();
int cpus = ProcessorUtils.availableProcessors();
if (executor instanceof ThreadPool.SizedThreadPool)
{
int threads = ((ThreadPool.SizedThreadPool)executor).getMaxThreads();

View File

@ -25,6 +25,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicBoolean;
import org.eclipse.jetty.util.ProcessorUtils;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@ -97,7 +98,7 @@ public class ThreadPoolBudget
*/
public ThreadPoolBudget(ThreadPool.SizedThreadPool pool)
{
this(pool,Math.min(Runtime.getRuntime().availableProcessors(),pool.getMinThreads()));
this(pool,Math.min(ProcessorUtils.availableProcessors(),pool.getMinThreads()));
}
/**

View File

@ -0,0 +1,36 @@
//
// ========================================================================
// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.util;
import org.junit.Assert;
import org.junit.Test;
/**
* we cannot really add env var in a unit test... so only test we get default value
*/
public class ProcessorUtilsTest
{
@Test
public void get_default_value(){
Assert.assertEquals(Runtime.getRuntime().availableProcessors(), ProcessorUtils.availableProcessors());
}
}

View File

@ -47,7 +47,7 @@ public class QueueBenchmarkTest
@Test
public void testQueues() throws Exception
{
int cores = Runtime.getRuntime().availableProcessors();
int cores = ProcessorUtils.availableProcessors();
Assume.assumeTrue(cores > 1);
final int readers = cores / 2;
@ -66,7 +66,7 @@ public class QueueBenchmarkTest
@Test
public void testBlockingQueues() throws Exception
{
int cores = Runtime.getRuntime().availableProcessors();
int cores = ProcessorUtils.availableProcessors();
Assume.assumeTrue(cores > 1);
final int readers = cores / 2;

View File

@ -56,6 +56,7 @@ import org.eclipse.jetty.unixsocket.UnixSocketConnector;
import org.eclipse.jetty.unixsocket.client.HttpClientTransportOverUnixSockets;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.LeakDetector;
import org.eclipse.jetty.util.ProcessorUtils;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.Scheduler;
@ -86,7 +87,7 @@ public class HttpClientLoadTest extends AbstractTest
unixSocketConnector.setUnixSocket( sockFile.toString() );
return unixSocketConnector;
}
int cores = Runtime.getRuntime().availableProcessors();
int cores = ProcessorUtils.availableProcessors();
ByteBufferPool byteBufferPool = new ArrayByteBufferPool();
byteBufferPool = new LeakTrackingByteBufferPool(byteBufferPool);
return new ServerConnector(server, null, null, byteBufferPool,