一个最简单的RPC服务流程(三)

简介: 一个最简单的RPC服务流程(三)

服务端的实现



  1. 服务端用到的技术点:注解+反射+socket通信+zookeeper。
  2. 注解主要是扫描有那些提供服务的接口实现。
  3. 反射主要依靠远程客户端调用提供的类的信息进行反射调用。
  4. zookeeper的节点数据结构再上篇已经介绍了,主要是提供调用类的服务端IP+端口地址暴露


服务端提供的服务流程


  1. 定义一个注解


@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Component
public @interface RpcService {
  String version() default "";
}
复制代码


  1. 初始化扫描提供服务的类信息


Map<Strng, Object> beans = applicationContext.getBeansWithAnnotation(RpcService.class);
复制代码


  1. 根据扫描保存一些服务提供的类,和再zk上写入对外服务暴露的地址

数据格式如下:

request:: '/PINGPANG_REGIST_SERVER/com.pingpang.test.Test,F response:: v{'127.0.0.1:18868}


服务端提供的socket服务


  1. socket服务端,客户端主要是用netty实现的。
  2. 客户端服务端传输的协议这里主要借助了netty对象的序列化编解码,
    下面是定义了一些序列化的工具


public enum CodeUtilEnum {
        HESSIAN(new HessianCodeUtil()),
        JSON(new JSONCodeUtil()),
  PROTOSTUFF(new ProtostuffCodeUtil());
  public final MessageCodecUtil serializer;
  private CodeUtilEnum (MessageCodecUtil serializer) {
        this.serializer = serializer;
    }
}
复制代码


这里主要是序列化的填充


//创建NIOSocketChannel成功后,在进行初始化时,将它的ChannelHandler设置到ChannelPipeline中,用于处理网络IO事件
                            protected void initChannel(SocketChannel channel) throws Exception {
                                ChannelPipeline pipeline = channel.pipeline();
                                pipeline.addLast(new IdleStateHandler(0, 0, 60));
                                //序列化定义
                                pipeline.addLast(new NettyDecoder(RequestBean.class, codeUtil));
                                //序列化定义
                                pipeline.addLast(new NettyEncoder(ResponseBean.class, codeUtil));
                                pipeline.addLast(businessGroup,handler);
                            }
复制代码


没有用想象中的协议(定义协议的开头有多少位是整个协议的长度,后面是一大堆字符串类的;这里可能跟序列化有关系,后台屏蔽了协议的一些东西)

服务端的启动是借助springboot启动了一个线程。


服务端响应客户端的请求


  1. 服务端根据传递过来的信息进行服务调用,主要就是反射(传输过来的数据基本上就是反射需要的数据信息)


/**
     * 通过反射,执行本地方法
     * @param request
     * @return
     * @throws Throwable
     */
    private  Object handler(RequestBean request) throws Throwable{
        String className = request.getClassName();
        Object serviceBean = serviceMap.get(className);
        if (serviceBean!=null){
            Class<?> serviceClass = serviceBean.getClass();
            String methodName = request.getMethodName();
            Class<?>[] parameterTypes = request.getParameterTypes();
            Object[] parameters = request.getParameters();
            Method method = serviceClass.getMethod(methodName, parameterTypes);
            method.setAccessible(true);
            return method.invoke(serviceBean, parameters);
            //return method.invoke(serviceBean, getParameters(parameterTypes,parameters));
        }else{
            throw new Exception("未找到服务接口,请检查配置!:"+className+"#"+request.getMethodName());
        }
    }


相关文章
|
7月前
|
Dubbo Cloud Native 网络协议
【Dubbo3技术专题】「服务架构体系」第一章之Dubbo3新特性要点之RPC协议分析介绍
【Dubbo3技术专题】「服务架构体系」第一章之Dubbo3新特性要点之RPC协议分析介绍
100 1
|
2月前
|
存储 前端开发 JavaScript
前端的全栈之路Meteor篇(四):RPC方法注册及调用-更轻量的服务接口提供方式
RPC机制通过前后端的`callAsync`方法实现了高效的数据交互。后端通过`Meteor.methods()`注册方法,支持异步操作;前端使用`callAsync`调用后端方法,代码更简洁、易读。本文详细介绍了Methods注册机制、异步支持及最佳实践。
|
7月前
|
网络协议 JavaScript 前端开发
性能工具之Jmeter压测Hprose RPC服务
【5月更文挑战第19天】性能工具之Jmeter压测Hprose RPC服务
85 5
|
7月前
|
JSON JavaScript Java
性能工具之Jmeter压测Thrift RPC服务
【5月更文挑战第21天】性能工具之Jmeter压测Thrift RPC服务
121 1
|
7月前
|
负载均衡 Dubbo Java
最简最快了解RPC核心流程
本文主要以最简易最快速的方式介绍RPC调用核心流程,文中以Dubbo为例。同时,会写一个简易的RPC调用代码,方便理解和记忆核心组件和核心流程。
最简最快了解RPC核心流程
|
7月前
|
XML JSON 网络协议
RPC远程服务如何调用
【2月更文挑战第12天】一个完整的 RPC 调用框架包括:通信框架、通信协议、序列化和反序列化三部分。
|
7月前
|
Java fastjson 数据安全/隐私保护
【Dubbo3技术专题】「云原生微服务开发实战」 一同探索和分析研究RPC服务的底层原理和实现
【Dubbo3技术专题】「云原生微服务开发实战」 一同探索和分析研究RPC服务的底层原理和实现
164 0
|
7月前
|
Go
Go语言RPC实战:打造自己的远程调用服务
Go语言RPC实战:打造自己的远程调用服务
163 0
|
Dubbo Java 应用服务中间件
为什么大厂用的都是RPC服务
在很久以前,笔者刚毕业开始工作那会儿,对于企业开发的模式一直以为HTTP接口开发,也就是我们常说的RESTful风格的服务接口。的确,对于在接口不多、系统与系统交互较少的情况下,解决信息孤岛初期常使用的一种通信手段;优点就是简单、直接、开发方便。
220 1
|
网络协议 网络安全 虚拟化
在 Hyper-V 虚拟机中更新组策略时出现 RPC 服务不可用的错误
在 Hyper-V 虚拟机中更新组策略时出现 RPC 服务不可用的错误
287 3