实现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记录/限流等功能,欢迎持续关注!


		
		
		

还没有评论,来说两句吧...