【问题标题】:How defensive to be when interacting with another internal microservice?与另一个内部微服务交互时要如何防御?
【发布时间】:2016-07-19 08:57:25
【问题描述】:

在这个场景中有两个 HTTP 微服务:

  1. 为客户提供数据的公共服务
  2. 对公共服务调用进行身份验证的内部微服务

服务 1 调用服务 2,要求它验证客户端提供给它的令牌。

协议(“合同”)是服务 2 应回复 200 OK 和关于已验证用户的 JSON 内容。

在服务 1 中,如果它收到响应 200 OK,是否值得进一步验证响应?

例如,响应的 JSON 正文被解析为一个对象。检查该对象是否被正确实例化而不是设置为 null 是否有价值?或者是否应该将其留给集成测试?

【问题讨论】:

标签: microservices defensive-programming


【解决方案1】:

严格来说,200 仅表示请求已成功处理。从业务角度来看,这与呼叫的实际结果无关。

您实际上依赖于“如果用户未通过身份验证,我们将抛出异常或以其他方式使调用失败”的约定来验证用户身份。

根据惯例,您可能会遇到用户未经身份验证但呼叫仍被成功处理的情况。

从这个角度来看,让 service2 返回一个响应可能是值得的,然后可以询问该响应以关闭这个循环。

或者,您可以让客户端直接调用身份验证服务,检索令牌,然后将此令牌与任何其他请求一起呈现。这意味着 service1 不再需要知道调用者是否经过身份验证。

问题是是否每次在服务 1 中进行测试 收到回复

抱歉,我似乎有点误解了问题的精神。

我有点困惑 - 你是在问,如果被测系统是 service1,那么 service2 的任何响应也应该是该测试的一部分吗?

我会说你必须进行一些测试来证明 service2 响应询问逻辑是正确的,但这可以在单元测试级别完成。我认为您不需要为针对已部署服务实例运行的测试执行此操作,这本质上更多是关于边界而不是内部的服务行为。

【讨论】:

  • “从这个角度来看,可能值得让 service2 返回一个响应,然后可以询问该响应以关闭这个循环。”这确实是服务 2 所做的。问题是每次收到响应时是否在服务 1 中进行测试,以验证它是否包含预期的属性。 (争论的另一面是不要打扰每个实时请求,并将其留给集成测试。)
【解决方案2】:

你的方法还不错!

某些 HTTP 状态代码是为格式错误的请求等情况保留的。但在您的情况下,您要求 Service2 返回令牌信息!如果该令牌存在,则您指定正确,Service2 必须返回200 OK。现在您只需要指定如果令牌不再有效或不存在(或将这两种情况视为相同......)会发生什么。如果您指定,Service2 必须返回 404 Not found,如果它不知道令牌或令牌已过期,那么(在大多数情况下)Service1 不需要再进一步!在几乎任何语言/环境中解析状态代码都很便宜,但是在成功和错误情况下强制反序列化内容的成本相比之下非常昂贵。身份验证需要快速 - 所以我会在这里获取状态码!

关键是,必须在某处指定此行为! (我们追求的是大摇大摆的定义!)

【讨论】:

  • 谢谢,关于 Swagger 的好建议。为了清楚起见,我需要解析用户 ID 的响应正文。所以这是一个这样做的问题,并假设我现在有一个带有用户 ID 的对象,或者如果没有返回该属性,则进行显式检查并抛出异常。
猜你喜欢
  • 1970-01-01
  • 2016-05-10
  • 2018-01-14
  • 2020-08-19
  • 2017-05-30
  • 1970-01-01
  • 2020-12-15
  • 2020-04-27
  • 2020-02-13
相关资源
最近更新 更多