电子商务系统的性能评测与数据存取优化
来源:万方数据 更新时间:2012-12-07

 随着J2EE技术不断成熟,人们基于J2EE技术架构,建设电子商务系统。J2EE标准是一个开发的标准,用户可以从众多的J2EE服务器中进行选择,人们关心J2FE服务器的性能及其可扩展性。利用EcPerf测试套件对J2EE系统进行了性能测试,结合测试过程找出数据存取的性能瓶颈,并且通过实用的优化策略,提高系统性能,这些策略包括数据库查询处理、数据库系统的加锁模式、异步消息传递、以及运行环境的配置等,通过优化,系统性能有了大幅度的提升。
1 前 言

    Java 2企业版(J2EE)技术自从诞生以来,经过近几年的发展,已经成为建没电子商务系统的重要的技术方案。不象.NET,J2EE是开放的工业标准,由Sun公司领导的工作小组负责制定。这样就带来一个好处,软件厂家就町以根据该标准开发包括应用构件、开发工具和J2EE服务器以及其它相关的产品。目前,有超过30家软件厂家致力于J2EE软件的开发。由于他们开发的产品都基于同样的标准。而该标准是基于Java技术的,不仅保证了J2EE应用程序和操作系统是无关的,还保证用户开发的应用软件可以在不同厂家生产的中间件上运行。给用户带来了前所未有的选择自由性。当平台的功能已经标准化,人们关心的焦点转移到了J2EE服务器的性能和扩展性上。标准化的测试基准成为人们评测和选择J2EE中间件的基本工具,EcPerf是Sun公司和其他J2EE服务器厂家共同设计和开发的基准测试包。软件,一家可以用之测试和改进各自的J2EE应用服务器,各个厂家产品性能的提高直接给用户带来益处。而对于用户来讲,则可以使用该基准测试,来评价和选择不同厂家的产品。我们正是站在用户的角度,通过对Jboss应用服务器和MySQL数据库服务器进行测试。找出系统的性能瓶颈,进行针对性的优化,有效地扩展系统,EcPerf是实际应用的一个缩影,通过运行该测试,把炎踺的性能瓶颈找出来,通过数据存取优化,提高系统的吞吐量:最后,结合测试的经验,提出了J2EE电子商务系统数据存取优化的若干关键原则。

2 J2EE技术体系结构

    J2EE技术是一个平台性的技术,为开发大型分布式的企业应用(包括电子商务系统)提供了基础服务。EJB技术规范是这个技术架构的核心,它定义了J2EE应用的基础关键模块,包括实体EJB、会话EJB和消息传递EJB以及必需的基础服务。J2EE平台使得用户只需要关心商业逻辑的实现,企业计算所需要的公共服务由平台来提供,这些服务包括缓存服务、连接缓冲池、机群管理、失败转移、负载均衡、名字服务等等。要建设一个具有高度扩展性的电子商务系统,这些服务足必需的。由于J2EE平台把基础服务和应甩逻辑清晰分开,中间件厂家致力于平台软件的开发和优化,用户只需要考虑商业逻辑的正确实现即可。

    面对众多的基于J2EE技术架构的中间件,用户如何进行选择呢?厂家一般发布各自的测试结果,这些结果采用的测试基准和测试方法一般不一样,不同厂家的测试可能得出相互矛盾的结论。标准化的测试基准正是适应用户的需要而开发出来的,EcPerf正是这样的测试标准。用户可以使用该标准评测不同厂家的中间件,度量其性能、可靠性和扩展性,从而做出选择。

3 测试基准

    EcPerf基准测试由技术规范和工具软件包构成。技术规范对基准测试进行了详细的描述,包括负载构成、测试运行过程、扩展准则、操作规范以及性能指标的测试等;而相关的工具软件包则提供运行测试和度量性能指标的源代码。EcPerf的开发得到了主要的J2EE厂商的支持,包括BEA、IBM、iPlanel、Oracle、sun、Borland以及IONA等。

    EcPerf基于一个大型的分布式应用进行建模,设计者选择制造过程管理、供应链管理、定单和库存管理作为整个系统的基本功能框架。这是一个重量级的业务系统,需要一个强大的中间件平台的支持。整个系统需要用到众多的中间件服务,包括分布式事务处理、机群管理、负载均衡、超强容错、缓存管理、持久化管理(数据库操作)、数据库连接缓冲池管理等。

    EcPerf数据模型包括四个商业领域的实体。分别是客户管理域(Customer)、制造过程管理域(Manufacturing)、供应链管理域(Supplier)、公司内部信息管理域(Corporation)等。客户管理域处理客户请求和进行其定单管理。制造过程管理域负责“及时”(Just In Time)制造的管理工作。供应链管理域则负责处理和供应商的外部交互事务。公司管理域负责管理包括客户、产品、供应商在内的基础信息。图1把各个管理域所管理的信息和主要事务以及各个管理域的关系表现了出来。


图1 EcPerf商业模理

  3.1 客户管理域

    客户管理域的事务属于在线处理类事务(OLAP),主要的事务包括客户下新的定单、修改定单、查询某个定单的状态、或者查询某个客户的所有定单等。定单的来源包括一般客户和公司客户(分销企业),公司客户的定单称为大定单(Big Orders)。当系统接收到新的定单,需要通过公司管理域,查询客户的信用状况,根据用户是分销商、第一次客户还是老客户,来决定不同的折扣率。已经下的定单还可以进行修改,客户可以查看自己的定单,销售人员则可以查看所有客户的定单。

    3.2 制造过程管理域

    制造过程管理域管理企业的生产线活动。生产的成品称为部件(Widgets),由构件(Components)组装而成。部件和构件,统称为零件(Pans)。生产线的类型有两种,包括计划生产线(Planned Lines)和大定单生产线(Large Order Lines)。计划生产线按照事先规定的数量和生产速度,生产部件;而大定单生产线则根据客户的大定单来进行生产。具体的生产过程由工作单(Work Order)来进行驱动。工作单描述某种类型的部件的数量及其说明。计划生产线的作用,是模拟现实中的根据预测来进行生产的活动,而大定单生产线则模拟现实中的根据客户定单进行生产的情形。当工作单进入系统,系统查询BOM(Bill of Materials,是对生产某个部件需要什么构件以及数量的描述),并且从库存中凋出相应的构件。当部件在生产线上移动,数据库里的部件状态相应进行更新。当工作单完成,数据库的工作单状态随即改变,零件库存量相应做出更新。如果某种构件的库存用光了(可以设置库存警戒线),系统向供应发出购买定单。

    3.3 供应链管理域

    供应链管理域负责和供应商的交互事务。它负责根据所需要汀购的零部件、订购的数量、供应商的报价等信息,决定联系哪个供应商。供应链管理域随即向选定的供应商发送一个采购单(Purchase Order)。采购单包含采购的零部件类型和数量、收货地址、以及发货的截止时间等信息。当供应链管理域接收到相应的零部件后,则往制造管理域发送更新库存的消息,由之更新库存。

    3.4 公司内部信息管理域

    公司内部信息管理域负责管理客户、零件、供应商等信息。客户的信用信息,包括其信用额度等,保存在公司内部信息管理域的独立数据库里,通过这样的信息部署,保证了最大的信息安全。当客户下新定单的时候,系统需要检查其信用信息,这个请求来自客户管理域,发到公司内部信息管理域,由其处理,并返回结果。给客户的折扣信息也在这里进行计算。

    通过以上的分析,各个管理域具有明确的管理职责,有些事务需要跨越多个管理域才可以完成,各个域之问的调用关系通过消息来驱动。系统有可能访问外部信息源,比如向供应商订购零部件等,这样的事务,不仅是跨越系统内各个管理域的、而且是跨越不同系统的事务。由此可见,EcPerf模拟了一个复杂的实际电子商务应用。

    3.5 应用架构

    与供应商的交互事务,使用Java Servlet技术来实现,称为Supplier Emulator,部署到不同的机器上。Supplier Emulator模拟系统向供应商发送零部件采购单,以及收到零部件的交互事务。Supplier Emulator从供应链管理域的Buye6es会话Bean接收定单,经过一定时间的定单处理(睡眠一段时间,时间的长度是定货到发货的平均时间),然后把订购的零部件发送给RreceiverSes会话Bean,图2描述了各个软件模块的关系。

    工作负载由一个多线程Java程序(EcPerf Driver)来生成。EcPerf Driver可以在多个客户端机器上运行,模仿多用户的并发访问。数据的持久化通过EJB技术的实体Bean来实现,系统持两种持久化方法,包括BMP(Bean MaIlaged Persistency)和CMP(Container Managed Persistency)。


图2 Supplier Emulator的交互


    通过没置事务导入速率(Transaction In胁tion Rate),指定每秒钟负载牛成器生成的新定单数量,以及每秒种在制造管理域安排生产的工作单数量。性能以每分种执行的商业操作来进行表示Bbops/min(Benchmark Business Opemtions per Minute),分别对客户管理域和制造域每分钟完成的操作数量进行度量,然后加权汁算出来。

4 测试与优化

    测试套件以J2EE技术(EJB)来实现,部署到测试系统上。测试系统的硬件和软件配置如图3所示。


图3 测试系统的软件和硬件配置


    对J2EE电子商务系统进行优化,有不同的设计模式可以遵循。我们把讨论的重点放在数据的持久化、对象缓存、以及数据库连接的缓冲池管理等几个关键问题上,即对数据存取进行优化。

    4.1 长事务的分解

    采用MySQL 5.0.27版本进行系统的测试。经过实验发现,当采用不同事务存储引擎时,系统的性能有很大的差异。solidDB for MySQL存储引擎,采用的是混合多版本并发控制算法,系统获得了较好的性能。当采用InnoDB存储引擎的时候,在相同的并发用户数量下,系统的性能发生大幅度的下降。如图4所示。


图4 不同存储引擎的系统性能


    InnoDB存储引擎采用的是悲观的加锁并发控制方法,这种并发控制方法是经典的两阶段锁协议。在两阶段锁协议的控制下,当用户需要存取某个数据的时候,该项数据必须事先进行加锁。当并发的事务需要存取相同的数据,导致加锁冲突的时候,请求加锁事务必须退出或者进行等待。利用管理工具,观察到大量的加锁冲突,加锁冲突导致了事务的等待,并且这些事务最终有超过40%被迫退出(因为等待超过时问,或者因为死锁)。于是系统的整体吞吐量大幅度下降。当把事务导入系统的速率提高到20以上的时候,则导致了系统吞吐量突然下降到一个极低的水平。

    改善上述性能I、uJ题的手段有两种,一个是降低锁的粒度,另外一个是降低事务的隔离级别。降低锁的粒度,比如把表级锁降低为行级锁,可以提高并发度,从而提高系统吞吐量。降低事务之间的隔离级别,也可以提高系统的并发度,但是必须考虑数据的一致性是否满足业务要求。使用这两种方法来优化系统,通过设置行级锁和把所有实体Bean的事务隔离级别没置到SQL_TRANSACTION_COMMITTED_READ,然后进行实验,系统的性能有了小幅度的提高,但是InnoDB存储引擎仍然跟SolidDB for MySQL存储引擎的性能彳撤大的差距,如图5所示。


图5 初步优化以后的系统性能


    为了找到性能问题的根源,对各个事务的表现进行了监控。发现scheduleworkOrder事务的执行时问相对比较长,而这个事务对存取的数据加了排他锁,导致需要加锁的其它事务的等待和阻塞。这个事务的执行过程足:建立新的工作单;开始处理该工作单,主要的工作是新建BOM,把需要的零部件从库存中取出,赋予BOM;如果库存里的零部件已经用完,或者数量不够,则需要建立新的零部件采购单,然后发往另一台机器上的Supplier Emulator,等待Supplier Emulator的处理和应答。

    通过仔细分析该事务,我们认为,这种实现方法,存在的问题是,在ScheduleWorkOrder事务中,发送零部件采购单这个步骤延迟了事务的处理,该事务由于需要对数据进行更新,所以所加的排他锁没有得到及时释放。,通过对数据库加锁情况的监控,确实发现执行该事务过程中,存在大量的M_WORKO_RDER、S_PURCHASE_0RDER、S_PURCHASE_ORDERLINE三张表上的加锁冲突,从而印证了上述的分析。

    解决这个性能问题的策略是,把这个大的事务分解成一系列的小事务,这个策略称为Transaction Chopping。把发送采购单的动作分离出来,作为单独的事务来处理,并且保证一旦工作单的事务提交.则采购单最后得到发送和处理。J2EE技术的异步消息传递机制恰恰能够解决这样的问题。

    消息传递机制f9和请求/应答(Request/Reply)的同步远程过程调用(RPC)不同,系统中引入了一个中间件,该中问件从消息的发送者收到消息,然后通过广播的方式发送给接收者(如果接收者只有一个,则是点对点通讯),通过这样的方式把消息的发送者和消息的处理者之问的紧密耦合给解除,消息发送者发送完消息后,可以继续进行其它工作。消息处理者町以异步地处理该消息,最后把处理结果通知消息发送者,而消息的可靠传递则靠中间件来实现。

    消息驱动Bean(Message Driven Bean)是处理消息的软件模块,消息的可靠传递靠消息驱动Bean和EJB服务器共同完成。我们实现一个消息驱动Bean,工作单处理完前两步以后,开始进行提交,那么向消息驱动Bean发送一个send Purchase Onler的消息请求,然后完成提交。EJB容器提供了可靠的消息分发(Guaranteed Message Delivery),保证一旦事务提交,那么它发出来的消息一定在事务提交后的某个时间得到发送,即便消息接收者这时候不在线,等到消息接收者在线后,系统仍然能够可靠地发送该消息。消息的发送过程以异步的方式运行,提高了系统的执行效率。经过上述的改进,系统的性能有了大幅度的提高,如图6所示。,从图中可以看出,innoDB for MysQL存储引擎的系统的吞吐量指标有了进一步的提高。


图6 进一步优化以后的系统性能

4.2 实体EJB的优化

    在J2EF系统中,数据的持久化通过实体EJB来实现。实体瞻an的性能问题一直是争论的焦点,有一部分开发人员反对使用实体Bean,凶为实体Bean的效率太低,而另有相当多的开发人员鼓励使用实体Bean来进行持久化操作。我们认为电子商务系统使片j实体Bt煳技术来进行持久化操作,开发时间大为缩短,经过适当的配置和优化,其性能达到可以接受的水平,但是,如果运行配置有问题,则性能问题就会比较严重。

    如何配置实体Bean的运行环境,才能获得足够的运行性能,是关心和讨论的问题。先来分析实体Bean的牛命周期、和运行原理,当EJB容器通过newInsTANnce生成新的实体Bean实例时,实体Bean开始了其生命周期,这个实例被加入到一个Bean缓冲池中,每类实体Bean有自己的缓冲池,当实体Bean在缓冲池中的时候,不同的实体Bean实例是一样的,没有和数据库里的任何数据行(对象)标泌进行关联,缓冲池中的实体Bean实例都可以响应ejbFind方法的调用。当容器决定使用缓冲池里的某个实体Bean实例来服务客户端的请求时,实体Bean进入Readv状态,这时候,实体Bean和某个对象标识关联起来,客户端可以调用该实体Bean的商业逻辑方法。E-jbLoad()方法和eihstore()方法的作用,是把实体Bean的状态和数据库数据进行同步,一般来讲。当事务开始的时候,容器调用eibLoad()方法把实体Bean的状态从数据库中装载进来,当事务提交的时候.容器又调用ejbstore()方法把实体Bean状态的改变更新到数据库里。实体Bean的生命周期如图7所示。


图7 实体Bean的生命周期


    容器负责对实体Bean的生命周期进行管理。不仅可以缓存实体Bean的实例(实体Bean和数据行不关联),还可以缓存实体Bean的数据(实体Bean和数据行关联)。EJB技术规范规定了三种缓存策略,分别是A(Obiects with Data)、B(Objecf with Identily)、C(0biect without IdenIiIy),这三种设置的具体含义和对性能的影响。JBoss应用服务器支持所有的缓存策略,利用这些缓存机制来提高系统性能。

    对实体Bean的另外一个优化策略是,当知道实体Bean的数据属性,在事务处理过程中不会受到改变,则可以通过对应用服务器的配置文件(JBoss xml)进行该实体Bean的只读属性(Read Only)的指定,来避免不必要的ejbStore()函数的调用。需要注意的是,底层的数据库系统仍然可能由其它应用程序来更新,所以对丁这类实体Bean,应该通过周期性地调用ejbLoad()函数来更新内存中实体Bean的状态。

    另外,当系统同时服务多个客户端的访问时,并发控制是协调用户访问、保证数据一致性的手段。可以把并发控制的责任落实到应用服务器,或者把并发控制的工作由数据库服务器来完成。前者闪为应用服务器负担r并发控制工作,数据库的访问冲突大大减轻,而后者则依赖于数据库系统的并发控制实现。

    对于实体Bean的持久化,有两种实现方式,分别是开发者编写SQL代码的BMP方式,以及容器自动生成SQL代码的CMP方式。ECPerf提供了不同版本的实体Bean实现代码,对其进行了实验比较。图8和图9是实验结果。图8比较了BMP和CMP实现的平均系统吞吐量,图9比较了BMP和CMP实现的事务平均响应时间。


图8 平均系统吞吐量比较


图9 平均响应时间比较


    从图8和图9可以看出,CMP获得了比BMP更好的性能。性能差异的原因是,BMP要装载一个实体,需要渊用两个方法,通过ejbFind()函数的调用获得实体的主键,再通过ejbLoad()获得实体的数据,而CMP的对象查找和数据装载是由容器来完成的,容器进行了针对性优化,把这两个动作合二为一,提高了效率。

    当然,在必须使用BMP的场合,开发人员也可以通过参数化的查询提高数据库查询的性能。容器接收到参数化的查询以后,可以进行预编译,并且在容器内缓存起来,后续的操作,如果查询的模式一样,而只是参数不同,则容器可以从缓存中把该参数化查询提取出来。和参数进行绑定,不需要重新编译,加快执行的过程,从而获得系统性能的提高。需要注意的是,SQL语句执行完毕后·定要关闭,这样后台数据库系统的游标(Cursor)也及时得到关闭,减少数据库服务器的资源开销。

    4.3 避免死锁与过度使JII实体Bean

    在不同的事务中,以不同的顺序访问实体的实例,有可能导致死锁,比如change Order事务和Order Status事务都需要访问到Items表,如果事务T1先访问Item X然后访问Item Y,而另外一个事务T2首先访问Item Y然后Item X。那么很有可能导致死锁。解决死锁的办法是,在不l司事务中以相同的顺序访问实体Bean。

    虽然通过实体Bean进行持久化管理是最自然的方法,但是在某些情形下,采用实体Bean却可能带来性能损失。比如,当需要给客户端展示一个静态的信息列表的时候,通过一个只读事务把一大串信息读取出来,绕过实体Bean这个层次,直接通过JDBC接口用SQL语言进行读取,效率会得到很大的提高,这就是sMP模式(Session Bean Managed Persislency)。

    4.4 优化策略总结

    通过利用标准的测试基准对电子商务应用系统进行测试,结合长期的实践经验,总结了J2EE电子商务系统数据存取方面若干关键的优化策略。包括:

    (1)通过测试不同应用服务器、数据库系统组合下的性能表现,来找出系统性能瓶颈所在。

    (2)度量关键的系统性能指标,来发现和确定真正的性能瓶颈,应用服务器的性能指标包括数据库缓冲池、实体Bean的实例Pool、线程数量、执行的事务等,数据库服务器的性能指标包括事务响应时间、加锁冲突、锁等待时间等。

    (3)对于实体EJB的持久化,CMP优于BMP。

    (4)当需要展示一个大的列表,并且不需要进行更新,则尽量使用SMP设计模式。

    (5)为了减少数据库加锁的冲突,尽可能选用低级别的事务隔离级别;对数据库的加锁粒度进行适当配置,冲突加剧的时候可以考虑使用行级锁。

    (6)使用EJB容器的实体Bean缓存技术,提高系统吞吐量。

    (7)在不同的事务中,以相同的顺序存取实体Bean,以避免死锁问题的发生。

    (8)在保证事务语义正确性的前提下,尽量把一个长的事务划分成适当的短事务,避免一个事务跨越若干个用户交互、跨越多个应用管理域。
    (9)考虑采用消息中间件实现系统的松耦合,消息中间件带来了性能的提高、更好的扩展性和可靠的消息分发保证。

5 总 结

    EcPerf是对J2EE电子商务应用系统进行测试的基准测试套件。利用EcPerf进行性能测试,通过有针对性的数据存取优化,提高了系统的吞吐量。实体刚B的优化是J2EE电子商务系统优化的关键所在,从应用的没计和运行环境的配置两个方面进行优化,获得良好的性能提升效果。