本项目中展示的是Netty和线程池的相关操作。 NettyServer端分别起了两个线程池做不同的事情: (1)MasterServer负责NettyServer的启动,处理客户端发送过来的消息,并将消息中的任务对象添加至阻塞队列 (2)WorkerServer负责从阻塞队列拉取任务执行,项目中的任务是执行jar包,在真实项目中时的任务可以是执行Spark任务等
NettyClient负责发送任务消息给NettyServer
真实使用场景下,NettyClient与NettyServer通常是两个不同的进程——如微服务,用于不同进程间的消息通信,其实Netty的通信方式 也可以用远程过程调用RPC的方式来替代,可以使用现有的spring feign调用的方式来替代Netty消息通信
MasterServer启动做的事情: (1)启动NettyServer,等待NettyClient客户端连接,发送消息; (2)MasterServer中的单线程池用于执行MasterSingleThread线程,该线程内部又有一个线程池用于执行 MasterTaskExecThread线程,MasterSingleThread线程的run()方法内部一直在循环,若有新的任务过来,使用线程池的方式 可以同时提交多个任务,提高效率,且线程池中的线程需要监控任务的执行状态直至任务执行完成。若当前正在执行的线程数大于线程 池的最大容量,则需要等待直至有空闲线程。而线程池中执行的MasterTaskExecThread线程则主要是将TaskCondition中taskQueue 队列中的任务添加至WaitExecTaskQueue对象的队列中供worker执行
综上,MasterServer启动了NettyServer,并启动了多个线程从TaskCondition的taskQueue阻塞队列中拉取任务,若没有 任务,则会阻塞等待,相当与MasterServer启动后起了n个线程等待拉取taskQueue中的任务
WorkerServer启动做的事情: (1)不断地从TaskCondition的WaitExecTaskQueue队列中拉取待执行任务进行执行; (2)将执行中的任务添加至TaskCondition的runningTasks映射中进行维护,便于后续的状态监控; WorkerServer中的单线程池用于执行WorkerSingleThread线程,该线程内部也有一个线程池用于执行WorkerTaskExecThread线程, WorkerSingleThread线程内部的run()方法一直在循环,不断地从WaitExecTaskQueue队列中拉取待执行的任务,一旦有任务,就会 起线程池中的线程来执行任务,提高任务执行的效率,前提是线程池还有可用线程,若没有则只能等待。