背景
各个服务应用,有很多restful api,不论是用哪种方式发布,部署,注册,发现,有很多场景需要各个微服务之间进行服务的调用,大多时候返回的json格式响应数据多,如果是前端直接调用倒没有什么大的问题,可是如果后台之间的服务调用,如果返回一坨json数据,再去拼写一边逻辑,是不是很繁琐,很烦,如何解决这个问题,服务调用这个技术产生了。
像调用本地程序一样调用远程的服务,是不是很爽,所谓的rpc需要了解。
当然这里只是举了一个json格式的例子,其实业界有很多服务接口,比如Webservicie。
基本概念
RPC & REST
微服务之间的接口调用通常包含两个部分,序列化和通信协议。常见的序列化协议包括json、xml、hession、protobuf、thrift、text、bytes等;通信比较流行的是http、soap、websockect,RPC通常基于TCP实现,常用框架例如dubbo,netty、mina、thrift。
REST:严格意义上说接口很规范,操作对象即为资源,对资源的四种操作(post、get、put、delete),并且参数都放在URL上,但是不严格的说Http+json、Http+xml,常见的http api都可以称为Rest接口。
RPC:即我们常说的远程过程调用,就是像调用本地方法一样调用远程方法,通信协议大多采用二进制方式。RPC:Remote Procedure Call(远程过程调用) 是一个计算机通信协议,这个协议允许运行于一台计算机的程序调用另一台计算机的子程序,程序员不用再为这个交互编写程序;
类似的是RMI(Remote Methods Invoke 远程方法调用)
实现远程调用其他服务;
- 像调用本地服务一样去调用远程的服务;
RPC强调的是过程调用,调用的过程对用户而言是应该是透明的,用户不用去关心调用的细节,可以像调用本地服务一样调用远程服务;所以RPC一定要对调用的过程进行封装;
RPC的网络通讯协议: RPC采用的是TCP作为底层的传输协议
RPC的数据传输格式:
两个程序间进行通讯,必须要约定好数据传输格式,必须定义好请求和响应的格式。
数据在网络中传输需要进行序列化,所以需要约定统一的序列化方式。
RPC框架有哪些
RPC框架有:dubbo、webservice(cxf)、hessian(RMI远程方法调用,比较轻量)
HTTP vs 高性能二进制协议
HTTP相对更规范,更标准,更通用,无论哪种语言都支持HTTP协议。如果你是对外开放API,例如开放平台,外部的编程语言多种多样,你无法拒绝对每种语言的支持,相应的,如果采用HTTP,无疑在你实现SDK之前,支持了所有语言,所以,现在开源中间件,基本最先支持的几个协议都包含RESTful。
RPC协议性能要高的多,例如Protobuf、Thrift、Kyro等,(如果算上序列化)吞吐量大概能达到http的二倍。响应时间也更为出色。千万不要小看这点性能损耗,公认的,微服务做的比较好的,例如,netflix、阿里,曾经都传出过为了提升性能而合并服务。如果是交付型的项目,性能更为重要,因为你卖给客户往往靠的就是性能上微弱的优势。
所以,最佳实践一般是对外REST,对内RPC,但是追求极致的性能会消耗很多额外的成本,所以一般情况下对内一般也REST,但对于个别性能要求较高的接口使用RPC。
Feign
Netflix Feign 是 Netflix 公司发布的一种实现负载均衡和服务调用的开源组件。Spring Cloud 将其与 Netflix 中的其他开源服务组件(例如 Eureka、Ribbon 以及 Hystrix 等)一起整合进 Spring Cloud Netflix 模块中,整合后全称为 Spring Cloud Netflix FeignFeign 对 Ribbon 进行了集成,利用 Ribbon 维护了一份可用服务清单,并通过 Ribbon 实现了客户端的负载均衡。
Feign 是一种声明式服务调用组件,它在 RestTemplate 的基础上做了进一步的封装。通过 Feign,我们只需要声明一个接口并通过注解进行简单的配置(类似于 Dao 接口上面的 Mapper 注解一样)即可实现对 HTTP 接口的绑定。通过 Feign,我们可以像调用本地方法一样来调用远程服务,而完全感觉不到这是在进行远程调用。
Feign 支持多种注解,例如 Feign 自带的注解以及 JAX-RS 注解等,但遗憾的是 Feign 本身并不支持 Spring MVC 注解,这无疑会给广大 Spring 用户带来不便。
OpenFeign
2019 年 Netflix 公司宣布 Feign 组件正式进入停更维护状态,于是 Spring 官方便推出了一个名为 OpenFeign 的组件作为 Feign 的替代方案。
OpenFeign 全称 Spring Cloud OpenFeign,它是 Spring 官方推出的一种声明式服务调用与负载均衡组件,它的出现就是为了替代进入停更维护状态的 Feign。
OpenFeign 是 Spring Cloud 对 Feign 的二次封装,它具有 Feign 的所有功能,并在 Feign 的基础上增加了对 Spring MVC 注解的支持,例如 @RequestMapping、@GetMapping 和 @PostMapping 等。
官方已经宣布停止更新Feign组件,所以可以使用OpenFeign进行代替
Feign 和 OpenFeign 都是 Spring Cloud 下的远程调用和负载均衡组件。
Feign 和 OpenFeign 作用一样,都可以实现服务的远程调用和负载均衡。
Feign 和 OpenFeign 都对 Ribbon 进行了集成,都利用 Ribbon 维护了可用服务清单,并通过 Ribbon 实现了客户端的负载均衡。
Feign 和 OpenFeign 都是在服务消费者(客户端)定义服务绑定接口并通过注解的方式进行配置,以实现远程服务的调用。
如何使用
参照若依的例子
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
参照 RemoteUserService.java RemoteUserFallbackFactory.java 两个类
写一个测试接口
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestUserController
{
@Autowired
private RemoteUserService remoteUserService;
/**
* 获取当前用户信息
*/
@GetMapping("/user/{username}")
public Object info(@PathVariable("username") String username)
{
return remoteUserService.getUserInfo(username);
}
}
这是基本使用,其他内容需要了解其配置,比如 负载均衡,请求传参,性能优化(GZIP、http连接池、日志、请求超时),异常配置,拦截器,innerAuth注解,参照其文档。
更多
- 关于rpc的模式和例子没有拓展
- 关于grpc的使用
- 关于C#下使用的方案
- 关于proto.actor的使用
以上内容,会在今后专门章节展开。