RPC与Dubbo
# RPC 与 Dubbo
# 第六阶段
# 主要内容
- 实现统一的接口鉴权和计费(RPC、Dubbo 讲解)
# 网关业务逻辑
问题: 网关项目比较纯粹,没有操作数据库的包,并且还要调用我们之前写过的代码?复制粘贴维护麻烦。
理想: 直接请求到其他项目的方法。
# 怎么调用其他项目的方法?
- 复制代码和依赖、环境
- HTTP 请求(提供接口,供其他项目调用)
- RPC(Remote Procedure Call)远程过程调用
- 把公共的代码打个 jar 包,其他项目去引用
面试常问:HTTP 请求和 RPC 有什么区别
# HTTP 请求怎么调用?
- 提供方提供一个接口(地址,请求方法,参数,返回值)
- 调用方使用 HTTP Client 之类的代码包去发送 HTTP 请求
# RPC
作用: 像调用本地方法一样去调用远程方法。
和直接 HTTP 调用的区别,RPC 优点:
- 对开发者更透明,减少很多的沟通成本
- RPC 向远程服务器发送请求时,未必使用 HTTP 协议,比如还可以使用 TCP/IP,性能更高。(内部服务更适用)
RPC 调用模型:

注意: 这里注册中心只提供信息,并不会帮助调用,实际调用还是提供者那边。
# Dubbo 框架(RPC 实现)
其他 RPC 框架:GRPC、TRPC。
最好的学习方式:阅读官方文档。
https://dubbo.incubator.apache.org/zh/docs3-v2/java-sdk/quick-start/spring-boot/
# 两种使用方式
- Spring Boot 代码(注解 + 编程式):写 Java 接口,服务提供者和消费者都去引用这个接口
- IDL(接口定义语言):创建一个公共的接口定义文件,服务提供者和消费者读取这个文件。优点是跨语言,所有的框架都认识
底层是 Triple 协议:
https://dubbo.incubator.apache.org/zh/docs3-v2/java-sdk/concepts-and-architecture/triple/
# 官方的示例项目学习
zookeeper 注册中心:通过内嵌的方式运行,更方便。
最先启动注册中心(EmbeddedZooKeeper,内嵌的注册中心),然后启动服务提供者(ProviderApplication),再启动服务消费者(ConsumerApplication)。
# 整合运用
- backend 项目作为服务提供者,提供 3 个方法:
- 实际情况应该是去数据库中查是否已分配给用户
- 从数据库中查询模拟接口是否存在,以及请求方法是否匹配(还可以校验请求参数)
- 调用成功,接口调用次数 +1
invokeCount
- gateway 项目作为服务调用者,调用这 3 个方法
ZooKeeper 会有版本问题,解决起来比较麻烦,建议用 Nacos!
整合 Nacos 注册中心:https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/registry/nacos/
注意:
- 服务接口类必须要在同一个包下,建议是抽象出一个公共项目(放接口、实体类等)
- 设置注解(比如启动类的
EnableDubbo、接口实现类和 Bean 引用的注解) - 添加配置
- 服务调用项目和提供者项目尽量引入相同的依赖和配置
# 添加依赖
依赖从官方示例项目中复制粘贴过来的不行,要从 maven 仓库中找来相应的版本依赖。
在 cmapi-backend、cmapi-gateway 中添加如下依赖:
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>3.0.9</version>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>2.2.0</version>
</dependency>
2
3
4
5
6
7
8
9
10
11
# 第七阶段
# 主要内容
- 开发抽象公共服务
- 实现网关核心业务流程
- 开发管理员接口分析功能
- 上线分析和扩展
# 梳理网关业务逻辑
以下操作可以复用:
- 去数据库中查是否已分配给用户秘钥(ak、sk 是否合法)
- 先根据 ak 判断用户是否存在,查到 secretKey
- 对比 sk 和用户传的加密后的 sk 是否一致
- 从数据库中查询模拟接口是否存在,以及请求方法是否匹配(还可以校验请求参数)
- 调用成功,接口调用次数 +1
invokeCount
# 临时问题:如何获取接口转发服务器的地址
思路: 网关启动时,获取所有的接口信息,维护到内存的 hashmap 中;有请求时,根据请求的 url 路径或者其他参数(比如 host 请求头)来判断应该转发到哪台服务器、以及用于校验接口是否存在。
# 抽象公共服务
项目名:cmapi-common
目的是让方法、实体类在多个项目间复用,减少重复编写。
服务抽取:
- 数据库中查是否已分配给用户秘钥(根据
accessKey拿到用户信息,返回用户信息,为空表示不存在) - 从数据库中查询模拟接口是否存在(请求路径、请求方法、请求参数,返回接口信息,为空表示不存在)
- 接口调用次数 +1
invokeCount(accessKey、secretKey(标识用户),请求接口路径)
步骤:
- 新建干净的 maven 项目,只保留必要的公共依赖
- 抽取 service 和实体类
install本地 maven 包- 让服务提供者引入 common 包,测试是否正常运行
- 让服务消费者引入 common 包
# 统计分析功能
# 需求
各接口的总调用次数占比(饼图),取调用最多的前 3 个接口,从而分析出哪些接口没有人用(降低资源、或者下线),高频接口(增加资源、提高收费),用饼图展示。
# 前端
强烈推荐用现成的库!比如:
- ECharts:https://echarts.apache.org/zh/index.html (推荐)
- AntV:https://antv.vision/zh (推荐)
- BizCharts
用法贼简单!
- 看官网
- 找到快速入门、按文档去引入库
- 进入示例页面
- 找到你要的图
- 在线调试
- 复制代码
- 改为真实数据
如果是 React 项目,用这个库:https://github.com/hustcc/echarts-for-react
# 后端
写一个接口,得到下列示例数据:
接口 A: 2次
接口 B: 3次
2
步骤:
- SQL 查的调用数据:
select interfaceInfoId, sum(totalNum) as totalNum
from user_interface_info
group by interfaceInfoId
order by totalNum desc
limit 3;
2
3
4
5
- 业务层去关联查询接口信息
# 上线计划
前端: 参考之前用户中心或伙伴匹配系统的上线方式。
后端:
- backend 项目:web 项目,部署 Spring Boot 的 jar 包(对外的)
- gateway 网关项目:web 项目,部署 Spring Boot 的 jar 包(对外的)
- interface 模拟接口项目:web 项目,部署 Spring Boot 的 jar 包(建议对外暴露的)
关键:网络必须要连通。
- 如果自己学习用:单个服务器部署这三个项目就足够
- 如果你是搞大事,多个服务器建议在同一内网,内网交互会更快、且更安全
# 扩展思路
1. 用户可以申请更换签名
2. 怎么让其他用户也上传接口?
- 需要提供一个机制(界面),让用户输入自己的接口 host(服务器地址)、接口信息,将接口信息写入数据库。可以在
interfaceInfo表里加个 host 字段,区分服务器地址,让接口提供者更灵活地接入系统。 - 将接口信息写入数据库之前,要对接口进行校验(比如检查他的地址是否遵循规则,测试调用),保证他是正常的。
- 将接口信息写入数据库之前遵循咱们的要求(并且使用咱们的 SDK)。
- 在接入时,平台需要测试调用这个接口,保证他是正常的。
3. 网关校验是否还有调用次数
需要考虑并发问题,防止瞬间调用超额。
4. 网关优化
比如增加限流/降级保护,提高性能等。还可以考虑搭配 Nginx 网关使用。
5. 功能增强
可以针对不同的请求头或者接口类型来设计前端界面和表单,便于用户调用,获得更好的体验。可以参考 swagger、postman、knife4j 的页面。
← 调用统计与API网关 笔记→