初识 RPC 接口设计
由于 RPC 中的术语每个程序员的理解可能不同,所以文章开始,先统一下 RPC 术语,方便后续阐述。
大家都知道共享接口是 RPC 最典型的一个特点,每个服务对外暴露自己的接口,该模块一般称之为 api;外部模块想要实现对该模块的远程调用,则需要依赖其 api;每个服务都需要有一个应用来负责实现自己的 api,一般体现为一个独立的进程,该模块一般称之为 app。
api 和 app 是构建微服务项目的最简单组成部分,如果使用 maven 的多 module 组织代码,则体现为如下的形式。
serviceA 服务
serviceA/pom.xml 定义父 pom 文件
<modules>
<module>serviceA-api</module>
<module>serviceA-app</module>
</modules>
<packaging>pom</packaging>
<groupId>moe.cnkirito</groupId>
<artifactId>serviceA</artifactId>
<version>1.0.0-SNAPSHOT</version>
serviceA/serviceA-api/pom.xml 定义对外暴露的接口,最终会被打成 jar 包供外部服务依赖
<parent>
<artifactId>serviceA</artifactId>
<groupId>moe.cnkirito</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<packaging>jar</packaging>
<artifactId>serviceA-api</artifactId>
serviceA/serviceA-app/pom.xml 定义了服务的实现,一般是 springboot 应用,所以下面的配置文件中,我配置了 springboot 应用打包的插件,最终会被打成 jar 包,作为独立的进程运行。
<parent>
<artifactId>serviceA</artifactId>
<groupId>moe.cnkirito</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<packaging>jar</packaging>
<artifactId>serviceA-app</artifactId>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
麻雀虽小,五脏俱全,这样一个微服务模块就实现了。
旧 RPC 接口的痛点
统一好术语,这一节来描述下我曾经遭遇过的 RPC 接口设计的痛点,相信不少人有过相同的遭遇。
查询接口过多
各种 findBy 方法,加上各自的重载,几乎占据了一个接口 80% 的代码量。这也符合一般人的开发习惯,因为页面需要各式各样的数据格式,加上查询条件差异很大,便造成了:一个查询条件,一个方法的尴尬场景。这样会导致另外一个问题,需要使用某个查询方法时,直接新增了方法,但实际上可能这个方法已经出现过了,隐藏在了令人眼花缭乱的方法中。
难以扩展
接口的任何改动,比如新增一个入参,都会导致调用者被迫升级,这也通常是 RPC 设计被诟病的一点,不合理的 RPC 接口设计会放大这个缺点。
升级困难
在之前的 “初识 RPC

本文探讨了RPC接口设计中常见的问题,如查询接口过多、难以扩展、升级困难和测试复杂等,并提出了单参数接口设计,利用Specification模式减少查询接口,提高接口的扩展性和兼容性。此外,通过引入Checked Exception来改善异常处理,确保调用者能够明确处理异常,减少无谓的升级。最后,建议以模块为单位单独进行版本管理,减少对调用者的影响。
最低0.47元/天 解锁文章
712

被折叠的 条评论
为什么被折叠?



