我有一个采用微服务架构的相对较新的项目。除了我们的安全服务之外,我对各个服务的大小和粒度感觉相当不错。
我有三个主要服务,比方说foo-service
,bar-service
和baz-service
。这些服务永远不需要通信,但所有三种服务都经常通过HTTP请求与security-service
进行通信。我希望这种情况因各种原因而停止 - 最大的问题是每个对我个人服务的请求都会产生对安全服务的请求,一旦你考虑到负载平衡等问题就会变成几个额外的跳跃。我一直在阅读Mark Richards撰写的“软件架构模式”,他建议在这些情况下,您应共享数据库并违反DRY:将所需功能复制到每个服务中。不过,他将此示例用于较小的“实用程序”类,这可能不适用于此实例。
安全服务并不是那么大,所以我绝对可以将其复制到其他每个服务中。也就是说,它足够大,以至于我感觉很难复制并粘贴它 - 根据工作服的314'相关'代码行(java所以有更多的实际代码;-)。我可以很容易地把它变成一个每个服务带来的模块 - 但是我的服务有一个共享的依赖,而且过去一点都没有。当然,随着我们添加身份验证方法,安全代码会随着时间的推移而增长,但是当涉及到auth时,我们并没有重新发明轮子,所以它主要与其他库和身份验证服务集成。也就是说,我不认为这个特定的代码库会变得庞大。
所以我的问题是,我应该复制并粘贴代码还是构建每个服务带来的模块?谢谢!
答案 0 :(得分:4)
我希望这种情况因各种原因而停止 - 最大的问题是每个对我个人服务的请求都会产生对安全服务的请求,一旦您考虑到负载平衡等,就会变成几个额外的跃点。
作为单独服务离职的PROS:
- 对安全业务逻辑的更改仅影响安全服务,不需要更改客户端服务。
将安全逻辑转移到客户服务中的PROS:
- 速度/性能。
- 减少一项管理服务可能意味着降低运营成本。
速度(性能)可能胜过这里,具体取决于要求,但会增加开发成本。
如果你确实将安全逻辑移动到可以从其他服务中调用的自己的可重用模块中,那么就可以很好地封装它并遵循基本的失败耦合紧密内聚设计。此外,由于你可能不得不在未来几年内为这个决定辩护,请你做一个很好的解释,这样你的未来老板就会在她问为什么要更新我们的安全逻辑时花费这么多钱时不会解雇你。有基准可供使用,人们撒谎,数字没有。我曾经为一个新的数据库提供了一页基准测试结果。我被不同的人多次询问我为什么选择新的数据库...我只是发送给他们一页,从未听过那个人的任何进一步的问题。
此视频可能会让您感觉更好,因为我们反对这种趋势:https://www.youtube.com/watch?v=StCrm572aEs
它展示了Netflix如何以及为什么逆转这一趋势,并没有采用REST架构来实现其API。基本上,建筑是需求和成本的客户,而不是相反。
编辑:作为服务离开的另一个重要的PRO是您可能必须为每种支持的语言创建多个模块。在我的工作中,我们的安全服务由多种语言的客户端服务使用。答案 1 :(得分:1)
如果您将安全逻辑嵌入到其他服务中,那么您现在真的无法将其称为微服务架构吗?我也明白,为每一项服务进行额外和双重的服务器往返可能会有点拖累。以下是一些可行的替代方案供您考虑。
将所有这四个微服务放在防火墙后面。公开面向公众的服务,该服务使用安全服务来验证传入请求,然后在请求对给定凭据有效时调用其他服务。其他服务始终信任调用者,这是在您信任的环境中拥有和运营的服务。
如果这是"“即发即忘”"对于具有过多协调责任的面向公众的服务,您会感到不舒服,然后考虑这个替代方案。面向公众的服务将入站请求发送到消息代理中的未授权队列。安全服务从该队列中消耗并执行身份验证。如果有效,则安全服务将消息排队在授权队列上。之后的任意数量的微服务从授权队列中消耗并执行它们各自的操作。
答案 2 :(得分:0)
安全性作为您描述的每个请求所需的单独服务是一个非常糟糕的主意。我可以向您介绍Parnas在On the Criteria To Be Used in Decomposing Systems into Modules 中如此雄辩地描述的模块化的基本思想。没有耦合也意味着没有凝聚力,工程学就是在该轴上找到最佳点。
与普遍看法相反,微服务需要相当大才能扩展。可扩展性的限制主要在于通信,因此需要将它们设计为不繁琐。问题主要是(除非你是netflix)不是带宽而是延迟。
您的安全模块需要比HTTP请求更接近您的服务,链接模块可以没问题。