在SOA和微服务架构中,远程通信是无法避免的,最常用的远程通信有两种方式:
restful的接口,使用Http通信
使用dubbo或是Spring Cloud组件进行
RPC协议远程调用,可选地使用socket通信
用 RPC准没错?
不同的人对
一为语义化的
RPC。没有统一的请求规范,数据格式在开发人员中很难达成一致,在使用传统Http调用时,交互的双方需要约定一份“API文档”以保证数据格式的唯一性,这样API格式本身就成为了一道大墙,耽误研发双方的时间。但如果服务间采用语义化 RPC进行交互,双方可能并不需要一份文档,只要一份约定好的代码,并以此作为双方的依赖,在请求时也仅仅是直接调用方法本身,如此强的语义性怎能让人不爱。语义化 RPC的背后其实仍旧是被封装的Http请求调用,但接口本身的定义已经不重要,约定都体现在了封装方法定义上。 二为真正的
RPC,Http请求要经过七层协议,有一套复杂的序列化和握手过程,其数据包封装本身其实已经有大量的损耗了,通过自定义协议,可以约定不同的序列化方式,从而达到真正的 RPC,可能只需走四层协议,由于数据包更小,服务间通过此种方式通信可能会有更高的性能和吞吐量。
语义化
为了解决请求的约定不一致问题,除去
语义化 RPC-OpenFeign
语义化
在SpringBoot中集成OpenFeign
暂且忽略客户端负载均衡层面,假定服server端已经注册上去了。我们只要在启动类添加注解:
@EnableFeignClients @EnableDiscoveryClient
然后便可以封装接口的调用,path即为项目的接口根目录(context-path),value为server注册的服务名,接口部分只需要与server服务中代码保持一致即可:
@FeignClient(value = "server1",path = "/") public interface TestCustFeignClient { @RequestMapping("/demo") @ResponseBody public String demo(@RequestParam String param); }
这样直接调用demo方法,便可进行远程调用,封装了调用的细节。
本质的 RPC-Dubbo(版本略有过时)
Dubbo是阿里巴巴提供的服务化治理框架,它省略了API方式调用的API侵入,并且通过一个注册中心实现服务的注册与发现,流程架构图为:
dubbo需与Spring共同使用,当provider在注册中心注册了一个服务(Sevice)后,consumer中可以申请获取这个Service,它将作为一个bean存在于项目中。
Dubbo的基本配置
<!-- 使用dubbo发布服务 --> <!-- 提供方应用信息,用于计算依赖关系,无关provider还是consumer --> <dubbo:application name="provider" /> <!-- 注册dubbo的服务 ,注册中心可以有多个 --> <dubbo:registry protocol="zookeeper" address="192.168.25.137:2181" /> <!-- 各配置项缺省值设置 --> <dubbo:provider retries="0" timeout="20000" /> <!-- 表明用dubbo协议在20880端口暴露服务 --> <dubbo:protocol name="dubbo" port="20880" /> <!-- 声明需要暴露的服务接口,作为provider --> <dubbo:service interface="cn.XXXX.service.ItemService" ref="itemServiceImpl" timeout="600000" /> <!-- 引用服务配置,用于创建一个远程服务代理,一个引用可以指向多个注册中心。--> <dubbo:reference id="demoService" interface="com.unj.dubbotest.provider.DemoService" />
接下来详细说一下这些配置项的参数,注意有一些共通的参数:
-Dubbo:service
interface:服务接口名,必填项,指向具体的class
ref:服务的实现引用(实现类),必填项,类名并且首字母小写
group:服务分组
version:服务版本
registry:指定注册中心,使用","分割多个注册中心的id,"N/A"表示空,默认向所有中心注册
timeout:设定超时时间(ms),默认1000
retries:重试次数(不重试为0,默认为2)
protocol:引用的协议,对应protocol的id
-Dubbo:reference
id:服务的bean id,必填项,作为bean的id
interface:服务的接口名,必填项,是服务提供方的接口的首字母小写类名
registry、group、version、timeout、retries
check:检查是否存在服务,为true会报错,反之忽略
-Dubbo:protocol
name:协议名称,必填项
port:端口,默认20880
id:协议的id,默认dubbo
-Dubbo:registry
address:注册中心地址,含端口,必填项,默认端口9090
port:服务端口,根据协议不同有不同的默认端口
protocol:注册中心地址协议,默认dubbo,还有html、local协议
-Dubbo:application
name:当前应用的名称,必填项
-Dubbo:provider
id:可在service的provider中引用id值