RPC项目UML结构图
2022-04-06 11:01:10 14 举报
Java版RPC项目UML结构图,方便大家理解RPC项目。
作者其他创作
大纲/内容
RandomLoadBalancer
+ select(List<Instance> instances) : Instance
ChannelProvider
MessageTobyteEncoder
ObjectWriter
+ MAGIC_NUMBER : int
Netty框架的一部分,用于管道信息的解码
RequestHandler类先通过ServiceProvider找到该接口的实现类。然后通过反射获取该实现类与客户端传来的rpcRequest中对应的method,通过method.invoke调用方法,返回结果
通过接口类的名称找到一个注册了该接口类的host地址的port端口
RpcMessageChecker
+ interfaceName : String
客户端入口: 定义一个RpcClient对象,将该对象传入代理类中。
核心是channelRead0方法,该方法通过检测客户端与服务端建立的channel中的信息,如果检测到有信息时,就自动调用该方法获取信息。一般服务端返回的都是一个RpcResponse对象,因为RpcResponse对象与RpcRequest对象的id一一对应,所有现在我们拿到了某个request对象的结果,可以根据其id去UnprocessedRequests里面根据id找到对应的Completable对象,调用该对象的complete方法为其传入结果,代表该任务已经完成。
Netty框架的一部分,用于对管道中的信息进行处理。channelRead0方法通过调用requestHandler.handle()来对管道中的RpcRequest进行处理。其余两个方法分别是应对处理信息过程中出现异常和发送心跳检查客户端是否还活跃。
Netty框架中的一部分,用于管道中的信息编码
同NettyServer,我们先会去调用构造方法给成员变量赋值。同样通过serviceProvider和serviceRegistry变量把当前模块的标注@Service注解的实现类注册到host地址的port端口上,并且完成与接口类绑定。初始化完成后,调用start方法:程序去监听一个host地址的port端口,当检测到有客户端连接时,立即创建一个Runnable对象(对象存有requestHandler请求处理器,定义的序列化器以及客户端的IP地址与接口)放入线程池中进行处理。
InetSocketAddress其实就是一个host和port对象,代表IP地址与端口。register方法就是把接口类的全限定名(如java.util.Scanner) 注册到IP地址为host的主机的port端口上
SocketRequestHandlerThread
+ requesthandler : RequestHandler+ socket : Socket+ serializer : CommonSerializer
+ run() : void
InvocationHandler
JsonSerializer
+ objectMapper : ObjectMapper
实现RpcServer接口,并且是一个抽象类,在该抽象类上面定义好scanServices()的实现,方便子类直接可以调用。且还可以在抽象类中提前定义好非private的属性(成员变量),子类可以继承父类中非private修饰的成员变量。
ObjectReader
+ readObject(InputStream in)
CommonDecoder
+ MAGIC_NUMBER : int
ServiceDiscovery
+ lookupService(String serviceName) : InetSocketAddress
SocketClient
+ serviceDiscovery : ServiceDiscovery+ serializer : CommonSerializer
+ sendRequest(RpcRequest rpcRequest) : Object
NacosServiceRegistry
NettyServer
+ serializer : CommonSerializer
把T service(即是标注了@Service注解的实现类)与接口类绑定,存到一个map中,到时候可以通过接口类找到实现类
用ObjectReader获取客户端socket对应的inputStream中的RpcRequest对象。调用requestHandler.handle()方法对RpcRequest对象进行处理。最后将处理后的结果用ObejctWriter输入到客户端socket对应的outputStream中。
NettyClientHandler
+ unprocessedRequests : UnprocessedRequests
NettyClient
+ serviceDiscovery : ServiceDiscovery+ serializer : CommonSerializer+ unprocessedRequest : UnprocessedRequests
+ sendRequest() : CompletableFuture<RpcResponse>
LoadBalancer
+ select(List<Instance> instances) : Instance
SimpleChannelInboundHandler<RpcResponse>
RandRobinLoad
+ index : int
Runnable
NacosUtil
+ SERVER_ADDR : String+ address : InetSocketAddress+ servicesName : Set<String>+ namingService : NamingService
序列化接口。无论是通过Netty框架还是Socket传输数据,都需要对请求和响应做序列化与反序列化处理。
ServiceRegistry
CommonEncoder
ServiceProviderImpl
先根据NacosUtil找到注册了该接口类的所有端口,通过选择的负载均衡策略选择其中一个返回。
KryoSerializer
+ kryoThreadLocal : ThreadLocal<Kryo>
NacosServiceDiscovery
+ loadBalancer : LoadBalancer
RpcClientProxy
+ client : RpcClient
ReplayingDecoder
RpcClient
+ DEFAULT_SERIALIZER : int+ sendRequest : Object
CommonSerializer
RpcServer
服务端入口: 通过创建 一个RpcServer实例,调用它的start方法即可以启动服务端
该类是在Netty框架下与接口类所在的端口建立channel,同时完成对该channel的初始化,包括序列化的方式,对channel中信息的处理操作以及产生异常的操作等
SimpleChannelInboundHandler<RpcRequest>
RequestHandler
+ serviceProvider : ServiceProvider
AbstractRpcServer
+ host : String+ port : int+ serviceRegistry : ServiceRegistry+serviceProvider : ServiceProvider
当定义的是一个NettyClient对象时:先建立一个CompletableFutrue对象用于储存请求的结果。然后与接口类所在的端口建立channel,往channel中传输RpcRequest,最后NettyClientHandler类会把结果储存Futrue对象中,返回Futrue对象。最后通过futrue对象的get方法获取Response对象。
当定义的是一个SocketClient对象时,通过serviceDiscovery找到一个注册了该接口类的端口后,与该端口建立socket连接,获取该socket对应的outputStream和inputStream,然后通过ObjectWriter将rpcRequest传输到outputStream,最后通过ObjectReader从inputStream获取结果。
该类是java8的新类,实现了Futrue接口。Futrue接口类在调用get方法的时候,会阻塞当前线程,直到任务完成,得出结果的时候,才继续执行当前线程后面的代码。而CompletableFutrue类可以相当于创建一个新的守护线程在其默认的ForkJoin线程池中运行,而当前线程仍可以继续运行后面的代码,当守护线程的程序代码运行完后会主动执行回调函数。这样我们就从不断地去询问完成了没,得出结果了没转换成它任务完成了再来通知我们的声明式编程。但是该RPC框架中并没有用到该特性,依然是通过其get方法获取结果,依然在没有得出结果前会阻塞。
判断返回的结果是否为空,判断是否是成功的代码,判断响应与请求的编号是否相同等。
ServiceProvider
通过传入的接口类获取其代理对象,当调用代理对象的方法时,就会去走invoke方法,走invoke方法的逻辑。在invoke方法里面就可以根据RpcClient的不同实现方式去选择调用其对应的sendRequest()方法。
SocketServer
+ threadPool : ExcecutorService+ serializer : CommonSerializer+ requesthandler : RequestHandler+ serviceProvider : ServiceProvider+ serviceRegistry : ServiceRegistry
+ start() : void
NettyServerHandler
+ requestHandler : RequestHandler
NamingService类是提供给使用者的接口,相当于一个服务注册中台(表)吧,记录了一个服务表中所有的服务,以及该服务注册在哪个地址与接口上。分别实现了注册服务,根据接口获取所有注册了该接口的端口,以及清空注册表
CompletableFuture
UnprocessedRequests
收藏
0 条评论
下一页