JStorm源码分析(一)Worker核心源码分析(草稿|无代码|无图版)

(一)属性分析

Worker 类下只有一个属性—— WorkerData,封装了所有与 Worker有关的属性,下面列表分类阐述这些属性的作用:

组的作用

变量名

类型

变量的作用

线程池

线程池

threadPool

ScheduledExecutorService

作为线程池,用来调度定时任务

 

 

THREAD_POOL_NUM

int 常量

线程池中任务的个数

 

 

context

IContext

消息上下文对象,即从外界获取消息的接口

 

 

topologyId, supervisorId, workerId

String

用来唯一标识这个 Worker

 

 

port

Integer

开放给外界,用来通信的端口

 

 

shutdown,

monitorEnable

AtomicBoolean

用于跟踪和控制 Worker 的运行状态——是否停止、是否允许监控

 

 

topologyStatus

StatusType|enum

集群当前的所处的状态

 

 

zkClusterState

ClusterState

集群在 zk 中记录的状态

 

 

zkCluster

StormClusterState

 

 

 

taskids

Set<Integer>

在当前 Worker 上运行的task的编号

 

 

nodeportSocket

ConcurrentHashMap<WorkerSlot, IConnection>

管理与其他worker 的连接对象

 

 

taskNodeport

ConcurrentHashMap<Integer, WorkerSlot>

 

 

 

outboundTasks

Set<Integer>|volatile

需要向外部输出信息的 Task 集合

 

 

localNodeTasks

Set<Integer>

本地节点上的 Task 集合

 

 

workerToResource

ConcurrentSkipListSet<ResourceWorkerSlot>

未知作用

 

 

innerTaskTransfer, controlQueues, deserializeQueues

ConcurrentHashMap<Integer, DisruptorQueue>

 

 

 

tasksToComponent

ConcurrentHashMap<Integer, String>

知晓某个 Task 运行在哪个Component 之上

 

 

componentToSortedTasks

ConcurrentHashMap<String, List<Integer>>

知晓某个 Component 上运行了哪些Task

 

 

defaultResources

Map<String, Object>

默认的资源

 

 

userResources

Map<String, Object>

用户的资源

 

 

executorData

Map<String, Object>

运行中的一些数据

 

 

registeredMetrics

 

 

 

 

rawTopology

StormTopology

由本地的 jar 包反序列化而来的Topology

 

 

sysTopology

StormTopology

worker 中运行的Topology

 

 

contextMaker

ContextMaker

上下文创建者

 

 

workHalt

AsyncLoopDefaultKill

关闭 Worker 的入口

 

 

transferCtrlQueue

DisruptorQueue

用来发送 Tuple 的队列

 

 

sendingQueue

DisruptorQueue

用来发送 Tuple 的队列

 

 

shutdownTasks

List<TaskShutdownDameon>

被终止的 Task 列表

 

 

outTaskStatus

ConcurrentHashMap<Integer, Boolean>

需要向外进行输出的任务的状态

 

 

flusherPool

FlusherPool

 

 

 

assignmentTS

Long|volatile

上次进行分配的时间

 

 

assignmentType

AssignmentType|volatile

上次进行分配的类型

 

 

recvConnection

IConnection

 

 

 

metricReporter

JStormMetricsReporter

 

 

 

healthReporterThread

AsyncLoopThread

异步汇报 Woker “健康状况”的线程

 

 

workeInitConnectionStatus

AtomicBoolean

 

 

 

atomKryoSerializer

AtomicReference<KryoTupleSerializer>

Tuple 序列化

 

 

atomKryoDeserializer

AtomicReference<KryoTupleDeserializer>

Tuple 反序列化

 

 

updateListener

UpdateListener

对于需要动态更新的数据或配置,通过 UpdateListener 进行更新。

 

 

deserializeThreads

List<AsyncLoopThread>

反序列化线程集合

 

 

serializeThreads

List<AsyncLoopThread>

序列化线程集合

(二)构造方法

首先来看 WorkerData 的构造方法,它的构造方法中仅有一个,接收的参数列表如下所示:

参数名

类型

含义

conf

Map

相关配置项

context

IContext

消息上下文,用来接收外部的消息

topology_id

String

唯一标识所属 Topology 的编号

supervisor_id

String

唯一标识所属 Supervisor 的编号

port

int

开放给外界,用来通信的端口号

worker_id

String

唯一标识该 Worker 的编号

jar_path

String

实例化 Topology 所需要的原始jar 包的路径

WorkerData 接收上述参数,按照如下步骤执行构造:

  1. 进行基本属性和初始状态的设置:包括配置项、消息上下文对象、编号等,同时将初始状态设置为未停止、可以被监控。由于此时还处于构造方法中,还没有进行任何连接。因此 topologyStatus置为 null ,workeInitConnectionStatus置为 false
  2. 确认是否为分布式状态:通过查看配置项判断当前是否处于分布式状态。如果是,那么创建一个配套的工作目录。
  3. 创建ZK接口:实例化ZK连接接口,用来获取当前集群在ZK 中记录的集群状态。
  4. 获取最新配置并注册配置更新接口。
  5. 进行相关监测量的注册工作,方便对 Worker 工作状态进行监控。
  6. 加载序列化当前 Worker 所需要的原始 jar 包。
  7. 实例化相关的消息队列。
  8. 获取资源和 Task 分配情况。
  9. 初始化其他属性,完成 WorkerData 的创建。

(三)关键方法

1)createTask() ——创建并启动任务

这个方法用于创建在Worker上运行的任务并启动它们。

  1. 首先,通过 WorkerData 对象获得需要创建并启动的任务编号;
  2. 根据 WorkerData 和任务编号,创建任务实例,并启动一个线程,运行该任务;
  3. 串行化所有线程,等待所有线程运行完毕;
  4. 获得所有任务的 TaskShutdownDameon 对象,用于监控和控制这些任务停止运行。这些对象作为方法的返回值返回

2)startDispatchThread() ——启动分发线程

  1. 首先,通过 WorkData 对象获得消息上下文IContext对象;
  2. 从配置项中获取配置信息,这些配置信息将用于决定创建一个怎样的DisruptorQueue,这个消息队列用于接收控制消息;
  3. 建立连接对象,然后根据消息队列和连接对象创建一个后台线程,并使其在后台异步循环,最后将这个线程作为返回值。【小贴士】进一步了解 AsyncLoopThread。

3)execute() ——启动 Worker

  1. 首先,调用 startDispatchThread() 生成消息分发线程,添加到待启动线程列表中;
  2. 然后,生成连接更新线程与 zk 活性保持线程,也添加到待启动线程列表中;
  3. 生成控制消息发送线程,同样添加到待启动线程列表中;
  4. 生成心跳线程、序列化和反序列线程,形成最终的线程列表,和 WorkData 对象一起,生成一个 WorkerShutdown 对象作为返回值。

4)mk_worker() ——创建一个 Worker实例并启动它

  1. 通过构造方法创建一个 Worker 实例,调用 execute() 方法启动该Worker 实例。

5)redirectOutput() ——重定向输出

  1. 该方法不涉及核心逻辑,故暂且略过。

6)getOldPortPids() ——找到旧的正在运行的 Worker进程

  1. 通过系统调用 ps -Af 来找到 Worker 进程,返回所有的Worker 进程号。

7)killOldWorker() ——强行停止旧的 Worker进程

  1. 调用 getOldPortPids() 获得所有旧的 Worker 进程号,然后强行停止这些进程。

8)main() ——主入口

  1. 首先,检查参数列表并从参数列表中获取拓扑编号、supervisor编号、端口号等参数;
  2. 调用 killOldWorker() 根据端口号找到所有的正在运行的 Worker 进程,强行停止这些进程;
  3. 调用 mk_worker() 生成 Worker 实例,在返回的WorkerShutdown 对象上调用join() 方法,则主线程将会阻塞等待,直到该线程运行完成。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值