Dubbo 框架现在在国内的中小企业当中已经成为 Java 生态下服务化的事实标准,出现这种状态的原因很多,比如 Dubbo 框架设计优秀、文档和资料丰富、配置灵活、特性丰富等,但最主要的,我认为是 Java 开发人员对速度这一因素的痴迷。
不可否认,Dubbo 框架设计和实现之初就将其自身定位为一款基于 TCP 长连接通信的高性能服务治理框架,但是,对于很多中小企业来说,不管从速度还是并发度,根本就没有到非要使用像 Dubbo 这样基于 TCP 长连接服务框架的程度。
笔者认为,不分场景和现状盲目选型 Dubbo 框架,或许就是 Dubbo 框架成为 java 生态下服务治理框架事实标准的原因。
Dubbo 框架虽然有很多优点,也确实面向高强度的互联网应用场景,且在多家知名的互联网企业的生产环境得到验证,但也并非没有缺点:
作为一名理性的研发人员,在项目技术选型的时候,需要综合考虑多种方案的优缺点,并根据现状进行权衡,实际上,对于大部分项目来说,性能可能并非技术选型的核心因素,开放和互通或许才是。
是要以互通性作为核心因素进行技术选型并构建一套开放繁荣的生态体系,还是以性能为核心因素进行技术选型构建一套封闭高效的生态体系,需要大家灵活把握,而本节我们将更多以 Web API 的形式,向大家展示如何基于 SpringBoot 构建一套开放、互通、稳定的 Web API 微服务体系。
使用 SpringBoot 构建 Web API 有几种选择,要么使用 spring-boot-starter-jersey 构建 RESTful 风格的 Web API,要么选择 spring-boot-starter-hateoas 构建更加有关联性和相对“智能”的 Web API,但笔者认为这些都有点儿“阳春白雪”。
对于大部分开发人员来说,HTTP 协议的 GET 和 POST 是直觉上最自然的选择,所以,我们选择使用最“下里巴人”的方式来构建 Web API。
Web API 强调统一和互通,所以,首先我们需要定义一套内外认知一致的 Web API 开发和访问规范,在 JSON 盛行、社群庞大的背景下,我们的 Web API 方案采用 JSON 作为数据交互格式并定义统一的协议格式,然后通过 HTTP 以及周边支持完成微服务的对外服务和开放访问。
首先从服务访问的交互上来说,我们可以选择较为纯粹的 JSON RPC Over HTTP 的方式,如图 1 所示。
图 1 JSON RPC Over HTTP 示意图
也可以选择约束相对松一些的 RPC Over HTTP 方式,如图 2 所示。
图 2 一般意义上基于HTTP的RPC交互示意图
相对于纯粹的 JSON RPC Over HTTP 方案,后者对请求格式不做任何限制(所以也同样支持纯粹 JSON 形式的请求格式),只对响应(Response)做 JSON 格式上的统一规定。
好处是,客户端各种工具都能够很好的支持,服务器端 SpringMVC 也可以少做 HttpMessage 转换,给服务的开发者和访问者都提供了比较灵活的操作余地,至于请求的类型差异,我们可以通过配套生成的 API 文档进行补足。
不管怎么样,我们选择基于后一种方案进行说明,现在剩下的主要工作就是定义服务响应格式,只有规范和统一了服务的响应格式,才能让内部和外部的服务访问者形成统一的认知。
以上面同样的方式“复制”对我们提供的任何 Web API 的访问行为,减少用户的接入成本,所以,姑且我们简单规定一个服务的响应格式如下:
{ "code" : 1, "error" : "XXXXX", "data" : { ... }}
其中,code 表示调用结果的状态,0 表示成功,非 0 表示失败,并且失败情况下 error 字段将提供对应的错误信息描述,data 字段用于规范定义特定于 Web API 的响应内容。
有了这样的规范定义,不同的开发者就可以根据情况选择打造对应的工具或者 SDK 了。而 Web API 的服务提供者也同样可以根据该规范考虑如何简化 Web API 的开发,或者通过约束减少规范认知不足可能导致的问题。
既然是使用 SpringBoot 构建 Web API,那么显然我们现在更加关注后者。
针对同样的汇率查询服务,这回我们采用 Web API 的形式对外提供服务。
使用