Spring cloud样例解读

395 阅读5分钟
原文链接: mp.weixin.qq.com

一,本文目的

提供一个开箱即用的Spring cloud脚手架工程,避免各种搜索,查找带来的麻烦。不同于很多样例只关注springcloud的某一个组件,本文从整个工程的角度出发,提供一个完整可用,可参考的样例程序。

 

二,本文涵盖哪些内容?

本文提供一个完整的spring cloud样例程序,由maven编译打包,包括:配置中心(config ),服务注册与发现(discovery),接口网关(gateway),用户鉴权中心(uaa),api 服务(api)。支持local,dev,prod多环境部署,规范化的日志输出;采用JPA ,Hibernate,mysql存储及访问框架,数据库连接池采用Hikari,支持mysqljson 的存取;支持单机和集群部署方案;Gateway支持代理discovery监控界面功能;支持swaggerapi UI。

 

三,本文未涵盖内容

本文未涉及微服务环境下的集中式日志跟踪,docker构建脚步;未提供CI,CD 继承方案;未提供服务熔断样例;未提供集中的swaggerapi ui。未涵盖内容后续陆续补充完整,敬请关注。

 

样例程序github地址:https://github.com/matoujun/spring-cloud-examples/tree/master。下面分几个部分,解读spring cloud版本说明,各微服务模块功能及依赖关系,配置管理,其他开发Tips几个部分详细介绍样例程序。

  1. spring cloud版本说明:采用spring boot 2.0.5.RELEASE,Spring cloud采用 Finchley.SR1。spring boot2默认采用Hikari连接池,通过注解支持swagger,支持 reactor编程模型。

  2. 微服务各模块功能及依赖关系:样例程序分为:config,discovery,gateway, uaa,api五个服务。如下图所示:

    1. Config是一个集中式的配置中心,其他服务的配置文件都放在该服务下进行管理。Config支持git, native(打进jar包的配置文件)方式访问配置项,例子采用native方式,后续会添加上支持git的方式。Config是一个“伪分布式”的配置中心,之所以这么说是因为多个 config服务之间没有心跳,不会进行信息同步。其他服务需要在bootstrap中指定config的ip和端口。

    2. Discovery提供服务注册与发现机制,样例提供了两种部署配置,一种single单点部署,一种multiple两点集群部署,当然也可以直接添加更多节点。集群环境下,为方便查看监控UI ,在gateway中实现了一个简单的代理功能,方便查看每一台discovery控制台UI。

    3. Gateway配置了三个场景下的路由规则,一是针对uaa相关的接口,路由至uaa;二是 api接口路由至api服务;三是针对discovery代理。实现了两种Filter,一个是限流 ThrottleGatewayFilter,一个url重写RewriteDiscoveryIpFilter。

    4.  Uaa提供了用户信息访问及sso模版,样例未提供真正的实现,因为用户鉴权服务依赖于具体环境,开发人员可通过集成oAuth ,springsecurity来完善该部分功能。Uaa和一般的微服务实现上类似,只是功能不同而已。

    5. Api提供了两个实体类Event和Tag,及其CRUD 接口,其中利用了json类型,引入了vladmihalcea包读取json数据,并定制了BeanPropertyRowMapper ,以兼容json数据的访问。

    6. 所有的微服务和discovery都依赖config;所有的微服务都依赖 discovery,uaa, api都通过gateway对外提供服务。

  3. 配置管理。系统配置由config 服务进行集中式管理,其他服务通过boostrap文件定位config 服务地址。因此可认为spring cloud的配置分为两部分,一是各个服务查找config的配置,即每个服务下的bootstrap.yml;二是由config管理的配置,即config工程下的配置文件或Git库。Config 通过rest api向其他服务提供配置信息,url 格式${app}[,${app}]/${env}[,${app}]。例如: api/default,获取api 默认配置,api/dev获取 apidev环境配置,api,common/dev获取api,common两个服务的配置,包括api.yml,api-dev.yml,comon.yml,comon-dev.yml。启动一个服务如果需要获取多个环境配置,1)可以通过配置 jvm启动参数,-Dspring.profiles.active=env1,env2,env3... 。需要注意对于同一个配置字段,环境列表中后面的会替换前面的,也就是说env2会替换 env1,env3 会替换env2。2)也可以在系统环境中配置。对于相对复杂一些的场景,可以通过环境+Profile的方式组织配置文件。例子中discovery区分dev,prod两种环境,通过discovery_dev.yml,discovery_prod.yml进行区分,每一种环境下又分为single,peer1,peer2,single对应单点部署,peer1,peer2对应集群环境下的实例1,实例2部署(部署样例时,需要添加hostname peer1,peer2)。

  4. 开发Tips:

    1. 访问mysql json类型的字段时,可通过在虚拟列上创建索引的方式提高性能。但对于比较复杂的查询场景,例如:json 是一个list,而查询时需要遍历list,不太适合使用json类型。

    2.  定制WEB 错误响应报文格式。Springboot默认的响应报文字段比较多,可通过extendsResponseEntityExceptionHandler定制不同异常情况下的响应报文。样例中对应CustomizedInvalidResponse.java 。

    3. 通过@EnableSwagger2注解,springboot2自动支持swaggerapi ui。但springcloud gateway由于采用了reactor框架,暂时不支持集中式的swagger ui,需要访问每一个微服务的swagger地址;要支持集中式的UI,需要定制开发。

    4.  spring boot jpa+hibernate要支持mysql 的json类型字段,需要使用mysql5.7以后的jdbcdriver。读取json 类型的字段时,可以引入vladmihalcea或者自己定制类型处理逻辑。如果读取的json需要自动转换为List<Object>,需要定制BeanPropertyRowMapper ,样例中为CustomizeBeanPropertyRowMapper类。