flink源码分析--RPC通信过程分析
flink的通信框架基于akka,但是不懂akka也关系不大。
首先介绍几个概念,大家记住名字和对应的作用:
xxxGateway:在flink中就是一个用来告诉调用者,xxx具有哪些方法可以调用的一个接口类。比如JobMasterGateway就是用来告诉所有需要调用JobMaster的用户,我JobMaster类只有比如10个方法,假设是start(),pause(),stop().........等十个方法,别的方法你就别调用了,调了也不通。我只有xxxGateway中定义过的方法。有点像thrift定义一些方法的过程吧。
xxxEntrypoint: 就是一个终端的意思。类比一个手机。JobMaster、ResourceManager这些都被抽象成一个终端了。
RpcService: 就是一个后台服务。类似手机里的后台一直在运行的程序,不是明面上的程序。类似我们微信的后台监听新消息服务,一直运行在后台,当有人发消息给你的时候,这个后台服务就可以拉起前台的程序。RpcService没啥作用,就是内部包装了一些对象,比如Server对象,启动的时候一起把这些对象都一并启动了。
RpcServer:这个和上面的Service有点像,别搞混淆。这个Server是更小的一个被Service包含的小程序。Service对象内含有一个server对象。当启动Service时候,会顺便启动Server。Server的职责是处理远程调用和本地调用。RpcServer是干实事的哈。RpcServer中还包含了很重要的AkkaRpcActor类,这个类是具体来传递消息的类。就是包装了一下akka的原生actor。
第一步:
调用RpcService的start方法,启动RpcService。
启动RpcService的过程中,会启动RpcServer。
启动了RpcServer后,整个Entrypoint对外就开放了一些gateway中定义好的端口了。(虽然暴露的端口代码在Server,但是对外来说,Server是包含在Entrypoint里的,就好像虽然提供服务的是你的手机的小程序,但是对外界看来,是你的手机向外暴露了一些端口。这里小程序就是Server,Entrypoint就是手机终端)
紧接着,调用发起者就可以通过自己的RpcService的connect方法来向别的已经启动好的终端发起服务调用了,其实是去调用对方的Entrypoint内部的Server类。然后对方的server类表示我的类不是随便调用的,会返回一个Gateway对象给调用方,调用方后续要调用就调用这个Gateway中声明好的方法。
这时候,调用方已经通过connect方法拿到了要调用的终端的Gateway。这样就可以通过调用Gateway的方法间接调用对方终端的Server方法了。(其实实际返回的是名为AkkaInvocationHandler的类,这个类也是RpcGateway的一个实现类。)
当调用发起方通过Gateway调用对方的方法时,实际调用的是对方的AkkaInvocationHandler的invoke方法,invoke()方法内部会根据请求的来源来决定是走invoke()还是invokeRPC()方法。如果是远程的调用,就走RemoteRpcInvocation()方法,如果是本地调用的,就走LocalRpcInvocation()方法。然后还根据是否需要返回值,决定是调用底层akka的tell()方法还是ask()方法。如果需要返回值就ask,如果不需要就tell。
然后如果对方要的返回值是CompetableFutere对象,就直接返回Future对象,不需要阻塞。否则就需要阻塞等待调用结果,然后把调用结果返回给调用方。