阅读原文:【技术分享】微服务开发的技术幸福感,是分享如何提升的?
点击关注“八戒技术团队” ,阅读更多技术干货
随着微服务的微服务开流行,越来越多公司使用了微服务架构,幸福但由于公司业务的感何特殊性、技术栈的提升历史原因等 ,都需要选择一个适合自己公司的技术服务开发框架 ,对框架进行规范定义,分享集成自研组件和系统,微服务开让业务迭代实现更快速,幸福让开发人员使用更便捷。感何
本文将基于SpringBoot,提升从框架约束 、技术自研中间件集成、分享强类型客户端、微服务开接口文档等多个方面介绍服务框架的设计与实践。
一、背景介绍
公司后端服务是以Java生态为主,有基于Dubbo的RPC服务、基于SpringBoot的HTTP服务两种开发模式,所有服务基于K8S的容器云双机房独立部署,支持双活流量的架构 。
结合公司上下文环境 、业务规模,综合考虑技术栈统一 、服务治理 、使用成本等多方面的因素,经过多部⻔商议,确定将“基于SpringBoot开发HTTP服务”作为主要开发模式。公司每天都有一些新的微服务产生 ,很多自研组件服务和中间件系统,需要服务开发者单独接入 ,为了规范和简化后端服务开发者集成应用,一套规范、集成的开发框架就变得非常有必要。
二、基于SpringBoot的服务框架设计
1 、如何统一规范框架的使用?
统一规范可以通过默认约定、强制校验 、自动内嵌等多种方式来实现 ,下面将分别举例说明 。
统一管理依赖包(默认约定)
基于Maven的依赖包管理,通过Partent统一定义依赖包及版本,默认引入必须的依赖包和插件。创建工程自动生成代码时 ,默认约定继承Parent,开发者只需引入必要的Starter即可,开发者可以修改继承关系 ,但不推荐 。
依赖包的统一管理 ,可以避免不同版本包冲突的麻烦 ,也方便后期公司统一升级依赖包和版本。
统一参数格式(强制校验)
返回参数都继承BaseResponse,请求参数都继承BaseRequest 。强制校验接口服务来保证参数规范性,在工程启动时自动检测,不遵循规范的工程将无法正常启动 ,绕过校验的工程不纳入公司后端体系 ,很多核心能力均无法正常使用 。
统一参数格式 ,不仅可以同时支持HTTP调用 、强类型客户端,同时规避了HTTP接口的滥用,简化规范了错误处理 。
统一处理异常(自动内嵌)
通过Spring的RestControllerAdvice可以对全局异常统一捕获,并对异常统一处理。异常处理自动内嵌到核心包中,只要使用该框架 ,就自动生效 。
统一异常处理,不仅规范了异常返回格式,兼容了强类型客户端,日志统一记录 ,并对返回的异常信息进行脱敏处理。
2、如何简化自研中间件组件和系统的集成?
所有中间件依赖包都在Parent中统一管理 ,对于自研的通用类组件(比如日志组件 、线程池组件、web安全组件、自研的工具类组件等),默认在Parent中已引入 ,开发者可以直接使用。
公司有很多自研的中间件组件或系统 ,或者根据公司环境二次开发过的开源组件 ,只能按照公司的特定的方式进行接入使用,有一定的接入成本 。为了接入更方便,都做成了可插拔的组件 ,通过Starter方式进行接入。
使用Starter方式 ,简化了依赖 、简化了配置、简化了接入代码。
作为后端服务 ,核心能力是对外提供服务 ,或者调用其他服务 。如果使用REST方式访问远程HTTP接口 ,难以将接口管理起来,当接口变动的时候可能需要修改多处。
在技术调研过程中 ,我们发现SpringCloud提供了OpenFeign来解决这个问题。
3、如何实现强类型的HTTP客户端?
OpenFeign是一种声明式 、模板化的HTTP客户端 ,在Spring Cloud中使用OpenFeign,只需要定义接口和注解 ,可以做到使用HTTP请求访问远程服务 ,就像调用本地方法一样。
但OpenFeign和我们公司技术环境不一致,加上太多历史项目也无法支持OpenFeign ,于是我们借鉴OpenFeign思想 ,基于开源Fegin开发了适合公司环境的ZbjFeign ,支持在SpringBoot和普通Spring环境中使用。
虽然实现了声明式调用 ,如果每次都要写接口定义和注解,还是很不方便。为了解决这个问题 ,我们开发了一键发布Client包功能,通过扫描Controller接口方法元数据,基于ZbjFeign生成接口调用Client,构建打包发布到公司Maven仓库。后端开发者只需引入一个包 ,就可以像调用本地接口一样调用远程HTTP接口 。对于前端NodeJS调用,也生成了对应的生成物,支持前端框架的“强类型”调用。如果开发者要看接口文档 ,我们也提供全公司统一、完整的接口文档 。
4 、如何实现文档的统一管理?
公司所有文档都是基于Confluence进行管理的,接口文档也不例外 ,于是我们也实现了在发布阶段 ,一键发布接口文档。后台实现也是自动扫描Controller接口元数据,通过模版生成HTML片段,并提交到Confluence。接口文档中提供了Java强类型客户端调用、HTTP调用两种方式的参考 。
Client和文档都有了,接下来我们通过案例看一下如何使用 。
三、框架使用案例
1 、Starter的使用案例
通过Starter方式使用分布式消息队列 RabbitMq,只需要引入Starter,就可以直接使用了。
第一步:引入依赖Starter。
第二步:消费者监听队列消息 。无需做任何配置 ,具体代码如下。
说明:公司的RabbitMQ是经过二次开发的,不是通过“地址+账号”访问,而是通过申请的业务ID进行访问。
2、强类型客户端使用案例
只需要引入Client包 ,无需做任何配置,就可以像调本地方法一样调HTTP服务 。
第一步:引入Client依赖。