微服务开发系列:开篇

1 开篇

微服务现如今已经是一个被绝大多数开发人员都熟知的概念了。

网上各种微服务开发系列层出不穷,各类的微服务框架也多如牛毛。

但是,在这样一种仿佛没什么必要介绍微服务的时间点,我还是要给出一系列我对于微服务开发的理解。

这些理解并不深奥,这些做法你可能每天都在做,某些地方你可能认为非常基础。

但是在我的理解中,这些很重要,并没有花里胡哨的实现方式,技术的目的,不是为了用繁琐的方法实现简单的目的,而是为了用简单的方法,实现一切目的。

因此我想介绍的框架,一切都是为了方便,方便排查,方便部署,方便开发,它只是一个方便的系统。

这些简单的技巧,朴实的做法,不仅仅为微服务框架提供有益的设计方式,还对一些开发人员的开发习惯和对开发的理解上,也能够有着一些助力。

2 源码地址

great-microservice-gradle-kotlin

上面的项目源码,是笔者自己亲手搭建并不断完善的,后续所有的《微服务框架系列》都是基于此写出。

源码使用 kotlin 开发,但是可以无缝转为 java。

后续我会单独写一篇我为什么要使用 kotlin。

3 系统结构

这是一个基于 gradle 构建微服务架构。

\--- server
    +---framework
    +---gateway
    \---business
        +---business-foundation
        +---business-web

其中拥有子节点的项目,是一个没有代码的管理项目,管理下面子项目的构建,依赖等。

4 各个模块的作用

4.1 server

整个微服务架构中的顶层项目,本身不包含任何代码,是所有项目的顶层项目。

拥有下面的功能:

  1. 管理项目都需要用到的依赖版本
  2. 定义了所有项目必须拥有的依赖,比如所有项目都需要依赖 frameworkhutoolspring-securityspring-cloudspring-admin-clientspring-redissonspring-alibaba-nacos-configspring-alibaba-nacos-discoverycaffeine
  3. 定义打包中需要包含或者排除的文件
  4. 定义各个项目的构建方式
  5. gradle 依赖仓库
  6. 依赖的 gradle 插件
  7. 设置其它一些共用参数

4.2 server:framework

基础模块,项目中所有的模块都需要依赖该模块,在 server 中已经设置好,拥有下面的功能:

  1. 所有项目共同需要使用类和 spring boot starter 自动装载的 bean。
  2. 包括了 http 请求中,项目所需使用的共用类
  3. jackson 封装
  4. redisson 基于 jackson 的序列化配置
  5. spring 数据统一序列化

4.3 server:gateway

网关模块,作用类似于 nginx,拥有下面的功能:

  1. 网关转发
  2. 跨域设置
  3. spring security 鉴权、验证码
  4. 请求响应中 content 的拦截打印
  5. 全局请求日志打印、采集
  6. 为所有请求的 response 中加上 cost 耗时监控,
  7. 为所有请求的 response 中加上 request-id 请求唯一 id,并且传递到下游,能够在下游追踪日志
  8. knif4j swagger 服务中心

有一些功能项目到了一定规模需要做的,目前未实现

  1. 请求限流
  2. 熔断

该模块使用了 webflux,是 spring cloud gateway 使用的 web 框架,有别于传统的 servlet。

4.4 server:business

业务模块,是一个小型的顶层模块,能够掌控所有的业务模块拥有的依赖,构建方式等,因为系统中大部分相同的功能都已经被 server 定义,所以这个模块不需要再做过多的配置,只需要专心处理与下面子业务模块相关的依赖或者配置。

4.5 server:business:business-foundation

是一个类似于 framework但是仅服务于业务模块的业务基础模块,随着系统的发展,能够不断扩充功能,例如某个组件是需要所有业务模块设置的,那么就可以在该模块下,做一个统一的配置。

目前拥有的功能:

  1. 提供所有业务模块需要共同依赖的业务类,比如业务对象、rpc 远程调用接口类。扩充的原则是

    1. 共享的代码范围必须限制在 business
    2. 代码共享范围必须至少是两个或者以上的项目
    3. 尽量剥离业务逻辑,不能把本来应该放在业务模块中的代码,不加思考的放在这里
  2. spring mvc security、跨域、日志、全局异常、http session 配置
  3. 一些业务共用参数例如封装的分页参数对象、分页结果对象
  4. mybatis plus 配置

4.6 server:business:business-web

一个系统的核心业务模块,这类模块为系统提供业务能力,是和外接环境交互最多的模块,这类模块可以分为多个,当业务过于复杂的时候,就可以考虑剥离开来,减少一个模块的复杂度。

但是剥离为多个时又需要考虑好每个业务模块之间的连接如何设计,需要考虑包含但不仅限于下面这些问题:

  1. 共用业务类如何剥离
  2. 系统间服务如何相互调用
  3. fegin 的使用该如何设计

这些问题不仅要在开发前思考,在开发和需求不断变化的过程中也要不断思考,以求其能够快速的适应新的开发方式。

相比于思考上层,开发反而是最简单的事情,只要上层结构定义好了,剥离与合并都是十分方便的事情。

这个微服务框架这样设计,就是为了在小中型系统中尽量获取更多的灵活性。

5 架构中使用到的第三方服务

在架构用采用一些第三方服务,应该要仔细思考引入的服务将会带来什么样的影响,在应用过程中,应该要不断地对服务本身的优缺点进行考量。

怎么样使用第三方服务,才是合理的、正确的,我在使用到下面的这些服务时,或多或少都会有一些问题,不断地磨合,寻找合适的解决方法,是一个不断进步的过程。

系统中引用过的第三方服务有下列这些,后面的一些章节,会详细说明一些服务为什么要这样用,更重要的是为什么不要这样用

5.1 mysql

目前使用的 orm 是 mybatis plus,mp 虽然好用,但是需要有一些限制,后面会介绍到。

5.2 redis

使用的客户端是 redisson,对于 redisson 的序列化后面会介绍。

5.3 nacos

作为注册中心和配置中心,其本身功能不错,但是也有一些问题和额外的配置。

5.4 elasticsearch

使用原生的 RestHighLevelClient,不考虑 spring data

不使用 spring data 的原因主要有两个

  1. elasticsearch 的版本升级太快,spring data 有点跟不上节奏
  2. spring data 的使用,需要三个版本一致,spring data 本身的版本,spring boot 的版本,elasticsearch 的版本,使用条件太苛刻

6 总结

这个微服务架构,由顶至下设计了整个项目的结构,尽可能的利用一些能够利用到的特性,把项目中与业务无关的代码全部剥离开来,让所有的模块都能享受到在一个整体架构中的优势,明确各个模块各自的职能,找到自身模块的定位。

这些职能并不是唯一不变的,每个系统都可以根据自身的实际情况去调整这个结构,架构也不是一成不变的,完全可以根据实际情况去做改变,但是尽量要遵循最大解耦的原则,并在任何情况中考量改变的影响,以方便开发人员开发的同时,也能维护框架本身的稳定性。

这个框架只是适合一些中型的系统,中型的系统体量上不会过于庞大,如果在这个架构中出现了十几个甚至几十个模块的时候,就要考虑到这个架构是否合适了,可能需要更加适合的架构去开发了,可能会产生多个中型项目相互配合的情况,甚至可能出现与业务结合紧密的网关模块。

同样也不适合一些小型项目,因为没有这个必要,简单开发一些业务功能,并且随后很难在扩充的情况下,只需要一个单独 spring boot 就可以完成所有功能。

因此没有一个框架是唯一的,能解决任何问题的。

这一系列的文章,是为了能够描述出一个理想的框架,是如何在不断思考的过程中,与各种服务不合理的地方做斗争,与各种开发习惯相互磨合,又如何做出妥协,不断进化的过程,从而能够帮助更多的开发者加深对框架的理解,在面对任何第三方服务时,都能够游刃有余的做出合理的选择。

本文参与了思否技术征文,欢迎正在阅读的你也加入。

你可能感兴趣的:(微服务开发系列:开篇)