微服务架构剖析

互联网早期、公司创立初期一般使用集中式架构(巨石架构),所有的服务、数据存储全部署在一台机器中。通常会对该机器的性能、硬件比较苛刻,选用HP、SUN、IBM这种小型机,但它们的价格比较昂贵。其次是故障时是单点故障,会造成比较大的影响。

为了降低单点故障的影响面、减少服务、数据存储的耦合性,提高开发效率,集中式架构逐渐演化成了分层架构(SOA)。按照业务纬度、功能纬度进行拆分后部署到不同的机器中,不同的服务、数据存储对机器的配置要求一般是不同的。分层架构的核心在于“分离”,让各个拆分后的服务、数据存储是独立的,逻辑上可以去合并在一起进行管理。

解决一个问题的时候又会引入新的问题,分层架构会让请求路径变长、系统的稳定性下降、定位问题变的复杂、运维成本增加。为了降低运维成本、项目快速迭代、项目持续交付,分层架构演化成了微服务架构。按照业务纬度、功能纬度、人员组织纬度进行架构。微服务架构并不是银弹,它的引入也带来了新的问题。每一种架构都有优点和缺点,只要能解决公司当前业务中的痛点就是好的架构。

什么是微服务

个人认为微服务一种人员组织、一套分布式架构的思想。

微服务架构由一系列小型自治服务组成。每项服务都是独立的,实现了单一的业务能力。以下是微服务的一些特征:

  • 松耦合:服务小,独立且松耦合。
  • 小型,专注的团队:每个服务都是一个单独的代码(项目),由一个个的小型开发团队管理。
  • 独立部署:服务可以独立部署,这样更新该服务不需要重建、重新部署整个应用程序。
  • 故障隔离:服务负责持久保持自己服务的数据或外部状态,整个服务相关的都有小型团队负责。
  • API相互通信:服务之间使用API相互通信,隐藏每个服务的内部实现细节。
  • 混合技术栈:服务可以是使用不同的技术栈开发,最终依靠API通信组合在一起就行。
  • 细粒度扩展:服务可以独立扩展,使用不同的机器配置。

微服务的组件

API网关

API网关是客户端的总入口,客户端请求不直接调用服务。它们先调用API网关,然后网关将调用转发到后端相应的服务。它有效的阻止了内部的敏感信息暴露给外部的客户端,为服务层增加了一道安全防线,把通用性的功能放到API网关层,设定了服务之间通信的规范。

API网关为使用者提供完整的API托管服务,提供身份认证、权限管理、请求代理转发、服务/API级别的流量控制(实现动态流控是难点)、服务/API级别的熔断,保证API安全,降低API开放风险。提供日志收集(包含APM的log)、API级别的监控、AB Test功能。

API网关

服务注册发现

微服务架构中存在很多独立自治的服务,而且微服务中是需要一套CICD(Jenkins、K8s)的基础组件的建设。服务如果预先定义运行在哪台服务器,会简单很多,我们硬编码就可以。但是预先定义运行的服务器要实现充分利用服务器资源几乎是不可能的。还有服务的自动伸缩性、故障后恢复都很困难。

为了更好的将服务自动部署到资源相对比较空闲的服务器中,充分的利用机器的资源,这样我们就需要一个能添加IP地址、端口、服务名称的地方。把这些数据存储到某处并可以被其它的服务进行查找,把数据对所有服务进行共享。就是我们说的服务注册和发现(高可用的配置中心 + 服务查找proxy)。

服务注册发现

调用链路追踪

微服务架构中由于也符合分层架构,同样的它存在请求链路较长、出现问题后定位复杂的困惑。它的实现可以是侵入业务方式也可以是非侵入式(API网关层去做)。

如果我们能把每个接口从用户发起请求开始,到整个调用正常结束/异常中断链路信息(通常是有向无环图)记录起来。这样一个个的接口就能绘制成一个API级别/服务级别/整个系统级别的调用地图。我们只需要提供一个接口的URL就能知道它的上下游依赖服务,也能看直观的从调用链路信息中看出到底是链路中哪个环节出现了问题。

调用链路追踪

CI/CD

持续集成、持续部署是微服务架构的主要优势之一。大大的缩短了发布周期,如果没有一套良好的CI/CD流程,我们将无法实现微服务承诺的灵活性、独立部署、细粒度扩展等特征。

代码仓库会选择使用gitlab,约束好项目的分支使用规范。可以固定几个特有功能的分支进行触发git hook,比如release、develop、master分支,分别对应不同的部署环境。持续集成的代码构建这块我们选用Jenkins进行,可以对每次构建输出详细的报告。Jenkins设置构建成功的钩子,当构件成功后去通知相关的CI系统。CI系统可以进行下一步的部署、自动化测试。CD我们使用的Kubernetes,可以是基于公有云/私有云进行搭建。

CI/CD

日志中心

日志按照请求数据流向分为:网关日志(access、error、info等)、业务日志(请求第三方、db等log)、机器日志(cpu、memory、进程、连接数...)等这些都是容易产生异常的环节。需要把log进行收集聚合到一起去,像调用链路追踪可以认为是基于业务日志产生的一个聚合应用

日志聚合到一起使用的存储可以选择Es、阿里云的SLS、HDFS。针对不同的数量级、不同的数据类型(结构化、半结构化、非结构化)、不同的查询量级、维护成本选择不同的存储、组合多个存储。日志数据由于体量很大,一般会保存一段期间内的log。使用计算引擎(spark、flink)把原始log经过筛选、过滤永久存储有意义的(错误的、支付相关的、重要服务的)log。可视化数据一般使用Grafana,支持多种数据源、提供了多样化的模板、丰富的图表。

监控报警

监控报警我们一般会基础日志平台的基础上去做。除此之外还有业务数据也与监控,业务数据指的是对重要服务的数据进行数据建模,同比、环节策略进行分析数据的趋势是否波动的超过了阈值。

监控数据的对象有网关日志、业务日志/数据、机器,监控指标的阈值可以通过全链路压测得出参考值。前期尽可能是多报警(存在误报)、不断调整阈值、对报警进行一定的收敛。监控工具有Zabbix、Open-flcon、Prometheus、第三方云服务,可以组合使用或者单一的使用。报警可以使用监控工具自带的,也可以是自研报警工具。报警的方式有短信、邮件、电话、内部IM。

业务数据的监控需要进行数据建模、分析、得出结论。业务数据从数据角度看都是INFO类型的,并不能像网关日志、业务日志一样直接就会有ERROR、Waring。业务数据的分析、建模会使用到Python中的statsmodels、数据分析用pandas,numpy,scipy、数据可视化使用seaborn、数据拟合使用matplotlib.pylab。

监控报警

常见疑问

Q1:微服务需要把全部的组件都实现一遍?

是否要全部实现一遍取决于公司对基础建设的投入、技术人员的能力、时间成本、运维成本综合考虑。这里微服务组件落地的建议是先把CI/CD做出来,其它组件可以慢慢的来。

Q2:微服务中的服务怎么拆分?

根据现有的架构以及演化后的架构,梳理清楚服务的层次(按照层次拆分)、禁止业务相互调用(引入MQ解耦)、通用性的功能拆出来、有状态的服务进行拆分(把状态放到存储层)。拆分的目的是为了快速迭代、持续部署、快速缩扩容。

Q3:wei'服务的设计原则?

  • 高内聚低耦合(单一职责、轻量级通信方式、服务之间的契约)
  • 高度自治(独立开发、部署、发布,进程隔离)
  • 以业务为中心(每个服务代表特定的业务、快速响应业务变化、围绕业务组织小团队)
  • 弹性设计(容错、服务降级)
  • 日志与监控(日志聚合、监控与报警)
  • 自动化(持续集成、持续交付)

相关文章

感觉本篇文章不错,对你有收获?

¥我要小额赞助,鼓励作者写出更好的教程
80 160 120

作者:

  • 出处: https://www.mi360.cn/articles/186
  • 本文版权归作者,欢迎转载,但未经作者同意必须保留 此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

评论区

最新评论

扫码关注