Spark通信框架rpc源码篇
·
核心要点如下:
- 核心的RpcEnv是一个特质(trait),它主要提供了停止,注册,获取endpoint等方法的定义,而NetyRpcEnv提供了该特质的一个具体实现。
- 通过工厂RpcEnvFactory来产生一个RpcEnv,而NettyRpcEnvFactory用来生成NettyRpcEnv的一个对象。
- 当我们调用RpcEnv中的setupEndpoint来注册一个endpoint到rpcEnv的时候,在NettyRpcEnv内部,会将该endpoint的名称与其本省的映射关系rpcEndpoint与rpcEndpointRef之间映射关系保存在dispatcher对应的成员变量中。
接下来,我们看一个具体的案例:在standalone模式中,worker会定时发心跳消息(SendHeartbeat)给master,那心跳消息是怎么从worker发送到master的呢,master又是怎么接收消息的?
- 在worker中,forwordMessageschedyer线程会定时每限心跳超时时间的四分之一时间向自己发送SendHeatbeat消息,在worker的receive系数中,我们看到一旦接收到SendHeartbeat消息,worker会调用sendToMaster函数,将Heartbeat消息(包含worker Id和当前worker的rpcEndpoint号用)发送给master。

- 在worker的sendToMaster函数中,通过masterRe,send(message)将消息发送出去,那这个调用背后又做了什么事情呢?NetrvRocEnv中send的实现如下:

可以看到,当前发送地址(nettyEnv.address),目标的master地址(this)和发送的消息(SendHeartbeat)被封装成了RequestMessage消息,如果是远程rpc调用的话,最终send将调用postToOutbox函数,并且此时消息会被序列化成Byte流。

- 在postToOutbox函数中,消息将经过0utboxMessage中的sendWith方法(client.,send(content)),最终通过Transportdlient的send方法(client.send(content)),而在TransportClient中将消息进一步封装,然后发送给master。

- 在master端TransportRequestHandler的handle方法中,由于心跳信息在worKer端被分装成了OneWayMessage,所以在该handle方法中,将调用
processOneWayMessage进行处理。

- processOneWayMessage函数将调用rpcHandler的实现类NettyRpcEnv中的receive方法。在该方法中,首先通过intealRecieve将消息解包成
RequestMessage。然后该消息通过dispatcher的分发给对应的endpoint。

- 那消息是怎么分发的呢?在Dispatcher的postMessage方法中,可以看到,首先根据对应的endpoint的EndpointData信息(主要是该endpoint及其应用以及其信箱(inbox)),然后将消息塞到给endpoint(此例中的master)的信箱中,最后将消息塞到recievers的阻塞队列中。

- 那队列中的消息是怎么被消费的呢?在Dispatcher中有一个线程池threadpool在MesageLoop类的run方法中,将receivers中的对象取出来,交由信箱的
process方法去处理。如果没有收到任何消息,将会阻塞在take处。

- 在inbox的process方法中,首先取出消息,然后根据消息的类型(此例中是oneWayMessage),最终将调用endpoint的receiver方法进行处理(也就是
master中的receive方法)。至此,整个一次rpc调用的流程结束。

更多推荐
所有评论(0)