一、业务简介

假设现在我们现在的应用有web端,app端和小程序端,而调用一个下单请求,需要调用库存检查,订单创建,订单支付,订单状态变更,订单拆分打包,订单物流处理等。

二、无网关时的请求处理流程

微服务网关 - 图1

三、无网关时存在的问题

  1. 每个业务端都存在相同的业务处理逻辑,需要重复实现,而app之类的发布都会比较麻烦,如果里面包含的业务逻辑太多,扩展升级不方便
  2. 每个业务端都需要知道具体每个服务的地址,调用协议和参数,业务端无法使用相同的一个调用协议来调用所有服务。
  3. 每个业务端需要发起很多请求到服务端,当流量很大时,可能导致服务连接过多,无法响应
  4. 每个服务为了避免单点故障,肯定会部署多个实例,此时客户端还需要集成负载算法,与业务无关
  5. 每个服务都需要相同的像权限身份验证等功能
  6. 每个服务都需要暴露地址给外网访问,不太安全

    四、有网关时的请求处理流程

    微服务网关 - 图2注:网关还有一种轻量级实现,不包含任何业务聚合处理,只是简单的通用功能,由下层服务来聚合业务,这样就是会再多一层,是否直接在网关里面包含业务聚合处理需要再考量。个人建议是直接放到网关里面。
    前轻后重,网关后的服务有两种类型的服务接口
  • 细api:面向资源
  • 粗api:聚合细api,面向业务

    五、错误码

    1.错误码定义

  1. message Status{
  2. //一个容易被客户端进行处理的错误码
  3. //实际的错误码在google.rpc.Code里面定义
  4. int32 code = 1;
  5. //面向开发人员的可读性高的英文错误信息
  6. //这个错误信息应该同时说明错误的原因以及提供一个可操作的处理错误的方法
  7. string message = 2;
  8. //额外的错误信息,这些错误信息可以被客户端代码用来处理这个错误
  9. //例如告诉客户端隔多长时间再次尝试或者提供一个帮助链接
  10. repeated google.protobuf.Any details = 3;
  11. }

2.错误分类

错误码分级:

  • 正数:业务错误
  • 负数:系统错误
  • 零:正常

我们会使用一个较小的标准错误集合来对应一个较大的资源集合。举个例子,对于NOT_FOUND错误,我们不会给不同的资源定义不同的错误,而是统一给客户端返回一个带有标准google.rpc.Code.NOT_FOUND错误码以及指明特定的资源没有被找到的错误。因为我们的错误状态集合比较小,这样可以减少api文档的复杂性,同时客户端的代码也可以使用更加惯用的映射来减少其逻辑的复杂性而且还可以从服务器返回的错误里面获得一些可操作的信息。

六、网关的作用

  1. 协议转换:比对对外提供http协议,对内转换为连接共用的rpc协议等
  2. 轻量交互:协议精简,聚合
    1. 精简:去掉服务返回的,但当前业务不需要的字段,只返回当前业务需要的字段
    2. 聚合:调用多个服务后,对结果进行整合为一个整体后返回给业务端
  3. 差异服务:数据裁剪以及聚合,针对终端定制化api
  4. 动态升级:原有系统兼容升级,更新服务而非协议
  5. 弹性设计:面向故障设计,流量入口瓶颈,业务集成度高
  6. 统一权限判断,用于统一的访问权限判断
  7. 统一日志记录
  8. 统一负载均衡,用于根据调度算法,调用相应的后台服务实例来实现业务
  9. 服务编排,通过编排并行调用服务来减少总体响应时间
  10. 缓存
  11. 调用链跟踪
  12. 熔断限流

    七、网关的选型

  13. asp.net&asp.net core:Ocelot

  14. java:zuul gateway