rpc与http区别

几年前对于Java技术栈的各种术语傻傻分不清楚,包括但不限于rpc,http,netty,dubbo,thrift,tomcat,长短链接,rest,socket等等,当然这些术语并不是一个层面上的。现在稍微清楚了一些,记录一下。

简单归类

osi七层模型应用层协议:http
远程方法调用:rpc 跨越了传输层和应用层
rpc框架:dubbo,thrift,gRpc,rmi
网络框架:netty
web服务器:tomcat
java网络基础:Socket 长短链接
资源服务命名风格:rest
http客户端: Spring Resttemplate ,OkHttpclient,HttpURLConnection
spi:“基于接口的编程+策略模式+配置文件”组合实现的动态加载机制
动态代理:jdk(生成具体的字节码Class文件是调用了ProxyGenerator类的generateProxyClass方法,传入InvocationHandler实例去构造一个代理类的实例),cglib,javaassit(通过直接操作字节码来生成代理对象, 不需要定义代理类),ASM
消息通信机制:同步(等待返回结果) 异步(调用发出后直接返回- Future 回调)
“阻塞”是指进程在发起了一个系统调用(System Call) 后, 由于该系统调用的操作不能立即完成,需要等待一段时间,于是内核将进程挂起为等待 (waiting)状态, 以确保它不会被调度执行, 占用 CPU 资源,调度其他进程的运行, 等到 它所请求的 I/O 操作完成了以后, 再将其状态更改回 ready
IO:操作系统内核在执行 System Call 时, CPU 需要与 IO 设备完成一系列物理通信上的交互,等待IO设备返回结果
bio— socket 的accept()和read操作会阻塞当前线程,客户端连接或者发送数据后线程继续执行
nio- 服务端channel注册到selector集合中,监听op_accept事件(同时该事件会关联当前的服务端channel和selector),Linux底层使用epoll selector为事件集合,
当连接事件发生时新建socketchannel并注册到elector,监听op_read事件
selector的select方法实际阻塞时间是否达到设置的时间,如果小于发生了空轮询
线程:虚拟机中的线程状态,不反应任何操作系统线程状态 无论是Timed Waiting ,Waiting还是Blocked,对应的都是操作系统线程的waiting(等待**)状态。而Runnable状态,则对应了操作系统中的ready和running状态

rpc 远程方法调用

是一个计算机通信协议,调用协议包含传输协议和序列化协议,dubbo,thrift都是rpc框架。服务器A远程请求请求服务器B的方法,那么完成一次prc调用需要什么呢?

  1. 最底层需要有网络传输。
    比如Dubbo 协议默认使用 Netty 作为基础通信组件,用于实现各进程节点之间的内部通信,Netty 是一个基于 JAVA NIO 类库的异步通信框架。Netty核心组件包括网络相关Channel,EventLoop,数据处理相关ChannelPipeline,ChannelHandler
    Tomcat是一个开源的Java Servlet容器。Tomcat实现了一些Java EE规范,包括Servlet,JSP,Java EL和WebSocket;同时提供了一个纯Java的HTTP Web服务运行环境,类似的还有jetty,resin等。Tomcat获取Socket数据包之后,解析HTTP协议,翻译成Tomcat内部的Request和Response对象,再映射相应Container。整个架构包括Server-Service-Enginee/Connector等,Tomcat可以使用APR来提供超强的可伸缩性和性能,更好地集成本地服务器技术。
    Dubbo 缺省协议采用单一长连接 通过单一连接,保证单一消费者不会压死提供者,长连接,减少连接握手验证等,并使用异步IO,复用线程池,防止C10K问题
    单连接、多连接 长、短连接
    客户端Request通过AtomicLong生成的当前进程全局唯一id,服务端响应回传该id;
    客户端通过FUTURES静态ConcurrentHashMap保存调用id和异步结果DefaultFuture之间的关系,服务端响应时,查询根据Response的回传请求id,获取该response对应的DefaultFuture,通过await和signal机制实现请求发起线程和结果获取线程之间的通信,最终请求发起线程得到最终的结果
    服务提供方 NettyServer 使用两级线程池,其中 EventLoopGroup(boss) 主要用来接受客户端的链接请求,并把接受的请求分发给 EventLoopGroup(worker) 来处理,boss 和 worker 线程组我们称之为 IO 线程

  2. 通信协议。协议是两个网络实体通信的基础。数据从机器A传递到机器B,如果没有协议就无法将 一维的字节流重塑为数据结构或者领域对象。dubbo协议介绍 。dubbo框架除了默认的dubbo协议(自定义二进制协议)还支持其他协议,包括http(基于spring httpinvoker)等。
    协议可以按需求使用。dubbo的spi支持依赖注入,aop以及获取单个实现类 @adaptive @Spi

  3. 序列化协议。序列化方式包括java原生,hessian,json,protobuf等。hessian使用时要注意父类和子类不能有同名属性;如果一个对象继承于HashMap,并且增加属性,这些增加的属性不会被序列化;serialVersionUID被无视的–修改了serialVersionUID,仍然能解析出来

  4. 执行调用。 效率提升,线程池; 单个请求耗时过长;client端超时之后,服务端处理?
    dubbo的调用方式:同步调用、异步调用,参数回调,事件通知( Consumer 端在调用之前、调用之后或出现异常时,触发 oninvoke、onreturn、onthrow 三个事件)

  5. 注册中心。consumer需要有provider提供的接口类,发起调用时经过路由和负载均衡策略获取到provider的地址。
    服务暴露:RegistryProtocol DubboProtocol,服务方法的地址包装成DubboExporter,创建服务器NettyServer,启动服务器并监听端口,将地址和ProviderInvokerWrapper保存在map中,服务地址同时保存到注册中心。

    服务引用:ReferenceBean是一个工厂bean,spring注入被调用接口时,工厂bean的getObject方法返回对象实例,根据注册中心地址服务地址创建客户端以及初始化客户端,连接服务端,保存订阅url地址和代理对象到map

    服务调用:Filter,调用失败策略,AbstractClusterInvoker,负载均衡,根据负载均衡策略选择invoker执行DubboInvoker,使用nettyclient发起请求获取结果并返回,超时以及重试

  6. 监控中心,请求次数以及耗时统计,服务提供者权重配置以及请求失败策略

参考:
https://blog.csdn.net/lengxiao1993/article/details/78154467
https://waylau.gitbooks.io/netty-4-user-guide/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值