一种数据获取方法、分析方法及系统与流程

文档序号:11154868阅读:296来源:国知局
一种数据获取方法、分析方法及系统与制造工艺

本发明涉及数据处理技术,具体的讲是一种数据获取方法、分析方法及系统。



背景技术:

现有技术中,对业务进行统计分析的实现方式中,对被测程序的源代码具有侵入性,要么引入了第三方的工具包,并按工具包的要求编写代码记录业务信息,要么不引入第三方包,自己实现记录log,或者数据库。而这样的实现方式带来的问题是,业务统计分析的代码带来了维护成本,不容易灵活地去做变更,更关键地是,这样的实现方式依赖于源代码,对没有源代码的部分,无法追踪。

即,现有技术对运行程序数据的获取,存在依赖源码,或对被测系统源码有侵入性等问题,即增加了系统的耦合性,导致维护成本大大提高。



技术实现要素:

为提供一种程序运行时的数据获取方法并利用获取的数据对程序性能参数进行分析,本发明实施例提供了一种数据获取方法,包括:

根据目标代码预先对应用服务器进行参数化配置;

应用服务器根据参数化配置对被测程序进行埋点;

被测程序运行时触发埋点获取程序运行时的数据。

本发明实施例中,所述的应用服务器根据参数化配置对被测程序进行埋点包括:

应用服务器根据参数化配置在函数的入口处和出口处对被测程序进行埋点。

本发明实施例中,所述的程序运行时的数据包括:被测程序代码执行过程中的函数调用数据,所述的函数调用数据包括:调用函数的程序执行时间、调用函数的参数及访问数据。

本发明实施例中,所述的被测程序为Java程序。

同时,本发明还提供一种数据分析方法,法包括:

根据目标代码预先对应用服务器进行参数化配置;

应用服务器根据参数化配置对被测程序进行埋点;

被测程序运行时触发埋点获取程序运行时的数据;

根据获取的程序运行时的数据生成数据分析结果。

本发明实施例中,所述的应用服务器根据参数化配置对被测程序进行埋点包括:

应用服务器根据参数化配置在函数的入口处和出口处对被测程序进行埋点。

本发明实施例中,所述的程序运行时的数据包括:被测程序代码执行过程中的函数调用数据,所述的函数调用数据包括:调用函数的程序执行时间、调用函数的参数及访问数据。

本发明实施例中,所述的根据获取的程序运行时的数据生成数据分析结果包括:

根据被测程序代码执行过程中的调用函数的程序执行时间生成性能分析结果;

根据被测程序代码执行过程中的调用函数的参数生成安全分析结果;

根据被测程序代码执行过程中的调用函数的访问数据生成访问行为分析结果。

本发明实施例中,所述的被测程序为Java程序。

进一步,本发明还提供一种数据分析系统,系统包括应用服务器和数据处理器;

所述的应用服务器包括:

配置模块,用于根据目标代码预先对应用服务器进行参数化配置;

埋点模块,用于根据参数化配置对被测程序进行埋点;

数据获取模块,用于被测程序运行时触发埋点获取程序运行时的数据;

所述的数据处理器,用于根据获取的程序运行时的数据生成数据分析结果。

本发明提供的数据获取方法、分析方法及系统,对被测系统无需额外改造,以应用服务器埋点方式记录了方法的调用参数,耗时等信息。遵循标准接口去埋点,具有良好的适配性,且可以按需要进行定制,具有良好的扩展性。服务端的分析组件能从各个维度分析数据,可按需要扩展,提升了数据利用的价值。能进行灵活的配置,能和服务端灵活通信和控制,系统整体设计的耦合度较低,灵活性较高。

为让本发明的上述和其他目的、特征和优点能更明显易懂,下文特举较佳实施例,并配合所附图式,作详细说明如下。

附图说明

为了更清楚地说明本发明实施例或现有技术中的技术方案,下面将对实施例或现有技术描述中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图仅仅是本发明的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据这些附图获得其他的附图。

图1为本发明公开的数据获取方法的流程图;

图2为本发明实施方式的系统架构图;

图3为本发明实施例中的代码截图;

图4为本发明实施例中的代码截图;

图5为本发明实施例中的代码截图;

图6为本发明实施例中的代码截图;

图7为本发明实施例中的代码截图;

图8为本发明实施例中的代码截图;

图9为本发明实施例中的一个树形调用结构框图;

图10为本发明实施例中服务器端组件框图。

具体实施方式

下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本发明保护的范围。

如图1所示,为本发明提供一种数据获取方法,其包括:

步骤S101,根据目标代码预先对应用服务器进行参数化配置;

步骤S102,应用服务器根据参数化配置对被测程序进行埋点;

步骤S103,被测程序运行时触发埋点获取程序运行时的数据。

本发明实施例中,所述的程序运行时的数据包括:被测程序代码执行过程中的函数调用数据,所述的函数调用数据包括:调用函数的程序执行时间、调用函数的参数及访问数据。

本发明的技术方案其特点是能对程序运行的函数代码做采样和分析,具体来说是在函数的入口和出口进行埋点采样,并可以按需要对函数输入参数做记录,本发明的实施例中,一份完整的采样记录是一个树形结构,其有且仅有一个根节点,树的节点表示一次函数调用,当前节点的子节点表示当前节点的函数调用了子节点函数。对业务相关的处理函数来说,其输入参数通常都有很强的业务相关性,只要获取了这些输入参数,就可以对业务统计分析。

现有的对业务进行统计分析的实现方式中,对被测程序的源代码具有侵入性,要么引入了第三方的工具包,并按工具包的要求编写代码记录业务信息,要么不引入第三方包,自己实现记录log,或者数据库。而这样的实现方式带来的问题是,业务统计分析的代码带来了维护成本,不容易灵活地去做变更,更关键地是,这样的实现方式依赖于源代码,对没有源代码的部分,无法追踪。而本案解决了这样的痛点:不需要被测程序的源代码,对被测程序没有侵入性,可随时打开或关闭追踪功能,将数据的获取与分析分离,并提供了丰富的分析功能。

如图2所示,为本发明实施方式的系统架构图,Java的应用程序一般是部署在应用服务器202(本发明实施例中应用服务器包括:weblogic,jboss,tomcat等)上的,当然也可能是独立的程序不需要应用服务器。但是不论应用部署方式如何,都需要在程序启动时加载agent,而agent会对应用程序代码进行埋点,并将埋点获得的数据传回数据处理服务器server202,由数据处理服务器202对数据进行进一步分析。

应用服务器Agent节点。Agent的任务包括:完成代码埋点;将收集到的数据传到服务端;接收服务端的控制指令。代码埋点只在函数的入口和出口处,此外,并不是每处函数入口参数都做记录,而只在必要的地方(如url访问入口)记录,这样设计的原因在于,一方面在于用户基本只关心部分组件的访问参数记录,另一方面在于由于程序自身的内在逻辑关联,可以大致推导前续的访问参数序列或后续的访问参数序列,甚至于可以根据关键参数在测试环境中还原整个运行过程,所以,记录关键的入口参数基本就满足了分析需要。同理,函数返回参数基本是不记录的,因为可以通过输入参数计算出返回参数,如确有需要(如统计返回的应答码),本案支持以配置或扩展的方式记录返回参数。

本发明实施例中,Agent埋点是标准的方式,简要说明如下:

Java程序启动方式是找到main函数入口并执行,举例写了一个Helloword的程序,里面包含一个main函数,则运行这个Helloword程序的方式是:java Helloword。要加载agent,就要将启动方式改为java-javaagent:agent.jar Helloword。-javaagent参数是java原生支持的接口,本案agent端的实现就是利用这一接口。所以,应用如果部署在weblogic上,我们需要将agent的jar包放到weblogic的bin目录下,并修改bin目录下weblogic的启动脚本,让其带上-javaagent的参数即可。其它应用服务器的如jboss,tomcat,过程与weblogic类似,只是目录结构,脚本不一样而已。Agent和server之间的通信通过参数进行配置。Agent的配置参数主要包括:include,exclude表示哪些代码需要埋点或不埋点;ip,port表示数据处理server端的通信地址;localport表示agent监听端口,用来接收服务端的启停等命令;localfile表示agent将数据写入本地文件的路径。

数据处理服务器Server节点。Server节点的任务包括:接收agent的数据;完成多样的数据分析;对agent进行启停等控制。Server端通过socket接收agent的数据,并记库,供后续分析。数据的分析包括,访问入口分析,安全分析,性能分析等。Agent提供启停接口是为了灵活控制,譬如只收集某段时间的数据。

本发明实施例系统的可扩展性:

当被测系统越来越多时,我们需要在每个被测系统上部署Agent,这是个一次性的操作。所以有多少被测系统就有多少agent节点存在。但server节点则可以按需分配,如果某server节点处理能力较强,则可以考虑接收多个agent的数据,如果server节点不够用了,则可以考虑扩充server节点。出于高可用考虑,如果agent发现某server不可用,可以将数据写入本地文件中,后续将文件导入server端即可。

对本发明实施例的Agent端埋点说明:

Agent埋点范围可以通过include,exclude进行参数化配置。埋点的技术原理在于java是基于字节码解释执行的,只需要对目标程序的字节码进行修改得到一份新的字节码,java虚拟机执行新的字节码,触发埋点代码就可以进行数据收集。本案对目标程序字节码的修改并不修改原程序的执行逻辑,只是在方法的入口处加入一段字节码表示方法调用开始,并在方法的出口处(如返回指令return)之前加入一段字节码表示方法调用结束,追踪记录一系列的调用开始和结束事件,就形成了方法在运行时的树形调用结构数据。

为完成字节码埋点任务,本发明实施例可采用java字节码操作工具asm,但并不以此为限。本发明实施例中agent埋点的一个特别考虑的地方是基于技术规范、标准接口去埋点,使agent能适应程序代码的不同实现。举例而言,java定义了数据操作的接口类如Connection,PreparedStatment等,并定义了接口类的相关函数,而DB2,mysql的数据库驱动程序基于接口定义给出了不同的实现,本案基于接口函数定义去进行埋点,就能适应不同的实现。同时,如果确有需要,如针对DB2做埋点优化,也可以定制agent进行特殊处理。

以一个简单的例子,说明如何埋点。参考如图3所示的代码片段,Calc类有一个做整数加法的函数add,该函数编译后的字节码截图如图4所示,其只列出了核心的字节码指令,略去了一些不影响函数执行补充信息指令,如表示行信息的LINENUMBER指令。JAVA字节码指令中,I表示int,ILOAD表示从某位置加载int,ISTORE表示将int存入某位置,IRETURN表示返回int值。

在add函数入口埋点,埋点逻辑要放在任何add函数的指令执行之前,即L0之前。在add函数出口埋点,埋点逻辑要放在返回指令之前,即IRETURN指令之前。如果是对源码做改动达成埋点的目的,则源码可能是如图5所示的形式,其中的StartEnd类的start方法和end方法,对add方法的入口和出口信息进行了捕捉。本例StartEnd只是做了简单的输出,代码截图如图6所示。

本申请的技术方案不依赖源代码,直接修改字节码完成了埋点,原理是使用字节码修改工具,在方法入口出口处插入函数调用INVOKE指令。埋点后的add函数字节码的截图如图7所示。

本发明实施例中的埋点,具体是利用了INVOKESTATIC函数调用指令,INVOKESTATIC指令之前的LDC,ILOAD指令是为函数调用传入参数,如此,就达到了和修改源代码一样的埋点效果。将埋点完后的add方法交由JAVA虚拟机执行,就会触发埋点,收集到add方法执行的信息。总结分析字节码时,入口和出口识别规律:在访问了方法的名称参数等信息后,接下来就是函数的入口,此时进行入口埋点,使函数的所有指令在入口埋点之后。在访问到返回指令时,如IRETURN,FRETURN等,先进行出口埋点,再访问返回指令,使出口埋点在返回指令之前。特别注意的是,函数的入口有且仅有一个,但出口可以有多个,所以,一个函数可能进行多次出口埋点。

本实施例中如何确认方法的开始和结束:

在前面的例子中,分别调用start和end方法,来进行入口和出口埋点,示例代码只是进行了输出,而要准确匹配方法的开始和结束,需要处理好父子函数调用关系。为此,本案设计了MethodFrame的数据结构,其包含一个指向父调用的引用,还包含当前方法的名称、参数等信息。处理流程如下:

1、发生start调用,表示方法执行开始,为该start调用创建MethodFrame数据结构,记为c。如果当前线程调用的MethodFrame信息为空,则此start调用是调用的根,且c.parent=null。如果当前线程调用的MethodFrame信息不为空,记为p,更新c.parent=p,且更新当前线程调用的MethodFrame信息为c,即由p变更为c。

2、发生end调用,表示方法执行完毕,取得当前线程调用的MethodFrame信息,记为c,并取得c的parent信息,记为p,即p=c.parent。将当前线程调用的MethodFrame信息更新为p,即由c变更为p。如果p==null,表示根调用结束,此时,我们已经拿到了完整的父子调用关系,保存该调用关系供后续分析。如果p不为null,表明还要处理更多的start-end调用事件。

举例:假设有如下start-end序列:start(a)start(b)end(b)start(c)start(d)end(d)end(c)end(a)。则由上面两步处理可得:a是根调用,b的parent是a,c的parent也是a,即a分别调用了b和c。d的parent是c,即c调用了d。

埋点数据的时序说明:

以一个简化的查看订单的网页访问为例,假定应用程序部署在jboss应用服务器上,可能的过程如下:

(1)用户在浏览器上,访问http://www.buy.com/order/listall.action?userid=1001;

(2)Jboss服务器收到请求,并将请求分配到能处理/order/listall.action这个url的http处理类中。如果没有对应的处理类,则返回HTTP 404应答。此处我们假定有相应的http处理类存在;

(3)为了返回订单信息在网页上展示,http处理类访问了数据库。即http处理类又调用了数据库的连接获取函数,并执行了sql语句(可能是select*from orders where userid=1001)进行数据库查询;

(4)用户在网页上产看到了订单信息。

本例中,应用的访问入口是http协议暴露的url(/order/listall.action),并带上了访问参数(userid=1001),在实际应用中,一般会暴露多个url访问入口,并配合使用各自的访问参数。Jboss是基于J2EE规范标准的应用服务器,而J2EE规范中,重要的一部分就是servlet规范。现阶段servlet的实现,主要还是对http协议做面向对象的封装,如将请求封装成HttpServletRequest对象,响应封装成HttpServletResponse对象。Servlet的接口规范中定义了2个函数,service(HttpServletRequest request,HttpServletResponse response)和doFilter(ServletRequest request,ServletResponse response,FilterChain chain),本案的实现就是对service和doFilter这样的标准函数做埋点,并对函数的输入参数做了处理,获取了http访问的url和参数。而weblogic和tomcat都是基于J2EE规范的服务器,所以,本案的实现方式具有通用性。此外,如果应用不是J2EE的程序,即采用了新的标准或新的实现方式,本案也还是可以做支持,引入的额外工作是要类似分析J2EE规范一样去分析新的标准和实现方式。

以service(HttpServletRequest request,HttpServletResponse response)为例,可以从第一个参数request对象中获取请求的url,因为request对象暴露了标准的getRequestURI()函数来分别获取请求url。本案的处理方式是在入口埋点时,先调用request对象的getRequestURI()函数拿到url值,并将url值传给埋点的start函数,这样start调用发生时,创建的MethodFrame信息就记录到了该url值。此番操作插入的字节码如图8的代码截图所示。

本发明实施例中访问参数的获取也是类似,调用request对象的getParameterMap()函数拿到结果值,并将该结果值传给start函数即可,将url和参数获取一并处理,稍稍复杂一点,即要插入更多的字节码来完成工作,但原理都是一致的。

假定本例第(2)步,是由一个processHttp的函数作为入口处理http的请求,并调用了函数isEmpty对参数userid进行是否为空的判断,接着调用了queryDB的函数进行数据库查询。本例第3步,进行数据库访问,假定由queryDB函数完成。数据库访问也有相应的标准接口函数定义,如prepareStatement(String sql)函数,在此不一一枚举,本案也对这种标准接口函数做了埋点,获取访问数据库的sql语句。具体到本例,假定queryDB函数调用了prepareStatement函数进行数据库查询,则其执行的sql语句(select*from orders where userid=1001)将会被记录下来。生成一树形调用结构,如图9所示,为本实施例生成的一树形调用结构图,用户的每一次访问都会得到一份调用结构数据,agent负责将这些数据传给server端。

Server端主要组件说明,如图10所示,下面对server端主要组件做说明。

通讯组件:负责网络通讯,主要任务包括接收来自agent的数据以及对agent的收集做开始、停止这样的控制操作。

性能分析组件:对抓取的数据做性能统计分析。Agent在对方法埋点的时候,记录了方法开始和结束的时间,以此为依据对方法耗时进行统计分析。方法的总执行时间是方法自身逻辑执行时间和该方法调用的其他方法耗时的和值,方法的净执行时间是方法的总执行时间减去该方法调用其他方法耗时的差值。用图2的树形调用结构来说,某节点的总耗时包含了该节点的所有直接子节点耗时以及自身耗时,某节点的净耗时是总耗时减去所有直接子节点耗时。性能分析组件主要是按特征进行分类统计。如以系统的url为特征进行分类,统计每个url访问的最短处理时间,最长处理时间,平均处理时间等。此外,通常应用的数据库访问是比较耗时的,性能分析组件会特别地对sql语句进行分析,指出哪些sql执行耗时较多,需要优化性能。如果需要以自定义的维度进行分析,可以对组件进行扩展。

安全分析组件:程序的访问入口可能接收到恶意的访问参数,引发数据泄露、程序异常等安全问题。Agent埋点时,在方法入口处会记录方法的参数,安全分析组件以此为基础进行安全分析。安全分析组件提供两方面的功能:一是识别恶意访问参数和程序异常,给出安全优化建议;二是以正常参数为基础,变异构造出异常参数,并以该异常参数访问程序,对程序做安全评估。就前文查看订单的例子来说,用户访问/order/listall.action这个url时,提供了参数userid=1001,其中key是userid,value是1001,而1001这个值,会作为参数传递到后续的数据库访问操作中,如果应用程序没有做防御机制,则就可能引起sql注入这一安全问题。安全分析组件会分析访问参数的<key,value>对的分布情况,包括是否出现了新的访问key值,是否key对应的value出现新的类型。具体到上例就是,是否出现了userid之外的key作为输入,如开源框架struts就曾发生过对http参数解析导致的任意代码执行漏洞,而这个漏洞是在访问时带上额外参数触发;是否userid的值出现了新的类型,如‘or 1=1是一种已知常见的sql攻击向量,则如果参数值出现了‘or 1=1就很可能是恶意的访问行为,同理,安全组件通过修改正常访问参数为攻击向量进行访问,就可以对应用做安全评估。对常见的风险如sql注入攻击,安全分析组件会对执行的sql进行分析,判断是否使用了安全的api函数,以及有没有sql注入发生。

访问行为分析组件:主要通过对访问数据进行在线或离线的挖掘分析,识别用户的行为特征,用户来源,偏好,留存率,活跃程度等。行为分析同时有助于测试人员对测试场景,案例进行查漏补缺。对不同的应用来说,需要识别的用户特征一般会有所不同。对搜索类应用来说,可能需要识别频度最高的关键词;对资讯类应用来说,可能需要识别访问的热点,如哪些url近期经常被访问;对购物应用来说,可能关注用户从下订单到支付的整体流程是否顺畅,是否重复购买等等。以上种种,本案可通过访问参数统计分析,url统计分析,访问序列分析实现。

本发明的技术方案对被测系统无需额外改造,以agent埋点方式记录了方法的调用参数,耗时等信息。agent遵循标准接口去埋点,具有良好的适配性,且可以按需要进行定制,具有良好的扩展性。服务端的分析组件能从各个维度分析数据,可按需要扩展,提升了数据利用的价值。agent能进行灵活的配置,能和服务端灵活通信和控制,系统整体设计的耦合度较低,灵活性较高。

本领域内的技术人员应明白,本发明的实施例可提供为方法、系统、或计算机程序产品。因此,本发明可采用完全硬件实施例、完全软件实施例、或结合软件和硬件方面的实施例的形式。而且,本发明可采用在一个或多个其中包含有计算机可用程序代码的计算机可用存储介质(包括但不限于磁盘存储器、CD-ROM、光学存储器等)上实施的计算机程序产品的形式。

本发明是参照根据本发明实施例的方法、设备(系统)、和计算机程序产品的流程图和/或方框图来描述的。应理解可由计算机程序指令实现流程图和/或方框图中的每一流程和/或方框、以及流程图和/或方框图中的流程和/或方框的结合。可提供这些计算机程序指令到通用计算机、专用计算机、嵌入式处理机或其他可编程数据处理设备的处理器以产生一个机器,使得通过计算机或其他可编程数据处理设备的处理器执行的指令产生用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的装置。

这些计算机程序指令也可存储在能引导计算机或其他可编程数据处理设备以特定方式工作的计算机可读存储器中,使得存储在该计算机可读存储器中的指令产生包括指令装置的制造品,该指令装置实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能。

这些计算机程序指令也可装载到计算机或其他可编程数据处理设备上,使得在计算机或其他可编程设备上执行一系列操作步骤以产生计算机实现的处理,从而在计算机或其他可编程设备上执行的指令提供用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的步骤。

本发明中应用了具体实施例对本发明的原理及实施方式进行了阐述,以上实施例的说明只是用于帮助理解本发明的方法及其核心思想;同时,对于本领域的一般技术人员,依据本发明的思想,在具体实施方式及应用范围上均会有改变之处,综上所述,本说明书内容不应理解为对本发明的限制。

当前第1页1 2 3 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1