分布式概念
垂直架构
所有功能模块在一个项目中编写,并集中部署。
- 优点:实现简单。
- 缺点:项目耦合度高,牵一发而动全身,不利于团队开发,也不利于后期升级和维护。
SOA & 微服务架构
*SOA(Service-Oriented Architecture) *
将应用程序不同功能单元(称为服务)进行拆分,并通过这些服务之间定义良好的接口和契约联系起来。
SOA(面向服务架构)是一种思想,采用粗粒度、松耦合的服务架构,服务之间通过简单、精确定义的接口进行通讯,不涉及底层编程接口和通讯模型。
微服务
SOA 发展出来的产物。将应用程序分为更细粒度的服务,并分布式部署。使各个服务之间可独立维护。
- 优点:SOA/微服务的引入,这使得整个系统的分工更加明确,责任更加清晰,每个人专心负责为其他人提供更好的服务。
- 缺点:但整个应用分散成多个服务使得整个系统变得更为复杂,也使得部署、管理、排障的工作量显著加大。
RPC(remote procedure call)
整个应用分散成多个服务使得整个系统变得更为复杂。我们需要在分布式开发中引入额外的技术,以解决服务之间交互和分布式部署导致的问题。
RPC(远程过程调用),即在本地调用远程机器的函数或者对象方法,使实际的体验和调用本地函数或者对象方法无异。
RPC 也是一种技术思想,HTTP 和 WebService 就是 RPC 思想的一种很好的体现方式,但 HTTP 已经满足不了企业内外部日益复杂的信息交互。因此许多优秀的 RPC 框架应运而生,比如著名的 Dubbo ,封装了一些像负载均衡、熔断降级、服务注册发现等面向对象的高级特性。
引入技术
消息队列
使用专用的中间件在网络中传输数据。通常由专用的机器集群来实现,从发送方接收数据,再将数据转发给相应的接收方。
使用消息系统具有以下优势:
- 将发送方和接收方解耦,统一使用消息系统提供的接口进行通信,易修改易扩展。
- 能够持久化保存数据,防止处理数据失败导致数据丢失。
- 分布式系统能够均衡负载,且能根据负载灵活调整机器数量,能够处理高吞吐量和流量突增的情况。
目前主流的消息队列有 kafka、RocketMQ 等等。
故障监控追踪
在高并发分布式的场景下,故障经常是突然间就雪崩式爆发。所以必须建立完善的监控体系,尽可能发现故障的征兆。
-
监控:微服务架构中组件繁多,各个组件所需要监控的指标不同。一般的做法是让各个组件提供报告自己当前状态的接口(metrics接口),这个接口输出的数据格式应该是一致的。然后部署一个指标采集器组件,定时从这些接口获取并保持组件状态,同时提供查询服务。最后还需要一个UI,从指标采集器查询各项指标,绘制监控界面或者根据阈值发出告警。
-
追踪:在微服务架构下,一个用户的请求往往涉及多个内部服务调用。为了方便定位问题,需要能够记录每个用户请求时,微服务内部产生了多少服务调用,及其调用关系。这个叫做链路跟踪。链路跟踪只能定位到哪个服务出现问题,不能提供具体的错误信息。
日志检索分析
当访问数变大、或服务器规模增多时,日志文件的大小会膨胀到难以用文本编辑器进行访问,更糟的是它们分散在多台服务器上面。排查一个问题,需要登录到各台服务器去获取日志文件,一个一个地查找(而且打开、查找都很慢)想要的日志信息。因此,在应用规模变大时,我们需要一个日志的“搜索引擎”。
在业界通常会使用大名鼎鼎的 ELK 日志分析组件:
- Elasticsearch:搜索引擎,同时也是日志的存储。
- Logstash:日志采集器,它接收日志输入,对日志进行一些预处理,然后输出到Elasticsearch。
- Kibana:UI组件,通过Elasticsearch的API查找数据并展示给用户。
权限校验控制
微服务架构中项目会出现大量的服务和接口,使得整个调用关系异常复杂。
网关负责把关微服务的调用。在调用者和被调用者中间加一层网关,每次调用时进行权限校验。另外,网关也可以作为一个提供服务接口文档的平台。
一般的微服务架构里都有两层 API GetWay:
- 外部 API GetWay,用于用户访问系统;
- 内部 API GetWay,解决的问题就是服务发现和服务注册。因此通信的方式要尽量单一,API GetWay 有一项工作就是协议转换。
服务注册发现
在实际开发中我们往往需要根据业务需求的变化,动态地调整机器数量,以便能够提高性能和容错。
由于服务的地址可能会频繁地动态变化,在调用服务时就需要使用统一的注册中心来查找服务的地址信息:
- 各个应用服务在启动时/定时将自动将自己注册到注册中心。
- 注册中心也会定期检查应用服务的健康状态,去掉不健康的实例地址。
Apache ZooKeeper(ZK) 是一个广泛使用,为分布式应用提供高性能整合的服务。
熔断/服务降级/限流
当一个服务因为各种原因停止响应时,调用方通常会等待一段时间,然后超时或者收到错误返回。如果调用链路比较长,可能会导致请求堆积,整条链路占用大量资源一直在等待下游响应。所以当多次访问一个服务失败时,应熔断,标记该服务已停止工作,直接返回错误。直至该服务恢复正常后再重新建立连接。
当下游服务停止工作后,如果该服务并非核心业务,则上游服务应该降级,以保证核心业务不中断。比如网上超市下单界面有一个推荐商品凑单的功能,当推荐模块挂了后,下单功能不能一起挂掉,只需要暂时关闭推荐功能即可。
一个服务挂掉后,上游服务或者用户一般会习惯性地重试访问。这导致一旦服务恢复正常,很可能因为瞬间网络流量过大又立刻挂掉,在棺材里重复着仰卧起坐。因此服务需要能够自我保护——限流。限流策略有很多,最简单的比如当单位时间内请求数过多时,丢弃多余的请求。另外,也可以考虑分区限流。仅拒绝来自产生大量请求的服务的请求。例如商品服务和订单服务都需要访问促销服务,商品服务由于代码问题发起了大量请求,促销服务则只限制来自商品服务的请求,来自订单服务的请求则正常响应。
- 点赞
- 收藏
- 关注作者
评论(0)