4. AcceptorExecutor#AcceptorRunner线程和TaskExecutors#BatchWorkerRunnable线程在初始化时作为守护线程启动,这里处理请求有批量和单个,但是共用一个AcceptorExecutor,只是参数maxBatchingSize不一样,AcceptorRunner#run,先判断线程有没有被强制停止,
public void run() {
long scheduleTime = 0;
while (!isShutdown.get()) {
try {
drainInputQueues();
int totalItems = processingOrder.size();
long now = System.currentTimeMillis();
if (scheduleTime < now) {
scheduleTime = now + trafficShaper.transmissionDelay();
}
if (scheduleTime <= now) {
assignBatchWork();
assignSingleItemWork();
}
// If no worker is requesting data or there is a delay injected by the traffic shaper,
// sleep for some time to avoid tight loop.
if (totalItems == processingOrder.size()) {
Thread.sleep(10);
}
} catch (InterruptedException ex) {
// Ignore
} catch (Throwable e) {
// Safe-guard, so we never exit this loop in an uncontrolled way.
logger.warn("Discovery AcceptorThread error", e);
}
}
}
然后通过drainAcceptorQueue方法把acceptorQueue队列中的任务取出来放入pendingTasks和processingOrder,代表的意思就是把需要执行的任务都放入待执行任务队列中。
private boolean isFull() {
return pendingTasks.size() >= maxBufferSize;
}
private void drainInputQueues() throws InterruptedException {
do {
drainReprocessQueue();
drainAcceptorQueue();
if (!isShutdown.get()) {
// If all queues are empty, block for a while on the acceptor queue
if (reprocessQueue.isEmpty() && acceptorQueue.isEmpty() && pendingTasks.isEmpty()) {
TaskHolder<ID, T> taskHolder = acceptorQueue.poll(10, TimeUnit.MILLISECONDS);
if (taskHolder != null) {
appendTaskHolder(tas

本文深入探讨Eureka的注册流程,包括AcceptorExecutor的AcceptorRunner和TaskExecutors的BatchWorkerRunnable线程的工作机制。内容涉及任务队列处理、批量与单个任务的区分、Semaphore信号量在批量任务中的作用,以及ReplicationTaskProcessor如何处理同步任务,通过http接口实现服务节点间的实例信息同步。
最低0.47元/天 解锁文章
483

被折叠的 条评论
为什么被折叠?



