使用Hadoop和ELK进行业务代码分析!分分钟捉到Bug!

大数据是计算领域的新高地,它有望提供一种方法来应对二十一世纪不断增长的数据生成。越来越多的大数据爱好者正在涌现,越来越多的公司正在采用各种大数据平台,并希望提出以客户为中心的解决方案,帮助他们在竞争激烈的市场中取得领先地位。虽然最常见的是使用大数据解决方案来推导针对业务收入的分析,但作为IT公司的开发人员,我的方法却略有不同。

以下是Hadoop生态系统用于监控,分析和改进IT公司软件组件的用例。

使用Hadoop和ELK进行业务代码分析!分分钟捉到Bug!_第1张图片


软件基础设施和组织


IBTech是QNB Finansbank的IT子公司,QNB Finansbank是土耳其最大的银行之一。银行交易在逻辑上划分为业务模块,如客户,存款,现金管理,财务,贷款等。一般又分为手机、网络、网银、呼叫中心、ATM、分行等进入渠道。

因此,我们内部开发的CoreBanking生态系统包含一个主要的后端群集,其中所有交易都在其中进行,并且几个前端应用程序在不同平台上工作并使用各种框架编写。我们的系统具有面向服务的体系结构,这意味着来自客户端的所有请求以及后端模块之间的所有交互都以服务的形式进行处理。

每个请求都作为服务调用进入到服务器,并在响应之前执行几个内部服务的调用。所有服务都由内存服务总线动态调用和路由。


我们的动机


在采用Hadoop之前,我们现有的监控工具无法捕获有关系统运行时的自定义详细信息。我们一直在使用HP-BSM,它可以监控我们的服务入口点和各种外部层。这是一个很好的起点,但在高级分析需要更详细或自定义的信息时会失败。

使用传统方法(如将数据存储在关系数据库或文件系统中)以及按顺序读取和分析数据的自定义实施监控和分析工具也证明是非常不可行的,尤其是当所涉及的系统每天处理超过2亿笔交易时,每个交易都会触发大约20个内部服务调用和15个SQL语句。

除了监控问题之外,由于服务调用的动态特性,我们无法正确和完全地识别从不同端点或静态模块依赖性发出的服务调用的可能路由和分支。相关分析将通过检查我们现有工具生成的静态代码分析来完成,该工具需要大量人力资源,结果还是不完整,使任务几乎不可能完成。

由于IT团队包含各种角色,这些角色使用不同的技术和不同的业务领域,并且彼此互不关心,因此,对于财务部后端开发人员来说,要了解他们在移动银行应用程序中对特定屏幕的特定服务更改的影响并不容易。当呼叫中心前端开发人员按下某个页面上的按钮调用某个服务时,他们也不清楚是什么导致了性能下降。

所有这些问题促使我们使用Hadoop及其各组件监控,分析和改进软件组件IT公司软件组件。


实施细节


我们编写了一个名为Milena的模块,它收集通过我们的核心银行服务器的所有运行时数据,并将数据发送到Kafka。我们配置了从Kafka读取这些流的Flume代理,并将它们保存到HDFS。前一天的数据在一天结束时通过Spark批次进行分析,结果在ElasticSearch上编制索引并在我们的Kibana仪表板中可视化。我们称这整个系统为Insights。

使用Hadoop和ELK进行业务代码分析!分分钟捉到Bug!_第2张图片

图1:整个系统的概述

我们的运行时数据包括有关事务的标识信息、有关客户机和用户的信息、已执行的服务、已执行的SQL语句和受影响的表、返回代码以及与每个可执行单元对应的开始和完成时间戳。

我们的OLTP服务器处理大约2亿个事务,每天产生3.3 TB的数据。存储的原始数据的一个示例是:

 
   
{	
"header": {	
      "aygKodu": "      ",	
      "transactionState": 9,	
      "entranceChannelCode": "999",	
      "jvmID": "999",	
      "pageInstanceId": "",	
      "channelTrxName": "IssueCreditTransaction",	
      "processTime": "075957",	
      "processState": 9,	
      "channelHostProcessCode": "0",	
      "processDate": "20170328",	
      "correlationId": "3e03bb4f-d175-44bc-904f-072b08116d4e",	
      "channelCode": "999",	
      "userCode": "XXXXXXXXX",	
      "transactionID": 99999999999999999999999999,	
      "processType": 0,	
      "environment": "XXXX",	
      "sessionId": "99999999999999999999999999",	
      "clientIp": "999.999.999.999"	
   },	
   "services": [	
  {	
         "returnCode": 0,	
         "channelId": "999",	
         "parent": 0,	
         "poms": [],	
         "endTime": 1490677197467,	
         "platformId": "9",	
         "serviceName": "CREDIT_ISSUANCE_SERVICE",	
         "startTime": 1490677197466,	
         "level": 1,	
         "environment": "XXXX",	
         "order": 1,	
         "additionalInfos": {},	
         "queries": [],	
         "referenceData": "CREDIT_ISSUANCE_OPERATION_PARAMETERS"	
      },	
  (...),	
  {	
         "returnCode": 0,	
         "channelId": "999",	
         "parent": 5,	
         "poms": [],	
         "endTime": 1490677197491,	
         "platformId": "9",	
         "serviceName": "GET_CUSTOMER_INFORMATION",	
         "startTime": 1490677197491,	
         "level": 6,	
         "environment": "XXXX",	
         "order": 18,	
         "additionalInfos": {},	
         "queries": [	
            {	
               "tables": "CUSTOMER_MAIN,CUSTOMER_EXT",	
               "startTime": 1490677197491,	
               "order": 1,	
               "queryName": "SELECT_CUSTOMER_DATA",	
               "isExecuted": true,	
               "parent": 18,	
               "type": 1,	
               "endTime": 1490677197491	
            }	
         ],	
         "referenceData": ""	
      },	
      {	
         "returnCode": 0,	
         "channelId": "999",	
         "parent": 6,	
         "poms": [],	
         "endTime": 1490677197467,	
         "platformId": "9",	
         "serviceName": "GET_PRICING_POLICY",	
         "startTime": 1490677197466,	
         "level": 7,	
         "environment": "XXXX",	
         "order": 7,	
         "additionalInfos": {},	
         "queries": [],	
         "referenceData": ""	
      },	
      {	
         "returnCode": 0,	
         "channelId": "999",	
         "parent": 5,	
         "poms": [],	
         "endTime": 1490677197468,	
         "platformId": "9",	
         "serviceName": "CALCULATE_ISSUANCE_COMMISSIONS",	
         "startTime": 1490677197466,	
         "level": 6,	
         "environment": "XXXX",	
         "order": 6,	
         "additionalInfos": {},	
         "queries": [],	
         "referenceData": ""	
      },	
      (...),	
      {	
         "returnCode": 0,	
         "channelId": "999",	
         "parent": 18,	
         "poms": [],	
         "endTime": 1490677197491,	
         "platformId": "9",	
         "serviceName": "CREDIT_ISSUANCE_DOCUMENT_SERVICE",	
         "startTime": 1490677197491,	
         "level": 9,	
         "environment": "XXXX",	
         "order": 19,	
         "additionalInfos": {},	
         "queries": [	
            {	
               "tables": "ISSUANCE_MAIN,CUSTOMER_MAIN",	
               "startTime": 1490677197491,	
               "order": 1,	
               "queryName": "SELECT_CUSTOMER_ISSUANCE_INFORMATION",	
               "isExecuted": true,	
               "parent": 19,	
               "type": 1,	
               "endTime": 1490677197491	
            }	
         ],	
         "referenceData": ""	
      },	
      (...)	
   ]	
}

我们有各种自定义仪表板,旨在提供有关核心银行业务应用程序的总体性能、模块间和模块内依赖性以及使用统计信息的见解。我们可以有效地可视化不同服务之间的关联。这使我们能够预见服务中的更改或中断对其他服务和应用程序的影响。以下是一些仪表板中的一些示例,其中假设场景涉及多个参与方。

假设IT监控专家着手减少核心银行系统的总体响应时间。他们首先检查General-TOP信息板,以查看最耗时的交易。他们很快发现移动银行应用程序的信用发行交易IssueCreditTransaction持续时间过长。

使用Hadoop和ELK进行业务代码分析!分分钟捉到Bug!_第3张图片

图2:通用TOP仪表板,其中观察到IssueCreditTransaction占核心银行总时服务器间的16%。

他们通知交易的所有者,移动银行的前端开发团队,关于这个发现的情况。团队中的前端开发人员继续分析这个特定事务的依赖性。

他们发现在这次交易中花费的时间有60%发生在CREDIT_ISSUANCE_SERVICE中,后者由CREDIT_ISSUANCE_DOCUMENT_SERVICE主导。因此,他们很容易找到CREDIT_ISSUANCE_DOCUMENT_SERVICE的低性能:

使用Hadoop和ELK进行业务代码分析!分分钟捉到Bug!_第4张图片

图3:上述JSON中事务的依赖关系树。最左边的图显示了此事务中内部服务的调用计数。中间的图表显示了内部服务中经过的总时间,最大的部分是此事务响应时间的主要负担。最右边的图显示了此事务的树结构,其中显示了从根到叶的所有可能路径。

移动前端开发团队要求CREDIT_ISSUANCE_DOCUMENT_SERVICE的所有者,贷款后端开发团队调查此问题。后端开发人员通过在Service Performance仪表板中搜索所述服务来开始检查所述服务。该分析揭示了两个独立的问题,代码中花费了大量时间,而SELECT_CUSTOMER_ISSUANCE_INFORMATION查询代价很高。

使用Hadoop和ELK进行业务代码分析!分分钟捉到Bug!_第5张图片

图4:示例JSON数据中CREDIT_ISSUANCE_DOCUMENT_SERVICE的详细服务分析。在上半部分,您可以看到此特定服务的平均持续时间,包括或排除其调用的内部服务所经过的时间。在右下图中,显示了此服务通过时间的层。

对于代码的性能问题,后端开发人员在将代码部署到生产环境之前对优化和测试请求进行了一些更改。测试人员,他们考虑到变更的服务,尝试列出测试用例。他们查看调用树分析,查看哪些入口点导致调用此服务,通过哪些路径,然后继续测试这些方案。

使用Hadoop和ELK进行业务代码分析!分分钟捉到Bug!_第6张图片



图5:CREDIT_ISSUANCE_DOCUMENT_SERVICE的调用树分析。左侧的图表说明了导致此服务的所有可能路径,包括示例JSON中的路径。右侧的图表显示了达到此服务的所有可能的入口点和通道。

对于查询的性能问题,数据架构师检查SQL stamement,并得出应在表ISSUANCE_MAIN上创建新索引的结论。他们请求创建索引以供数据库管理员批准。在收到为ISSUANCE_MAIN表创建新索引的请求后,DBAs意识到索引创建成本很高,并且可能导致表被锁定一段时间。

它们通知流程管理专家在索引创建期间将受服务阻塞影响的事务,并通过观察表的调用树分析来相应地计划操作。

使用Hadoop和ELK进行业务代码分析!分分钟捉到Bug!_第7张图片

图6:ISSUANCE_MAIN表的调用树分析。


结果


该系统的第一阶段于2016年10月投入生产,并根据客户反馈和需求不断扩展和改进。大约在2017年1月左右,它已经成熟到最终状态,此后一直在频繁使用。现在该项目是实时且稳定的,它已经大大影响了项目的生命周期。已经吸引了来自不同背景的各种角色。

开发人员和测试人员正在审查变更中受影响的组件,并确保与必要的开发和测试顺利集成。

项目投入使用后,由于影响分析不充分,缺乏影响分析而导致的生产误差大大减少。流程管理专家可以审核结果,以查看哪些特定交易会受到特定功能计划内或计划外中断的影响,并相应地采取相应措施。


结论


对于一家现代科技公司来说,探索大数据以分析具体业务收入的数据至关重要。然而,不应忽视的是,一旦消除了手工和琐碎的工作负荷,高能力的IT员工将能够专注于他们工作中更具创新性的方面。

除此之外,软件基础设施是企业整个系统最低层次的核心,是是否允许系统的敏捷性、性能、灵活性和能力的关键组件。如果想在软件基础架构中正确地进行改进,并达到一定程度效果和产生更大的收入,这可以通过有效的监控和分析来实现。因此使用Hadoop或另一个大数据平台来达成这一目标,是一个非常值得考虑的方案。

640?wx_fmt=jpeg

长按二维码 ▲

订阅「架构师小秘圈」公众号

如有启发,帮我点个在看,谢谢↓

你可能感兴趣的:(使用Hadoop和ELK进行业务代码分析!分分钟捉到Bug!)