编者的话|本文来自 Nginx 官方博客, 是微服务系列文章的第二篇, 本文将探讨: 微服务架构是如何影响客户端到服务端的通信, 并提出一种使用 API 网关的方法.
Chris Richardson 微服务系列全 7 篇:
1. 微服务架构的优势与不足 http://blog.daocloud.io/microservices-1/
2. 使用 API 网关构建微服务
3. 深入微服务架构的进程间通信
4. 服务发现的可行方案以及实践案例
5. 微服务的事件驱动数据管理
6. 选择微服务部署策略
7. 将单体应用改造为微服务
Chris Richardson 所著所有文章已独家授权 DaoCloud 翻译并刊载.
本期内容
微服务系列文章的第一篇介绍了微服务架构模式, 讨论了使用微服务的优缺点, 以及为什么微服务虽然复杂度高却是复杂应用程序的理想选择.
在决定以一组微服务来构建自己的应用时, 你需要确定应用客户端如何与微服务交互.
在单体式程序中, 通常只有一组冗余的或者负载均衡的服务提供点. 在微服务架构中, 每一个微服务暴露一组细粒度的服务提供点. 在本篇文章中, 我们来看它如何影响客户端到服务端通信, 并提出一种使用 API 网关的方法.
简要概述
让我们想象一下, 你要为一个购物应用程序开发一个原生移动客户端. 你很可能需要实现一个产品详情页面, 展示任何指定商品的信息.
下图展示了 Amazon Android 应用在商品详情页显示的内容.
即使只是个智能手机应用, 产品详情页面也显示了大量的信息. 该页面不仅包含基本的产品信息(如名称, 描述, 价格), 而且还显示了如下内容:
购物车中的商品数量
历史订单
客户评论
低库存预警
送货选项
各种推荐, 包括经常与该商品一起购买的其它商品, 购买该商品的客户购买的其它商品, 购买该商品的客户看过的其它商品
其它的购物选择
使用单体应用程序架构时, 移动客户端通过向应用程序发起一次 REST 调用 (GET API.company.com/productdetails/) 来获取这些数据. 负载均衡器将请求路由给 N 个相同的应用程序实例中的其中之一. 然后, 应用程序会查询各种数据库表, 并将响应返回给客户端.
相反, 若是采用微服务架构, 显示在产品页上的数据会分布在不同的微服务上. 下面列举了可能与产品详情页数据有关的一些微服务:
购物车服务 -- 购物车中的件数
订单服务 -- 历史订单
目录服务 -- 商品基本信息, 如名称, 图片和价格
评论服务 -- 客户的评论
库存服务 -- 低库存预警
送货服务 -- 送货选项, 期限和费用, 这些信息单独从送货方 API 获取
推荐服务 -- 推荐商品
我们需要决定移动客户端如何访问这些服务. 让我们看看有哪些方法.
客户端与微服务直接通信
从理论上讲, 客户端可以直接向每个微服务发送请求. 每个微服务都有一个公开的端点(https ://.API.company.name). 该 URL 映射到微服务的负载均衡器, 由后者负责在可用实例之间分发请求. 为了获取产品详情, 移动客户端将逐一向上文列出的 N 个服务发送请求.
遗憾的是, 这种方法存在挑战和局限. 问题之一是客户端需求和每个微服务暴露的细粒度 API 不匹配. 在这个例子中, 客户端需要发送 7 个独立请求. 在更复杂的应用程序中, 可能要发送更多的请求; 按照 Amazon 的说法, 他们在显示他们的产品页面时就调用了数百个服务. 然而, 客户端通过 LAN 发送许多请求, 这在公网上可能会很低效, 在移动网络上就根本不可行. 这种方法还使得客户端代码非常复杂.
客户端直接调用微服务的另一个问题是, 部分服务使用的协议对 web 并不友好. 一个服务可能使用 Thrift 二进制 RPC, 而另一个服务可能使用 AMQP 消息传递协议. 不管哪种协议对于浏览器或防火墙都不够友好, 最好是内部使用. 在防火墙之外, 应用程序应该使用诸如 HTTP 和 WebSocket 之类的协议.
这种方法的另一个缺点是, 它会使得微服务难以重构. 随着时间推移, 我们可能想要更改系统拆分成服务的方式. 例如, 我们可能合并两个服务, 或者将一个服务拆分成两个或更多服务. 然而, 如果客户端与微服务直接通信, 那么执行这类重构就非常困难了.
由于上述三种问题的原因, 客户端直接与服务器端通信的方式很少在实际中使用.
来源: https://www.cnblogs.com/long2050/p/12080200.html