一文搞懂微服务架构演进( 四 )


一文搞懂微服务架构演进

文章插图
图片
 
06 定位问题 - 链路跟踪在微服务架构下 , 一个用户的请求往往涉及多个内部服务调用 。为了方便定位问题 , 需要能够记录每个用户请求时 , 微服务内部产生了多少服务调用 , 及其调用关系 。这个叫做链路跟踪 。
 
我们用一个Istio文档里的链路跟踪例子来看看效果:
 
一文搞懂微服务架构演进

文章插图
图片来自Istio文档
 
从图中可以看到,这是一个用户访问productpage页面的请求 。在请求过程中,productpage服务顺序调用了detAIls和reviews服务的接口 。而reviews服务在响应过程中又调用了ratings的接口 。整个链路跟踪的记录是一棵树:
 
一文搞懂微服务架构演进

文章插图
图片
 
要实现链路跟踪,每次服务调用会在HTTP的HEADERS中记录至少记录四项数据:
  • traceId:traceId标识一个用户请求的调用链路 。具有相同traceId的调用属于同一条链路 。
  • spanId:标识一次服务调用的ID,即链路跟踪的节点ID 。
  • parentId:父节点的spanId 。
  • requestTime & responseTime:请求时间和响应时间 。
 
另外,还需要调用日志收集与存储的组件,以及展示链路调用的UI组件 。
 
一文搞懂微服务架构演进

文章插图
图片
 
以上只是一个极简的说明,关于链路跟踪的理论依据可详见google的Dapper
 
了解了理论基础后,小明选用了Dapper的一个开源实现Zipkin 。然后手指一抖,写了个HTTP请求的拦截器,在每次HTTP请求时生成这些数据注入到HEADERS,同时异步发送调用日志到Zipkin的日志收集器中 。这里额外提一下,HTTP请求的拦截器,可以在微服务的代码中实现,也可以使用一个网络代理组件来实现(不过这样子每个微服务都需要加一层代理) 。
 
链路跟踪只能定位到哪个服务出现问题,不能提供具体的错误信息 。查找具体的错误信息的能力则需要由日志分析组件来提供 。
07 分析问题 - 日志分析日志分析组件应该在微服务兴起之前就被广泛使用了 。即使单体应用架构,当访问数变大、或服务器规模增多时,日志文件的大小会膨胀到难以用文本编辑器进行访问,更糟的是它们分散在多台服务器上面 。排查一个问题,需要登录到各台服务器去获取日志文件,一个一个地查找(而且打开、查找都很慢)想要的日志信息 。
 
因此,在应用规模变大时 , 我们需要一个日志的“搜索引擎” 。以便于能准确地找到想要的日志 。另外 , 数据源一侧还需要收集日志的组件和展示结果的UI组件:
 
一文搞懂微服务架构演进

文章插图
图片
 
小明调查了一下,使用了大名鼎鼎的ELK日志分析组件 。ELK是Elasticsearch、Logstash和Kibana三个组件的缩写 。
  • Elasticsearch:搜索引擎,同时也是日志的存储 。
  • Logstash:日志采集器 , 它接收日志输入 , 对日志进行一些预处理,然后输出到Elasticsearch 。
  • Kibana:UI组件,通过Elasticsearch的API查找数据并展示给用户 。
 
最后还有一个小问题是如何将日志发送到Logstash 。一种方案是在日志输出的时候直接调用Logstash接口将日志发送过去 。这样一来又(咦,为啥要用“又”)要修改代码……于是小明选用了另一种方案:日志仍然输出到文件,每个服务里再部署个Agent扫描日志文件然后输出给Logstash 。
08 网关 - 权限控制,服务治理拆分成微服务后,出现大量的服务,大量的接口 , 使得整个调用关系乱糟糟的 。经常在开发过程中,写着写着,忽然想不起某个数据应该调用哪个服务 。或者写歪了,调用了不该调用的服务 , 本来一个只读的功能结果修改了数据……
 
为了应对这些情况,微服务的调用需要一个把关的东西,也就是网关 。在调用者和被调用者中间加一层网关,每次调用时进行权限校验 。另外 , 网关也可以作为一个提供服务接口文档的平台 。


推荐阅读