赞
踩
RPC是什么
Remote Procedure Call,远程过程调用。
首先来说本地方法调用,假设在main方法中调用一个本地的方法multiply(同一个进程内的方法调用)。无非是做了内存寻址和一些堆栈操作。
而假设main方法和multiply方法不在同一个进程中,两者则通过RPC的方式进行调用(通信)。由于是跨网络通信,需要考虑将方法调用和参数,如何变成网络上可传输的二进制流(涉及到参数和结果的序列化,反序列化,socket网络编程等细节)。而这就是RPC框架的意义,它帮助开发人员,屏蔽了网络编程和网络传输的细节,让开发人员像调用本地方法一样,调用远程方法。
需要注意,RPC并不是一种具体的技术框架,而是一种技术思想。
广义上讲,任何通过网络,远程调用另一个进程中的方法的技术,都可以称为RPC。
RPC并不是一个新的概念,也不是和微服务同一个时代的概念。
在微服务之前,就有很多可以称之为RPC的技术理念。比如RMI,WebService。
RMI
Remote Method Invocation。比较古老。是EJB的通信基础,是实现RPC的一套Java Api,依赖JVM,所以仅支持Java应用之间的方法调用,不能实现跨语言调用。
WebService
跨语言,跨平台。因为WebService底层依赖的是HTTP和XML,这两者都是语言无关的。
RPC有哪些具体的例子
随着时代的发展,越来越多优秀的RPC框架进入我们的视野,如
引入RPC后会给项目带来什么
当我们引入RPC框架,并对整体系统进行了微服务化的拆分。会导致:
提升系统的扩展性(优点)
提升了系统的可维护性(优点)
系统变得复杂(缺点)
引入新的组件,导致在调试代码,维护系统时会变得更加复杂
跨网络调用可能会增加性能开销(缺点)
所以,引入RPC框架对系统进行微服务化的拆分时,一定要综合扩展性,维护性,复杂度,成本,性能等多方面的考虑。需要慎之又慎。
RPC主要是为了解决服务的远程调用问题,即客户端和服务器之间的通信问题。当设计一款RPC框架时,主要有如下几个方面需要考虑
RPC调用的通信过程是怎样的?
这样就完成了一次RPC通信
需要注意处理TCP粘包的问题。解决方案通常有
通常使用第2种方式,或者第2和第3种结合的方式,来设计通信协议。
序列化,是将数据和二进制流进行相互转换的方式。
每次RPC调用,都会涉及到2次序列化和2次反序列化的过程(共4次)。
所以,选择序列化方式时需要注意,要避免让序列化成为整个RPC通信的性能瓶颈。在选择序列化方式时,需要关注:
性能
(反)序列化执行的耗时
序列化后的包的大小
因为网络带宽是一定的,选择压缩比较高的序列化方式,可以减少高并发下RPC通信对带宽的占用
可读性
类似json,xml,是可读性较强的序列化方式,它们序列化后的结果都是文本。良好的可读性,主要是便于调试和问题排查。
需要在这3者之间做取舍和权衡。
常见的序列化方式
常见的IO模型,如下
通常使用较多的是多路复用IO。异步IO还不够成熟
目前业界开源的RPC框架中,更多的都是属于服务框架,而不是单纯的RPC框架。
服务框架和RPC框架的区别在于:RPC框架只是简单的解决通信问题,而服务框架,除了解决通信问题,还需要解决服务管理的问题。
所以我们需要了解,服务治理需要解决什么问题,以及它是如何解决的。
服务治理有哪些方面?
过程
优点
选型
分布式一致性协调系统
zookeeper,etcd,consul
可以当作注册中心使用,但可能功能不是很齐全,比如无法对服务做健康检测
开源的,专门的注册中心
nacos(阿里开源),eureka(springCloud),vintage(微博使用)
功能比较完善
分布式追踪系统,主要是用于解决分布式环境下的问题排查的问题。
当我们把一个系统,拆成多个微服务之后,一次来自客户端的请求,可能会引发微服务之间的十几次,甚至几十次请求,才能得到最终的结果。
比如系统的响应时间变慢了,或者系统出了一些问题,那么我们需要知道是具体哪个微服务导致的,这就需要对整个调用链进行追踪。
分布式追踪的基本原理是:
一次来自客户端的调用,对应一个唯一的traceId,用这个traceId来标识整个完整的调用链路
用另外一个spanId来标识一次微服务的调用。通过spanId来标识微服务之间的层级关系。
比如微服务A被调用,产生一个spanId为2,A又调用了另外2个微服务B和C,产生的spanId分别为2.1和2.2。这样就能清晰的知道微服务之间调用的层级关系
对这些调用日志进行收集,进行简单的聚合操作后, 写入到NoSQL数据库中
使用traceId就可以从NoSQL数据库中跟踪整个请求的链路,并得到各个链路的耗时
注意:由于一次客户端调用会导致很多次的微服务之间的调用,所以调用日志的量是巨大的。我们可以在收集调用日志后,进行一些简单的聚合操作,来减少日志量,或者通过采样的方式,只采样1%的调用日志。
项目所使用的一些配置文件的管理。
将配置做成文件,这样是静态的配置。将配置放到一个服务上,这样可以实现动态的配置管理和更新。
配置主要分为两种:
静态配置通常放在项目的配置文件中即可,而动态的配置则通常放到配置服务中。
选型
一个系统拆成了多个服务。原本只有1个可能出现问题的点,现在变成了多个。
当系统出现未知问题,或者系统流量超出极限时,要如何应对?常见方式如下
选型
为了应对大流量,通常对于一个服务会部署多台节点。那么此时就需要将流量分配到多个服务节点。
常见负载均衡算法
从运维上对服务进行监控。
通常关注2个方面:需要监控什么?怎么监控?
服务监控的指标:
监控系统构成
以dubbo为例,进行分析
dubbo的扩展点是通过SPI(Service Provider Interface)机制实现的(借鉴了JDK的SPI机制)。dubbo会从以下目录加载实现类
META-INF/services/*
META-INF/dubbo/*
META-INF/dubbo/internal/*
格式:key=实现类的全限定名
在代码中即可通过这个key
来加载某个接口的某个特定的实现类
略
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。