实现consumer端通过接口类来调用远程服务,主要核心在于使用动态代理和反射,这里就一步一步来实现。
这里贴出github代码地址,想直接看代码的可以直接下载运行:https://github.com/whiteBX/wrpc
首先来看consumer端代码,RPCConsumer完整代码如下:
* url处理器
urlHolder
* netty客户端
nettyClient
* 远程调用
*
appCode param
serverIp urlHolderappCode
serverIp
out
clientHandler
clientHandlerparam
nettyClientserverIp clientHandler
result clientHandler
out serverIp param result
result
e
out e
* 获取代理类
clazz appCode
clazz clazz
proxy method args
param JSONargs
beanMessage BEAN_STRING clazz
method method
JSONappCode beanMessageparam method
这里getBean方法主要是通过动态代理来获取代理类,传入的就是我们自己的Service的接口类,其中绑定了InvocationHandler来在调用接口类的方法时执行对应的远程调用操作,包括远程调用包装和返回值解析.
接下来看provider相关类,在RPCProvider类中新增服务注册方法,将我们自己的Service注册进系统缓存:
* netty客户端
nettyClient
* zookeeper客户端
zkClient
server port
nettyClientport
zooKeeper zkClientZK_CONNECTION_STRING
ZK_SESSION_TIME_OUT
serverIp server COMMOA port
zkClientzooKeeper APP_CODE serverIp
* 注册服务提供者
clazz obj
clazz obj
其中的ProviderBeanHolder类代码如下,主要负责缓存服务注册信息:
* bean注册缓存
providerList
* 注册
clazzName obj
providerListclazzName obj
out clazzName
* 获取
clazzName
providerListclazzName
接下来来看RpcServerNettyHandler类,这个类负责接收客户端请求并处理,这里通过反射来调用服务注册的方法。
ctx msg
out msg
splitParam msgDOLLAR_SPLIT
beanMessage splitParamSHARP_SPLIT
object beanMessage
object
out beanMessage
paramType beanMessage
method objectbeanMessage paramType
response methodobject JSONsplitParam paramType
ctxJSONresponse
e
out
这里主要就是用到了反射相关的知识,实现了服务的调用和响应,到这里相关的代码就实现了,下面来写个service测试一下:
seq
content
code
message
request
request
out request
response
response
response request
response
测试代码如下:
args
provider
provider
provider
provider
provider
provider
provider
MAX_VALUE
args
consumer
helloService consumer APP_CODE
i
request
requesti
helloResponse helloServicerequest
out JSONhelloResponse
MAX_VALUE
执行结果如下:
zookeeper连接成功
临时节点创建成功:registry
zookeeper连接成功
临时节点创建成功:registry
zookeeper连接成功
临时节点创建成功:registry
zookeeper连接成功
临时节点创建成功:registry
zookeeper连接成功
临时节点创建成功:registry
注册provider:
服务端收到请求#hello#$
服务端收到请求序列号
服务端收到请求#hello#$
服务端收到请求序列号
服务端收到请求#hello#$
服务端收到请求序列号
zookeeper连接成功
调用服务器请求参数#hello#$响应参数
客户端收到响应
调用服务器请求参数#hello#$响应参数
客户端收到响应
调用服务器请求参数#hello#$响应参数
客户端收到响应
此时修改Provider类里的端口,重新启动4个服务,可以看到客户端有如下日志:
zookeeper连接成功zookeeper连接成功
zookeeper连接成功
zookeeper连接成功
调用服务器请求参数#hello#$响应参数
客户端收到响应
调用服务器请求参数#hello#$响应参数
客户端收到响应
调用服务器请求参数#hello#$响应参数
客户端收到响应
调用服务器请求参数#hello#$响应参数
客户端收到响应
调用服务器请求参数#hello#$响应参数
客户端收到响应
调用服务器请求参数#hello#$响应参数
可以看到,新增了服务,客户端什么都不用改,就能连接到新的服务,此时关闭新启的服务,会发现客户端会访问剩余的服务,不会出现任何问题。
到这里就实现了RPC框架的自己注册bean并通过接口调用.
后续将一步一步实现负载均衡/调用链路Trace记录/限流等功能,欢迎持续关注!
还没有评论,来说两句吧...