开发服务导向架构。
基础设施(34), 建筑(30)在过去的四年里,推出和维护面向服务的体系结构,这是我希望我积累了足够的伤疤,以近似智慧。这是尝试分享一些有用的Tidbits。
首先,我将简要介绍一下我一直在努力提供一些上下文的两个不同的SOA,然后在我学到的教训中发射和我所做的观察。
掘客
在Digg,我们的SOA由许多Python后端服务组成,这些服务相互通信,并被我们的PHP前端服务器和服务器使用龙卷风API服务器。他们用Apache Trift.用于定义接口、客户机和作为底层协议的。我们有三个主要的服务(用户、故事、评论),还有一些较小的服务。
所有后端服务都托管在一类机器前端服务器上是一个单独的类 - 所有后端服务都是从单个Git存储库齐起部署的。
社会代码
在Digg的SOA体验之后,我们在构建SOA时做了一些改变社会代码. 后端服务和API仍停留在Python中,而不是使用Thrift,我们选择HTTP作为协议,并将前端产品实现为JavaScript应用程序,直接与httpapi通信,使浏览器成为本地API客户机。
api被隔离到自己的服务器上,以便进行解耦的调试和扩展,具有独立的代码库,并且单独部署。
随着这两种不同的方法,是时候通过这些系统的开发和维护学习的经验教训了:
SOA是为了缩放人
soa不是万能的,相反,它们会使您的体系结构大大复杂化。它们也不是一个基本的高性能体系结构,它们通过添加更多的部件来阻碍性能。
基本上,他们提供的唯一价值是大型团队通过两种机制共同努力的抽象:定义的接口减少了通信和破损成本,并隐藏了这些界面后面的内部,可以逐步投资质量而无需任何额外的跨团队协调(you can rewrite the internals for various improvements without impacting API clients as long as you don’t change the interfaces).
这些优势可以通过大型团队移山。
它们不一定为非常小的团队提供大量价值。我的肠道感觉是,看到从移动到SOA的小团队可能会通过任何系统重写/大修来获得同样的胜利,并且SOA是一个红鲱鱼。
采用SOA很慢
如果您不应该立即从SOA开始,那么您如何转向SOA?答案是“慢慢地,非常小心地”,你要么在完全重写的过程中移过去——在这种情况下,祝你好运!–或者您将从现有的单片体系结构逐步过渡。
如果您正在运行成功,不断增长的公司,需要在构建新功能和基础架构投资之间进行分割时间,然后增量迁移是可能的策略。
首先添加简单且无vervatroverial的服务,如用户身份和身份验证服务,并且在添加另一个之前将每个服务滚动到所有应用程序。然后添加另一个,另一个,直到您达到了所需的一致性。(这可能仅仅是几个服务。不要害怕慢慢走。)
迁移过程中要考虑的一个有趣的模式是创建新的服务API,但让它共享现有的数据库,从而允许现有的客户机通过新的API进行增量迁移。一旦它们完全使用了新的API(仍然使用相同的旧数据库),那么您就可以迁移到独立的数据库。特别是如果您要处理四个或五个具有不同开发计划的不同团队,这种技术可以帮助您避免在长时间切换期间出现数据不一致。
协议事项
从Digg到SocialCode,我们做出的最重要的决定之一就是从节约协议切换到HTTP。这使得浏览器成为一个直接使用api的本地客户机,但更重要的是,它还使调试和实验变得更容易,因为大多数软件开发人员对HTTP和HTTP服务器非常熟悉,而相对较少的人对节约非常熟悉。(这也扩展到重用他们现有的专业知识来优化和调试web服务器和请求。)
另一方面,Thrift是非常自我文档化的,与许多HTTPAPI(我们已经使用过)相比,它可以使工作更加愉快味觉要创建一致的API,这已经是现象,但它的API和数据结构仍然比使用节俭构建的可比较的API更具隐含和神奇。
根据您使用的语言的不同,您将在Thrift和HTTP之间获得不同的每小时优化性能。对于Python,我发现使用HTTP更容易获得高性能,原因很简单,因为这个生态系统非常健壮,Python旧版服务器在性能方面没有看到太多的社区投资。相反,我可以很容易地想象,对于更健壮的节俭实现,比如Java实现,节俭协议固有的紧凑性将有助于实现优于HTTP的性能。
需要考虑的最后一个元素是,即使使用HTTP,您也不会免费获得浏览器支持。相反,如果要允许Web浏览器直接访问API,则每个API端点都需要实现请求认证和授权机制。This is very doable (anecdote: we’re doing it), but takes some time and consideration versus offloading authn and authz to an authorization layer (at Digg this was our PHP and Tornado services which auth(n|z)ed the requests and then acted as trusted users of our internal APIs).
愚蠢的API客户端,聪明的API客户端
挑选SOA协议的高跟鞋正在决定您使用的API客户端与API进行交互。广泛地,使用复杂的客户之间的权衡,这些客户可以隐藏尽可能多的复杂性(在控制或感知丧失时购买易用性)与愚蠢的客户泄露底层API的所有丑陋细节(以费用为代价的控制和意识“正常情况”实施速度)。
就我个人而言,我是愚蠢的API客户机的坚定支持者。
我相信智能客户鼓励工程师将SOA视为单片应用,这是一个漏洞的抽象。对于我们当前的设置,我们的每一个API请求我们都在同一主定位 - 强加了20ms的成本UWSGI.要为请求提供服务(以及任何额外的时间来在API本身内执行逻辑或查找)。
这是抽象的很多开销。
If you and your team are experienced working with SOAs, then by all means use a smart client, but if you’re not then I tend to believe it’s important to be exposed to the underlying implementation costs until you can build a mental cost model for the new development style.
跨团队热点是糟糕的服务
如果您的组织更多地通过自愿协作和布道来管理系统架构,而不是fiat,那么防止采用服务的最简单方法就是创建一个服务,该服务将多个团队正在积极实施的功能统一起来。
乍一看,这显然是错误的:当然您应该避免两次编写相同的组件。
但是在实践中,如果多个团队已经实现了类似的功能,并且被提交到一个时间表中,那么在不强迫一个或两个团队放弃其项目的时间表或设计的情况下尝试统一实现可能为时已晚。在各种实现稳定之后,就可以将它们用作构建共享服务的具体需求。
在“通过避免无果辩论来更快地进入目的地”下文件。
总之,我相信转向面向服务的体系结构是将工程团队从大约五个扩展到二十个的重要阶段。这可能也与寻找适合市场的产品和扩大适合业务的过渡期相吻合。
在写这篇文章时,我一直在思考一下的一些事情:
- 有效缩放工程团队的其他方法是什么?
- 有哪些其他重要建议是创造出优秀的SOA?测量和监督可能是探索的好主题。
我还错过了什么?