基于ServiceComb的分布式运维思路

本文介绍一种不同于微服务架构下通常的运维方式,这种方式能够更加简单、经济的解决一些常见的运维问题。

举个例子。分析业务日志通常采用ELK方案,日志采集系统首先将微服务的日志集中,然后提供给搜索工具进行分析处理,最后通过界面呈现出来,这种方式是比较常见的集中式方式,集中式的好处是能够全局性的分析和处理数据。就错误定位这种场景,如果通过调用链等工具定界到具体的微服务,就不需要采集全局日志,只需要采集出错的微服务的日志即可。分布式运维的思路,就是让运维数据不进行集中存储,独立查询具体微服务运维数据的方法。

分布式运维相对于集中式运维有如下差异:

  • 分布式运维的所有数据都存储在微服务本地,不需要提供强大的分布式数据采集和分析工具,极大的减少用户运维成本。
  • 分布式运维适用于问题已经定界后的场景。
  • 分布式运维需要微服务自己提供运维数据查询接口,在微服务出现故障的时候,可能无法获取到运维数据;同时还需要考虑对于运维数据的访问,不能影响对业务接口的访问。

下面的章节中,介绍使用ServiceComb进行分布式运维的实践。进行分布式运维,需要采用弹性微服务架构:

基于ServiceComb的分布式运维思路_第1张图片

 

本文涉及到的实际例子代码,请访问:

# ServiceComb-Samples
https://github.com/apache/servicecomb-samples/tree/master/porter_lightweight

# 本例子对应PR
https://github.com/apache/servicecomb-samples/pull/4

1 分布式日志查询

ServiceComb实现分布式日志查询,只需要在每个微服务实现日志文件列表查询、日志内容下载两个接口,下面是一个简单的示例。

@RestSchema(schemaId = "log")
@RequestMapping(path = "/v1/log")
public class LogEndpoint implements LogService {
 // protect your file in real applications
 private static final File LOG_DIR =
 new File(DynamicPropertyFactory.getInstance().getStringProperty("servicecomb.samples.logdir", ".").get());
 
 private static final String FILE_POST_FIX = ".log";
 
 @Override
 @GetMapping(path = "/getLogFileList")
 public List getLogFileList() {
   File[] files = LOG_DIR.listFiles(new FileFilter() {
     @Override
     public boolean accept(File file) {
       return isLogFile(file);
     }
   });
 
   List result = new ArrayList<>(files.length);
   for (int i = 0; i < files.length; i++) {
     result.add(files[i].getName());
   }
   return result;
 }
 
 @Override
 @GetMapping(path = "/getLogFileContent")
 public File getLogFileContent(@RequestParam(name = "fileName") String fileName) {
   File file = new File(LOG_DIR, fileName);
   if (isLogFile(file)) {
     return file;
   }
   return null;
 }
 
 private boolean isLogFile(File file) {
   return file.isFile() && file.canRead() && file.getName().endsWith(FILE_POST_FIX);
 }
}

 

可以将这个REST接口作为一个公共模块,所有的微服务都可以依赖使用。查询网关的所有日志文件列表:

http://localhost:9090/v1/log/getLogFileList

查询用户服务的所有日志文件列表:

http://localhost:9090/api/user-service/v1/log/getLogFileList

下载网关的日志文件:

http://localhost:9090/v1/log/getLogFileContent?fileName=access.log

下载用户服务的日志文件:

http://localhost:9090/api/user-service/v1/log/getLogFileContent?fileName=access.log

2 分布式契约管理

ServiceComb通过inspector提供了微服务契约管理能力。具体启用方式请参考:

# 使用inspector功能查看和管理契约
https://bbs.huaweicloud.com/blogs/f0eaa0095c2611e9bd5a7ca23e93a891 

目前这个版本的inspector的REST不会注册到服务中心,因此通过网关调用会提示找不到接口。所以为了演示分布式契约管理,将InspectorImpl的代码拷贝了一份,直接发布为REST接口,详细参考本案例的PR链接:

# 参考 InspectorEndpoint
https://github.com/apache/servicecomb-samples/pull/4

inspector的原理和分布式文件管理的原理一样,也是通过REST接口将相关能力开放出来,供开发者使用。

访问网关的契约管理界面:

http://localhost:9090/inspector/index.html

访问用户管理服务的契约管理界面:

http://localhost:9090/api/user-service/inspector/index.html

3 运维接口线程池隔离

为了让运维接口不影响业务接口的正常运行,一个好的策略是将运维接口放到独立的隔离仓里面运行,ServiceComb配置隔离仓非常容易。

首先定义一个executor

 

 

给运维接口分配独立的executor即可。

servicecomb:
 executors:
   Provider:
     log: servicecomb.samples.executor.groupThreadPool
     inspector: servicecomb.samples.executor.groupThreadPool

建议开发者可以在运维接口的入口打上断点,观察下运维接口与实际业务接口在执行的过程中,所使用的线程池的差异。

4 后续工作

目前的ServiceComb版本还没支持通过网关查询具体某个实例的日志或者契约,需要在负载均衡策略方面进行调整,能够支持按照微服务实例ID进行路由。分布式运维是一个很广泛的课题,除了例子中给出的分布式日志查询、契约管理外,还可以开发非常多解决用户实际问题的功能。对于分布式运维,大家怎么看,可以在文章末尾留言,分享对于这种运维方式的看法,以及期望的分布式运维功能,这些见解和想法可以为ServiceComb启动分布式运维项目,提供一些用户输入。

你可能感兴趣的:(技术剖析)