tomcat 스 레 드 탱크 정책
10206 단어 tomcat
tomcat 의 스 레 드 탱크 는 jdk 의 executor 를 확장 하 였 으 며, 대기 열 은 자신의 task quue 를 사용 하 였 으 므 로, 그 전략 은 jdk 와 다 르 므 로 주의해 야 합 니 다. 그렇지 않 으 면 구 덩이 를 밟 기 쉽 습 니 다.
tomcat 스 레 드 탱크 정책
tomcat minSpareThreads
에 이 르 지 않 았 습 니 다. tomcat 는 스 레 드 를 시작 하여 이 요청 을 처리 합 니 다.offer
에 넣 었 습 니 다. 대기 열 에 넣 으 면 되 돌아 갑 니 다. 대기 열 에 넣 지 못 하면 작업 스 레 드 를 추가 하려 고 합 니 다. 현재 스 레 드 개수 그리고 TaskQueue 의 대기 열 capacity 는 max Queue Size 이 고 기본 값 도 Integer. MAX 입 니 다.VALUE。그러나, offer 를 다시 쓰 는 방법 은 스 레 드 탱크 크기 가 maximumPoolSize 보다 작 을 때 false 로 돌아 갑 니 다. 즉, 대기 열 이 가득 찬 논 리 를 어느 정도 바 꾸 었 고, LinkedBlockingQueue 를 사용 하 는 기본 capacity 는 Integer. MAX 입 니 다.VALUE 때 max Threads 가 실 효 된 'bug' 입 니 다.따라서 max Threads 까지 스 레 드 를 계속 늘 리 고 초과 한 후에 대기 열 에 계속 넣 을 수 있 습 니 다.
TaskQueue 의 offer 동작
@Override
public boolean offer(Runnable o) {
//we can't do any checks
if (parent==null) return super.offer(o);
//we are maxed out on threads, simply queue the object
if (parent.getPoolSize() == parent.getMaximumPoolSize()) return super.offer(o);
//we have idle threads, just add it to the queue
if (parent.getSubmittedCount()
StandardThreadExecutor
/**
* Start the component and implement the requirements
* of {@link org.apache.catalina.util.LifecycleBase#startInternal()}.
*
* @exception LifecycleException if this component detects a fatal error
* that prevents this component from being used
*/
@Override
protected void startInternal() throws LifecycleException {
taskqueue = new TaskQueue(maxQueueSize);
TaskThreadFactory tf = new TaskThreadFactory(namePrefix,daemon,getThreadPriority());
executor = new ThreadPoolExecutor(getMinSpareThreads(), getMaxThreads(), maxIdleTime, TimeUnit.MILLISECONDS,taskqueue, tf);
executor.setThreadRenewalDelay(threadRenewalDelay);
if (prestartminSpareThreads) {
executor.prestartAllCoreThreads();
}
taskqueue.setParent(executor);
setState(LifecycleState.STARTING);
}
주의해 야 할 것 은 tomcat 의 스 레 드 탱크 는 Executors 공장 방법 에 사용 되 는 링크 드 BlockingQueue 가 아 닌 확장 taskQueue 를 사용 합 니 다.(
offer
) 여기 max QueueSize 기본 값 은
/**
* The maximum number of elements that can queue up before we reject them
*/
protected int maxQueueSize = Integer.MAX_VALUE;
org/apache/tomcat/util/threads/ThreadPoolExecutor
/**
* Executes the given command at some time in the future. The command
* may execute in a new thread, in a pooled thread, or in the calling
* thread, at the discretion of the Executor implementation.
* If no threads are available, it will be added to the work queue.
* If the work queue is full, the system will wait for the specified
* time and it throw a RejectedExecutionException if the queue is still
* full after that.
*
* @param command the runnable task
* @param timeout A timeout for the completion of the task
* @param unit The timeout time unit
* @throws RejectedExecutionException if this task cannot be
* accepted for execution - the queue is full
* @throws NullPointerException if command or unit is null
*/
public void execute(Runnable command, long timeout, TimeUnit unit) {
submittedCount.incrementAndGet();
try {
super.execute(command);
} catch (RejectedExecutionException rx) {
if (super.getQueue() instanceof TaskQueue) {
final TaskQueue queue = (TaskQueue)super.getQueue();
try {
if (!queue.force(command, timeout, unit)) {
submittedCount.decrementAndGet();
throw new RejectedExecutionException("Queue capacity is full.");
}
} catch (InterruptedException x) {
submittedCount.decrementAndGet();
throw new RejectedExecutionException(x);
}
} else {
submittedCount.decrementAndGet();
throw rx;
}
}
}
jd k 라인 풀 의 기본 Rejected 규칙, 즉 catch 가 Rejected Execution Exception 을 바 꾸 었 습 니 다.정상 jdk 의 규칙 은 core 스 레 드 수 + 임시 스 레 드 수 > max Size 일 때 Rejected Execution Exception 을 던 집 니 다.여기 catch 가 있 으 면 taskQueue 에 계속 넣 으 세 요.
public boolean force(Runnable o, long timeout, TimeUnit unit) throws InterruptedException {
if ( parent==null || parent.isShutdown() ) throw new RejectedExecutionException("Executor not running, can't force a command into the queue");
return super.offer(o,timeout,unit); //forces the item onto the queue, to be used if the task is rejected
}
여기 서 호출 된 슈퍼. offer (o, timeout, unt), 즉 링크 드 BlockingQueue 입 니 다. 열 이 가득 찼 을 때 false 로 돌아 가 야 Rejected Execution Exception 을 다시 던 집 니 다.(
jdk ThreadPoolExecutor RejectedExecutionException , maxThreads RejectedExecutionException, , taskQueue , RejectedExecutionException
) JD K 라인 풀 정책
/**
* Executes the given task sometime in the future. The task
* may execute in a new thread or in an existing pooled thread.
*
* If the task cannot be submitted for execution, either because this
* executor has been shutdown or because its capacity has been reached,
* the task is handled by the current {@code RejectedExecutionHandler}.
*
* @param command the task to execute
* @throws RejectedExecutionException at discretion of
* {@code RejectedExecutionHandler}, if the task
* cannot be accepted for execution
* @throws NullPointerException if {@code command} is null
*/
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
/*
* Proceed in 3 steps:
*
* 1. If fewer than corePoolSize threads are running, try to
* start a new thread with the given command as its first
* task. The call to addWorker atomically checks runState and
* workerCount, and so prevents false alarms that would add
* threads when it shouldn't, by returning false.
*
* 2. If a task can be successfully queued, then we still need
* to double-check whether we should have added a thread
* (because existing ones died since last checking) or that
* the pool shut down since entry into this method. So we
* recheck state and if necessary roll back the enqueuing if
* stopped, or start a new thread if there are none.
*
* 3. If we cannot queue task, then we try to add a new
* thread. If it fails, we know we are shut down or saturated
* and so reject the task.
*/
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
else if (!addWorker(command, false))
reject(command);
}
작은 매듭
tomcat 의 스 레 드 탱크 와 jdk 의 사용 무 계 링크 드 BlockingQueue 는 주로 다음 과 같은 두 가지 차이 가 있 습 니 다.
의문: taskQueue 가 무한 한 이상 tomcat 서버 의 수신 요청 제한 을 어디서 제어 하고 스스로 보호 하 는 지.그리고 acceptCount 와 max Connections 는 어떤 관계 입 니까?
doc
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
EC2 인스턴스에 Tomcat 설치전제 조건: Amazon 계정이 있어야 합니다. Amazon 계정에 로그인하고 EC2 인스턴스를 시작합니다. 여기에서 프리 티어를 선택했고 Amazon Linux 2를 실행하는 EC2 인스턴스를 시작했습니다. 시작 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.