## OpenFeign 通信组件 ### 服务提供方 ![](https://git.kancloud.cn/repos/owenwangwen/open-capacity-platform/raw/6bd496638277e7acc58344aa1f8d29cc9773ef10/images/screenshot_1583305352854.png?access-token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MTc4NDg4NzgsImlhdCI6MTYxNzgwNTY3OCwicmVwb3NpdG9yeSI6Im93ZW53YW5nd2VuXC9vcGVuLWNhcGFjaXR5LXBsYXRmb3JtIiwidXNlciI6eyJ1c2VybmFtZSI6Im93ZW53YW5nd2VuIiwibmFtZSI6Im93ZW4iLCJlbWFpbCI6IjYyNDE5MTM0M0BxcS5jb20iLCJ0b2tlbiI6ImI3MmI4MjM5M2M3ZDFiNjIyNDdiOGJhOTNhMjIxODlhIiwiYXV0aG9yaXplIjp7InB1bGwiOnRydWUsInB1c2giOnRydWUsImFkbWluIjp0cnVlfX19.RB0Gs3ILQ0FvYijoVYyDnsbQvJ4LqaXIOkitYKm19hU) ### 服务消费方 ![](https://git.kancloud.cn/repos/owenwangwen/open-capacity-platform/raw/6bd496638277e7acc58344aa1f8d29cc9773ef10/images/screenshot_1592989764436.png?access-token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MTc4NDg4NzgsImlhdCI6MTYxNzgwNTY3OCwicmVwb3NpdG9yeSI6Im93ZW53YW5nd2VuXC9vcGVuLWNhcGFjaXR5LXBsYXRmb3JtIiwidXNlciI6eyJ1c2VybmFtZSI6Im93ZW53YW5nd2VuIiwibmFtZSI6Im93ZW4iLCJlbWFpbCI6IjYyNDE5MTM0M0BxcS5jb20iLCJ0b2tlbiI6ImI3MmI4MjM5M2M3ZDFiNjIyNDdiOGJhOTNhMjIxODlhIiwiYXV0aG9yaXplIjp7InB1bGwiOnRydWUsInB1c2giOnRydWUsImFkbWluIjp0cnVlfX19.RB0Gs3ILQ0FvYijoVYyDnsbQvJ4LqaXIOkitYKm19hU) ## RESTful 与 RPC 的区别 在微服务定义中提道,每个小服务运行在自己的进程中,并以轻量级的机制进行通信。这里并没有明确给出具体的通信方式,只是要求以轻量级的机制进行通信,虽然作者推荐使用 RESTful 作为首选方案,但微服务间通信本身还有另一个轻量级的选择:以 Dubbo 为代表的 RPC通信方式。 那什么是 RPC 呢?RPC 是远程过程调用(Remote Procedure Call)的缩写形式,RPC 与 RESTful 最大的不同是,RPC 采用客户端(Client) - 服务端(Server) 的架构方式实现跨进程通信,实现的通信协议也没有统一的标准,具体实现依托于研发厂商的设计。 ![](https://img.kancloud.cn/9d/63/9d635a9bd68d477d1889ffea7f6649a4_873x498.png) 目前开源市场上 RPC 框架有很多,例如 GoogleRPC、Alibaba Dubbo、Facebook Thrift,每一种产品都有自己的设计与实现方案。 RESTful 与 RPC 对比 ![](https://img.kancloud.cn/77/3b/773bc931967460d80eb60b3eb2160b0e_852x451.png) RESTful 通信更适合调用延时不敏感、短连接的场景。而 RPC 则拥有更好的性能,适用于长连接、低延时系统。两者本质是互补的,并不存在孰优孰劣。在微服务架构场景下,因为大多数服务都是轻量级的,同时 90%的任务通过短连接就能实现,因此马丁福勒更推荐使用 RESTful 通信。这只是因为应用场景所决定的,并不代表 RPC 比 RESTful 落后。 ## Dubbo Dubbo 架构中,包含 5 种角色。 * Provider:RPC服务提供者,Provider 是消息的最终处理者。 * Container:容器,用于启动、停止 Provider 服务。这里的容器并非 Tomcat、Jetty 等 Web 容器,Dubbo 也并不强制要求 Provider 必须具备 Web 能力。Dubbo 的容器是指对象容器,例如 Dubbo 内置的 SpringContainer 容器就提供了利用 Spring IOC 容器管理 Provider 对象的职能。 * Consumer:消费者,调用的发起者。Consumer 需要在客户端持有 Provider 的通信接口才能完成通信过程。 * Registry:注册中心,Dubbo 架构中注册中心与微服务架构中的注册中心职责类似,提供了 Dubbo Provider 的注册与发现职能,Consumer通过 Registry 可以获取Provider 可用的节点实例的 IP、端口等,并产生直接通信。需要注意的是,前面我们讲解的 Alibaba Nacos 除了可以作为微服务架构中的注册中心外,同样对自家的 Dubbo 提供了 RPC 调用注册发现的职责,这是其他 Spring Cloud 注册中心所不具备的功能。 * Monitor:监控器,监控器提供了Dubbo的监控职责。在 Dubbo 产生通信时,Monitor 进行收集、统计,并通过可视化 UI 界面帮助运维人员了解系统进程间的通信状况。Dubbo Monitor 主流产品有 Dubbo Admin、Dubbo Ops 等。 ## Dubbo与 Nacos共存 ### 服务提供方 #### pom依赖 ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.7.8</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> ``` #### 配置 ``` server: port: 7000 #服务端口 spring: application: name: user-center #微服务id cloud: nacos: #nacos注册地址 discovery: server-addr: 127.0.0.1:8848 username: nacos password: nacos dubbo: #dubbo与nacos的通信配置 application: name: user-dubbo #provider在Nacos中的应用id registry: #Provider与Nacos通信地址,与spring.cloud.nacos地址一致 address: nacos://127.0.0.1:8848 protocol: name: dubbo #通信协议名 port: 20880 #配置通信端口,默认为20880 scan: base-packages: com.open.capacity.dubbo ``` ![](https://img.kancloud.cn/12/dc/12dc22bff0cb5ed6364ae113e38f6a49_1477x449.png) 为什么上面配置了 spring.cloud.nacos.discovery.server-addr 还要在下面配置 dubbo.registry.address 呢?前面介绍架构时介绍了,Dubbo 需要依托 Container(容器)对外暴露服务,而这个容器配置与微服务配置是分开的,需要额外占用一个网络端口20880提供服务。这里还有一个配置点需要特别注意:dubbo.scan.base-packages 代表在 Dubbo 容器启动时自动扫描 com.open.capacity.dubbo 包下的接口与实现类,并将这些接口信息在Nacos 进行登记,因此 Dubbo 对外暴露的接口必须放在该包下。 ### 定义api层 ``` package com.open.capacity.user.service; import java.util.List; import java.util.Map; import java.util.Set; import com.open.capacity.common.auth.details.LoginAppUser; import com.open.capacity.common.exception.service.ServiceException; import com.open.capacity.common.model.SysRole; import com.open.capacity.common.model.SysUser; import com.open.capacity.common.web.PageResult; import com.open.capacity.common.web.Result; import com.open.capacity.user.model.SysUserExcel; /** * @author 作者 owen * @version 创建时间:2017年11月12日 上午22:57:51 */ public interface SysUserService { LoginAppUser findByUsername(String username) throws ServiceException; LoginAppUser findByMobile(String mobile) throws ServiceException; } ``` ### 用户服务 ``` import org.apache.dubbo.config.annotation.DubboService; import org.springframework.stereotype.Service; @DubboService public class SysUserServiceImpl implements SysUserService { } ``` 重点是在实现类上需要额外增加 @DubboService注解。@DubboService 是 Provider 注解,说明该类所有方法都是服务提供者,加入该注解会自动将类与方法的信息在 Nacos中注册为 Provider。 ### 服务消费方 #### pom依赖 ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.7.8</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> ``` #### 配置 ``` spring: application: name: auth-server cloud: nacos: discovery: server-addr: 127.0.0.1:8848 username: nacos password: nacos server: port: 9000 dubbo: application: name: auth-dubbo registry: address: nacos://127.0.0.1:8848 ``` ### 消费方代码 ``` @DubboReference private SysUserService SysUserService ; ``` 业务逻辑非常简单,前文讲过不再赘述,关键点是第三行 @DubboReference 注解。该注解用在 Consumer 端,说明 SysUserService 是 Dubbo Consumer 接口,Spring 会自动生成 SysUserService接口的代理实现类,并隐藏远程通信细节,处理流程如下图所示: ![](https://img.kancloud.cn/d4/d0/d4d019bacafd205cb1d5a1f78b31357c_2120x774.png)