基于Karma构建微服务

基于Karma构建微服务

“微服务”和“微服务架构”在开发社者区中是一个热门话题,但实际中的微服务例子仍然很少。通过简要介绍一下我们在Karma上构建的后端API可会对现在的情况有所帮助。这不是“如何去做”的例子,而更像是“为什么要做”或“这样做的原因”的一个例子,希望这个例子能让您对微服务适用范围和使用方法有所了解。

我们为什么选择微服务

当开始构建Karma时,我们决定将项目分成两个部分:后端API和前端应用程序。后端负责处理来自商店的订单,账目,用户管理,设备管理等等,而前端为访问此API的用户提供接口。我们注意到,如果后端API是一个集成整合的,那么由于系统太过复杂而不能很好地工作。

例如,我们有用户,设备和商店。正如您可以想象的,用户从商店购买设备。这听起来很简单,但是当它是一个应用程序时,与用户相关的代码很容易出现在商店和设备API中,很快商店API就由于设备API的快速更新而落后了(比如分配设备给用户)。很难跟踪什么是什么,什么涉及什么,什么改变了什么。

我们可以将整体功能分割成库,然后将它们合并为一个API,但是我们发现了这种方法的三个主要问题:

  1. 缩放问题。当你想扩展时,你必须一次扩展整个API。例如,Karma中,我们需要设备和用户API比商店API快得多。
  2. 版本。通过库方法,单一依赖能允许整个应用程序其余部分不升级。例如,从Rails 3升级到Rails 4是一件困难的事情。因为我们所有的代码都分布在多个项目中,所以我们不需要一次更新所有内容。我们可以让旧的API运行,并在适当时升级它们。
  3. 多种语言和框架。目前我们是Ruby语言开发的,但我们希望能够在新技术和语言出现时进行实验。我们目前正在使用Go和Clojure,由于我们暴露了REST API,所以通信不是问题——最终都是HTTP协议。

微服务的极大地推动了程序员的生产力:我们不必将整件事记在脑袋中!只需要集中关注我们要做的事,不用担心破坏了其他部分。

如何开始

我们采用微服务技术。后端使用一个大的应用程序,并在适当的时候分成几个。这对我们来说非常有效,我们也因此能够不断学习。

通过继续开发应用程序,我们对要解决的问题有了更多的了解,很重要的一点是我们需要应用程序各个方面之间设置界限。每当我们遇到看起来应该是单独的东西时,我们就把它变成一种服务。

起初,这些作品相对较大,但与其他微服务发展的故事一样,我们发现这些作品越变越小。

例如,我们在大型应用程序中开始使用“store”,该应用程序完成与store相关的所有操作。我们发现shipping可以从中分离出来。然后我们认识到跟踪shipment与shipping不同。该store现在由三个API组成:第一个API处理订单,第二个将订单发送到处理中心,第三个由FedEx发送包裹。我们的下一步是将订单处理分割。我们一直在学习构建这些东西的最佳方式,微服务为我们提供了灵活性。

最终,一个微服务只承担一部分功能 —— 甚至会将一部分依赖包装在一起,避免和其他服务的依赖关系。一到两个星期就能构建或重建微服务,而对系统其他部分的更改不需要重写。我们有两年前写过的一个叫做“Collector”的服务,除了偶尔的依赖关系更新之外,基本没有改变过。

我们的架构

我们的微服务可以通过两种方式进行通信:HTTP请求和消息队列。

刚开始的时候我们在后端使用HTTP和Sinatra。服务通过URL请求将消息传递给另一个。目前这个方式非常有用,但当交互的服务变多时,它就变得很复杂。

例如,一个订单输入,它需要被shipped。这很简单,但如果我们想要在收到订单后再做更多事情呢?商店可能需要与发票或邮件程序API进行交互,这会将关于变得很难处理。

所以我们开始将部分任务分解成基于事件的系统。我们使用Amazon SNS(简单通知服务 Simple Notification Service)发布事件,并使用Amazon SQS(简单队列服务 Simple Queue Service)存储事件。SNS接受一个服务传递给它的消息,并通过SQS将它发布到适当的队列中。然后,微服务可以将作业从队列中取出,处理它们,并在成功时删除它们。如果一个进程失败了,那么这个消息会返回到队列中,这样进程的另一个实例就可以对其进行工作。

当部署一个新的微服务时,它包含一个配置文件,该文件描述了想要侦听的消息类型以及要发布的消息类型。我们有一个名为Fare的内部工具,它读取配置并设置适当的SQS和SNS队列。

架构图

平台架构的简化图

现在,当订单进入时,会发布一个事件,表示:“已下订单(包括订单的详细信息)。”发货应用程序监听消息系统,一旦订单发生,查看详细信息,并说, “好的,我需要向这个人发送两个信箱。”任何其他对订单发生有兴趣的服务都可以在他们自己的队列中完成他们需要的任何事情,而store API也不需要担心。

当我们需要对消息立即响应时,我们仍然使用HTTP请求,例如登录或覆盖地图。这取决于服务是请求信息还是返回信息。如果是请求信息,它可能需要立即作出回应,如果它返回信息将不需要应答 。

面临的挑战

微服务最大的挑战就是测试(testing)。使用常规的Web应用程序,端到端测试非常简单:只需单击网站上的某个位置,即可查看数据库中的更改。但在我们的案例中,行动和最终结果离测试目标很远,很难看到确切的原因和结果。一个问题可能会从一个链中冒出来,但是链中哪里出了问题?这是我们还没有解决的问题。

相反,我们专注于使每个组件尽可能完善,并且看看将它们组合一起时会发生什么。我们试图让每个微服务都履行合同。“当我这样做时,我得到了这个回报。”我们拿这些合同(contracts),并手动确保他们履行。然而,合同是隐含的,并不明确,所以我们还没有想出一个自动化的方法来测试它。

这样做的结果是,我们必须假设一切都会在某个时候失败。微服务结构意味着问题是局部的,不扩散。其中一部分组件可能会失败,并直接影响其他部分,不会阻止其他任何部分。而且,多亏队列,一旦服务恢复在线状态,就可以继续工作。

接下来的工作

以上就是我们的微服务架构......现在。我们一直在寻找改进方法,正如您可以看到我们走向微服务的途径一直在变化。我们不仅继续添加功能,而且不断重新审视系统的不同部分,我们认为我们可以做得更好。还有一些我们建立的工具,例如Fare,我们希望一旦它们适合公共时就开源。请让我们知道你是否感兴趣!

微服务不是万能的,它们并不能解决所有问题,但它们对于Karma这个项目来说非常有效。也许他们会适合你未来的项目?

本文的版权归 轻吻晴雯 所有,如需转载请联系作者。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏CSDN技术头条

实用简介:MQTT协议及其在物联网中的应用

MQTT (Message Queuing Telemetry Transport,消息队列遥测传输) 是一种标准化的发布/订阅消息传输协议,设计于1999年,...

4416
来自专栏逍遥剑客的游戏开发

从Native到Web(五), emscripten学习笔记: 初体验

1573
来自专栏非著名程序员

绝对干货:供个人开发者赚钱免费使用的一些好的API接口

不久前,我写了一篇文章,名为《科普技术贴:个人开发者的那些赚钱方式》,讲了一些个人开发者接私活和自己做软件加广告的一些科普知识。可是做软件,需要服务器,需要后台...

4369
来自专栏BIT泽清

App Store审核成功解决2.1大礼包被拒后,通过最后一关的元数据被拒分享

最近这周帮一个客户上线一个棋牌游戏的项目,已经被3.2.1过后处理成功,又出现了2.1大礼包App完成度的问题;经过连续2天的加班通宵(当然是团队伙伴们车轮战拉...

1.3K9
来自专栏技巅

docker解决数据存储问题的方案

2537
来自专栏架构师小秘圈

存储的瓶颈--大型网站技术演进思考

作者:夏天的森林 出处:cnblogs.com/sharpxiajun/p/4237704.html 一,题记 前不久公司请来了位互联网界的技术大牛跟我们做了一...

4108
来自专栏程序员的知识天地

为何Node.js 能成为 Web 应用开发最佳选择?

一项颠覆性的技术进入技术市场总会带来一阵震惊,但随之而来往往是被放弃。然而,Node.js 当然不是这样的情况,它是一个开源的、跨平台的基于 Chrome 的 ...

1503
来自专栏微服务

关于大型网站技术演进的思考(一)--存储的瓶颈(1)

前不久公司请来了位互联网界的技术大牛跟我们做了一次大型网站架构的培训,两天12个小时信息量非常大,知识的广度和难度也非常大,培训完后我很难完整理出全部听到的知识...

41415
来自专栏跟着阿笨一起玩NET

五层拆解 网站架构

本人转载:http://www.cnblogs.com/scottckt/archive/2010/09/15/1826925.html

1551
来自专栏杨建荣的学习笔记

今天琢磨的几件事情(r7笔记第74天)

今天在琢磨几件事情,也是和工作相关。 数据灾难切换的几点认识: 在unix中可能会碰到在处理网络问题时,超时时间会远远高于linux的情况,这个时候如果尝试做f...

3064

扫码关注云+社区

领取腾讯云代金券