Java开源接口微服务代码框架

1. 开源微服务框架自述

  1. 本人从事Java方面的工作已10+年了,经历了SSH/SpringMVC,终于等到了SpringBoot/SpringCloud,迎来了分布式微服务的崛起,盼来了云原生,这是最好的coding时代,也是最复杂的coding时代;
  2. 本人最近几年一直在金融科技领域从事AI相关的算法商业化落地,能够深刻体会AI对各种行业的颠覆与创新,但是AI还远没有达到可以取代coding的程度;落后就要淘汰却是真实的;
  3. 工作是最好的老师,在工作的过程中,逐渐总结出来了一套相对来说比较通用的架构设计思路、一套通用代码框架,该框架经过了团队的不断实践迭代,并逐步形成了一个不错的微服务解决方案。当然这主要是偏向特定领域的微服务解决方案,不可能通用于所有业务场景;本方案的特点是非常关注业务安全和业务的可扩展性;
  4. 在给大家分享个人经验的同时,也是在自我梳理和总结,所谓温故而知新。与君共勉;

个人感悟

  • 一路走来,Java语言世界已经发生了翻天覆地的变化,任我不眠不休,终究无法穷尽;
  • 学以致用,我发现只有真正用过的,才会有真切的感悟,才能把框架里面的门道搞得清楚明白;
  • 适合的,才是最好的;

2. 微服务逻辑架构设计

  • 基于业务场景规划,整体的逻辑架构如下:
    bq逻辑架构

    说明:

    1. bq-service-gateway:基于SpringCloud-Gateway,统一的接入网关,进出都要经过本网关,主要用作JwtToken鉴权,并提供了接口、数据加解密的安全保障能力,可以依赖集群缓存,但不依赖数据库;已开源
    2. bq-service-auth:基于spring-authorization-server,负责生成和刷新JwtToken,同时对网关服务提供访问权限的查询接口,且只读取数据库数据;已开源
    3. bq-service-biz:基于spring-boot-starter-web,负责实现具体的业务逻辑,且只读数据库数据;已开源
    4. 对接服务(bq-integration) : 负责和外部平台对接,通过网关服务中转,且只读数据库数据;
    5. 后台管理(bq-mgr) : 负责维护接口平台,严格来讲不属于微服务集群,也不对外暴露,仅通过数据持久层异步通知认证服务业务服务对接服务其数据变更并生效;
    6. 网关服务认证服务实现了鉴权和认证的分离;
    7. 后台管理认证服务业务服务对接服务实现了数据库的读写分离;
    8. k8s在上述微服务架构中,承担起了服务注册和服务发现的作用,鉴于k8s云原生环境构造较为复杂,实际开源的代码时,以Nacos(为主)/Eureka做服务注册和服务发现;
    9. 以上所有服务都以docker容器作为载体,确保服务有较好地集群迁移和弹性能力,并能够逐步平滑迁移至k8s的终极目标;

3. 开源部署架构设计

  • 在逻辑架构的基础上,补充下带有服务注册、服务发现、熔断降级限流及链路追踪的中间件的部署架构设计,如下图所示。
    bq部署架构

    说明:

    • NacosServer:负责服务注册和服务发现,同时也是Sentinel熔断限流和网关服务路由的配置中心;后续会使用K8S自带的服务注册和服务发现替代NacosServer
    • Sentinel:负责熔断降级和非业务的限流,同时支持基于spring-boot-starter-webflux网关服务和基于spring-boot-starter-web的其他服务;
    • ZipkinServer:负责链路追踪汇总查询,同时支持基于spring-boot-starter-webflux网关服务和基于spring-boot-starter-web的其他服务;
    • 为了后续能够平滑切换至新SpringCloud架构的组件,当然也包括切换至k8s,当下都是极简使用NacosServerZipkinServer

4. 开源代码架构设计

  • 在开发初期,便想着从springframework/springboot入手,建立起不完全依赖springboot/springcloud微服务体系的分层开发基础包,如移动端开发或者桌面Application开发,我可能只需要springframework
    的bean生命周期管理即可。当然,springboot/springcloud是当下的主流技术框架,也是我们微服务的基础依赖包。
    bq代码架构

    开源说明:

    1. bq-encryptor:基于BouncyCastle安全框架,加解密介绍见链接文档 ,支持RSA /AES /PGP /SM2 /SM3 /SM4 /SHA-1 /HMAC-SHA256 /SHA-256 /SHA-512 /MD5等常用加解密算法,并封装好了多种使用场景、做好了为SpringBoot所用的准备,已开源
    2. bq-base:基于springframework的基础代码框架,支持json/redis/DataSource/guava/http/tcp/thread/jasypt等常用工具API,已开源
    3. bq-log:基于SpringBoot框架的基础日志代码,支持接口调用日志、业务操作日志等日志文件持久化,可根据实际情况扩展,已开源
    4. bq-boot-root:基于springboot,但是不包含spring-boot-starter-web,也不包含spring-boot-starter-webflux,可通用于servletnettyweb容器场景,封装了redis/http/定时器/加密机/安全管理器等的自动注入,已开源
    5. bq-boot-base:基于spring-boot-starter-web(核心是servlet),提供常规的业务服务基础能力,支持PostgreSQL/限流/bq-log/Web框架/业务数据加密机加密等可配置自动注入,已开源
    6. bq-service-gateway:见逻辑架构介绍,已开源
    7. bq-service-auth:见逻辑架构介绍,已开源
    8. bq-service-biz:见逻辑架构介绍,已开源
    9. bq-integration:见逻辑架构介绍,待开源;
    10. bq-mgr:见逻辑架构介绍,待开源;

4. 微服务运行说明

4.1 微服务运行依赖

微服务运行前,需要运行如下公共组件:

  1. 进入zipkin目录并启动zipkin:
    java -jar ./zipkin-server/target/zipkin-server-*exec.jar
    
  2. 启动nacos:
    sh ~/opensource/nacos-2.2.1/distribution/target/nacos-server-2.2.1/nacos/bin/startup.sh -m standalone
    
  3. 启动本地redis:
    redis-server
    

4.2 微服务的运行指导

各微服务的运行参见其详细说明如下:

  1. bq-service-auth初始化指导:
  • 把bq-service-auth/bq-service-auth-startup/src/main/resources/sql下的sql全部执行一遍;
  • 启动bq-service-auth服务,成功后执行如下curl命令:
    curl --location 'http://localhost:9991/auth/user/add' \
    --header 'Content-Type: application/json' \
    --data '{
        "app_id":"app001",
        "app_key":"hao123",
        "app_name":"bq-app",
        "expire_time":1676800613607
    }'
    
  • 查询数据库表select * from sys_access;,会发现新增了用户数据:
    [
      {
        "id": "a4b42fa45e6f4dd8a942c34c62a6bf57",
        "app_name": "2a6fd05579481bfa4b08ebe9251a7f88eb376f1ea6fe",
        "app_id": "app001",
        "app_key": "4b649584514495a77a50f72495c7f31351b1b493cb40",
        "status": 1,
        "expire_time": 1715348560590,
        "create_time": 1683812560590,
        "sec_key": "3045022100b5b41861fb3b87fd6e0f1cfce423eae5db77672fe5cde4e63c11a7fe58d2bc52022040d8e0de733b10baa64cb843071e577c1a998cb60e84b844f0e53688ddf4adb1"
      }
    ]
    
  • 执行curl命令:
    curl --location --request POST 'http://127.0.0.1:9991/oauth/token?scope=read&grant_type=client_credentials' \
    --header 'Authorization: Basic YXBwMDAxOmhhbzEyMw==' \
    
  • 生成JwtToken的响应结果:
    {
      "code": "100001",
      "msg": "通过",
      "data": {
        "access_token": "eyJraWQiOiI2ZTNjN...",
        "token_type": "Bearer",
        "scope": "read",
        "refresh_token": "eyJhbGciOiJSUzI1...",
        "client_id": "app001",
        "jti": "a0042c89671e420599b24808ef3ecdce",
        "resources": [
      	"/auth/wx"
        ],
        "expires_in": 1799
      },
      "cost": 0
    }
    

    如果代码编译不过,则需要更换alibaba maven代理为官方代理:https://repo1.maven.org/maven2/ ,因为alibaba在2022年底之后就更改了同步策略,新的jar包不保证同步;下同。

  1. 正常运行bq-service-biz即可;
  2. bq-service-gateway初始化指导:
  • 在启动服务前,需要在nacos配置列表创建配置bq-gateway-route-id,并把bq-service-gateway-startup下的application-routes中注释掉的路由配置填入其中:

    • GROUP: DEFAULT_GROUP
    • 配置内容JSON:
      [
        {
          "id": "auth-route",
          "uri": "lb://bq-auth/",
          "order": 1,
          "predicates": [
            {
              "name": "Path",
              "args": {
                "pattern1": "/oauth/**",
                "pattern2": "/auth/**",
                "pattern3": "/bq-auth/monitor/**"
              }
            }
          ],
          "filters": [
            {
              "name": "CircuitBreaker",
              "args": {
                "name": "circuitBreaker",
                "fallbackUri": "forward:/fallback"
              }
            }
          ]
        },
        {
          "id": "biz_route",
          "uri": "lb://bq-biz/",
          "order": 1,
          "predicates": [
            {
              "name": "Path",
              "args": {
                "pattern1": "/bq-biz/demo/**",
                "pattern2": "/bq-biz/monitor/**",
                "pattern3": "/demo/**"
              }
            }
          ]
        },
        {
          "id": "fallback_route",
          "uri": "http://localhost:9992",
          "order": 1,
          "predicates": [
            {
              "name": "Path",
              "args": {
                "pattern": "/fallback"
              }
            }
          ]
        },
        {
          "id": "test_route",
          "uri": "lb://bq-test/",
          "order": 1,
          "predicates": [
            {
              "name": "Path",
              "args": {
                "pattern1": "/test/**",
                "pattern2": "/bq-test/monitor/**"
              }
            }
          ]
        }
      ]
      
  • 启动网关服务;

  • 从网关bq-service-gateway处发起对bq-service-auth的JwtToken生成调用:

    curl --location --request POST 'http://127.0.0.1:9992/oauth/token?scope=read&grant_type=client_credentials' \
    --header 'bq-integrity: 966b52885179be9c5842074f66cdd6c6a79f67445c3a27329a401072cdc536ff' \
    --header 'Authorization: Basic YXBwMDAxOmhhbzEyMw==' \
    
  • 响应结果:

    {
      "code": "100001",
      "msg": "通过",
      "data": {
        "access_token": "eyJraWQiOiI2ZTNjN...",
        "token_type": "Bearer",
        "scope": "read",
        "refresh_token": "eyJhbGciOiJSUz...",
        "client_id": "app001",
        "jti": "86f64939b1804c1ca5bd478a2220cdd9",
        "resources": [
      	"/auth/wx"
        ],
        "expires_in": 1800
      },
      "cost": 0
    }
    

    由此,完成了网关bq-service-gatewaybq-service-auth的服务发现;

  • 网关bq-service-gateway再根据jwt token发起对bq-service-biz服务的调用:

    curl --location 'http://localhost:9992/demo/qr' \
    --header 'Authorization: Bearer eyJraWQiOiI2ZTNjN...' \
    --header 'userAgent: ASas' \
    --header 'bq-integrity: c999d31229e1b6a7b7b6329e0eff9b39d92389248c7cffa5d81ef910c34cfa82' \
    --header 'Content-Type: application/json' \
    --data '{
        "code":"test123"
    }'
    
  • 响应结果:

    {
      "code": "100001",
      "msg": "通过",
      "data": {
        "open_id": "6c241d49a18742f1a9c5715f828e17a2"
      },
      "cost": 0
    }
    

    由此,完成了网关bq-service-gatewaybq-service-biz的服务发现;

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐