发布新日志

  • 测试需求分析方法

    2011-07-07 10:36:03

    转载http://www.uml.org.cn/requirementproject/201011304.asp
     

    软件测试需求的分析方法

     

    2010-11-30 作者: sdstc 来源: 软件测试网采编

     

      软件测试需求是开发测试用例的依据,测试需求分解的越详细精准,表明对所测软件的了解越深,对所要进行的任务内容就越清晰,对测试用例的设计质量的帮助越大。详细的测试需求还是衡量测试覆盖率的重要指标,测试需求是计算测试覆盖的分母,没有详细的测试需求就无法有效的进行测试覆盖计算。

     软件测试执行阶段是由一系列不同的测试类型的执行过程组成的,每种测试类型都有其具体的测试目标和支持技术,每种测试类型都只侧重于对测试目标的一个或多个特征或属性进行测试,准确的测试类型可以给软件测试带事半功倍的效果。

     现有的软件测试分析技术不太成熟,对测试需求和测试类型的分析,所采用的方法主要是根据经验进行收集、整理,该方法依赖于测试设计人员的测试经验,由此方法得出的测试需求、测试类型往往导致测试用例设计不充分,测试覆盖度低,测试目的性不强,容易遗漏等缺陷。

     可见,如何对测试需求进行细致的整理分析,明确测试执行时的测试类型,是一个亟待解决的问题。

     有鉴于此,本方法的主要目的在于提供一种软件测试需求的分析方法,可以方便、详尽的获取测试需求,明确测试执行时需要实施的测试类型。

     为实现上述目的,本方法提供了一种软件测试需求分析的方法,包括以下步骤:

     a)列出软件开发需求中具有可测试性的开发需求;

     b)对步骤a)列出的每一条开发需求,形成可测试的分层描述的测试需求;

     c)对步骤b)形成的每一条测试需求,从GB/T 16260.1-2006《软件工程 产品质量 第1部分:质量模型》中定义的软件内部/外部质量模型来确定软件产品的质量需求;

     d)对步骤c)所确定的质量需求,分析测试执行时需要实施的测试类型;

     e)建立测试需求跟踪矩阵,对测试需求进行管理。

     具体实施方式:

     下面结合附图及实施例对本方法做详细的说明。

     建立开发需求列表,参见图2。将每一条软件需求对应的开发文档及章节号作为软件需求标识,使用软件需求的简述作为原始测试需求描述,没有文档来源的开发需求可用隐含需求或遗漏需求进行标识,标明软件需求获取的来源信息,如开发文档、相关标准、与用户或开发人员的交流等。

     由于在提取的开发需求中可能存在重复和冗余,需要进行整理,通过以下方法整理开发需求:

     1)删除:删除原开发需求列表中重复的、冗余的含有包含关系的开发需求描述;

     2)细化:对太简略的开发需求描述进行细化;

     3)合并:如果有类似的开发需求,在整理时需要对其进行合并。

     在图2表中,对于每一条开发需求,从测试角度来考虑,形成可测试的分层描述的测试需求。具体地,通过分析每条开发需求描述中的输入、输出、处理、限制、约束等,给出对应的验证内容;通过分析各个功能模块之间的业务顺序,和各个功能模块之间传递的信息和数据,对存在功能交互的功能项,给出对应的验证内容。

     对每一条测试需求,从GB /T16260.1定义的软件质量子特性角度出发,确定所对应的质量子特性。即,从适合性、准确性、互操作性、保密安全性、成熟性、容错性、易恢复性、易理解性、易学性、易操作性、吸引性、时间特性、资源利用性、易分析性、易改变性、稳定性、易测试性、适应性、易安装性、共存性、易替换性和依从性方面的定义出发,确定每一条测试需求所对应的质量子特性。

     软件测试可以划分为以下测试类型:功能测试、安全性测试、接口测试、容量测试、完整性测试、结构测试、用户界面测试、负载测试、压力测试、疲劳强度测试、恢复性测试、配置测试、兼容性测试、安装测试等。

     不同的质量子特性可以确定出不同的测试内容,这些测试内容可以通过不同的测试类型来实施。例如,从易安装性方面考虑,测试内容包括测试软件安装的工作量、安装的可定制性、安装设计的完备性、安装操作的简易性、是否容易重新安装,这对应了测试类型中的安装测试,通过安装测试可以验证这些测试内容。

     本方法的一个实施例是建立一个质量子特性与测试类型的关系表,参见图3,该对应表给出了质量子特性与测试类型的对应关系。对所确定的质量子特性,可以使用该对应表来确定测试类型。

     建立测试需求跟踪矩阵,参见图4。将上述步骤分析、确定的开发需求、测试需求、测试类型填入测试跟踪需求矩阵。

     使用测试需求跟踪矩阵对测试需求进行管理。对于测试工作而言,需求变更管理是一个相对被动的过程,软件需求发生了变更,测试需求必须随之变化。软件需求一旦发生变化,就要对需求跟踪表进行维护,启动配置管理过程,将与软件需求变更相关的内容进行同步变更。

     实施例:假设一个开发需求是这样描述:

     需求名:增加员工信息

     需求描述:一条完整的培训信息包括培训的主题、证书、内容、起止时间、费用、地点、机构,其中培训的主题、内容、起止时间、费用、机构为必填项。培训的起始时间不能晚于截止时间,培训费用精确到元角分。每一个输入项的数据规格应遵循数据字典的要求。

     一种软测试需求分析方法的分析过程如下:

     1、建立开发需求列表,列出具有可测试性的开发需求。 

    序号

    开发需求标识

    开发需求描述

    信息来源

    1

    增加员工信息

    一条完整的培训信息包括培训的主题、证书、内容、起止时间、费用、地点、机构,其中培训的主题、内容、起止时间、费用、机构为必填项。培训的起始时间不能晚于截止时间,培训费用精确到元角分。每一个输入项的数据规格应遵循数据字典的要求。

    《人力资源管理系统业务需求说明书》

      2、根据开发需求的描述,从测试角度来考虑,分析每条开发需求描述中的输入、输出、处理、限制、约束等,形成可测试的分层描述的测试需求。

      3、从GB /T16260.1定义的软件质量子特性角度出发,确定每条测试需求所对应的质量子特性。

      4、参考图3,对于所确定的质量子特性,选择适合的测试类型。

      5、建立测试需求矩阵,将上述步骤分析、确定的开发需求、测试需求、测试类型填入测试跟踪需求矩阵。

          图1分析方法流程图

    序号

    开发需求标识

    开发需求描述

    信息来源

         图2开发需求列表

         图3质量子特性与测试类型对应表

  • 性能测试、负载测试、压力测试

    2010-08-01 19:46:10

        在面试测试人员的时候,这是一个很好的问题:你如何定义性能/负载/压力测试?在很多时候,人们都是将它们作为可互相替换的相同术语来使用,然而实际上他们之间的差异是比较大的。这个贴子是根据我自己的一些经验,针对这三个概念写的一个比较简单的评论,当然也同时参考了一些测试文献资料里的定义,比如说:
    "Testing computer software" by Kaner et al
    "Software testing techniques" by Loveland et al
    "Testing applications on the Web" by Nguyen et al


    Update July 7th, 2005
        从网站的访问日志中我可以看到这篇贴子经常会被人们在GOOGLE中搜索到,所以我在这里加上一个我写的一个后续贴子的地址连接'More on performance vs. load testing'.

    性能测试

        性能测试的目的不是去找bugs,而是排除系统的瓶颈,以及为以后的回归测试建立一个基准。而性能测试的操作,实际上就是一个非常小心受控的测量分析过程。在理想的情况下,被测软件
    在这个时候已经是足够稳定了,所以这个过程得以顺利的进行。

        一组清晰已定义好的预期值是让一次有意义的性能测试的基本要素。如果连你自己都不知道系统性能有些什么是要测的,那么它对于你要测试的方法手段是没有指导意义的*。例如,给一个web应用做性能测试,你要知道至少两样东西:
            在不同并发用户数或者HTTP连接数情况下的负载预期值*
            可接受的响应时间

        当你知道你的目标后,你就可以开始使用对系统持续增加负载的方法来观察系统的瓶颈所在。重新拿web应用系统来做例子,这些瓶颈可存在于多个层次,你可以使用多种工具来查明它们的所在:
            在应用层,开发人员可以通过profilers来发现低效率的代码,比如说较差的查找算法
            在数据库
    层,开发人员和数据库管理员(DBA)可以通过特定的数据库profilers及事件探查器*(query optimizers)
            在操作系统层,系统工程师可以使用一些工具如在Unix类的操作系统中的top,vmstat,iostat,在Windows系统中的PerfMon来监控CPU,内在,swap,磁盘I/O等硬件资源;专门的内核监控软件也可以在这一层面上被使用。
            在网络层上,网络工程师可以使用报文探测器(如tcpdump),网络协议分析器(如ethereal),还有其它的工具(如netstat,MRTG,ntop,mii-tool)

        从测试的观点来看,上面所有描述的活动都是一种白盒的方法,它对系统从内到外及多角度进行审查及监控。测度数据*被取得及分析后,对系统的调整则成为理所当然的下一个步骤。

        然而,(除了上面的方法外)测试人员在给被测系统运行负载试验*(这里为了不与我们所理解的负载测试-load testing的概念搞混,特译做负载试验)的时候,也采取了黑盒的方法。像对于WEB应用来讲,测试人员可以使用工具来模拟并发用户或者HTTP连接及测量响应时间。在我以前使用过的轻量级的负载测试开源工具有ab,siege,httperf。一个更重量级的工具是OpenSTA,但我没用过。我也还没有用过The Grinder这个工具,但它在我将要做的事情中排名靠前。

        当负载试验*的结果显示出系统的性能来没有达到它的预期目标时,这就是要对应用和数据库的调整的时候了。同时你要确保让你的代码运行得尽可能高效,以及数据库在给定的操作系统和硬件配置的情况下最优化。测试驱动开发(TDD)的实践者会发现这种上下文结构框架是非常有用的*,如可以通过负载试验*及时间试验的函数性*来增强现存单元测试
    代码的Mike Clark的jUnitPerf*。当一个特定的函数或者方法被剖析过*和调试过后,开发人员就可以在jUnitPerf中,放入它的单元试验*来确保它可以达到负载及时间上的性能需求。Mike Clark称这为“持续性能测试”。我顺便也提一下我已经做了一个基于Python的jUnitPerf的初步研究,我称之为pyUnitPerf.

        假若在调试过应用程序及数据库后,系统还是没有达到性能的预期目标,在这种情况下,还是有一些其它的调试的流程*可以针对前面讲过的那几个层次来使用的。下面就是一些在应用程序代码*之外仍可以提高WEB应用系统性能的例子:
            使用WEB缓存装制,如Squid提供的装置
            将高访问量的网页静态化,以避免这些高访问量对数据库进行大量的调用
            通过负载平衡的方法来水平缩放WEB服务器的结构*
            在水平缩放数据库群及将它们分为读写服务器和只读服务器后,还要对只读服务器群负载平衡。*
            通过增加更多的硬件资源(CPU,内存,磁盘等)纵向的缩放WEB及数据库服务器群
            增加网络的带宽

        由于现在的WEB应用系统都是十分复杂的系统,性能调试有时要具有一些艺术性才行。在每次修改一个变量及重新测度的时候一定要非常小心,否则的话,在变化中将会有很多难于确定和重复的不确定因素*。

        在一个规范的测试环境比如说一个测试实验试,它是不会常常的重现实际应用时的服务器配置环境。在这样的情况下,分段测试环境,也就是生产实际环境的一个子集就可以派上用场了。但同时系统的期望性能也需要相应的调低一点。

        “运行负载试验*->测度性能->调试系统”这个循环一直要被重复执行到被测试系统达到了期望的性能标准了才可以停。在这个时候,测试人员就可以明了在正常条件下的系统运转怎么样,同时这些就可以做为以后在回归测试中,评价新版本的软件性能的一个标准了。

        性能测试还有另一个目标就是建立一组被测系统的基准数据。在很多行业中都会有这种行业标准的基准数据,比如说TPC公布的。还有很多软硬件厂家都为了在TCP排名中靠前而对他们的机器进行精心调试。所以说你应当非常谨慎的说明在你进行测试的时候,并没有在种类繁多的软硬件产品中进行全部测试*。

    负载测试
        我们都已经在性能测试调试的过程中,见识过负载测试了。在那种环境中,它意味着通过自动化工具来持续对系统增加负载。但对于WEB应用来讲,负载则是并发用户或者HTTP连接的数量。
    术语“负载测试”在测试文献资料中通常都被定义为给被测系统加上它所能操作的最大任务数的过程。负载测试有时也会被称为“容量测试”,或者“耐久性测试/持久性测试”*

        容量测试的例子:
            通过编辑一个巨大的文件来测试文字处理软件
            通过发送一个巨大的作业来测试打印机
            通过成千上万的用户邮箱来测试邮件服务器
            有一种比较特别的容量测试是叫作“零容量测试”,它是给系统加上空任务来测试的。
        耐久性测试/持久性测试的的例子:
            在一个循环中不停的运行客户端超过一个扩展时间段*。
        负载测试的目的:
            找到一些在测试流程中前面的阶段所进行的粗略测试中没有被找出的bugs,例如,内存管理bugs,内存泄露,缓冲器溢出等等。
            保证应用程序达到性能测试中确定的性能基线。这个可以在运行回归试验时,通过加载特定的最大限度的负载来实现。

        尽管性能测试和负载测试似乎很像,但他们的目的还是有差异的。一方面,性能测试使用负载测试的技术,工具,以及用不同的负载程度来测度和基准化系统。在另一方面来讲,负载测试是在一些已经定义好的负载程度上进行测试的,通常对系统加上最大负载之后,系统应该仍然可以提供全部功能。这里需要明确一点,负载测试并不是要对系统加载上过度的负载而使系统不能工作
    ,而是要使系统像一个上满了油的机器嗡嗡叫*。

        在负载测试的相关内容中,我想应该非常重要的是要有十分充足的数据来进行测试。从我的经验中得知,假若不用非常大的数据*去测的话,有很多严重的bug是不会的到的。比如说,LDAP/NIS/Active Directory数据库中成千上万的用户,邮件服务器中成千上万的邮箱,数据库中成G成G的表,文件系统中很深的文件或者目录的层次,等等。显然,测试人员就需要使用自动化工具来产生这些庞大的数据集,比较幸运的是任何优秀的脚本语言
    都可以胜任这些工作。

    压力测试

        压力测试是指通过对系统加载过度的资源或者例系统没有应该具有的令系统可以正常运作的资源,来使系统崩溃(在某些情况的时候,它又可以叫做负面测试)。进行这个疯狂行为的主要目的是为了保证系统出故障及可以适当的恢复,而这个恢复得怎么样的特性则是叫做可恢复性。

        当性能测试需要的是一个可控制的环境和不断的测度的时候,压力测试则是令为欢喜的引起混乱及不可预测性(译者按:从这一点可以看出作者是一个很优秀的测试人员)。还是举WEB应用系统为例,下面是一些对系统可行的压力测试方法:
            两倍的已经基线的并发用户数或者HTTP连接数
            随机的关闭及重开连接到服务器上的网络上集线器/路由器的端口(例如,可以通过SNMP命令来实现)
            把数据库断线然后再重启
            当系统还在运行的时候,重建一个RAID阵列
            在WEB和数据库服务器上运行消耗资源(如CPU,内存,磁盘,网络)的进程

        我可以肯定一些经常使用非常规方法来破坏系统的测试人员可以进一步充实这个列表的。只是压力测试并不是简单的为了一种破坏的快感而去破坏系统,实际上它是可以让测试工程师观察系统对出现故障时系统的反应。系统是不是保存了它出故障时的状态?是不是它就突然间崩溃掉了?它是否只是挂在那儿啥也不做了?它失效的时候是不是有一些反应*?在重启之后,它是否有能力可以恢复到前一个正常运行的状态?它是否会给用户显示出一些有用的错误信息,还是只是显示一些很难理解的十六进制代码?系统的安全性是否为因为一些不可预料的故障而会有所降低?这些问题可以一直问下去的。

    结论
        我明白我只是提到一些在性能/负载/压力测试中应该值得注意的一些比较基础的问题,工具及方法。我个人觉得性能测试及调试是一个很有趣的话题,我将会在以后贴更多的相关内容上来的。

    【源文】
    Monday, February 28, 2005
    Performance vs. load vs. stress testing
    Here's a good interview question for a tester: how do you define performance/load/stress testing? Many times people use these terms interchangeably, but they have in fact quite different meanings. This post is a quick review of these concepts, based on my own experience, but also using definitions from testing literature -- in particular: "Testing computer software" by Kaner et al, "Software testing techniques" by Loveland et al, and "Testing applications on the Web" by Nguyen et al.

    Update July 7th, 2005

    From the referrer logs I see that this post comes up fairly often in Google searches. I'm updating it with a link to a later post I wrote called 'More on performance vs. load testing'.

    Performance testing

    The goal of performance testing is not to find bugs, but to eliminate bottlenecks and establish a baseline for future regression testing. To conduct performance testing is to engage in a carefully controlled process of measurement and analysis. Ideally, the software under test is already stable enough so that this process can proceed smoothly.

    A clearly defined set of expectations is essential for meaningful performance testing. If you don't know where you want to go in terms of the performance of the system, then it matters little which direction you take (remember Alice and the Cheshire Cat?). For example, for a Web application, you need to know at least two things:
    •        expected load in terms of concurrent users or HTTP connections
    •        acceptable response time
    Once you know where you want to be, you can start on your way there by constantly increasing the load on the system while looking for bottlenecks. To take again the example of a Web application, these bottlenecks can exist at multiple levels, and to pinpoint them you can use a variety of tools:
    •        at the application level, developers can use profilers to spot inefficiencies in their code (for example poor search algorithms)
    •        at the database level, developers and DBAs can use database-specific profilers and query optimizers
    •        at the operating system level, system engineers can use utilities such as top, vmstat, iostat (on Unix-type systems) and PerfMon (on Windows) to monitor hardware resources such as CPU, memory, swap, disk I/O; specialized kernel monitoring software can also be used
    •        at the network level, network engineers can use packet sniffers such as tcpdump, network protocol analyzers such as ethereal, and various utilities such as netstat, MRTG, ntop, mii-tool
    From a testing point of view, the activities described above all take a white-box approach, where the system is inspected and monitored "from the inside out" and from a variety of angles. Measurements are taken and analyzed, and as a result, tuning is done.

    However, testers also take a black-box approach in running the load tests against the system under test. For a Web application, testers will use tools that simulate concurrent users/HTTP connections and measure response times. Some lightweight open source tools I've used in the past for this purpose are ab, siege, httperf. A more heavyweight tool I haven't used yet is OpenSTA. I also haven't used The Grinder yet, but it is high on my TODO list.

    When the results of the load test indicate that performance of the system does not meet its expected goals, it is time for tuning, starting with the application and the database. You want to make sure your code runs as efficiently as possible and your database is optimized on a given OS/hardware configurations. TDD practitioners will find very useful in this context a framework such as Mike Clark's jUnitPerf, which enhances existing unit test code with load test and timed test functionality. Once a particular function or method has been profiled and tuned, developers can then wrap its unit tests in jUnitPerf and ensure that it meets performance requirements of load and timing. Mike Clark calls this "continuous performance testing". I should also mention that I've done an initial port of jUnitPerf to Python -- I called it pyUnitPerf.

    If, after tuning the application and the database, the system still doesn't meet its expected goals in terms of performance, a wide array of tuning procedures is available at the all the levels discussed before. Here are some examples of things you can do to enhance the performance of a Web application outside of the application code per se:
    •        Use Web cache mechanisms, such as the one provided by Squid
    •        Publish highly-requested Web pages statically, so that they don't hit the database
    •        Scale the Web server farm horizontally via load balancing
    •        Scale the database servers horizontally and split them into read/write servers and read-only servers, then load balance the read-only servers
    •        Scale the Web and database servers vertically, by adding more hardware resources (CPU, RAM, disks)
    •        Increase the available network bandwidth
    Performance tuning can sometimes be more art than science, due to the sheer complexity of the systems involved in a modern Web application. Care must be taken to modify one variable at a time and redo the measurements, otherwise multiple changes can have subtle interactions that are hard to qualify and repeat.

    In a standard test environment such as a test lab, it will not always be possible to replicate the production server configuration. In such cases, a staging environment is used which is a subset of the production environment. The expected performance of the system needs to be scaled down accordingly.

    The cycle "run load test->measure performance->tune system" is repeated until the system under test achieves the expected levels of performance. At this point, testers have a baseline for how the system behaves under normal conditions. This baseline can then be used in regression tests to gauge how well a new version of the software performs.

    Another common goal of performance testing is to establish benchmark numbers for the system under test. There are many industry-standard benchmarks such as the ones published by TPC, and many hardware/software vendors will fine-tune their systems in such ways as to obtain a high ranking in the TCP top-tens. It is common knowledge that one needs to be wary of any performance claims that do not include a detailed specification of all the hardware and software configurations that were used in that particular test.

    Load testing

    We have already seen load testing as part of the process of performance testing and tuning. In that context, it meant constantly increasing the load on the system via automated tools. For a Web application, the load is defined in terms of concurrent users or HTTP connections.

    In the testing literature, the term "load testing" is usually defined as the process of exercising the system under test by feeding it the largest tasks it can operate with. Load testing is sometimes called volume testing, or longevity/endurance testing.

    Examples of volume testing:
    •        testing a word processor by editing a very large document
    •        testing a printer by sending it a very large job
    •        testing a mail server with thousands of users mailboxes
    •        a specific case of volume testing is zero-volume testing, where the system is fed empty tasks
    Examples of longevity/endurance testing:
    •        testing a client-server application by running the client in a loop against the server over an extended period of time
    Goals of load testing:
    •        expose bugs that do not surface in cursory testing, such as memory management bugs, memory leaks, buffer overflows, etc.
    •        ensure that the application meets the performance baseline established during performance testing. This is done by running regression tests against the application at a specified maximum load.
    Although performance testing and load testing can seem similar, their goals are different. On one hand, performance testing uses load testing techniques and tools for measurement and benchmarking purposes and uses various load levels. On the other hand, load testing operates at a predefined load level, usually the highest load that the system can accept while still functioning properly. Note that load testing does not aim to break the system by overwhelming it, but instead tries to keep the system constantly humming like a well-oiled machine.

    In the context of load testing, I want to emphasize the extreme importance of having large datasets available for testing. In my experience, many important bugs simply do not surface unless you deal with very large entities such thousands of users in repositories such as LDAP/NIS/Active Directory, thousands of mail server mailboxes, multi-gigabyte tables in databases, deep file/directory hierarchies on file systems, etc. Testers obviously need automated tools to generate these large data sets, but fortunately any good scrīpting language worth its salt will do the job.

    Stress testing

    Stress testing tries to break the system under test by overwhelming its resources or by taking resources away from it (in which case it is sometimes called negative testing). The main purpose behind this madness is to make sure that the system fails and recovers gracefully -- this quality is known as recoverability.

    Where performance testing demands a controlled environment and repeatable measurements, stress testing joyfully induces chaos and unpredictability. To take again the example of a Web application, here are some ways in which stress can be applied to the system:
    •        double the baseline number for concurrent users/HTTP connections
    •        randomly shut down and restart ports on the network switches/routers that connect the servers (via SNMP commands for example)
    •        take the database offline, then restart it
    •        rebuild a RAID array while the system is running
    •        run processes that consume resources (CPU, memory, disk, network) on the Web and database servers
    I'm sure devious testers can enhance this list with their favorite ways of breaking systems. However, stress testing does not break the system purely for the pleasure of breaking it, but instead it allows testers to observe how the system reacts to failure. Does it save its state or does it crash suddenly? Does it just hang and freeze or does it fail gracefully? On restart, is it able to recover from the last good state? Does it print out meaningful error messages to the user, or does it merely display incomprehensible hex codes? Is the security of the system compromised because of unexpected failures? And the list goes on.

    Conclusion

    I am aware that I only scratched the surface in terms of issues, tools and techniques that deserve to be mentioned in the context of performance, load and stress testing. I personally find the topic of performance testing and tuning particularly rich and interesting, and I intend to post more articles on this subject in the future.
    posted by Grig Gheorghiu at 7:33 AM  

    此文来源于51testing博客,转载请注明出处
    原始链接:
    http://blog.51testing.com/?61747/action_viewspace_itemid_3036.html

  • 网络安全学习笔记(更新中)

    2010-07-14 00:22:51

     
    //////////////////////////////////////////////////企业网络安全结构
    网络设备(路由器、交换机)
    操作系统
    应用程序
    //////////////////////////////////////////////////网络设备面临的威胁
    路由器:内部网络与外界通信出口。一旦黑客攻陷路由器,就掌握了控制内部网络访问外部网络的权力。
    -弱口令  密码简单
    -IOS自身漏洞  (路由器的操作系统)版本低,需要经常更新
    -非授权用户可以管理设备  权限低
    -CDP协议造成信息的泄露  思科设备之间相互了解。(尽量关闭)
    //////////////////////////////////////////////////操作系统面临的威胁
    1、Windows系统
    -未及时安装补丁
    -开启不必要的服务
    -管理员口令设置不正确  暴力破解
    -默认共享漏洞
    2、Linux系统
    -账号与口令安全
    -NFS文件系统漏洞  把移动硬盘的某个目录挂载下来
    -作为root运行的程序安全  应用程序被黑客控制得到权限
    //////////////////////////////////////////////////操作系统面临的威胁
    1、Web服务
    -II5.0超长文件名请求存在漏洞
    -其他漏洞
    2、邮件服务
    -垃圾邮件的骚扰
    -邮件附件中的病毒
    3、数据库
    -Sa账号为空  1、不开启Sa账号。2、为Sa设置强壮的密码。
    //////////////////////////////////////////////////企业网络面临的其他威胁
    1、病毒
    -蠕虫
    2、木马
    -冰河
    -灰鸽子
    3、来自内部的攻击  80%来自企业内部员工 20%来自网络
    -对企业不满的员工
    -对安全不了解的员工
    //////////////////////////////////////////////////网络安全解决方案
    1、网络设备
    2、操作系统
    3、应用程序
    4、防火墙+IDS+网络发病毒体系——IDS网络监测系统

    操作系统安全加固:
    1、主机物理安全——计算机不要让外人碰,有专门的机房及管理人员。
    2、账户安全——密码口令复杂度高。
    3、文件系统的安全——NTFS比FTP32安全,权限涉及到了文件夹和文件级别。
    4、停止多余的服务——减少黑客入侵可能,用最先进的漏洞监测工具。
    5、Windows日志维护——了解服务器最近是否有遭受到攻击。
    计算机病毒防治:
    1、全面部署防病毒系统——部署企业版杀毒软件
    2、及时更新病毒库和产品
    3、预防为主
    4、加强培训、提高防毒意识——给企业员工进行安全培训
    IDS入侵检测系统
    1、对系统的运行状态进行监视
    2、发现各种攻击企图、攻击行为或者攻击结果
    3、保证系统资源的机密性、完整性和可用性
    4、是防火墙的合理补充
    5、第二道安全闸门
     
    IPS (Intrusion Prevention System , 入侵防御系统)
    IPS的出现,应该说是IDS技术的一种新发展趋势,IPS技术在IDS监测的功能上又增加了主动响应的功能,一旦发现有攻击行为,立即响应,主动切断连接。它的部署方式不像IDS并联在网络中,而是以串联的方式接入网络中。

    //////////////////////////////////////////////////网络攻击常见手法
    1、扫描攻击——扫描计算机开放哪些服务和端口
    2、安全漏洞攻击——根据服务缺陷进行攻击
    3、口令入侵——反复尝试密码登录,暴力破解软件
    4、木马程序
    5、电子邮件攻击——附件里放木马
    6、DoS攻击——拒绝服务攻击,DDoS分布式拒绝服务攻击
    扫描攻击:
    1、黑客利用专门工具进行系统端口扫描,找到开放端口后进行入侵
    2、主机扫描
    -ping
    -Tracert
    -Nmap
    3、端口扫描
    -一个端口就是一个潜在的通信通道
    -扫描方法
      手动扫描
      工具扫描
    扫描软件:
    SuperScan  扫描计算机开放的端口和服务
    PortScanner
    Xscan
    MBSA 微软官方提供的系统安全检测软件
    安全漏洞攻击:
    1、操作系统或应用软件自身具有的Bugs
    2、安全漏洞举例:
    -缓冲区溢出
      当目标操作系统收到了超过它所能接收到的信息量时产生缓冲区溢出。
      例:用户名10个字符,黑客输入100个字符,有90个字符注入到内存中。(解决:当超过10个字符时,重新输入)
    -Http协议漏洞导致黑客攻击
    口令入侵:
    1、黑客攻击目标时必须破译用户的口令,只要攻击者能猜测用户口令,就能获得机器访问权
    -通过网络监听
        使用Sniffer工具捕获主机间通讯来获取口令,嗅探器
    -暴力破解
      John the Ripper
      L0pht Crack 5 :LC5   根据密码字典对计算机反复尝试登陆
    -利用管理员失误
      网络安全中人是薄弱的一环
      提高用户、特别是网络管理员的安全意识
    木马程序:
    1、特洛伊木马
     在对方机器上运行打开个端口为黑客提供服务
    2、常见的木马
    -BO(BackOriffice)
    -冰河、灰鸽子——国人的骄傲
    电子邮件:
    1、内容不健康邮件
    2、广告邮件——可能打开一个病毒网页
    3、被感染的邮件
    4、病毒邮件
    5、木马邮件
    DoS(Denial of Service,拒绝服务攻击)
    1、消耗系统资源(带宽、内存、队列、CPU)
    2、导致目标主机宕机
    3、阻止授权用户正常访问服务(慢、不能连接、没有响应)
    DoS攻击种类
    SYN Flood  需要为TCP连接分配内存,从而使其他功能不能分配足够内存。三次握手,进行了两次(SYN)(SYN/ACK),不进行第三次握手(ACK),连接队列处于等待状态,大量的这样等待,占满全部队列空间,系统挂起。60S系统自动RST,但系统已经崩溃。
    Ping of Death  IP应用的分段使打包不得不重装配,从而导致系统崩溃。
                   偏移量+段长度>65535,系统崩溃,重新启动,内核转储等。
    Teardrop  分段攻击,利用重装配错误,通过将各个分段重叠来使目标系统崩溃或挂起。
    Smurf(程序名)  网络上广播通信量泛滥,导致网络堵塞。攻击者向广播地址发送大量欺骗性的ICMP ECHO请求,这些包被放大,并发送到被攻击的地址,大量计算机向一台计算机回应ECHO包,目标系统将崩溃。

    //////////////////////////////////////////////////网络安全基础防护
    1、设备安全防护
    -路由器安全管理
    -交换机安全管理
    2、操作系统安全防护
    -Windows安全防护
    -Linux安全防护
    3、应用程序安全防护
    -Web安全防护
    -数据库安全防护

    //////////////////////////////////////////////////路由器安全管理
    针对路由器攻击类型:
    -直接侵入到系统内部——远程控制路由器
    -远程攻击使路由器崩溃或运行效率显著下降
    -网络管理协议

    路由器支持的配置方式:
    TELNET——远程控制协议
    TFTP——文件传输,基于UDP,向路由器传输设置文件
    FTP——文件传输,基于TCP
    HTTP——不需要远程登录,通过IE浏览器直接登录路由器
    SNMP——远程监控路由器,效率高
    Console——对路由器直接配置
    Aux——通过电话线、ISDN进行远程拨号

    面临的威胁:
    Telnet信息为明文——没有进行加密
    HTTP存在漏洞
    Console口——用笔记本直接连接配置
    SNMP协议缺省设置——如果不对SNMP设置,黑客会利用默认设置修改路由器配置

    防护措施:
    及时更新IOS——更新路由器操作系统
    登录路由器,要设置加密口令
    设置远程登录控制
    -Router(config)#line vty 0 4  设置远程控制端口0-4,共5个端口
    -Router(config-line)#login  启用端口
    -Router(config-line)#password AAA  设置密码
    -Router(config-line)#exec-timeout 10  超时10秒自动退出登录
    设置控制台与AUX登录控制
    -Router(config)#line console 0
    -Router(config-line)#transport input none  支持的协议,none表示不支持任何协议
    -Router(config-line)#password AAA
    -Router(config)#line sux 0
    -Router(config-line)#transport input none
    -Router(config-line)#no exec
    应用强密码策略
    -Router(config)#service password-encryption  red5加密
    -Router(config)#enable secret AAA  secret比password优先级高,password不生效
    关闭基于Web的配置
    -Router(config)#no ip http server 关闭不必要的服务
    利用ACL禁止Ping相关接口
    -Router(config)#access-list 101 deny icmp any host 192.168.2.1 echo  拒绝icmp协议ping主机,ping主机时,主机不应答
    -Router(config)#access-list 101 permit ip any any  允许其他协议访问
    -Router(config-if)#ip access-group 101 in
    关闭CDP
    -Router(config)#no cdp run 关闭整个路由器CDP协议
    -Router(config-if)#no cdp enable 进入端口,关闭该端口的CDP协议
    禁止不需要的服务
    -Router(config)#no ip domain-lookup 域名解析
    -Router(config)#no ip bootp server  协议DHCP
    -Router(config)#no snmp-server  简单网络管理协议
    -Router(config)#no snmp-server community public RO
    -Router(config)#no snmp-server community admin RW

    //////////////////////////////////////////////////交换机安全管理
    及时下载新的IOS
    使用管理访问控制系统
    禁用未使用的端口
    关闭危险服务
    利用VLAN加强内部网络安全——VLAN虚拟局域网,局域网的物理链路上隔离了广播域。计算机端口绑定在VLAN上,
                                用Sniffer抓包,只能抓到同一个VLAN里的包。

    //////////////////////////////////////////////////Windows安全
    1、关闭不必要的服务
    -Remote Registry Service  远程注册服务,允许远程修改注册表。services.msc
    -Messenger  网络信使服务
    2、关闭不需要的端口
    -telnet
    -Netbios
    -FTP
    -Web
    3、打开审计策略——本地安全设置->本地策略->审核登录事件。
                       对文件夹及文件添加审核->属性->安全->高级->审核
    4、重要文件安全存放——尽量不要放在系统盘,文件系统选择NTFS。
    5、登录时不显示上次登录名——本地安全设置->本地策略->安全选项->交互式登录:不显示上次用户名。
                                 本地安全设置->本地策略->安全选项->账户:重命名系统管理员账户。让黑客猜不到管理员账号
                                 gpupdate /force 强制更新组策略
    6、禁止建立空连接——打了XPsp3和2003sp2补丁后安全
    7、关闭默认共享——net share 查看共享
                       net share c$ /delete 删除共享
    8、设定账户锁定阀值——本地安全设置->帐户策略。可防止暴力破解。
                    
    //////////////////////////////////////////////////Linux安全

     

    //////////////////////////////////////////////////防火墙介绍及ACL
    防火墙主要功能:
    1、强化安全策略——防火墙通过仅允许“认可的”和符合规则的请求通过的方式来强化安全策略
    2、有效的记录网上活动——所有经过防火墙的流量都可以被记录下来,包括企业用户上网情况
    3、隐藏用户站点或网络拓扑——防火墙在隔离内网和外网的同时利用NAT来隐藏内网的各种细节
    4、安全策略的检查——所有信息都必须经过防火墙,防火墙就成为一个安全检查点

    NAT:“Network Address Translation”,中文意思是“网络地址转换”,NAT就是在局域网内部网络中使用内部地址,
    而当内部节点要与外部网络进行通讯时,就在网关(可以理解为出口,打个比方就像院子的门一样)处,将内部地址替换成公用地址,
    从而在外部公网(internet)上正常使用,NAT可以使多台计算机共享Internet连接,这一功能很好地解决了公共IP地址紧缺的问题。

    防火墙分类:
    1、包过滤型防火墙——网络层,对数据报进行检测
    2、代理型防火墙——应用程,用代理服务器上网
    3、状态检测型防火墙——网络层,根据数据包状态

    包过滤型防火墙:
    -根据定义好的过滤规则审查每个数据包,以便确定其是否与某一条包过滤规则匹配
    -过滤规则是根据数据包的报头信息进行定义的
    -没有明确允许的都被禁止

    代理型防火墙:
    -也被称为代理服务器
    -位于客户机与服务器之间,完全阻挡二者间的数据流
    -可以针对应用层进行侦测和扫描,对付基于应用层的浸入和病毒十分有效

    状态检测型防火墙:
    -检测每一个有效连接的状态,并根据这些信息决定网络数据包是否能够通过防火墙

     
  • Loadrunner实用技巧1

    2010-07-09 12:53:16

    #######################################################reg注册函数

    检查登录后的页面信息时
    web_reg_find,web_reg_save_param   //带reg的函数要放在登录语句前
    web_submit_form()
    web_find    //不带reg的函数放在登录语句后

    做关联时,记着要把reb_reg_save_param函数放在要关联的事务前面。
    ######################################################运行脚本遇到错误时继续执行下去
    Action()
    {
      lr_continue_on_error(1);           lr_continue_on_error(1)与lr_continue_on_error(0)之间代码执行出错时不停止,继续执行下面的语句。
        web_link("test",                 lr_continue_on_error(1)相当于Run-time Setting中 continue on error 打勾。
             "test=www.baidu.com",
             LAST);
      lr_continue_on_error(0);
        lr_output_message("finished linking");
       
        return 0;
    }
    #######################################################
    View->Antimated run 动态运行
    选取脚本中函数,F1显示该函数的帮助。
    #######################################################选择java Vuser协议
    Eclipse SDK

    package com.lr.test; 包名
    public class HelloWorld{
       public static void main(String[] args){
           System.out.println("Hello World");
       }
    }

    import lrapi.lr;
    import com.lr.test.*;  导入包
    public class Actions
    {

     public int init() throws Throwable {
      return 0;
     }//end of init


     public int action() throws Throwable {
            HellpWorld.main((String[])null);
            System.out.println("不调用直接写java语句");
      return 0;
     }//end of action


     public int end() throws Throwable {
      return 0;
     }//end of end
    }
    #######################################################加载dll
    1、不适合录制功能点的业务
    2、基于C++开发的业务系统
    lr_load_dll("D:\\test\\dlltest.dll");  如果dll文件在脚本的文件夹中,可直接写lr_load_dll("dlltest.dll");
    双引号中转义字符
    vuser_init()
    { lr_load_dll("D:\\test\\dlltest.dll");
      return 0;
    }
    int sum;  声明变量在Action外面(变量过多LoadRunner会报错)
    Action
    {  sum=add(100,200);
    }

    #######################################################录制SQL脚本,ODBC协议
    int 选择查询分析器  \\Mcrosoft SQL Server\80\Tools\inn\isqlw.exe
        登录
    Action  进入数据库
            查询表内容
    #######################################################

     

     

     


     

  • 测试人员需要掌握哪些技能

    2010-07-08 12:25:43

    开发语言
    C/C++
    java
    C#
    VB
    Delphi
    Phthon、Shell、PHP

    数据库
    MS SQL
    Oracle
    My SQL
    DB2

    网络分析工具
    Sniffer Pro
    Omnipeek、Solarwinds、科来网络分析系统
    IRIS

    功能自动化
    QTP
    WinRunner
    Robot
    RFT
    Selenium
    Watir
    TestComplete、Silktest
    Webking、MaxQ

    性能测试
    Loadrunner
    Jmeter
    Robot
    Web Application Load Simulator、RPT
    Application Center Test、apacheAB、Webking、TPTest

    测试管理
    QC/TD
    bugzilla
    bugfree
    jira
    mantis
    TestLink
    Clearquest
    RQM

    单元测试
    Junit
    C++ test
    jtest
    Quantify
    Purify

  • IP包头结构详解

    2010-07-07 09:27:06

    版本号(Version):长度4比特。标识目前采用的IP协议的版本号。一般的值为0100(IPv4),0110(IPv6)

    IP包头长度(Header Length):长度4比特。这个字段的作用是为了描述IP包头的长度,因为在IP包头中有变长的可选部分。该部分占4个bit位,单位为32bit(4个字节),即本区域值= IP头部长度(单位为bit)/(8*4),因此,一个IP包头的长度最长为“1111”,即15*4=60个字节。IP包头最小长度为20字节。

    服务类型(Type of Service):长度8比特。8位 按位被如下定义 PPP DTRC0
    PPP:定义包的优先级,取值越大数据越重要
       000 普通 (Routine)
       001 优先的 (Priority)
       010 立即的发送 (Immediate)
       011 闪电式的 (Flash)
       100 比闪电还闪电式的 (Flash Override)
       101 CRI/TIC/ECP(找不到这个词的翻译)
       110 网间控制 (Internetwork Control)
       111 网络控制 (Network Control)

    D 时延: 0:普通 1:延迟尽量小
    T 吞吐量: 0:普通 1:流量尽量大
    R 可靠性: 0:普通 1:可靠性尽量大
    M 传输成本: 0:普通 1:成本尽量小
    0 最后一位被保留,恒定为0

    IP包总长(Total Length):长度16比特。 以字节为单位计算的IP包的长度 (包括头部和数据),所以IP包最大长度65535字节。

    标识符(Identifier):长度16比特。该字段和Flags和Fragment Offest字段联合使用,对较大的上层数据包进行分段(fragment)操作。路由器将一个包拆分后,所有拆分开的小包被标记相同的值,以便目的端设备能够区分哪个包属于被拆分开的包的一部分。

    标记(Flags):长度3比特。该字段第一位不使用。第二位是DF(Don't Fragment)位,DF位设为1时表明路由器不能对该上层数据包分段。如果一个上层数据包无法在不分段的情况下进行转发,则路由器会丢弃该上层数据包并返回一个错误信息。第三位是MF(More Fragments)位,当路由器对一个上层数据包分段,则路由器会在除了最后一个分段的IP包的包头中将MF位设为1。

    片偏移(Fragment Offset):长度13比特。表示该IP包在该组分片包中位置,接收端靠此来组装还原IP包。

    生存时间(TTL):长度8比特。当IP包进行传送时,先会对该字段赋予某个特定的值。当IP包经过每一个沿途的路由器的时候,每个沿途的路由器会将IP包的TTL值减少1。如果TTL减少为0,则该IP包会被丢弃。这个字段可以防止由于路由环路而导致IP包在网络中不停被转发。

    协议(Protocol):长度8比特。标识了上层所使用的协议。
    以下是比较常用的协议号:
        1    ICMP
        2    IGMP
        6    TCP
       17    UDP
       88    IGRP
       89    OSPF

    头部校验(Header Checksum):长度16位。用来做IP头部的正确性检测,但不包含数据部分。 因为每个路由器要改变TTL的值,所以路由器会为每个通过的数据包重新计算这个值。

    起源和目标地址(Source and Destination Addresses):这两个地段都是32比特。标识了这个IP包的起源和目标地址。要注意除非使用NAT,否则整个传输的过程中,这两个地址不会改变。

    至此,IP包头基本的20字节已介绍完毕,此后部分属于可选项,不是必须的部分。

    可选项(Options):这是一个可变长的字段。该字段属于可选项,主要用于测试,由起源设备根据需要改写。可选项目包含以下内容:

        松散源路由(Loose source routing):给出一连串路由器接口的IP地址。IP包必须沿着这些IP地址传送,但是允许在相继的两个IP地址之间跳过多个路由器。

        严格源路由(Strict source routing):给出一连串路由器接口的IP地址。IP包必须沿着这些IP地址传送,如果下一跳不在IP地址表中则表示发生错误。

        路由记录(Record route):当IP包离开每个路由器的时候记录路由器的出站接口的IP地址。

        时间戳(Timestamps):当IP包离开每个路由器的时候记录时间。

    填充(Padding):因为IP包头长度(Header Length)部分的单位为32bit,所以IP包头的长度必须为32bit的整数倍。因此,在可选项后面,IP协议会填充若干个0,以达到32bit的整数倍。

  • 网络基础学习笔记

    2010-07-07 09:03:55

    /////////////////////////////////////////////////////广域网与互联网
    广域网:公司之间连接、企业私网(银行之间搭建光纤)
    Internet:遵守TCP/IP,有病毒、容易受黑客攻击
    /////////////////////////////////////////////////////网络标准化
    国际标准化组织(ISO)
    电子电器工程师协会(IEEE) 802.3
    美国国家标准局(ANSI)
    电子工业协会(EIA/TIA)
    国际电信联盟(ITU)
    INTERNET行动委员会(IAB)
    /////////////////////////////////////////////////////七层OSI
    Application       All           应用层   发送邮件SMTP、HTTP
    Presentation      People        表示层   统一编码 如ASCII编码  不同系统间互联
    Session           Seem          对话层   客户端向服务器请求
    Tranport          To            传输层   传输保障 TCP
    Network           Need          网络层   地址、包交换、路由  三层交换机(带网络功能)
    DataLink          Data          数据链路层 帧、二层交换机
    Physical          Processing    物理层    1010
    /////////////////////////////////////////////////////物理层
    目的:保证原始数据比特流的无误传输
    任务:确定于物理媒体相关的电气特性、机械特性、功能特性急规程特性

    带宽  bps   bits/sec
    UTP/STP 非屏蔽/屏蔽 双绞线
    5类/超5类/6类双绞线   100M/1000M/10000M
    RJ45接口  水晶头    千兆8根都用
    直通线,两边一样,一般两边接T568B、网卡与交换机
    交叉线,T568B T568A   交换机与交换机、网卡与网卡

    多模光纤:多种波传输,带宽大,传输距离4-5km,50 or 62.5/125
    单模光纤:一种波传输,带宽小,传输距离40km,8.3-10/125

    无线网络:
    802.11

    模拟调制解调器:Modem  转声音
    数字传输的调制方法:脉码调制(PCM)
    PCM的二种体制:北美24路PCM-简称T1(1.544Mb/s)
                   欧洲30路PCM-简称E1(2.048Mb/s)
    我国采用E1标准(华为 ),cisco(T1)
    /////////////////////////////////////////////////////数据链路层
    两个子层组成:逻辑链路层 LLC,媒体访问层MAC

    媒体访问层MAC:解决发送方占用信道问题(我要传送数据,网络是否可用)
    目的:完成发送方占用信道问题
    任务:将上层传下来的数据封装成帧进行发送
          实现和维护MAC协议
          比特差错检测

    占用信道方法:
    争用-Contention  以太网采用的
    令牌-Token Passing 令牌环网
    轮询-Polling 有一台计算机控制信道
    SNMP 简单网络管理协议,网管工作站检查主机工作情况时,使用轮询

    MAC寻址:广播寻址
    互联网:域名解析

    逻辑链路层 LLC:把高层的数据怎么变成货物
    目的:保证帧传送的完整性与无误性
    任务:建立和释放LLC层的逻辑连接
          提供与高层(网络层)的接口
          差错控制
          流量控制:保证快速与慢速设备之间帧无误传输(防止流量益处)

    IEEE802.3标准:以太网
    媒体存取方式:争用
    争用方式:CSMA/CD
    坚持方式:1
    编码:曼彻斯特编码   高电压1,低电压0

    以太网原理CSMA/CD  载波侦听多路访问/冲突检测

    交换机最多级联7级,停留查看帧的去向,级联越多延迟越大。
    /////////////////////////////////////////////////////网络层
    目的:完成网络间数据传输
    任务:寻找网络地址-网络寻址
          完成网络间数据传输-交换传输
          路由选择算法-路径选择
    MAC地址,不分层,广播 所以不能路由,能路由的是单播、分层。086-029-8824-3027电话可以路由

    单播
    广播 网段中的最大地址是广播地址
    组播

    tracert IP/域名   追踪路由
    linux下查看IP    ifconfig
    netsend "不要玩CS" 192.168.255.255  对192.168网段广播

    255.255.255.255 局域网广播
    网络号……255   对一个子网广播
    ping 127任意值(除去全零全1) 环回地址

           可用范围   网段   主机
    0       1-126  A   W      X.Y.Z
    10     128-191 B   W.X      Y.Z
    110    192-223 C   W.X.Y      Z
    1110   224-239 D   组播
    11110  240-247 E   保留

    路由+NAT:直接修改局域网的包,以外网地址发出
    代理:对用户不透明,

    特殊地址:0、255、127
    保留地址:
              保留值                        实际可用值
    A    10.0.0.0-10.255.255.255      10.0.0.1-10.255.255.254
    B  172.16.0.0-172.31.255.255    172.16.0.1-172.31.255.254
    C 192.168.0.0-192.168.255.255  192.168.0.1-192.168.255.254

    子网划分
    192.168.0.0   利用子网掩码,把三类地址变为二类地址,把0,1网段划分到一个网段。
    192.168.1.0
    255.255.0.0

    192.168.0.1
    255.255.255.224
               11100000
    000 00000 - 000 11111   0-31  192.168.0.0-31  可用地址192.168.0.1-30   最小:网络号
    001 00000 - 001 11111   32-63                                          最大:广播地址
    010 00000 - 010 11111
    ……
    route add 192.168.0.32 255.255.255.224

    路由环境
    路由表:
    最终目的          方向     尺度
    192.168.0.1/24  10.0.0.2    1
    172.16.0.1/10   10.0.0.1    1
    尺度:多少跳,跨一个路由器为1跳,直连路由0跳(与交换机相连的路由器)

    交换传输:
    电路交换cuicurt switch 一旦通路建立,保持至数据传输完毕
    消息交换message switch 数据被分成多个消息,每个消息独立选择路径
    分组交换package switch 数据被分成多个组,每个分组独立选择路径 
    IP协议就是分组交换协议

    网络路径选择routing
    路由发现:
    距离矢量法distance vector
    状态连接法link state
    路由选择:
    静态选择-人为建立路由表
    动态选择-hop,tick  路由器之间互相学习路由表

    /////////////////////////////////////////////////////会话层
    目的:逻辑地址(低层提供)服务地址
    任务:对话控制
          会话管理
    对话控制
    单工通信    发出去就不回来,例如:广播
    半双工通信  在同一时间只能发或者收
    全双工通信 

    会话管理:
    建立连接
    数据传输
    释放连接

    /////////////////////////////////////////////////////表示层
    目的:将数据转换成计算机应用程序互相理解的格式
    任务:翻译
          加密
    翻译:
    -ASCII

    /////////////////////////////////////////////////////应用层
    目的:完成网络服务应用
    任务:网络服务的协议
          网络应用程序
          网络服务通告
    域名解析

    /////////////////////////////////////////////////////常用协议
    TCP/IP
    IPX/SPX Internet分组交换/顺序分组交换,Novell公司的通信协议集
    Apple Talk 苹果机对等网协议
    NetBIOS NetBIOS名(计算机名46字符)
    NetBEUI 局域网通信很快,但不能路由
    SNA  sna网用在IBM小型机
    DECent

    /////////////////////////////////////////////////////TCP/IP协议
    TCP/IP协议栈
    IP数据报:IP协议向上层(主要是TCP层)提供统一的IP数据报

    ICMP
    ping www.baidu.com
    tracert www.baidu.com  跟踪路由

    TCP  传输控制协议
    -传输层协议,由上层协议接收任意长度的报文,并提供面向连接的传输服务。
    -TCP接收数据流,并分成段,然后将这些段送给IP,因IP为无连接的,所以TCP必须为每个段提供顺序同步。

    流量控制:由于计算机的处理速度不同,在传输过程中传输层调整传输速度。

    IP套接字:类似192.168.0.1:80  IP地址+端口号
    端口号范围:
    0-255      公共应用  1-1023 众所周知
    255-1023   商业公司  >=1024 随即端口
    1024-65535 没有限制
    常见端口号:
    应用协议  端口号 传输协议
    HTTP     80      TCP
    FTP      21      TCP
    TELNET   23      TCP
    SMTP     25      TCP
    DNS      53      TCP/UDP
    TFTP     69      UDP
    SNMP    161      UDP
    RIP     520      UDP
    NTP 微软时间同步协议

    QQ 4000
    远程桌面 3389

    UDP137、138 在网络邻居中显示计算机
    TCP139、445  \\IP

    netstat 查看TCP协议端口 netstat -n显示活动连接 netstat -an显示所有端口连接

    三次握手
             连接请求  send SYN   ---->   SYN received 接受请求   当不接受请求时,fin-wait->time wait->close
               (seq=100 ctl=SYN)
                  SYN received   <----    Send SYN ACK 请求连接 回送确认    
                                          (seq=300 ack=101 ctl=syn,ack)
    发送数据回送确认 Established  ---->   连接成功
       (seq=101 ack=301 ctl=ack)

    DoS攻击:拒绝服务攻击,重复二次握手(只进行 SYN ,SYN ACK )

    UDP:与TCP相比没有三次握手,没有校验,失去质量换取速度
    nslookup 解析域名命令


    /////////////////////////////////////////////////////ARP地址解析协议
    arp -a  arp表
    arp协议:发送Arp广播,目标地址10.1.1.254。把一个IP地址MAC地址做具体解析。广播式寻址(自动)
    二层交换设备:交换机、网卡,只认MAC地址(互联网用IP),局域网通信必须知道主机MAC地址。
    全网发ARP请求(replay请求),回应请求把自己MAC地址告诉主机。
    IPV6取消ARP协议,转用“邻居协议”。
    ARP病毒:病毒主机本身MAC为22-22-22-22-22-22,得到网关IP 192.168.1.1和MAC地址 11-11-11-11-11-11,他向全网广播说自己是网关后,其他主机学到的网关地址为192.168.1.1但MAC地址为22-22-22-22-22-22。
    更恶意的病毒:在病毒机上安装个小代理,让其他主机可以上网,但数据走的是病毒机。
    把ARP表做成静态项:arp -s 192.168.1.1 11-11-11-11-11-11
    Win7 ARP绑定: netsh ii show in
    netsh -c "ii" add neighbors 11 "IP地址" "mac地址"

    双向欺骗,欺骗路由器,在路由器上绑定IP的MAC地址。
    /////////////////////////////////////////////////////DNS域名解析协议
    域名和IP进行解析
    DNS Server
    nslookup 域名解析命令


     

  • Oracle学习笔记

    2010-06-07 10:47:48

    连接Oracle工具
    运行:sqlplusw、sqlplus、Oracle
    sqlplus worksheet 开发用的
    Enterprise Manager Console  图形操作

    ###########################################################远程连接
    pl/sql developer连接远程数据库
    开始-》所有程序-》Oracle-OraHome92-》Configuration and Migration Tools-》Net Manager
    打开一个界面点  本地-》服务命名
    再点左面的绿色的“+”,Net服务名填写你想要显示的名字例如(orcl_ip),然后下一步
    选 TCP/IP(Internet协议)  下一步
    主机名: 远程数据库的IP地址,端口默认(远程oracle的端口)  下一步
    服务名:windows看服务名,unix好像echo $ORACLE_HOME,我的机器orcl 下一步
    测试,更改用户密码测试,如果成功显示如下
    scott  tiger

    ###########################################################登录数据库
    conn 用户名/密码@网络服务名 as sysdba|sysoper
    connect scott/tiger@oracle
    conn  scott/tiger@oracle   远程访问,服务名oracle
    conn scott/tiger   本地
    conn system as sysdba
    conn system/123456 as sysdba

    show user
    disc 断开连接
    passw  修改密码

    ###########################################################文件操作命令
    文件操作命令:
    @ d:\a.sql  或 start d:\a.sql  执行.sql里德SQL命令
    edit d:\a.sql  编写a.sql
    spool d:\b.sql  …… spool off  将sql*plus屏幕上的内容……输出到指定文件中

    ###########################################################显示和设置环境变量
    显示和设置环境变量
    show linesize
    set linesize 90  每行显示90个字符
    set pagesize 5   每5行分页
    ###########################################################权限
    创建用户(需要system权限)
    create user 用户名 identified by my123;   创建用户时不能以数字开头
    password 用户名;   修改用户密码,修改别人密码需dba或拥有alter user权限
    alter user 用户名 identified by 密码
    drop user  用户名     自己不能删除自己
    drop user 用户名 cascade     在删除用户时,如果用户已经创建了表,连表一起删除
    刚创建的用户,没有任何权限,连登录权限都没有。
    权限分为:系统权限140多个、对象权限25个(select、insert、update、delete、all)
    系统权限:create session有此权限才可登录到数据库
    角色:具有一系列权限 connect、dba、resource(在任何一个表空间建表)
    grant connect to 用户名    具备登录数据库权限
    grant resource to 用户名   具备建表权限
    grant select on emp to 用户名  把对emp表的select权限付给用户。
    在scott用户执行grant select on emp to 用户名(把对scott的emp表的select权限付给用户)。登录用户名执行select * from scott.emp;
    grant all on emp to 用户名;   把emp表操作的所有权限付给用户。

    revoke select on emp from 用户名;   收回权限

    grant select on emp to 用户名 with grant option   对象权限+with grant option可将获得的权限再次分给其他用户
    grant   connect     to 用户名 with admin option   系统权限+with admin option可将获得的权限再次分给其他用户

    注:如果用户A将权限分给B,B将权限跟给C,将B的权限收回后,C权限也将自动被收回。株连模式

    ########################################################### profile文件实现管理用户口令

    create profile 文件名加锁 limit failed_login_attempts 3 password_lock_time 2;  密码输入3次,锁定2天
    alter user 用户名 profile 文件名加锁;  给用户加锁
    alter user 用户名 account unlock;   解锁

    create profile 文件名 limit password_life_time 10 password_grace_time 2;   每10天修改密码,宽限期2天
    create profile 文件名 limit password_life_time 10 password_grace_time 2 password_reuse_time 5; 指定口令可重用时间5天后可重用

    drop profile 文件名      删除profile文件,被profile约束的用户可释放
    ###########################################################表管理,数据类型
    以字母开头
    长度30字符
    不能用oracle保留字
    A-Z,a-z,0-9,$,#等
    字符型:
    char 最大2000字符
    例: char(10) '小韩'前4个字符放'小韩',后添6个空格不全。查询速度快,例如身份证,全字符比较。
    varchar2(20) 变长 最大4000字符
    例:varchar2(10) '小韩' 只分配4个字符。节省空间,查询速度慢,一个一个字符比较。
    clob(character large objient) 字符型大对象 最大4G
    数字型:
    number 10-38次方-10+38次方
    number(5,2)  表示一个小数有5位有效数,2位小数,范围-999.99-999.99
    number(5) 表示一个5位整数,范围-99999-99999
    日期:
    date 年月秒
    datestamp 毫秒级,银行项目
    图片:
    blob 二进制数据,可存放图片、声音 4G , 一般保密性高的图片、声音可以放入数据库,普通只存放图片路径
    ###########################################################表管理,表操作
    学生表
    create table student(
    xh number(4),--学号
    xm varchar2(20),--姓名
    sex char(2),--性别
    birthday date,--出生日期
    sal number(7,2) --奖学金
    );
    desc student  --查看表结构
    alter table student add (classid number(2)); --添加字段
    alter table student modify (xm varchar2(30)); --修改字段
    alter table student drop column sal; --删除字段 (一般不用)
    rename student to stu; --修改表名
    drop table student; 删除表
    ###########################################################表管理,数据操作
    insert into student values ('A001','张三','男','01-5月-05',10);   oracle默认日期格式'DD-MON-YY'
    alter session set nls_date_format='yyyy-mm-dd'; --修改默认日期格式
    insert into student(xh,xm,sex) values('A003','John','女'); --插入字段
    insert into student(xh,xm,sex) select * from student;  --复制自身插入数据,速度2的N次方。
    insert into student(xh,xm,sex,birthday) values(''A003','John','女',null); --插入空数据
    select * from student where birthday is null/not null;  --查询空数据
    update student set sex='女',birthday='1997-12-11' where xh='A001'; --修改数据
    delete from student;  删除所有记录,表结构还在,写日志,可以恢复,删除速度慢
    savepoint aa; 保存点
    roolback to aa; --回滚
    drop table student; --删除表的结构和数据
    delete from student where xh='A001'; --删除一条记录
    truncate table student; --删除表中所有记录,表结构还在,不写日志,无法找回删除记录,删除速度快
    ###########################################################表管理,select操作
    set timing on;  显示sql语句执行完成时间
    如何处理null值
    select sal*13+nvl(comm,0)*13 "年工资",ename,comm from emp; --nvl(comm,0) 如果nvl为空,就用0计算,如果不为空就用本身值。
    日期大于1982-1-1要写成  date>'1-1月-1982'  不能写成 date>'1982-1-1'  此为Oracle默认的日期格式
    like % _  0到多个字符,1个字符
    is null / is not null
    select * from emp by deptno,sal desc;   --desc降序
    select ename,(sal+nvl(comm,0))*12 as "年薪" from emp order by "年薪"
    ###########################################################Oracle复杂查询、子查询
    max,min,avg,sum,count分组函数
    select deptno,avg(sal) from emp group by deptno having avg(sal)<2000;
    1、分组函数只能出现在选择列,或having、order by子句中;
    2、如果在select语句中同时包含group by,having,order by顺序为group by,having,order by;
    3、选择列中如果有列、表达式、分组函数,则这些列和表达式必须有一个出现在group by子句中。
    多表查询条件,至少为表个数-1。笛卡尔集。
    between  1 and 2;
    自连接:
    select worker.ename,boss.ename from emp worker,emp boss where worker.ename=FROD;
    子查询:
    把能排除最多查询数据的条件放在子查询的左边,SQL语句扫描 左->右。
    in
    select * from emp where sal> all(select sal from emp where deptno=30); 
    select * from emp where sal> (select max(sal) from emp where deptno=30); --效率高
    select * from emp where sal> any(select sal from emp where deptno=30);
    select * from emp where sal> (select min(sal) from emp where deptno=30); --效率高
    多列子查询:
    select * from emp where (deptno,job)=(select deptno,job from emp where ename="SMITH";
    不能给表取别名。
    ###########################################################Oracle分页 三种方式
    1、根据rowid分来
    select * from emp where rowid in (select rid from (select rownum rn,rid
    from(select rowid rid,cid from emp drder by cid desc) where rownum<=10) where rn>=6 order by cid desc;
    执行时间0.03秒
    2、按分析函数来分
    select * from (select a1.*,row_number() over (order by cid desc) rk from emp a1) where rk<10000 and rk>9980;
    执行时间1.01秒
    3、按rownum来分
    select a1.*,rownum rn from (select * from emp) a1 where rownum<=10;
    select * from (select a1.*,rownum rn from (select * from emp order by cid desc) a1 where rownum<=10) where rn>=6; 二分法,查询速度快
    修改列显示,只需修改select * from emp。
    执行时间0.1秒
    emp表明,cid关键字段,取第6-第10记录,7万条记录。

    ###########################################################Oracle合并查询
    M union N where  合并排重   --M、N为表
    M union all N where  合并
    M minus N   M减N
    M intersect N 取M、N交集
    ###########################################################Oracle 创建数据库
    Configuration and Migration Tools——Database Configuration Assistant
    Data Warehouse  数据仓库
    General Purpose 普通用途
    New Database 
    Transaction Processing 事物处理
    ###########################################################Oracle 事务和锁
    create table myemp (id,ename,sal) as select empno,ename,sql from emp; --用查询结果创建一个新表
    insert into myemp (Myid,myname,mydept) select empno,ename,deptno from emp where deptno=10; --批量插入数据
    update emp set (job,sal,comm) = (select job,sal,comm from emp where ename='SMITH' where ename='SCOTT';

    commit; --提交事务,执行后,会确认事务的变化、结束事务、删除保存点、释放锁
    事务几个重要操作:
    1、设置保存点  savepoint a
    2、取消部分事务 rollback to a
    3、取消全部事务 rollback

  • SQL基础学习笔记

    2010-06-07 10:39:26

    数据定义
    create
    alter
    drop

    table、view、index、procedure、trigger、schema、domain

    数据操作
    select
    insert
    delete
    update

    数据控制
    grant
    deny
    revoke

    事物控制
    commit
    rollback
    set transaction

    注明:以下SQL语句中M,N为表 A,B,C为栏目
    select distinct A from M where A>100 or (A<50 and A>30)  对栏目A排重
    select * from M where A in ('namea','nameb')   取出A=namea,A=nameb的数据
    select * from M where A between '1982' and '1992' 取出1982-1992的数据
    select * from M where A like 'a_z' 'a%' '%a' '%a%'  _:一个字符 %:多个字符
    select * from M order by A asc, B desc  asc升序 desc降序

    select sum(A),B from M group by A having sum(A)>100  如果被select的只有函数栏,不需要group by子句//avg,count,max,min,sum
    select count(distinct A),B from M group by B

    内部连接
    select * from M,N where M.A=N.A
    外部连接
    where A1.A=A2.A(+)  新表数据都要
    select concat(A,B) from M 把A,B数据字符串串连起来
    select substr(A,3,4) from M 抓出A中第3个字符开始向后抓4个字符
    select trim(' sample ')   'sample' 移除sample左右字符
    select ltrim(' sample ')  'sample '
    select rtrim(' sample ')  ' sample'

    表格处理
    create table M (SID integer Unique,First_name char(50) not null,Last_name char(50),Birth_date date)
    create table M (SID integer Unique)
    create table M (SID integer Check (SID>0))
    create table M (SID integer,Primary Key(SID))  //MySQL
    create table M (SID integer Primary Key)        //Oracle,SQLServer
    alter table M Add Primary Key (SID)   //必须先确认主键栏位not null

    限制
    not null
    unique 不允许输入重复值
    check  栏位中数据符合某些条件 (未用在MySQL)

    create view 视图名 as select * from M   创建视图
    create index 索引名 on M(A,B)  为栏目A,B创建索引

    alter table M add C char(50)  添加栏目C
    alter table M change A C char(50) 修改栏目A为C
    alter table M modify C char(30)  修改栏目C
    alter table M drop C  删除栏目C

    drop table M       删除表
    truncate table M   清空表

    insert into M (A,B) values ('a','b')  插入数据
    insert into M (A,B) select A,B from N where ……  将N表A,B数据插入M表
    update M set A=a,B=2 where …… 修改数据
    delete from M where ……  删除数据

    select A from M
    union/union all/intersect/minus   M,N的A栏目合并且剔除重复/不剔除重复/A字段交集/M中有N中没有
    select A from N

    子查询
    select * from M exists (select * from N where ……)  如果内查询(select * from N where ……)有数据,则执行外查询select * from M
    select A ,case A
      when 条件 then B*2   //条件可以是一个值或公式
      when 条件 then B*2
      ……
      else B 
      end
      New_B,C from M  New_B为CASE栏位的栏位名

     

  • Oracle init.ora常用配置详解

    2010-05-25 15:56:14

    以下内容摘自: www.51testing.com

    db_name = "51test"

      一个数据库标识符,应与CREATE DATABASE 语句中指定的名称相对应。

    instance_name = 51test

      在多个例程使用相同服务名的情况下,用来唯一地标识一个数据库例程。

    INSTANCE_NAME

      不应与SID混淆,它实际上是对在一台主机上共享内存的各个例程的唯一标识。

    service_names = 51test

      为 Net8 监听程序可用于识别一个服务 (如:复制环境中的一个特定数据库) 的例程指定服务名。如果该服务没有域,将附加 DB_DOMAIN 参数。

    control_files = ("/opt/apps/oracle/oradata/51test/control01.ctl", "/opt/apps/oracle/oradata/51test/control02.ctl", "/opt/apps/oracle/oradata/51test/control03.ctl")
    open_cursors = 320

      库高速缓存 指定一个会话一次可以打开的游标(环境区域)的最大数量,并且限制 PL/SQL 使用的 PL/SQL 游标高速缓存的大小,以避免用户再次执行语句时重新进行语法分析。请将该值设置得足够高,这样才能防止应用程序耗尽打开的游标。

    max_enabled_roles = 32
    db_block_buffers = 5120

      高速缓存与I/O 缓冲区高速缓存中 Oracle 块的数量。该参数会显着影响一个例程的 SGA 总大小。

    shard_pool_size = 75497472
    large_pool_size = 15728640

      池--指定大存储池的分配堆,它可被多线程服务器 (MTS) 用作会话内存、用作并行执行的消息缓冲区以及用作 RMAN备份和恢复的磁盘 I/O 缓冲区。

    java_pool_size = 65536

      以字节为单位,指定 Java 存储池的大小,它用于存储 Java 的方法和类定义在共享内存中的表示法,以及在调用结束时移植到 Java 会话空间的 Java 对象。

    log_checkpoint_interval = 10000

      指定在出现检查点之前,必须写入重做日志文件中的 OS 块(而不是数据库块)的数量。无论该值如何,在切换日志时都会出现检查点。较低的值可以缩短例程恢复所需的时间,但可能导致磁盘操作过量。

    log_checkpoint_timeout = 1800

      指定距下一个检查点出现的最大时间间隔(秒数)。将该时间值指定为 0,将禁用以时间为基础的检查点。较低的值可以缩短例程恢复的时间,但可能导致磁盘操作过量

    processes = 220
    log_buffer = 8388608

      以字节为单位,指定在 LGWR 将重做日志条目写入重做日志文件之前,用于缓存这些条目的内存量。重做条目保留对数据库块所作更改的一份记录。如果该值大于65536,就能减少重做日志 文件 I/O,特别是在有长时间事务处理或大量事务处理的系统上  **最大值为 500K 或 128K * CPU_COUNT,两者之中取较大者

    oracle_trace_enable = true

      启动一个默认的 Oracle Trace 集合,直到该值再次设置为 NULL。

    sql_trace=false

      这些信息对改善性能很有用。由于使用 SQL 跟踪设备将引发系统开销,只应在需要优化信息的情况下使用 TRUE。

    timed_statistics=true

      收集操作系统的计时信息,这些信息可被用来优化数据库和 SQL

      语句。要防止因从操作系统请求时间而引起的开销,请将该值设置为零。 将该值设置为 TRUE 对于查看长时间操作的进度也很有用。

    background_dump_dest = /opt/apps/oracle/admin/51test/bdump

      指定在 Oracle 操作过程中为后台进程(LGWR,DBW n 等等)写入跟踪文件的路径名(目录或磁盘)。它还定义记录着重要事件和消息的数据库预警文件的位置。

    core_dump_dest = /opt/apps/oracle/admin/51test/cdump

      指定核心转储位置的目录名(用于 UNIX)。

    resource_manager_plan = system_plan

      如果指定该值,资源管理器将激活计划和例程的所有子项 (子计划、指令和使用者组)。如果不指定,资源管理器将被禁用,但使用 ALTER SYSTEM 命令还可以启用。

    user_dump_dest = /opt/apps/oracle/admin/51test/udump

      为服务器将以一个用户进程身份在其中写入调试跟踪文件的目录 指定路径名。例如,该目录可这样设置: NT 操作系统上的 C:/

      ORACLE/UTRC;UNIX 操作系统上的 /oracle/utrc;或 VMS 操作系统上的DISK$UR3:[ORACLE.UTRC]。

    db_block_size = 8192

      一个 Oracle 数据库块的大小(以字节计)。该值在创建数据库时设置,而且此后无法更改。 1024 - 65536 (根据操作系统而定)。

    remote_login_passwordfile = exclusive

      指定操作系统或一个 文件是否检查具有权限的用户的口令。如果设置为 NONE,Oracle 将忽略口令文件。如果设置为    EXCLUSIVE,将使用数据库的口令文件对每个具有权限的用户进行验证。如果设置为 SHARED,多个数据库将共享 SYS 和     INTERNAL 口令文件用户

    os_authent_prefix = ""

      使用用户的操作系统帐户名和口令来验证连 接到服务器的用户。该参数的值与各用户的操作系统帐户连接在一起。要去除 OS

      帐户前缀,请指定空值。

    job_queue_processes = 4

      只用于复制环境。它指定每个例程的 SNP 作业队列进程的数量 (SNP0, ... SNP9, SNPA, ... SNPZ)。要自动更新表快照或执行由 DBMS_JOB 创建的请求,请将该参数设置为 1 或更大的值。   0 到 36

    job_queue_interval = 60

      作业队列 只用于复制环境。它以秒为单位指定该例程的每个 SNPn 后台进程的唤醒频率。  1 到 3600

    distributed_transactions = 10

      一个数据库一次可参与的分布式事务处理的最大数量。如果由于网络故障异常频繁而减少该值,将造成大量未决事务处理。

    open_links = 4

      指定在一次会话中同时打开的与远程数据库的连接的最大数量。该值应等于或超过一个引用多个数据库的单个 SQL 语句中引用的数据库的数量,这样才能打开所有数据库以便执行该语句。

    mts_dispatchers = "(protocol=TCP)(mul=ON)(tick=15)(pool=(in=2)(out=2))"

      为设置使用多线程服务器的 共享环境而设置调度程序的数量和类型。可以为该参数指定几种选项。这是字符串值的一个示例:"(PROTOCOL=TCP) (DISPATCHERS=3)"。

    compatible = "8.1.0"

      允许使用一个新的发行版,同时保证与先前版 本的向后兼容性。

    sort_area_size = 524288

      以字节为单位,指定排序所使用的最大内存量。排序完成 后,各行将返回,并且内存将释放。增大该值可以提高大型排序的效率。如果超过了该内存量,将使用临时磁盘段。相当于 6 个数据库块的值 (最小值) 到操作系统确定的值(最大值)。

    sort_area_retained_size = 131072

      以字节为单位,指定 在一个排序运行完毕后保留的用户全局区 (UGA) 内存量的最大值。最后一行从排序空间中被提取后,该内存将被释放回 UGA,而不是释放给操作系统。

  • 有效编写高质量软件的75条建议

    2010-05-25 15:36:27

    以下内容摘自www.51testing.com

      1. 你们的项目组使用源代码管理工具了么?

      应该用。VSS、CVS、PVCS、ClearCase、CCC/Harvest、FireFly都可以。我的选择是VSS。

      2. 你们的项目组使用缺陷管理系统了么?

      应该用。ClearQuest太复杂,我的推荐是BugZilla。

      3. 你们的测试组还在用Word写测试用例么?

      不要用Word写测试用例(Test Case)。应该用一个专门的系统,可以是Test Manager,也可以是自己开发一个ASP.NET的小网站。主要目的是Track和Browse。

      4. 你们的项目组有没有建立一个门户网站?

      要有一个门户网站,用来放Contact Info、Baselined Schedule、News等等。推荐Sharepoint Portal Server 2003来实现,15分钟就搞定。买不起SPS 2003可以用WSS (Windows Sharepoint Service)。

      5. 你们的项目组用了你能买到最好的工具么?

      应该用尽量好的工具来工作。比如,应该用VS.NET而不是Notepad来写C#。用Notepad写程序多半只是一种炫耀。但也要考虑到经费,所以说是“你能买到最好的”。

      6. 你们的程序员工作在安静的环境里么?

      需要安静环境。这点极端重要,而且要保证每个人的空间大于一定面积。

      7. 你们的员工每个人都有一部电话么?需要每人一部电话。而且电话最好是带留言功能的。当然,上这么一套带留言电话系统开销不小。不过至少每人一部电话要有,千万别搞得经常有人站起来喊:“某某某电话”。《人件》里面就强烈谴责这种做法。

      8. 你们每个人都知道出了问题应该找谁么?

      应该知道。任何一个Feature至少都应该有一个Owner,当然,Owner可以继续Dispatch给其他人。

      9. 你遇到过有人说“我以为…”么?

      要消灭“我以为”。Never assume anything。

      10. 你们的项目组中所有的人都坐在一起么?

      需要。我反对Virtual Team,也反对Dev在美国、Test在中国这种开发方式。能坐在一起就最好坐在一起,好处多得不得了。

      11. 你们的进度表是否反映最新开发进展情况?

      应该反映。但是,应该用Baseline的方法来管理进度表:维护一份稳定的Schedule,再维护一份最新更改。Baseline的方法也应该用于其它的Spec。Baseline是变更管理里面的一个重要手段。

      12. 你们的工作量是先由每个人自己估算的么?

      应该让每个人自己估算。要从下而上估算工作量,而不是从上往下分派。除非有其他原因,比如政治任务工期固定等。

      13. 你们的开发人员从项目一开始就加班么?

      不要这样。不要一开始就搞疲劳战。从项目一开始就加班,只能说明项目进度不合理。当然,一些对日软件外包必须天天加班,那属于剥削的范畴。

      14. 你们的项目计划中Buffer Time是加在每个小任务后面的么?

      不要。Buffer Time加在每个小任务后面,很容易轻易的就被消耗掉。Buffer Time要整段的加在一个Milestone或者checkpoint前面。

      15. 值得再多花一些时间,从95%做到100%好值得,非常值得。

      尤其当项目后期人困马乏的时候,要坚持。这会给产品带来质的区别。

      16. 登记新缺陷时,是否写清了重现步骤?

      要。这属于Dev和Test之间的沟通手段。面对面沟通需要,详细填写Repro Steps也需要。

      17. 写新代码前会把已知缺陷解决么?要。每个人的缺陷不能超过10个或15个,否则必须先解决老的bug才能继续写新代码。

      18. 你们对缺陷的轻重缓急有事先的约定么?

      必须有定义。Severity要分1、2、3,约定好:蓝屏和Data Lost算Sev 1,Function Error算Sev 2,界面上的算Sev 3。但这种约定可以根据产品质量现状适当进行调整。

      19. 你们对意见不一的缺陷有三国会议么?必须要有。要有一个明确的决策过程。这类似于CCB (Change Control Board)的概念。

      20. 所有的缺陷都是由登记的人最后关闭的么?

      Bug应该由Opener关闭。Dev不能私自关闭Bug。

      21. 你们的程序员厌恶修改老的代码么?

      厌恶是正常的。解决方法是组织Code Review,单独留出时间来。XP也是一个方法。

      22. 你们项目组有Team Morale Activity么?

      每个月都要搞一次,吃饭、唱歌、Outing、打球、开卡丁车等等,一定要有。不要剩这些钱。

      23. 你们项目组有自己的Logo么?

      要有自己的Logo。至少应该有自己的Codename。

      24. 你们的员工有印有公司Logo的T-Shirt么?

      要有。能增强归属感。当然,T-Shirt要做的好看一些,最好用80支的棉来做。别没穿几次就破破烂烂的。

      25. 总经理至少每月参加次项目组会议要的。

      要让team member觉得高层关注这个项目。

      26. 你们是给每个Dev开一个分支么?

      反对。Branch的管理以及Merge的工作量太大,而且容易出错。

      27. 有人长期不Check-In代码么?

      不可以。对大部分项目来说,最多两三天就应该Check-In。

      28. 在Check-In代码时都填写注释了么?

      要写的,至少一两句话,比如“解决了Bug No.225”。如果往高处拔,这也算做“配置审计”的一部分。

      29. 有没有设定每天Check-In的最后期限?

      要的,要明确Check-In Deadline。否则会Build Break。

      30. 你们能把所有源码一下子编译成安装文件吗?

      要的。这是每日编译(Daily Build)的基础。而且必须要能够做成自动的。

      31. 你们的项目组做每日编译么?

      当然要做。有三样东西是软件项目/产品开发必备的:1. bug management; 2. source control; 3. daily build。

      32. 你们公司有没有积累一个项目风险列表?

      要。Risk Inventory。否则,下个项目开始的时候,又只能拍脑袋分析Risk了。

      33. 设计越简单越好越简单越好。

      设计时候多一句话,将来可能就带来无穷无尽的烦恼。应该从一开始就勇敢的砍。这叫scope management。

      34. 尽量利用现有的产品、技术、代码千万别什么东西都自己Coding。BizTalk和Sharepoint就是最好的例子,有这两个作为基础,可以把起点提高很多。或者可以尽量多用现成的Control之类的。或者尽量用XML,而不是自己去Parse一个文本文件;尽量用RegExp,而不是自己从头操作字符串,等等等等。这就是“软件复用”的体现。

      35. 你们会隔一段时间就停下来夯实代码么?

      要。最好一个月左右一次。传言去年年初Windows组在Stevb的命令下停过一个月增强安全。Btw,“夯”这个字念“hang”,第一声。

      36. 你们的项目组每个人都写Daily Report么?

      要写。五分钟就够了,写10句话左右,告诉自己小组的人今天我干了什么。一则为了沟通,二则鞭策自己(要是游手好闲一天,自己都会不好意思写的)。

      37. 你们的项目经理会发出Weekly Report么?

      要。也是为了沟通。内容包括目前进度,可能的风险,质量状况,各种工作的进展等。

      38. 你们项目组是否至少每周全体开会一次?

      要。一定要开会。程序员讨厌开会,但每个礼拜开会时间加起来至少应该有4小时。包括team meeting, spec review meeting, bug triage meeting。千万别大家闷头写code。

      39. 你们项目组的会议、讨论都有记录么?

      会前发meeting request和agenda,会中有人负责主持和记录,会后有人负责发meeting minutes,这都是effective meeting的要点。而且,每个会议都要形成agreements和action items。

      40. 其他部门知道你们项目组在干什么么?

      要发一些Newsflash给整个大组织。Show your team’s value。否则,当你坐在电梯里面,其他部门的人问:“你们在干嘛”,你回答“ABC项目”的时候,别人全然不知,那种感觉不太好。

      41. 通过Email进行所有正式沟通

      Email的好处是免得抵赖。但也要避免矫枉过正,最好的方法是先用电话和当面说,然后Email来确认。

      42. 为项目组建立多个Mailing Group

      如果在AD+Exchange里面,就建Distribution List。比如,我会建ABC Project Core Team,ABC Project Dev Team,ABC Project All Testers,ABC Project Extended Team等等。这样发起Email来方便,而且能让该收到email的人都收到、不该收到不被骚扰。

      43. 每个人都知道哪里可以找到全部的文档么?

      应该每个人都知道。这叫做知识管理(Knowledge Management)。最方便的就是把文档放在一个集中的File Share,更好的方法是用Sharepoint。

      44. 你做决定、做变化时,告诉大家原因了么?

      要告诉大家原因。Empower team member的手段之一是提供足够的information,这是MSF一开篇的几个原则之一。的确如此,tell me why是人之常情,tell me why了才能有understanding。中国人做事喜欢搞限制,限制信息,似乎能够看到某一份文件的人就是有身份的人。大错特错。权威、权力,不在于是不是能access information/data,而在于是不是掌握资源。

      45. Stay agile and expect change 要这样。

      需求一定会变的,已经写好的代码一定会被要求修改的。做好心理准备,对change不要抗拒,而是expect change。

      46. 你们有没有专职的软件测试人员?

      要有专职测试。如果人手不够,可以peer test,交换了测试。千万别自己测试自己的。

      47. 你们的测试有一份总的计划来规定做什么和怎么做么?这就是Test Plan。要不要做性能测试?要不要做Usability测试?什么时候开始测试性能?测试通过的标准是什么?用什么手段,自动的还是手动的?这些问题需要用Test Plan来回答。

      48. 你是先写Test Case然后再测试的么?

      应该如此。应该先设计再编程、先test case再测试。当然,事情是灵活的。我有时候在做第一遍测试的同时补上test case。至于先test case再开发,我不喜欢,因为不习惯,太麻烦,至于别人推荐,那试试看也无妨。

      49. 你是否会为各种输入组合创建测试用例?

      不要,不要搞边界条件组合。当心组合爆炸。有很多test case工具能够自动生成各种边界条件的组合——但要想清楚,你是否有时间去运行那么多test case。

      50. 你们的程序员能看到测试用例么?

      要。让Dev看到Test Case吧。我们都是为了同一个目的走到一起来的:提高质量。

      51. 你们是否随便抓一些人来做易用性测试?

      要这么做。自己看自己写的程序界面,怎么看都是顺眼的。这叫做审美疲劳——臭的看久了也就不臭了,不方便的永久了也就习惯了。

      52. 你对自动测试的期望正确么?

      别期望太高。依我看,除了性能测试以外,还是暂时先忘掉“自动测试”吧,忘掉WinRunner和LoadRunner吧。对于国内的软件测试的现状来说,只能“矫枉必须过正”了。

      53. 你们的性能测试是等所有功能都开发完才做的么?

      不能这样。性能测试不能被归到所谓的“系统测试”阶段。早测早改正,早死早升天。

      54. 你注意到测试中的杀虫剂效应了么?

      虫子有抗药性,Bug也有。发现的新Bug越来越少是正常的。这时候,最好大家交换一下测试的area,或者用用看其他工具和手法,就又会发现一些新bug了。

      55. 你们项目组中有人能说出产品的当前整体质量情况么?

      要有。当老板问起这个产品目前质量如何,Test Lead/Manager应该负责回答。

      56. 你们有单元测试么?

      单元测试要有的。不过没有单元测试也不是不可以,我做过没有单元测试的项目,也做成功了——可能是侥幸,可能是大家都是熟手的关系。还是那句话,软件工程是非常实践、非常工程、非常灵活的一套方法,某些方法在某些情况下会比另一些方法好,反之亦然。

      57. 你们的程序员是写完代码就扔过墙的么?

      大忌。写好一块程序以后,即便不做单元测试,也应该自己先跑一跑。虽然有了专门的测试人员,做开发的人也不可以一点测试都不做。微软还有Test Release Document的说法,程序太烂的话,测试有权踢回去。

      58. 你们的程序中所有的函数都有输入检查么?

      不要。虽然说做输入检查是write secure code的要点,但不要做太多的输入检查,有些内部函数之间的参数传递就不必检查输入了,省点功夫。同样的道理,未必要给所有的函数都写注释。写一部分主要的就够了。

      59. 产品有统一的错误处理机制和报错界面么?

      要有。最好能有统一的error message,然后每个error message都带一个error number。这样,用户可以自己根据error number到user manual里面去看看错误的具体描述和可能原因,就像SQL Server的错误那样。同样,ASP.NET也要有统一的Exception处理。可以参考有关的Application Block。

      60. 你们有统一的代码书写规范么?

      要有。Code Convention很多,搞一份来发给大家就可以了。当然,要是有FxCop这种工具来检查代码就更好了。

      61. 你们的每个人都了解项目的商业意义么?

      要。这是Vision的意思。别把项目只当成工作。有时候要想着自己是在为中国某某行业的信息化作先驱者,或者时不时的告诉team member,这个项目能够为某某某国家部门每年节省多少多少百万的纳税人的钱,这样就有动力了。平凡的事情也是可以有个崇高的目标的。

      62. 产品各部分的界面和操作习惯一致么?

      要这样。要让用户觉得整个程序好像是一个人写出来的那样。

      63. 有可以作为宣传亮点的Cool Feature么?

      要。这是增强团队凝聚力、信心的。而且,“一俊遮百丑”,有亮点就可以掩盖一些问题。这样,对于客户来说,会感觉产品从质量角度来说还是acceptable的。或者说,cool feature或者说亮点可以作为质量问题的一个事后弥补措施。

      64. 尽可能缩短产品的启动时间要这样。

      软件启动时间(Start-Up time)是客户对性能好坏的第一印象。

      65. 不要过于注重内在品质而忽视了第一眼的外在印象程序员容易犯这个错误:太看重性能、稳定性、存储效率,但忽视了外在感受。而高层经理、客户正相反。这两方面要兼顾,协调这些是PM的工作。

      66. 你们根据详细产品功能说明书做开发么?

      要这样。要有设计才能开发,这是必须的。设计文档,应该说清楚这个产品会怎么运行,应该采取一些讲故事的方法。设计的时候千万别钻细节,别钻到数据库、代码等具体实现里面去,那些是后面的事情,一步步来不能着急。

      67. 开始开发和测试之前每个人都仔细审阅功能设计么?

      要做。Function Spec review是用来统一思想的。而且,review过以后形成了一致意见,将来再也没有人可以说“你看,当初我就是反对这么设计的,现在吃苦头了吧”

      68. 所有人都始终想着The Whole Image么?要这样。项目里面每个人虽然都只是在制造一片叶子,但每个人都应该知道自己在制造的那片叶子所在的树是怎么样子的。我反对软件蓝领,反对过分的把软件制造看成流水线、车间。参见第61条。

      69. Dev工作的划分是单纯纵向或横向的么?

      不能单纯的根据功能模块分,或者单纯根据表现层、中间层、数据库层分。我推荐这么做:首先根据功能模块分,然后每个“层”都有一个Owner来Review所有人的设计和代码,保证consistency。

      70. 你们的程序员写程序设计说明文档么?

      要。不过我听说微软的程序员1999年以前也不写。所以说,写不写也不是绝对的,偷懒有时候也是可以的。参见第56条。

      71. 你在招人面试时让他写一段程序么?

      要的。我最喜欢让人做字符串和链表一类的题目。这种题目有很多循环、判断、指针、递归等,既不偏向过于考算法,也不偏向过于考特定的API。

      72. 你们有没有技术交流讲座?

      要的。每一两个礼拜搞一次内部的Tech Talk或者Chalk Talk吧。让组员之间分享技术心得,这笔花钱送到外面去培训划算。

      73. 你们的程序员都能专注于一件事情么?

      要让程序员专注一件事。例如说,一个部门有两个项目和10个人,一种方法是让10个人同时参加两个项目,每个项目上每个人都花50%时间;另一种方法是5个人去项目A,5个人去项目B,每个人都100%在某一个项目上。我一定选后面一种。这个道理很多人都懂,但很多领导实践起来就把属下当成可以任意拆分的资源了。

      74. 你们的程序员会夸大完成某项工作所需要的时间么?

      会的,这是常见的,尤其会在项目后期夸大做某个change所需要的时间,以次来抵制change。解决的方法是坐下来慢慢磨,磨掉程序员的逆反心理,一起分析,并把估算时间的颗粒度变小。

      75. 尽量不要用Virtual Heads 最好不要用Virtual Heads。

      Virtual heads意味着resource is not secure,shared resource会降低resource的工作效率,容易增加出错的机会,会让一心二用的人没有太多时间去review spec、review design。一个dedicated的人,要强过两个只能投入50%时间和精力的人。我是吃过亏的:7个part time的tester,发现的Bug和干的活,加起来还不如两个full-time的。参见第73条。73条是针对程序员的,75条是针对 Resource Manager的。

  • Linux基础学习

    2010-05-18 17:45:39

    startx  从字符界面Console进入图形界面X-Window    Ctrl+Alt+BackSpace回到字符界面
    init [0123456]
    在X-Window图形操作界面中按“Alt+Ctrl+功能键Fnn=1~6
    0:停机(记住不要把initdefault 设置为0,因为这样会使Linux无法启动 )
    1:单用户模式,就像Win9X下的安全模式。
    2:多用户,但是没有 NFS 。
    3:完全多用户模式,标准的运行级。
    4:一般不用,在一些特殊情况下可以用它来做一些事情。
    5:X11,即进到 X-Window 系统。
    6:重新启动 (记住不要把initdefault 设置为6,因为这样会使Linux不断地重新启动)。
    /etc/inittab
    重启 ,按“e”, 第二行 按“e”,最后添 空格1。Esc 按b 进入单用户模式(单用户模式不读inittab文件)

    shutdown -h now  关机
    shutdown -r now  重启  reboot
    shutdown -a now  重启进入单用户模式

    su - root  切换到root用户
    su root 获取root权限

    logout  用户注销

    useradd 用户名
    passwd 用户名 ->输入密码
    userdel 用户名 删除用户
    userdel -r 用户名 删除用户以及用户主目录

    //////////////////////////////////////////////////////////////////////////////////////
    route   显示网关
    #route del default gw xx.xx.xx.xx. xxx.xxx.xx.xxx
    #route add default gw xx.xx.xx.xx. xxx.xxx.xx.xxx
    netconfig  窗口配置网络
    /etc/init.d/network restart  或 service network restart  重启网络服务
    ip都可以在/etc/sysconfig/network-scrips/ifcfg-ethX里面更改,下面是我的ifcfg-eth0内容
      DEVICE=eth0
      BOOTPROTO=none
      NBOOT=yes
      IPADDR=192.168.0.2
      NETMASK=255.255.255.0
      USERCTL=no
      PEERDNS=no
      GATEWAY=192.168.0.1
      TYPE=Ethernet
      NETWORK=192.168.0.0
      BROADCAST=192.168.0.255
    ////////////////////////////////////////////////////////////////////////////////////////
    mount /dev/cdrom /mnt/cdrom/   挂载光盘
    mount -t iso9660 xxxx.iso /mnt/cdrom -o loop  本地iso挂载

    etc/vsftpd/vsftpd.conf
    var/ftp/pub
    service vsftpd start/restart

    ///////////////////////////////////////////////////////////////////////////////////////////
    pwd 显示当前目录
    ls -a 显示隐藏文件
    ls -l 显示长列表格式
    ls -al
    ls -l /etc | more  管道命令  把上一个命令结果交给 | 后面的命令处理

    mkdir 建立目录
    rmdir 删除目录

    touch 建立空文件
    cp 复制 cp a.out /home/xiaoming/   (tab键可自动填全命令,按2下显示选择)
    cp -r dir1 dir2 递归复制(复制子目录信息)

    mv 移动文件和改文件名
    rm 删除文件和目录

    more 显示文件内容,带分页
    grep 在文本中查询内容
    grep -n "ab" install.log  在install.log中查找ab(显示在第几行)
    grep "ab" install.log

    find /home -name *.*   查找/home中,文件名为*.*的文件

    ls -l > 1.txt  重定向,grep -n "ab" install.log > kkk.txt
    ls -l >>1.txt  将结果追加到1.txt

    cat 1.txt 只看不改
    /////////////////////////////////////////////////////////////////////////////////////////////
    cat /etc/group | more
    groupadd 组名
    useradd -g 组名 用户名  创建用户并分配到组
    usermod -g 组名 用户名  修改用户所在组
    cat /etc/passwd

    r 4    100读
    w 2    010写
    x 1    001可执行
    rwx 7  111
    rw 6   110读写

    -rw-r--r-- 1 root root 1213 Feb 2 09:39 abc
    文件类型  文件所有者  文件所在组 其他组用户
    第一个字符代表文件-,目录d,链接l
    1    连接的文件数
    root 用户
    root 组
    1213 文件大小(字节)
    Feb 2 09:39 abc 最后修改日期
    abc  文件名

    ls -ahl 看文件所有者
    chmod 777 文件夹和文件

    /////////////////////////////////////////////////////////////////////////////////////////////////
    fdisk -l 查看分区     逻辑分区从/dev/sda5  开始
    df [-参数]  df -l / df -h查看磁盘使用情况
    df [目录全路径]  查看目录在哪个分区
    mount [-参数] [设备名称] [挂载点]  挂载光驱时,可直接使用 mount /mnt/cdrom 或 mount /dev/cdrom /mnt/cdrom
    umount 卸载命令
    find -size +100000K  显示100M以上的文件


    ////////////////////////////////////////////////////////////////////////////////////////////////////
    shell 
    Bourne  S.R.Borne  /bin/sh -> bash    大陆
    C      Bill Joy    /bin/csh -> tcsh
    Kom     David      /bin/ksh    欧洲
                       /bin/bsh -> ash

    env 查看linux环境变量
    chsh -s /bin/csh

    history n  显示最后n条命令
    !5 执行第5行命令

    ///////////////////////////////////////////////////////////////////////////

    setup  linux设置
    /etc/rc.d/init.d/network restart  或 service network restart 网卡配置生效
    ifconfig eth0 192.168.1.5 临时生效IP,重启后又变回原来IP
    /etc/sysconfig/netwrok-scripts/ifcfg-eth0  网卡配置文件(linux中所有设备都是文件)
    ifconfig eth0 down 禁止使用eth0
    ifconfig eth0 up 打开

    ////////////////////////////////////////////////////////////////////////////////////////
    RPM  ReadHat Package Manager (RedHat软件包管理工具)
    apache-1.3.23-11.i386.rpam    软件名称-主版本号-次版本号-运行平台
    rpm -qa | more ,rpm -qa | grep X 查找所有安装的rpm包,查询含有X字符的rpm包
    rpm -q mozilla 查包是否安装
    rpm -qi mozilla 查看包信息
    rpm -ql mozilla 查包中的文件
    rpm -qf /etc/passwd 查文件所属的包
    rpm -

    安装:
    rpm -i RPM包全路径
    rpm -ivh RPM包全路径
    参数:i  install 安装
          v  verbose 提示
          h  hash   进度条
    删除:
    rpm -e RPM包名称   rpm -e --nodeps samba 强行删除
    升级:
    rpm -U RPM包全路径

    tar -zxfv filename.tar.gz  解压

     

  • loadrunner录制登录密码转md5

    2010-04-06 22:54:51

    在录制用户注册登录脚本时,常常会遇到Web程序对用户密码进行MD5加密,例如下面一段脚本:
     web_submit_data("MagaRegister.aspx_2",
      "Action=http://www.feidubook.com/MagaRegister.aspx",
      "Method=POST",
      "TargetFrame=",
      "RecContentType=text/html",
      "Referer=http://www.feidubook.com/MagaRegister.aspx",
      "Snapshot=t13.inf",
      "Mode=HTML",
      ITEMDATA,
      "Name=__EVENTTARGET", "Value=", ENDITEM,
      "Name=__EVENTARGUMENT", "Value=", ENDITEM,
      "Name=__VIEWSTATE", "Value={Siebel_Analytic_ViewState4}", ENDITEM,
      "Name=topNaviId$txtUserName", "Value=", ENDITEM,
      "Name=topNaviId$txtUserPwd", "Value=", ENDITEM,
      "Name=topNaviId$ValidCodeId", "Value=", ENDITEM,
      "Name=searchType", "Value=qikan", ENDITEM,
      "Name=searchdomain", "Value=", ENDITEM,
      "Name=q", "Value=", ENDITEM,
      "Name=txtUserName", "Value=user0001", ENDITEM,
      "Name=txtUserPwd", "Value=e10adc3949ba59abbe56e057f20f883", ENDITEM, //密码123456被转为32位的MD5
      "Name=txtUserPwd2", "Value=e10adc3949ba59abbe56e057f20f883", ENDITEM,
     
    遇到此种情况时,第一种方法就是将“用户名”参数化,密码设为一样,即每个用户名的密码都为e10adc3949ba59abbe56e057f20f883
    还有一种方法就是利用MD5函数。这里介绍一种算法:
    #ifndef MD5_H
    #define MD5_H
    #ifdef __alpha
    typedef unsigned int uint32;
    #else
    typedef unsigned long uint32;
    #endif
    struct MD5Context {
            uint32 buf[4];
            uint32 bits[2];
            unsigned char in[64];
    };
    extern void MD5Init();
    extern void MD5Update();
    extern void MD5Final();
    extern void MD5Transform();
    typedef struct MD5Context MD5_CTX;
    #endif
    #ifdef sgi
    #define HIGHFIRST
    #endif
    #ifdef sun
    #define HIGHFIRST
    #endif
    #ifndef HIGHFIRST
    #define byteReverse(buf, len)    /* Nothing */
    #else
    void byteReverse(buf, longs)unsigned char *buf; unsigned longs;
    {
        uint32 t;
        do {
        t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |((unsigned) buf[1] << 8 | buf[0]);
        *(uint32 *) buf = t;
        buf += 4;
        } while (--longs);
    }
    #endif
    void MD5Init(ctx)struct MD5Context *ctx;
    {
        ctx->buf[0] = 0x67452301;
        ctx->buf[1] = 0xefcdab89;
        ctx->buf[2] = 0x98badcfe;
        ctx->buf[3] = 0x10325476;
        ctx->bits[0] = 0;
        ctx->bits[1] = 0;
    }
    void MD5Update(ctx, buf, len) struct MD5Context *ctx; unsigned char *buf; unsigned len;
    {
        uint32 t;
        t = ctx->bits[0];
        if ((ctx->bits[0] = t + ((uint32) len << 3)) < t)
        ctx->bits[1]++;
        ctx->bits[1] += len >> 29;
        t = (t >> 3) & 0x3f;
        if (t) {
        unsigned char *p = (unsigned char *) ctx->in + t;
        t = 64 - t;
        if (len < t) {
            memcpy(p, buf, len);
            return;
        }
        memcpy(p, buf, t);
        byteReverse(ctx->in, 16);
        MD5Transform(ctx->buf, (uint32 *) ctx->in);
        buf += t;
        len -= t;
        }
        while (len >= 64) {
        memcpy(ctx->in, buf, 64);
        byteReverse(ctx->in, 16);
        MD5Transform(ctx->buf, (uint32 *) ctx->in);
        buf += 64;
        len -= 64;
        }
        memcpy(ctx->in, buf, len);
    }
    void MD5Final(digest, ctx)
        unsigned char digest[16]; struct MD5Context *ctx;
    {
        unsigned count;
        unsigned char *p;
        count = (ctx->bits[0] >> 3) & 0x3F;
        p = ctx->in + count;
        *p++ = 0x80;
        count = 64 - 1 - count;
        if (count < 8) {
        memset(p, 0, count);
        byteReverse(ctx->in, 16);
        MD5Transform(ctx->buf, (uint32 *) ctx->in);
        memset(ctx->in, 0, 56);
        } else {
        memset(p, 0, count - 8);
        }
        byteReverse(ctx->in, 14);
        ((uint32 *) ctx->in)[14] = ctx->bits[0];
        ((uint32 *) ctx->in)[15] = ctx->bits[1];
        MD5Transform(ctx->buf, (uint32 *) ctx->in);
        byteReverse((unsigned char *) ctx->buf, 4);
        memcpy(digest, ctx->buf, 16);
        memset(ctx, 0, sizeof(ctx));
    }
    #define F1(x, y, z) (z ^ (x & (y ^ z)))
    #define F2(x, y, z) F1(z, x, y)
    #define F3(x, y, z) (x ^ y ^ z)
    #define F4(x, y, z) (y ^ (x | ~z))
    #define MD5STEP(f, w, x, y, z, data, s) ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
    void MD5Transform(buf, in)
        uint32 buf[4]; uint32 in[16];
    {
        register uint32 a, b, c, d;
        a = buf[0];
        b = buf[1];
        c = buf[2];
        d = buf[3];
        MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
        MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
        MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
        MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
        MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
        MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
        MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
        MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
        MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
        MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
        MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
        MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
        MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
        MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
        MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
        MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
        MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
        MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
        MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
        MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
        MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
        MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
        MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
        MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
        MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
        MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
        MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
        MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
        MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
        MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
        MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
        MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
        MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
        MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
        MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
        MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
        MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
        MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
        MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
        MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
        MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
        MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
        MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
        MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
        MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
        MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
        MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
        MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
        MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
        MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
        MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
        MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
        MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
        MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
        MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
        MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
        MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
        MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
        MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
        MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
        MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
        MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
        MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
        MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
        buf[0] += a;
        buf[1] += b;
        buf[2] += c;
        buf[3] += d;
    }
    void GetMd5FromString(const char* s,char* resStr)
    {
         struct MD5Context md5c;
         unsigned char ss[16];
         char subStr[3];
         int i;
         MD5Init( &md5c );
         MD5Update( &md5c, s, strlen(s) );
         MD5Final( ss, &md5c );
         strcpy(resStr,"");
         for( i=0; i<16; i++ )
         {
             sprintf(subStr, "%02x", ss[i] );
             itoa(ss[i],subStr,16);
             if (strlen(subStr)==1) {
                 strcat(resStr,"0");
             }
             strcat(resStr,subStr);
         }
         strcat(resStr,"\0");
    }
     
    将以上算法粘贴到记事本并保存为md5.h
    在LR里添加头文件md5.h,在globals.h里添加引用#include "md5.h"
    md5在线查询破解 www.cmd5.com
  • LoadRunner函数中文翻译2

    2010-04-06 02:37:59

     

    LoadRunner函数中文翻译系列之二--Check

    web_find

     语法:
     int web_find (const char *StepName, <Attributes and Specifications list>, char *searchstring, LAST );

    参数:
     1StepName:步骤名称,在Tree视图中出现。

    2Attributes and Specifications list

    支持的属性有:

    Frame:在多Frame的情况下,定义要查找Frame的范围。

    Expect:定义在什么情况下函数检查成功:找到了指定的搜索标准或者没有找到。例如说,可以检查指定的错误信息是否出现在web页面中。合法的值有2个:foundnotfound。默认值是“found”

    Matchcase:指定搜索是否区分大小写。

    Repeat:指定当第一次发现要查找的字符串时,搜索是否继续。当一个web页面中包含多个被查找的字符串时,此参数是非常有用的。合法的值有2个:yesno。默认值是“yes”

    Report:指定在什么情况下,VuGen在执行日志中显示此函数的检查结果。合法的值有:successfailurealways。默认值是“always”

    Onfailure:此参数决定在函数检查失败后,Vuser是否中断。参数值是abort。如果指定了Onfailure=abort,当函数检查失败时,不论在运行时设置中的error-handling是什么,脚本都会中断。

    如果没有指定Onfailure=abort,那么运行时设置中error-handling将会起作用。

    支持的特性有:RightOf, LeftOf (不支持7.x及更高版本)。

    RightOf:要查找的字符串右边的内容。

    LeftOf:要查找的字符串左边的内容。

    3Searchstring:需要查找的字符串,格式为“What=stringxyz”。此搜索不区分大小写。

    4LAST:属性列表结束符。

    返回值
     整型。 成功时返回LR_PASS(0),失败时返回LR_FAIL (1)

    说明
     此函数的作用是在HTML页面中查找指定的字符串。

    此函数只能在基于HTML录制的脚本中使用。当指定的HTML请求全部完成以后,开始执行搜索过程,比web_reg_find要慢。

    web_find函数在C语言的脚本中已经被web_reg_find所替代,web_reg_find运行速度比较快,而且在HTML-basedURL-based的录制方式中都可以使用。 C语言脚本中,web_find是向后兼容的。JavaVisual Basic脚本中不再支持它。

    运行在HTTP模式下的WAP用户都和运行在WSP回放模式下的WAP用户都不支持此函数。

    web_global_verification

     语法:
     int web_global_verification (<List of Attributes>, LAST )

    参数:
     List of Attributes

    1Text:此属性是一个非空的,以NULL结尾的字符串,表示要查找的内容。语法是”Text=string”。还可以使用text flags自定义字符串。

    2TextPfx:没有指定Text的情况下使用此属性。要查找的字符串的前缀。语法是” TextPfx =string”。还可以使用text flags自定义字符串。

    3TextSfx:没有指定Text的情况下使用此属性。要查找的字符串的后缀。语法是” TextSfx =string”。还可以使用text flags自定义字符串。

    4Search:可选项,在哪里查找字符串。可选的值是:HeadersBodyNORESOURCEAll。默认值是NORESOURCE。语法是“Search=value”

    5Fail:当字符串找不到时的处理选项:Found (默认值)或NotFoundFound表示当找到对应的字符串时发生了错误(例如“Error”)。NotFound表示当找不到字符串时发生了错误。语法是“Fail=value“

    6ID:在日志文件中标识当前函数。

    LAST:属性列表结束符。

    注:text flags/IC表示忽略大小写;/BIN表示指定的是二进制数据。

    返回值
     整型。 成功时返回LR_PASS(0),失败时返回LR_FAIL (1)

    说明
     web_global_verification属于注册函数,注册一个在web页面中搜索文本字符串的请求,与web_reg_find只在下一个Action函数中执行搜索不同的是,它是在之后所有的Action类函数中执行搜索的。可以搜索页面的bodyheadershtml代码或者是整个页面。

    在检测一些应用程序级别(不通过http状态码来表现)的错误时,web_global_verification是非常有用的。如果要定位通过HTTP状态码表现的错误时,使用web_get_int_property

    查找范围:all:这个HTML页面;Headers:页面的头;body:页面的体,包含所有的资源但不包含头;NORESOURCE(默认选项):仅仅包含页面的体,把包括头和资源。

    如果不知道要查找的精确的文本,或者要查找的多个文本不是完全相同的,可以使用前缀和后缀来表示。这时需要用到TextPfxTextSfx属性。这2个属性必须同时指定,一旦指定了其中一个,就不能指定Text属性了。

    注意:web_global_verificationWAP协议下不能运行。

    web_image_check

     语法:
     int web_image_check(const char *CheckName, <List of Attributes>, <"Alt=alt"|| "Src=src">, LAST );

    参数:
     1CheckName:名称,在Tree视图中出现。

    2List of Attributes

    支持的属性有:Frame(在多Frame的情况下,定义要查找Frame的范围)。

    支持的选项有:expect, matchcase, repeat, report, onfailure

    Tip:选项跟属性的区别,大部分选项都只允许设置预定义的值,其他的值都是无效的。

    3Alt:检查图象的ALT标记。不允许空值。

    4Src:检查图象的SRC标记。不允许空值。

    5LAST:参数列表结束的指示符。

    返回值
     整型。

    说明
     web_image_check检查指定的图象是否在HTML页面中出现。

    Alt或者Src两者必须有一个在参数列表中出现。如果两项都通过,那么检查成功。

    此函数仅仅支持基于HTML的脚本。

     web_reg_add_cookie

     语法:
     int web_reg_add_cookie(const char * cookie, const char * searchstring, LAST );

    参数:
     1Cookie:定义需要增加或修改的Cookie

    Cookie的参数格式为:<name>=VALUE; (required)domain=DOMAIN_NAME;(required)expires=DATEpath=PATH(default path is "/")secure

    此参数中的cookie元素和HTTP响应头中的Set-Cookie是相同的。例如“Session=1234domain=sanditon.com”,在这里,“Session”cookie的名称。

    2Searchstring:要查找的文本字符串。字符串不能为空,以null结尾。格式为“Text=string”

    3LAST:属性列表的结束符。

    返回值
     整型。 成功时返回LR_PASS(0),失败时返回LR_FAIL (1)

    说明
     web_reg_add_cookie是注册类型的函数。它首先注册一个搜索文本字符串的请求。检查动作在后续的Action函数之后进行。如果字符串被找到,就添加到cookie中。

    需要注意,尽管web_reg_add_cookie在功能上跟HTTP Set_Cookie头相似,它们还是有个明显的区别。 根据HTTP标准,domain属性在Set-Cookie头中是可选的。如果没有指定,默认的domain的值是产生cookie的服务器的host name。当使用web_reg_add_cookie函数时,服务器的hostname对于压力测试的机器来说是不可用的,所以domain属性是必选项。

    此函数在HTML-based URL-based的脚本中都可以使用。(参照录制选项的录制标签页)。此函数是在服务器内容到达客户端之前注册搜索请求的,所以当所请求的内容一到就会执行搜索操作,脚本会比较高性。

    web_reg_add_cookie是用户手动添加的,无法录制。

    web_reg_find

     语法:
     int web_reg_find (const char *attribute_list, LAST);

    参数:
     1attribute_list

    通过Name=Value对来传递参数。例如“Text=string”TextTextPfxTextSfx三个必须有一个出现。其他的属性是可选的。

    a) Text:要搜索的字符串,字符串必须非空,以NULL结尾。可以使用text flags自定义搜索字符串。

    b) TextPfx:要搜索的字符串的直接前缀。

    c) TextSfx:要搜索的字符串的直接后缀。

    d) Search:搜索的范围。可选的值是:Headers Body(在请求体中搜索)、Noresource (仅仅在HTML请求体中搜索,不包括头和资源)ALL (在请求体、头和资源中搜索),默认值是“BODY”

    e) SaveCount:匹配的个数。

    f) Fail:设置函数检查在什么状态下失败。

    g) ID:日志文件中标识此函数的一个字符串。

    h) RelFrameId:相关联的FrameId。注意:此参数在GUI级别的脚本中不受支持。

    2LAST:属性列表结束的标记符。

    返回值
     整型。 成功时返回LR_PASS(0),失败时返回LR_FAIL (1)

    说明
     web_reg_find属于注册函数,注册一个在web页面中搜索文本字符串的请求,在接下来的Action(象web_url)类函数中执行搜索。

    通过查找期望的字符是否存在来验证是否返回了期望的页面。例如,通过查找“Welcome”来检查主页是否完全打开了。也可以查找“Error”检查浏览器是否发生错误。还可以使用此函数注册一个请求来统计特定字符串出现的次数。

    如果检查失败,在接下来的Action类的函数中会报告错误。此函数仅仅注册请求,并不执行。函数的返回值只表明注册是否成功,并不表示检查的结果。

    此函数不仅能够查找text,还能查找到围绕着textstrings。不要同时指定text和前缀后缀。

    Fail,处理选项,可以是“Found“NotFound”。默认是“NotFound”

    “Fail=Found” 指示当对应的字符找到时,函数检查失败。例如,查找单词“Error”,如果找到了,说名web请求没有成功,你想把函数检查设置为失败。

    “Fail=NotFound”指示当对应的字符找不到时,函数检查失败。如果查找的是web请求成功时出现的字符串时,需要使用NotFound

    SaveCount参数指示保存到参数中的匹配的字符串的个数。使用这个属性,需要指定“SaveCount=param”。检查操作被执行后,param 的值是null结尾的数字类型的值。

    如果指定了SaveCount,且没有使用Fail参数,检查不会失败,无论需要查找的字符串是否找到。通过检查SaveCount的值确定字符串是否被找到。 <SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family:

  • LoadRunner函数中文翻译1

    2010-04-06 02:08:57

    转载:www.51testing.com

    LoadRunner函数中文翻译系列之一--Action

    web_url
    语法:
            Int Web_url(const char *name, const char * url, <Lists of Attributes>, [EXTRARES,<Lists of Resource Attributes>,LAST)

    返回值
            成功时返回LR_PASS (0),失败时返回 LR_FAIL (1)。

    参数:
            Name:VuGen中树形视图中显示的名称,在自动事务处理中也可以用做事务的名称。

            url:页面url地址。

            List of Attributes

            EXTRARES:分隔符,标记下一个参数是资源属性的列表了。

            List of Resource Attributes

            LAST:属性列表结束的标记符。

    说明
            Web_url根据函数中的URL属性加载对应的URL,不需要上下文。

            只有VuGen处于URL-based或者HTML-based(此时A script. containing explicit URLs only选项被选中时)的录制模式时,web_url才会被录制到。

            可以使用web_url 模拟从FTP服务器上下载文件。web_url 函数会使FTP服务器执行文件被真实下载时的操作。除非手工指定了"FtpAscii=1",下载会以二进制模式完成。

            在录制选项中,Toos—Recording Option下,Recording选项中,有一个Advanced HTML选项,可以设置是否录制非HTML资源,只有选择了“Record within the current script. step”时,List of Resource Attributes才会被录制到。非HTML资源的例子是gif和jpg图象文件。

            通过修改HTTP头可以传递给服务器一些附加的请求信息。使用HTTP头允许请求中包含其他的内容类型(Content_type),象压缩文件一样。还可以只请求特定状态下的web页面。

            所有的Web Vusers ,HTTP模式下的WAP Vusers或者回放模式下的Wireless Session Protocol(WSP),都支持web_url函数。

    web_image
    语法:
            Int web_image (const char *StepName, <List of Attributes>, [EXTRARES, <List of Resource Attributes>,] LAST );

    返回值
            成功时返回LR_PASS (0),失败时返回 LR_FAIL (1)。

    参数:
            StepName:VuGen中树形视图中显示的名称,在自动事务处理中也可以用做事务的名称。

            List of Attributes(服务器端和客户端映射的图片):SRC属性是一定会被录制到的,其他的ALT、Frame、TargetFrame、Ordinal则是有的话会被录制到。

    1、ALT:描述图象的元素。用鼠标指向图象时,所浮出来的文字提示。

    2、SRC:描述图象的元素,可以是图象的文件名. 如: button.gif。也可以使用SRC/SFX来指定图象路径的后缀。所有拥有相同此后缀的字符串都会被匹配到。

    3、Frame:录制操作时所在的Frame的名称。

    4、TargetFrame:见List of Attributes的同名参数。

    5、Ordinal:参见Web_link的同名参数。

            List of Attributes(客户端映射的图片):

    1、AreaAlt:鼠标单击区域的ALT属性。

    2、AreaOrdinal:鼠标单击区域的顺序号。

    3、MapName:图象的映射名。

            List of Attributes(服务器端映射的图片):尽管点击坐标不属于属性,但还是以属性的格式来使用。

    1、Xcoord:点击图象时的X坐标。

    2、Ycoord:点击图象时的Y坐标。

            EXTRARES:分隔符,标记下一个参数是资源属性的列表了。

            List of Resource Attributes:参见List of Resource Attributes一节。

            LAST:属性列表结束的标记符。

    说明
            web_image模拟鼠标在指定图片上的单击动作。此函数必须在有前置操作的上下文中使用。

            在Toos—Recording Option,如果录制级别设为基于HMTL的录制方式时,web_image才会被录制到。

            web_image支持客户端(client-side)和服务器端server-side的图片映射。

            在录制选项中,Toos—Recording Option下,Recording选项中,有一个Advanced HTML选项,可以设置是否录制非HTML资源,只有选择了“Record within the current script. step”时,List of Resource Attributes才会被录制到。非HTML资源的例子是gif和jpg图象文件。

            通过修改HTTP头可以传递给服务器一些请求附加信息。使用HTTP头允许请求中包含内容,如同压缩文件一样。还可以只请求特定状态的web页面。

            web_image支持Web虚拟用户,不支持WAP虚拟用户。

    例子
            下面的例子模拟用户单击Home图标以回到主页(黑体部分):

    web_url("my_home", "URL=http://my_home/", LAST);

    web_link("Employees", "Text=Employees", LAST);

    web_image("Home.gif", "SRC=../gifs/Buttons/Home.gif", LAST);

    web_link("Library", "Text=Library", LAST);

    web_image("Home.gif", "SRC=../../gifs/buttons/Home.gif", LAST);

            下面的例子模拟用户在客户端映射的图片上单击:

    web_image("dpt_house.gif",

           "Src=../gifs/dpt_house.gif",

           "MapName=dpt_house",

           "AreaOrdinal=4",

           LAST);

            下面的例子模拟用户在服务端映射的图片上单击:

    web_image("The Web Developer's Virtual Library",

           "Alt=The Web Developer's Virtual Library",

           "Ordinal=1",

           "XCoord=91",

           "YCoord=17",

           LAST);

            下面是一个使用文件名后缀的例子:它指定了dpt_house.gif作为后缀,所以象../gifs/dpt_house.gif、/gifs/dpt_house.gif、gifs/dpt_house.gif、/dpt_house.gif等都会匹配到。

    web_image("dpt_house.gif",
            "Src/sfx=dpt_house.gif", LAST);

    web_link
    语法:
            Int web_link (const char *StepName, <List of Attributes>, [EXTRARES, <List of Resource Attributes>,] LAST );

    返回值
            成功时返回LR_PASS (0),失败时返回 LR_FAIL (1)。

    参数:
            StepName:VuGen中树形视图中显示的名称,在自动事务设置中也被用做事务名称。

            List of Attributes:支持下列的属性:

    1.      Text:超链接中的文字,必须精确匹配。

    2.      Frame:录制操作时所在的Frame的名称。

    3.      TargetFrame、ResourceByteLimit:见List of Attributes一节。

    4.      Ordinal:如果用给出的属性(Attributes)筛选出的元素不唯一,那么VuGen使用此属性来指定其中的一个。例如:“SRC=abc.gif”,“Ordinal=3”标记的是SRC的值是“abc.gif”的第3张图片。

            EXTRARES:表明下面的参数将会是list of resource attributes了。

            LAST:结尾标示符。

    说明
            模拟鼠标在由若干个属性集合描述的链接上进行单击。此函数必须在前置动作的上下文中才可以执行。

            web_link 仅仅在基于HTML的录制方式中才会被VuGen捕捉到。

            非HTML生成的资源的例子有.gif 和.jpg图像。对于List of Resource Attributes参数来说,仅仅当Recording Options--Recording --HTML-based script-- Record within the current script. step选项被选中时,它们才会被插入到代码中。

            可以通过改变HTTP头信息给服务器传递一些附加信息。使用HTTP头信息可以,允许响应体中包含其他的内容类型(Content-Type),例如压缩文件,或者只有满足了特定的状态才去请求web页。

            此函数值支持Web虚拟用户,不支持WAP虚拟用户。

    web_submmit_form
    语法:
    Int web_submit_form. (const char *StepName, <List of Attributes>, <List of Hidden Fields>, ITEMDATA, <List of Data Fields>, [ EXTRARES, <List of Resource Attributes>,] LAST );

    返回值
            成功时返回LR_PASS (0),失败时返回 LR_FAIL (1)。

    参数:
            StepName:Form的名字。VuGen中树形视图中显示的名称,在自动事务处理中也可以用做事务的名称。

            List of Attributes:支持以下属性:

    1.      Action:Form中的ACTION属性,指定了完成Form中的操作用到的URL。也可以使用“Action/sfx” 表示使用此后缀的所有Action。

    2.      Frame:录制操作时所在的Frame的名称。

    3.      TargetFrame、ResourceByteLimit:见List of Attributes的同名参数。

    4.      Ordinal:参见Web_link的同名参数。

            VuGen通过记录数据域唯一的标识每个Form。如果这样不足以识别Form,VuGen会记录Action 属性。如果还不足以识别,则会记录Ordinal 属性,这种情况下不会记录Action属性。

            List of Hidden Fields:补充属性(Serves)。 通过此属性可以使用一串隐含域来标识Form。使用下面的格式:

    STARTHIDDENS,

    "name=n1", "value=v1", ENDITEM,

    "name=n2", "value=v2", ENDITEM,

    ENDHIDDENS,

    List of Data Fields

            Data项用来标识form。Form是通过属性和数据来共同识别的。

            使用下面的格式来表示数据域列表

    "name=n1", "value=v1", ENDITEM,

    "name=n2", "value=v2", ENDITEM,

            ITEMDATA:Form中数据和属性的分隔符。

            EXTRARES:一个分隔符,标记下一个参数是资源属性的列表了。

    List of Resource Attributes:参见List of Resource Attributes一节。

    LAST:属性列表结束的标记符。

    说明
            web_submit_form. 函数用来提交表单。此函数可能必须在前一个操作的上下文中执行。在Toos—Recording Option,只有录制级别设为基于HMTL的录制方式,web_image才会被录制到。

            在录制选项中,Toos—Recording Option下,Recording选项中,有一个Advanced HTML选项,可以设置是否录制非HTML资源,只有选择了“Record within the current script. step”时,List of Resource Attributes才会被录制到。非HTML资源的例子是gif和jpg图象文件。

            通常情况下,如果录制了web_submit_form. 函数,VuGen会把“name”和“value”一起录制到ITEMDATA属性中。如果不想在脚本中以明文显示“value”,可以对它进行加密。把“Value”改为“EncryptedValue”,然后把录制到的值改为加密后的值。

            例如:可以把 "Name=grpType", "Value=radRoundtrip", ENDITEM

            改为:"Name=grpType", EncryptedValue=409e41ebf102f3036b0549c799be3609", ENDITEM

            如果你完整的安装了LoadRunner,那么打开开始菜单--Mercury LoadRunner—Tools--Password Encoder,这个小工具是用来加密字符串的。把需要加密的值粘贴到Password一栏,再点Generate按钮。加密后的字符串会出现在Encoded string框中。接着点Copy按钮,然后把它粘贴到脚本中,覆盖原来显示的“Value”。

            加密的另一种方法时使用lr_decrypt函数。方法:选择整个字符串,例如“Value=radRoundtrip”(注意不要选择引号),右击鼠标,选择Encrypt string选现,脚本会变为:

    "Name=grpType", lr_decrypt("40d176c46f3cf2f5fbfaa806bd1bcee65f0371858163"), ENDITEM,

    web_submit_form支持Web虚拟用户,不支持WAP虚拟用户。

    例子:
            下面的例子中,web_submit_form. 函数的名字是“employee.exe”。此函数提交了一个请求,此请求包含雇员信息John Green。此函数没有使用属性(Attributes)是因为通过数据项已经能唯一的标识这个Form了。

    web_submit_form("employee.exe",

           ITEMDATA,

           "name=persons", "value=John Green - John", ENDITEM,

           "name=go_page", "value=Go to Page", ENDITEM,

           LAST);

    web_submmit_data
    语法:
    Int web_submit_data ( const char *StepName, <List of Attributes>, ITEMDATA, <List of data>, [ EXTRARES, <List of Resource Attributes>,] LAST ); 

    返回值
            返回LR_PASS(0)代表成功,LR_FAIL(1)代表失败。

    参数:
            StepName:步骤名称,VuGen中树形视图显示的名称。

    List of Attributes:支持以下属性:

    1.      Action:Form中的ACTION属性,指定了完成Form中的操作用到的URL。

    2.      Method:表单提交方法:POST或GET(默认是POST)。

    3.      EncType:编码方式。

    4.      EncodeAtSign:是否使用ASCII值对符号“@”编码。Yes或者 No。

    5.      TargetFrame:包含当前链接或资源的Frame。参见List of Attributes的同名参数。

    6.      Referer、Mode:参见List of Attributes的同名参数。

            ITEMDATA:数据域和属性的分隔符。

    List of Data:

            数据域列表定义了表单提交的内容。由于此请求是上下文无关的,因此数据域包含了所有的隐含域。使用Form的编码规则组织数据域。

            数据域列表可以使用下面任意一种格式:

             "name=n1", "value=v1", ENDITEM,

    "name=n2", "EncryptedValue=qwerty", ENDITEM,

            EXTRARES:分隔符,标记下一个参数将是资源属性的列表。

    List of Resource Attributes:参见List of Resource Attributes。

    LAST:结束标记符。

    说明
            web_submit_data函数处理无状态或者上下文无关的表单提交。它用来生成表单的GET或POST请求,这些请求与Form自动生成的请求是一样的。发送这些请求时不需要表单上下文。

            当VuGen设为基于URL的录制模式,或者基于HTML的录制方式但是Recording Options—HTML Advanced 下的A script. containing explicit URLs only 选项被选中时,web_submmit_data函数才会录制到。

            不论你采用URL查询的方式(GET),还是采用请求体发送(POST)的方式,此函数都指示出Form中的数据是如何发送到服务器的。

            如果VuGen处于HTTP录制模式下,此时记录Web进程时,会产生此函数。在提交Form时,如果无法生成web_submit_form函数,VuGen也会生成web_submit_data函数。

            在录制选项中,Toos—Recording Option下—Recording选项中,有一个Advanced HTML选项,可以设置是否录制非HTML资源。只有选择了“Record within the current script. step”时,List of Resource Attributes才会被录制到。非HTML资源的例子是gif和jpg图象文件。

            EncType属性给出一个内容类型,指定其做为“Content-Type”请求头的值。它指示了根据参数生成HTTP请求时使用的编码类型(不是URL-encoding就是multi-part)可以是下面的格式:

    1.      “EncType=application/x-www-form-urlencoded”

    2.      “EncType=multipart/form-data” (任何的“; boundary=”都会被默认忽略掉)

    3.      “EncType=” (空串,表明没有产生内容类型(“Content-Type”)请求头)

            任何对于“EncType”的指定都会覆盖web_add_[auto_]header函数指定的Content-Type。当省略了“EncType”时,任何一个web_add_[auto_]header函数都会起作用。如果既没有指定EncType也没有web_add_[auto_]header函数,且“Method=POST”,“application/x-www-form-urlencoded”会做为默认值来使用。其他情况下,不会产生Content-Type请求头。

            ContentType:文件类型标识符,如果“EncType”是“multipart/form-data”用来上传文件时,需要用到“ContentType”。当在ITEMDATA中的Data子句中指定了“File=Yes”,且文件也在此子句中,ContentType才适用,此时它会作为同一个子句的值来传递。

            正常情况下,“Content-Type”根据所上传文件的扩展名自动生成。例如:

    -----------------------------7d025e2b16b064e\r\n Content-Disposition: form-data; name="uploaded_file"; filename="D:\\temp\\a.txt"\r\n Content-Type: text/plain\r\n \r\n

            无论如何,对于非浏览器的程序来说是特殊的,根据文件类型生成的“ContentType”不一定是正确的。这时,通过手工指定来覆盖默认的“ContentType”。如果指定了空值,那么“Content-Type”头将不包含在文件中。

            如果没有显示的指定“ContentType”的值,当上传的文件为空时,不管文件扩展名是什么,都默认使用“application/x-unknown-content-type”做为”ContentType”的值。

            VuGen不会检查指定的ContentType是否有效。

            通常情况下,如果录制了web_submit_data 函数,VuGen会把“name”和“value”一起录制到ITEMDATA一节中。如果不想在脚本中以明文显示“value”,可以对它进行加密。把“Value”改为“EncryptedValue”,然后把录制到的值改为加密后的值。请参考web_submit_form中相关的内容。

            所有的Web虚拟用户,运行在HTTP模式下的WAP用户,运行在WSP回放模式下的WAP用户都可以使用本函数。

    例子
            下面的例子中,web_submit_data函数使用POST方法提交了一个表单。

    web_submit_data("default.aspx",

           "Action=http://lazarus/flightnet/default.aspx",

           "Method=POST",

           "TargetFrame=",

           "RecContentType=text/html",

           "Referer=http://lazarus/flightnet/",

           "Snapshot=t7.inf",

           "Mode=HTML",

           ITEMDATA,

           "Name=grpType", "Value=radRoundtrip", ENDITEM,

           "Name=lstDepartingCity", "Value=DEN", ENDITEM,

           "Name=lstDestinationCity", "Value=LAX", ENDITEM,

           "Name=txtDepartureDate", "Value=8/19/2003", ENDITEM,

           "Name=txtReturnDate", "Value=8/19/2003", ENDITEM,

           "Name=txtQuantity", "Value=1", ENDITEM,

           "Name=radClass", "Value=1", ENDITEM,

           "Name=radSeat", "Value=1", ENDITEM,

           "Name=btnAvailableFlights", "Value=Next >", ENDITEM,

           LAST);

            下面的例子, web_submit_data函数使用POST方法提交了2个文件。

    web_submit_data("Attachments",

           "Action=http://barton.cottage@.Devonshire.uk/Attachments?YY=45434",

           "Method=POST",

           "EncType=multipart/form-data",

           "TargetFrame=",

           "RecContentType=text/html",

           "Referer=http:///barton.cottage@.Devonshire.uk/Compose?YY=20435",

           "Snapshot=t5.inf",

           "Mode=HTML",

           ITEMDATA, "Name=userFile0",

                  "Value=E:\\sense_sensibility\\Elinor.txt",

                  "File=yes",

                  "ContentType=text/html", // 覆盖了文本文件默认的“text/plain” 值。

           ENDITEM,

                  "Name=userFile1",

                  "Value=E:\\sense_sensibility\\Marianne.jpg",

                  "File=yes",

           ENDITEM,

           LAST);

    web_custom_request
    语法:
    Int web_custom_request (const char *RequestName, <List of Attributes>,

      [EXTRARES, <List of Resource Attributes>,] LAST );

    返回值
            返回LR_PASS(0)代表成功,LR_FAIL(1)代表失败。

    参数:
            RequestName:步骤的名称,VuGen中树形视图中显示的名称。

            List of Attribute:支持的属性有以下几种:

    1.      URL:页面地址。

    2.      Method :页面的提交方式,POST或GET。

    3.      TargetFrame:包含当前链接或资源的frame的名称。参见List of Attributes的同名参数。

    4.      EncType:编码类型。

    5.      RecContentType:响应头的内容类型。参见List of Attributes的同名参数。

    6.      Referer:参见List of Attributes的同名参数。

    7.      Body:请求体。参见List of Attributes的同名参数。

    8.      RAW BODY:参见List of Attributes的同名参数。

    9.      BodyFilePath:作为请求体传送的文件的路径。它不能与下面的属性一起使用:Body,或者其他Body属性或Raw Body属性包括BodyBinary,BodyUnicode, RAW_BODY_START或Binary=1。

    10.  Resource、ResourceByteLimit、Snapshot、Mode:参见List of Attributes的同名参数。

    11.  ExtraResBaseDir:参见List of Attributes的同名参数。

    12.  UserAgent:用户代理,它是一个HTTP头的名字,用来标识应用程序,通常是浏览器,它呈现的是用户和服务器的交互。

            例如:头信息“User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)”识别的是Window NT下的IE浏览器6.0。其他的User-Agent的值用来描述其他的浏览器,或者非浏览器程序。通常,一个应用程序中所有的请求都使用相同的用户代理,录制者作为一个运行时参数来指定(Run-Time Setting—Browser Emulation—User Agent)。不管怎么说,即使是在一个简单的浏览器进程中,仍有可能会用到直接与服务器交互的非浏览器组件(例如ActiveX控件),通常他们有着不同于浏览器的用户代理属性。指定“UserAgent”表示这是一个非浏览器的请求。指定的字符串被HTTP头“User-Agent:” 使用,在某些情况下,它同时会影响回放脚本时的行为。例如,不使用浏览器缓存,假设指定的URL属于资源等等。

            LoadRunner本身不检查指定的字符串与浏览器本身的值是否相同。

    13.  Binary:“Binary=1”表示页面请求体中的每一个以\\x##形式出现的值(在这里“##”代表2个十六进制数字),都会被替换为单字节的十六进制的值。

            如果“Binary=0”(默认值),所有的字符序列只是按照字面的值传递。

            需要注意双斜杠的用法。在C编译器中双斜杠被解释为单斜杠。如果不需要零字节,单斜杠可以在Binary不等于1的情况下使用(例如,使用\x20代替\\x20)。如果需要零字节,那么只能使用\\x00且设置 “Binary=1”,\x00在逻辑上会被截断。

    14.  ContentEncoding

            指定请求体的使用指定的方式(gzip或者deflate)进行编码(例如,压缩),相应的“Content-Encoding:” HTTP头会和此请求一起发送。这个参数适用于web_custom_request和web_submit_data。

            EXTRARES:表明下面的参数将会是List Of Resource Attributes了。 

            LAST :结尾的标示符。

    说明
            允许使用任何方法和请求体创建自定义的HTTP请求。默认情况下,当VuGen无法使用其他函数解释用户请求时,会生成此函数。

            使用Add对话框(在脚本环境下,右击鼠标,会出现快捷菜单),可以手工插入此函数。要指定特殊的HTTP头信息,需要增加web_add_header或者web_add_auto_header函数。

    RecContentType:参见List of Attributes的同名参数。

            EncType:编码类型。此参数给出一个内容类型(Content-Type),指定其做为回放脚本时“Content-Type”请求头的值,例如 “text/html”。Web_custom_request函数不处理未编码的请求体。请求体参数将会使用已经指定的编码方式。因此,如果指定了不匹配HTTP请求体的“EncType”,会引发服务端的错误。通常我们建议不要手动修改录制时的“EncType”值。

            任何对于“EncType”的指定都会覆盖web_add_[auto_]header函数指定的Content-Type。当指定了“EncType=” (空值)时,不会产生“Content-Type” 请求头。当省略了“EncType”时,任何一个web_add_[auto_]header函数都会起作用。如果既没有指定EncType也没有web_add_[auto_]header函数,且“Method=POST”,且“Method=POST”,“application/x-www-form-urlencoded”会做为默认值来使用。其他情况下,不会产生Content-Type请求头。

            仅仅当Recording Options--Recording --HTML-based script-- Record within the current script. step选项被选中时,List of Resource Attributes才会被插入到代码中。

            所有的Web Vusers ,运行在HTTP模式或者Wireless Session Protocol (WSP) 回放模式下的WAP Vusers都支持web_custom_request函数。

    Using Binary Code

            可以使用下面的格式在web_custom_request 函数的“Body”属性中加入二进制字符串。

    \x[char1][char2]

            通过2个字符[char1][char2]来表示十六进制的值。

            例如:\x24表示16*2+4=36,它代表“$”符号,\x2B代表的是“+”符号。

            如果不足2个字符,也不是有效的十六进制字符,VuGen则会当作ASCII文本处理。所以要注意,对于不足2个字符的十六进制,要在前面补0。例如 “\x2”是无效的十六进制串,需要边为“\x02”。

            注意二进制的值是以“\\x” 的形式出现在脚本中的,也就是说在“x” 前面有2个反斜杠。这是由C语言的转义语法决定的。但是,当使用VuGen生成web_custom_request 函数时,只需要输入一个反斜杠。

            如果在web_custom_request 中使用参数化,定义参数时只需要包含一个反斜杠这是由于参数替换时是不考虑C的语法转换的。

    List of Attributes
    FtpAscii:“1”使用ASCII模式处理FTP操作;"0" 使用二进制模式。

            TargetFrame: 当前链接或资源所在Frame的名称。除了Frame的名字,还可以指定下面的参数:

    _BLANK:打开一个空窗口。

    _PARENT:把最新更改过的的Frame替换为它的上级。

    _SELF:替换最新更改过的的Frame。

    _TOP:替换整个页面。

            RecContentType:录制脚本时响应头的内容类型。例如text/html、 application/x-javascript等。当没有设置Resource属性时,用它来确定目标URL是否是可记录的资源。此属性包含主要的和次要的资源。最频繁使用的类型是 text、application、image。次要的类型根据资源不同变化很多。例如:"RecContentType=text/html":表示html文本。"RecContentType=application/msword":表示当前使用的是Msword。

            Referer: 当前页面关联的页面。如果已经显式指定了url的地址,此项可以省略。

            Resource:指示URL是否属于资源。1 是;0 不是。设置了这个参数后,RecContentType参数被忽略。“Resource=1”,意味着当前操作与所在脚本的成功与否关系不大。在下载资源时如果发生错误,是当作警告而不是错误来处理的;URL是否被下载受“Run-Time Setting—Browser Emulation--Download non-HTML resources” 这个选项的影响。此操作的响应信息是不做为HTML来解析的。“Resource=0”,表明此URL是重要的,不受发送请求(RTS)的影响,在需要时也会解析它。

            ResourceByteLimit:web页面下载资源的极限大小。当达到设置的极限后,无法下载其他资源。仅仅对需要下载的资源有效。

            下载过程:如果总计下载大小小于极限值,则正常开始下载。如果当下载时达到了设置的极限值,资源大小可知(在HTTP响应头中指定了Content-Length),这中情况下,如果只需要一个缓冲区,那么下载可以正常完成。如果需要的不止一个缓冲区,或者资源大小不可知,下载就会中断同时关闭当前连接。

            这个特性可以用来模拟用户不等待一个页面下载完成时导航到另一个页面的情况。

            ResourceByteLimit 在HTTP模式中无法使用,在Concurrent Groups(Vuser脚本中的一个区,此区中的所有函数并发执行)区中也无法使用。仅仅适用于Sockets的回放,WinInet也是不适用的。

    Snapshot:快照的文件名,关联时使用。

            Mode:两种录制级别HTML、HTTP。

            HTML级别:在当前Web界面上录制直观的HTML动作。以一步步的web_url、web_link、web_image、web_submit_form来录制这些动作。VuGen仅仅录制返回HTML页面的请求,不处理脚本和应用程序。

            HTTP级别:VuGen把所有的请求录制为web_url指令,不生成web_link、web_image、web_submit_form这些函数。这种方法更为灵活,但是生成的脚本不够直观。

            ExtraResBaseDir(目前仅适用与web_custom_request函数):根URL,放在EXTRARES组里。它是用来解析相对URL的(译者加:类似于Windows的相对路径和绝对路径)。

            URL可以是绝对路径(例如http://weather.abc.com/weather/forecast.jsp?locCode=LFPO),也可以是相对路径(例如“forecast.jsp?locCode=LFPO”)。

            真正的URL的下载是通过绝对路径进行的,所以相对URL路径必须使用根路径URL去解析。例如,使用http://weather.abc.com/weather/做为根路径来解析“forecast.jsp?locCode=LFPO”,最后的URL是:http://weather.abc.com/weather/forecast.jsp?locCode=LFPO。如果没有指定“ExtraResBaseDir”,默认的根URL是主页面的URL。

            Body(目前仅适用与web_custom_request函数):请求体。不同的应用中,请求体分别通过Body、BodyBinary或者BodyUnicode参数来传递。请求体可以只使用其中一个参数,也可以使用一连串的分开的参数组成多请求体。例如:

    web_custom_request(

    ……

    "BodyUnicode=REPRICE"

    "BodyBinary=\\x08\\x00\\xCC\\x02\\x00\\x00"

    "Body=.\r\n"

    "-dxjjtbw/(.tp?eg:ch/6--\r\n",

    LAST);

            在上面的代码中,使用了3个参数来划分请求体,一个是Unicode段,一个是二进制段,最后一个是常规的字符串。最终的请求体是这3个参数按照在函数中的顺序连接起来的值。

            还有一个很少用到的参数,Binary。它也能描述二进制请求体,但只允许函数中只有一个请求体参数。

            所有的请求体都是ASCII字符,以null结束。

            Body:表示规则的,可打印的字符串。无法表示空字节。所有的字符都以一个反斜杠表示。注意:在旧的脚本中,可以看见不可打印的字符在请求体中以16进制方式进行编码。(例如 “\\x5c”),在这种情况下,必须使用“Binary=1”来标识。空字节使用"\\00"来表示。 相反,新脚本则会把把请求体分开放在不同的参数中("Body=...", "BodyBinary=...", Body=...")。

            BodyBinary :表示二进制代码。不可打印的字符在请求体中以16进制方式\\xHH进行编码。在这里HH 表示十六进制值。空字节使用"\\00"来表示。

            BodyUnicode:美国英语, 特指拉丁 UTF-16LE(little-endian)编码。这种编码方式会在在每个字符末尾附加一个0字节,以便使字符更可读。但是在VuGen中实际的参数把所有的0字节都去掉的。但是在发送给Web 服务器之前, web_custom_request函数会重新添加0字节的。对于不可打印的字符,使用单反斜杠表示,无法表示空字节。

            注意:如果请求体大于100K,会使用一个变量来代替Body参数。变量是在 lrw_custom_body.h中定义的。

            Raw Body(目前仅适用与web_custom_request函数):请求体是作为指针传递的,此指针指向一串数据。 二进制的请求体可以使用BodyBinary 属性来发送(或者使用Body 属性来传递,前提是必须设置"Binary=1" )。无论如何,这种方法需要使用转义字符反斜杠把不可打印的字符转换为ASCII字符。为了能有一种更简便的表现原始数据的方式,Raw Body属性应运而生,可以传递指向二进制数据的指针。

            使用4个连续的参数集来表示指针,而且必须按照顺序排列:

        RAW_BODY_START

            指向数据缓冲区的指针

    (int) 长度

    RAW_BODY_END

    例子:

    char *abc= .../* a pointer to the raw data */

    web_custom_request("StepName",

                   "URL=http://some.url ",

     "Method=POST",

         RAW_BODY_START,

         "abc",

                        3,

      RAW_BODY_END,

         LAST);

            在应用中,即使设置了数据的长度为0,指针也必须有值,不能为空。

            在“Binary=1”时,不能使用上面的语法传递原始数据。

            数据缓冲区中的数据不能使用参数化。也就时说,缓冲区中的任何参数(例如 "{MyParam}")不能被正确的替代为相应的值,只会以字面值发送。

    List of  Resource  Attributes
            Web页面中的非HTML机制产生了资源列表,包含了Javascript, ActiveX, Java applets and Flash所请求的资源。VuGen's 的Recording 选项中,可以设置把这些资源录制在当前的操作中(默认是此设置)还是作为单独的步骤来录制。

            支持以下资源:

    URL

    要加载的web资源的url

    Referer

    关联的url

    ENDITEM

    每个资源的结束标记

     

            相对于把每个资源都录制为单独的步骤来说,不录制非HTML元素使脚本更加简短和可读,特别是在VuGen的Tree视图下更为突出。

            当VuGen录制过程中发现附加的资源(比如JS)时,会以列表的形式加到附加资源项中。回放脚本时,这些资源文件也是请求的一部分。可以对一些按规则变化的资源使用关联。

  • 谷歌Google系统架构

    2010-03-09 16:40:04

    转载 http://www.ctoof.com/archives/1610

    Google系统架构在伸缩性上可以说称王了,Google一直的目标就是构建高性能高伸缩性的基础组织来支持它们的产品。

    平台
    Linux
    使用大量开发语言:Python,Java,C++

    状态
    在2006年大约有450,000台廉价服务器;
    在2005年Google索引了80亿Web页面,现在没有人知道数目;
    目前在Google有超过200个GFS集群。一个集群可以有1000或者甚至5000台机器。成千上万的机器从运行着5000000000000000字节存储的GFS集群获取数据,集群总的读写吞吐量可以达到每秒40兆字节;
    目前在Google有6000个MapReduce程序,而且每个月都写成百个新程序;
    BigTable伸缩存储几十亿的URL,几百千千兆的卫星图片和几亿用户的参数选择;

    堆栈
    Google形象化它们的基础组织为三层架构:
    1、产品:搜索,广告,email,地图,视频,聊天,博客;
    2、分布式系统基础组织:GFS,MapReduce和BigTable;
    3、计算平台:一群不同的数据中心里的机器;
    4、确保公司里的人们部署起来开销很小;
    5、花费更多的钱在避免丢失日志数据的硬件上,其他类型的数据则花费较少;

    可信赖的存储机制-谷歌文件系统GFS(Google File System)
    1、可信赖的伸缩性存储是任何程序的核心需求,谷歌文件系统GFS就是Google的核心存储平台;
    2、Google File System – 大型分布式结构化日志文件系统,Google在里面扔了大量的数据;
    3、为什么构建GFS而不是利用已有的东西?因为可以自己控制一切并且这个平台与别的不一样,Google需要:
    -跨数据中心的高可靠性;
    -成千上万的网络节点的伸缩性;
    -大读写带宽的需求;
    -支持大块的数据,可能为上千兆字节;
    -高效的跨节点操作分发来减少瓶颈;
    4、系统有Master和Chunk服务器
    -Master服务器在不同的数据文件里保持元数据。数据以64MB为单位存储在文件系统中。客户端与Master服务器交流来在文件上做元数据操作并且找到包含用户需要数据的那些Chunk服务器;
    -Chunk服务器在硬盘上存储实际数据。每个Chunk服务器跨越3个不同的Chunk服务器备份以创建冗余来避免服务器崩溃。一旦被Master服务器指明,客户端程序就会直接从Chunk服务器读取文件;
    5、一个上线的新程序可以使用已有的GFS集群或者可以制作自己的GFS集群;
    6、关键点在于有足够的基础组织来让人们对自己的程序有所选择,GFS可以调整来适应个别程序的需求;

    使用MapReduce来处理数据
    1、现在你已经有了一个很好的存储系统,你该怎样处理如此多的数据呢?比如你有许多TB的数据存储在1000台机器上。数据库不能伸缩或者伸缩到这种级别花费极大,这就是MapReduce出现的原因;
    2、MapReduce是一个处理和生成大量数据集的编程模型和相关实现。用户指定一个map方法来处理一个键/值对来生成一个中间的键/值对,还有一个reduce方法来合并所有关联到同样的中间键的中间值。许多真实世界的任务都可以使用这种模型来表现。以这种风格来写的程序会自动并行的在一个大量机器的集群里运行。运行时系统照顾输入数据划分、程序在机器集之间执行的调度、机器失败处理和必需的内部机器交流等细节。这允许程序员没有多少并行和分布式系统的经验就可以很容易使用一个大型分布式系统资源;
    3、为什么使用MapReduce?
    -跨越大量机器分割任务的好方式;
    -处理机器失败;
    -可以与不同类型的程序工作,例如搜索和广告。几乎任何程序都有map和reduce类型的操作。你可以预先计算有用的数据、查询字数统计、对TB的数据排序等等;
    4、MapReduce系统有三种不同类型的服务器
    -Master服务器分配用户任务到Map和Reduce服务器。它也跟踪任务的状态;
    -Map服务器接收用户输入并在其基础上处理map操作。结果写入中间文件;
    -Reduce服务器接收Map服务器产生的中间文件并在其基础上处理reduce操作;
    5、例如,你想在所有Web页面里的字数。你将存储在GFS里的所有页面抛入MapReduce。这将在成千上万台机器上同时进行并且所有的调整、工作调度、失败处理和数据传输将自动完成;
    -步骤类似于:GFS -> Map -> Shuffle -> Reduction -> Store Results back into GFS;
    -在MapReduce里一个map操作将一些数据映射到另一个中,产生一个键值对,在我们的例子里就是字和字数;
    -Shuffling操作聚集键类型;
    -Reduction操作计算所有键值对的综合并产生最终的结果;
    6、Google索引操作管道有大约20个不同的map和reduction;
    7、程序可以非常小,如20到50行代码;
    8、一个问题是掉队者。掉队者是一个比其他程序慢的计算,它阻塞了其他程序。掉队者可能因为缓慢的IO或者临时的CPU不能使用而发生。解决方案是运行多个同样的计算并且当一个完成后杀死所有其他的;
    9、数据在Map和Reduce服务器之间传输时被压缩了。这可以节省带宽和I/O;

    在BigTable里存储结构化数据
    1、BigTable是一个大伸缩性、错误容忍、自管理的系统,它包含千千兆的内存和1000000000000000的存储。它可以每秒钟处理百万的读写;
    2、BigTable是一个构建于GFS之上的分布式哈希机制。它不是关系型数据库。它不支持join或者SQL类型查询;
    3、它提供查询机制来通过键访问结构化数据。GFS存储存储不透明的数据而许多程序需求有结构化数据;
    4、商业数据库不能达到这种级别的伸缩性并且不能在成千上万台机器上工作;
    5、通过控制它们自己的低级存储系统Google得到更多的控制权来改进它们的系统。例如,如果它们想让跨数据中心的操作更简单这个特性,它们可以内建它;
    6、系统运行时机器可以自由的增删而整个系统保持工作;
    7、每个数据条目存储在一个格子里,它可以通过一个行key和列key或者时间戳来访问;
    8、每一行存储在一个或多个tablet中。一个tablet是一个64KB块的数据序列并且格式为SSTable;
    9、BigTable有三种类型的服务器:
    -Master服务器分配tablet服务器,它跟踪tablet在哪里并且如果需要则重新分配任务;
    -Tablet服务器为tablet处理读写请求。当tablet超过大小限制(通常是100MB-200MB)时它们拆开tablet。当一个Tablet服务器失败时,则100个Tablet服务器各自挑选一个新的tablet然后系统恢复;
    -Lock服务器形成一个分布式锁服务。像打开一个tablet来写、Master调整和访问控制检查等都需要互斥;
    10、一个locality组可以用来在物理上将相关的数据存储在一起来得到更好的locality选择;
    11、tablet尽可能的缓存在RAM里;

    硬件
    1、当你有很多机器时你怎样组织它们来使得使用和花费有效?
    2、使用非常廉价的硬件;
    3、如果使用故障多发的基础设施,提高计算能力将大大提高成本,因此建立可靠的基础设施架构一个重要的战略问题。
    4、Linux,in-house rack design,PC主板,低端存储;
    5、电费是一个难以提高的问题,大电量和冷却也是很大问题;
    6、使用一些collocation和Google自己的数据中心;

    其他
    1,迅速更改而不是等待QA;
    2,库是构建程序的卓越方式;
    3,一些程序作为服务提供;
    4,一个基础组织处理程序的版本,这样它们可以发布而不用害怕会破坏什么东西;

    Google将来的方向
    1、支持地理位置分布的集群;
    2、为所有数据创建一个单独的全局名字空间。当前的数据由集群分离;
    3、更多和更好的自动化数据迁移和计算;
    4、解决当使用网络划分来做广阔区域的备份时的一致性问题(例如保持服务即使一个集群离线维护或由于一些损耗问题);

    学到的东西
    1、基础组织是有竞争性的优势。特别是对Google而言。Google可以很快很廉价的推出新服务,并且伸缩性其他人很难达到。许多公司采取完全不同的方式。许多公司认为基础组织开销太大。Google认为自己是一个系统工程公司,这是一个新的看待软件构建的方式;
    2、跨越多个数据中心仍然是一个未解决的问题。大部分网站都是一个或者最多两个数据中心。我们不得不承认怎样在一些数据中心之间完整的分布网站是很需要技巧的;
    3、如果你自己没有时间从零开始重新构建所有这些基础组织你可以看看Hadoop。Hadoop是这里很多同样的主意的一个开源实现;
    4、平台的一个优点是初级开发人员可以在平台的基础上快速并且放心的创建健全的程序。如果每个项目都需要发明同样的分布式基础组织的轮子,那么你将陷入困境因为知道怎样完成这项工作的人相对较少;
    5、协同工作不一直是掷骰子。通过让系统中的所有部分一起工作则一个部分的改进将帮助所有的部分。改进文件系统则每个人从中受益而且是透明的。如果每个项目使用不同的文件系统则在整个堆栈中享受不到持续增加的改进;
    6、构建自管理系统让你没必要让系统关机。这允许你更容易在服务器之间平衡资源、动态添加更大的容量、让机器离线和优雅的处理升级;
    7、创建可进化的基础组织,并行的执行消耗时间的操作并采取较好的方案;
    8、不要忽略学院。学院有许多没有转变为产品的好主意。Most of what Google has done has prior art, just not prior large scale deployment.
    9、考虑压缩。当你有许多CPU而IO有限时压缩是一个好的选择;

  • 使用聚集索引和非聚集索引的区别

    2009-12-02 15:07:45

    使用聚集索引

        聚集索引确定表中数据的物理顺序。聚集索引类似于电话簿。由于聚集索引规定数据在表中的物理存储顺序,因此一个表只能包含一个聚集索引。但该索引可以包含多个列(组合索引),就像电话簿按姓氏和名字进行组织一样。

    聚集索引对于那些经常要搜索范围值的列特别有效。使用聚集索引找到包含第一个值的行后,便可以确保包含后续索引值的行在物理相邻。避免每次查询该列时都进行排序,从而节省成本。

    注意事项
    定义聚集索引键时使用的列越少越好。
    • 包含大量非重复值的列。
    • 使用下列运算符返回一个范围值的查询:BETWEEN、>、>=、< 和 <=。
    • 被连续访问的列。
    • 返回大型结果集的查询。
    • 经常被使用联接或 GROUP BY 子句的查询访问的列;一般来说,这些是外键列。对 ORDER BY 或 GROUP BY 子句中指定的列进行索引,可以使 SQL Server 不必对数据进行排序,因为这些行已经排序。这样可以提高查询性能。
    • OLTP 类型的应用程序,这些程序要求进行非常快速的单行查找(一般通过主键)。应在主键上创建聚集索引。


    聚集索引不适用于:

    • 频繁更改的列 。这将导致整行移动(因为 SQL Server 必须按物理顺序保留行中的数据值)。这一点要特别注意,因为在大数据量事务处理系统中数据是易失的。

    • 宽键 。来自聚集索引的键值由所有非聚集索引作为查找键使用,因此存储在每个非聚集索引的叶条目内。

    使用非聚集索引

    非聚集索引与课本中的目录类似。数据存储在一个地方,索引存储在另一个地方,索引带有指针指向数据的存储位置。索引中的项目按索引键值的顺序存储,而表中的信息按另一种顺序存储(这可以由聚集索引规定)。如果在表中未创建聚集索引,则无法保证这些行具有任何特定的顺序。

    多个非聚集索引
    有些书籍包含多个索引。例如,一本介绍园艺的书可能会包含一个植物通俗名称索引,和一个植物学名索引,因为这是读者查找信息的两种最常用的方法。对于非聚集索引也是如此。可以为在表中查找数据时常用的每个列创建一个非聚集索引。


    注意事项

    在创建非聚集索引之前,应先了解您的数据是如何被访问的。可考虑将非聚集索引用于:
    • 包含大量非重复值的列,如姓氏和名字的组合(如果聚集索引用于其它列)。如果只有很少的非重复值,如只有 1 和 0,则大多数查询将不使用索引,因为此时表扫描通常更有效。
    • 不返回大型结果集的查询。
    • 返回精确匹配的查询的搜索条件(WHERE 子句)中经常使用的列。
    • 经常需要联接和分组的决策支持系统应用程序。应在联接和分组操作中使用的列上创建多个非聚集索引,在任何外键列上创建一个聚集索引。
    • 在特定的查询中覆盖一个表中的所有列。这将完全消除对表或聚集索引的访问。

    索引都是一种排序,只是聚集索引的排序和物理表中的数据排序相同,一致的;而非聚集索引的排序和物理表数据的排序不同。

    当我们在更新统计信息的时候,对于那些聚集索引列不但要更新索引页还要同时对数据物理表数据重新排序;而对非聚集索引列则只需要更新索引页。

    转载:http://hi.baidu.com/yuleboxcn/blog/item/1a2464faf153ad6d034f5697.html

  • 数据库索引的详细说明

    2009-12-02 15:03:44


    一、简介

      自从你和你的团队成功的开发和部署了一个INTERNET网站,已经过去数月了,这个网站在很短的时间内吸引了数千用户前来注册和使用,因此你有了一个非常满意的客户。包括你和你的团队、管理层、客户,每个人都非常高兴。

      生活并不总是一帆风顺的。当站点的用户开始日均高速增长的时候,问题随即出现了,客户发来邮件开始抱怨网站性能太慢,同时称网站正在丢失客户。

      你开始调查这个系统,很快你发现当系统访问或更新数据的时候,速度非常慢。打开数据库一看,数据库的记录增加的很快,有些表的记录达到了成千上万行,测试团队在产品数据库上做了一个测试,结果发现在测试服务器上仅2/3秒就能完成的一个处理过程,现在需要5分钟。”

      这个古老的故事发生在全球范围内的数以千计的系统身上。包括我在内,几乎每个开发人员在他或她的开发过程中会碰到同样的事情。我知道为什么这样的情形会发生,同时我也知道如何去克服它。

      二、阅读范围

      请注意本一系列文章讨论的主要的焦点是“事务性的SQLServer数据库数据访问性能优化”,但大部分优化技术同样适用于其他的数据库。

      我将要讨论的优化技术仅仅适用于软件开发人员。作为一个开发者,你需要跟随我关注的问题,确认你已经作了所有能做的事情,去优化你已经写的或将要写的数据访问代码。数据库管理人员(DBA)同样在优化和提高性能上扮演了很重要的角色,但是DBA领的优化将不属于这篇文章讨论的范围。

      三、开始优化一个数据库

      当基于数据库的应用系统放慢的时候,99%的可能是系统的数据访问过程没有优化,或者没有使用最好的方式。所以你需要回顾和优化你的数据访问/操作过程,提高系统的全局性能。接下来我们通过一步一步的方式开始我们的优化任务。

      第一步:在列上采用正确的索引

      有些人可能争论实施正确的索引是否是数据库优化过程的第一步。但是我认为在数据库应用正确的索引是第一位的。原因有2点:

      1.在一个产品系统里,它将使你在很快的时间内提高尽可能大的性能。

      2.创建数据库索引不需要你做任何的系统修改,因此不需要任何重新编译和部署

      如果你发现有当前的数据库没有很好的处理索引,你建了索引,结果就是性能的快速提升。然而,如果索引已经处理了,我们进入下面的步骤。

      什么是索引

      我相信你已经明白了什么是索引,但是,我仍旧看到很多人对索引不太清楚。让我们再一次弄明白什么是索引,请看下面的小故事。

      很久以前,在一个古城市里有一个很大的图书馆,里面有数以千计的图书,图书凌乱的存放在书架上。因此,一旦有读者向图书员索要一本图书,图书员除了一本一本的检查图书,看是否匹配读者索要的图书,其它没有更好的办法。发现一本渴望的图书往往需要花费图书员数个小时。同时读者也不得不等很长的时间。

    [这看起来象一个没有主键的表,当在表里进行搜索数据的时候,数据库引擎需要遍历全部的数据来查找相关的记录,所以运行起来非常慢。]

      当读者和图书每天都在大量增加的时候,图书员的工作越来越繁重。有一天,有一个智者来到图书馆,看到图书员的繁重的工作,建议他给每一本书编号,同时按顺序码放在书架上。“我可以从中得得什么好处?”图书员问,那个智者回答到:“如果有读者通过给你一个书号来索要图书,你很快就能发现在哪个书架上存放了包含该书号的图书,然后在这个书架上,你同样能很快的找到需要的图书”

      [给书编号就象在数据表里创建一个主键,当你在一个表里创建了一个主健后,系统就创建了一个聚集索引树,所有的包含记录的数据页按照主键的值在文件系统中进行排序.每一个数据页内部也同样按照主键的值进行排序.所以,当你向数据库请求任何一个数据行的时候,首先数据库服务器使用聚焦索引找到合适的页(象首先发现书架一样),接着在页里查找包含主键值的记录(象在书架发现一本书)]

      “这正是我所需要的”,兴奋的图书员开始给书编号,接着把它们排列在不同的书架上,他花费了一天的时间来排序.在那天快结束的时候,他做了测试,结果发现几乎不用花费时间就能找到一本书.图书员高兴极了.

      [这正是你创建了主键后所发生的事情.首先,创建了聚焦索引,接着数据页在物理文件里按照主键的值被排序.有一点我想你应该很容易理解,因为数据仅仅只能使用一列的值作为凭证来排序,所以一个表只能创建一个聚焦索引.就象图书只能使用一个标准即书号来排序一样.]

      等一等,问题还没有被完全解决,在接下来的时间里,有个读者没有图书的编号,只有图书的名字,他想通过书名索要图书,如何办呢?可怜的图书员只能按照从1到N来查遍所有已经编号的图书.如果图书存放在67号书架上,他可能需要20分钟,相比早间图书没有被排序的时候,他所花费的2-3个小时.这确实有一个进步.但是和花费30秒通过书号查找一本书比较起来,,20分钟仍旧是一个不短的时间.还有没有更好的办法呢?他问那个智者。

      [假设你有一个产品表,如果你只有一个ProductID主键而没有其它的索引,上述的情况同样会发生,所以,当使用产品名字来搜索的时候,数据引擎只能遍历文件里所有物理排序的数据页,没有其它的办法.]

      那个智者告诉图书员:因为你已经按照书号对图书做了排序,你不能使用其它的凭证重新排序,所以,较好的方法是创建一个包含书名和与之对应的编号的目录或索引,在这个目录上,按照图书的字母顺序排序,并使用阿拉伯字母进行分组,例如,当有人想查找DatabaseManagementSystem这本书的时候,你使用下列的规则就能发现这本书

      1.在书名目录里跳到D章,找到包含你的书名的图书.

      2.得到这本书的书号,然后用书号去查找这本书

      “你真是一个天才”,图书员喊到,他立即花费了一些时间创建了书名的目录,通过一个快速的测试,他发现使用书名来查询仅仅需要1分钟,其中30秒查找书的编号,30秒用编号来找书.

      图书员想到,读者还可能使用其它的凭证来查找图书,例如作者的名字,所以他为作者创建了同样的目录.在创建了这些目录后,图书员可以使用这些凭证在1分钟内找到图书.图书员的繁重的工作终于结束了,许多读者也因为很快的查找到图书而聚集在图书馆,图书馆变的非常热闹起来.

      图书员随后开始过着他的快乐的生活,故事结束了.

      到这里,现在我确信你已经明白了什么是索引,为什么它们如此重要以及它们的内部工作原理,,例如,我们有一个已创建聚焦索引的产品表Products,因为当创建了主键的时候,随即就创建了聚焦索引。我门应当在Productname列创建一个非聚焦索引,一旦我们这样作了,数据库引擎就为非聚焦索引创建一个索引树,象故事里的书名目录,按照产品的名字在索引页里排序。每个索引页包含一定范围的产品名字和与之对应的ProductID,所以当使用产品名字作为凭证搜索的时候,数据库引擎首先查询产品名字的非聚焦索引树来发现这本书的主键productID,一旦发现,数据库引擎就使用主键ProductID来搜索聚焦索引树,从而并得到正确的结果。

    索引树的工作原理

    被称做为B+树,中间的节点包含一定数量的值,指示数据库引擎当从跟节点搜索一个索引值的时候如何遍历.如果这是一个聚焦索引树,页节点是物理数据页.如果是非聚焦索引树,页节点包含包含索引值和与之对应的聚焦索引值.

      通常,在索引树里发现需要的值并且转到目标数据记录,对于数据库引擎来说花费的时间是很短的,所以,在数据库应用索引极大的提高了数据的检索操作.

      请跟随下列的步骤确保正确的索引包含在你的数据库里。

      确保数据库的每个表有一个主健

      这么做会确保每个表有一个聚焦索引,通过主健的值,表的数据页通按物理顺序排列在磁盘上。所以,任何使用主健的数据检索操作,任何在主健字段的排序操作都能非常迅速的检索数据。

      在这些列上创建非聚焦索引

      经常被作为搜索凭证的列

      用来联合其它表的列

      用来作为外健的列

      用来排序的列

      高选择性列

      Xml类型

      下面是一个创建索引的命令的例子

      CREATEINDEX

      NCLIX_OrderDetails_ProductIDON

      dbo.OrderDetails(ProductID)

    第二步:创建正确的复合索引

      现在,你是否已经在数据库创建了所有的适合的索引?假设,在一个Sales表(SelesID,SalesDate,SalesPersonID,ProductID,Qty),你已经在外键(ProductID)创建了索引,如果ProductID是一个高选择性列,任何在where语句里使用索引列(ProductID)的检索数据的SELECT查询都会运行的非常快吗?

      对,相对没有在外键创建索引的情况(这需要全部数据页的遍历)来说,这是非常快的,但是,还有进一步提升的空间.

      让我们假设:Sales表包含10,000行数据,下面的SQL语句选择400行。


      SELECTSalesDate,SalesPersonIDFROMSalesWHEREProductID=112

      首先让我们弄明白在数据库引擎怎么执行SQL语句的:

      1.Sales表有在ProductID列一个非聚焦索引,所以,首先查询非聚焦索引树,发现包含ProductID=112的入口。

      2.包含ProductID=112入口的索引页同样同样也包含了聚焦索引的值(所有的主健的值,即SalesID)

      3.对于每一个主健(共400个),数据库引擎进入聚焦索引树来发现正确的行的位置

      4.对于每一个主健,一旦发现正确的行的位置,数据库引擎会从匹配的行得到SalesDate和SalesPersonID的列的值。

      请注意,在上述的步骤中,对于每一个ProductID=112的主键入口(共400个),数据库引擎必须搜索聚焦索引树400次,来检索附加的列(SalesDate,SalesPersonID)。

    让我们猜想一下,如果非聚焦索引不但包含了聚焦索引的值(主健),同时还包含查询里标注的其他的2个列(SalesDate,SalesPersonID)的值,数据库引擎就不用执行上述的第3步和第4步,只须进入ProductID的列的非聚焦索引树,从索引页上读取3个列的值,这样运行的速度不是更快吗?

      幸运的是,有一种办法来实施这种特点,这就是复合索引。你可以在表的列上创建复合索引,标明哪些列是和聚焦索引一起的应该附加存储的列。下面是一个在表Sales表的列ProductID创建复合索引的例子。


      CREATEINDEXNCLIX_Sales_ProductID--Indexname
      ONdbo.Sales(ProductID)--Columnonwhichindexistobecreated
      INCLUDE(SalesDate,SalesPersonID)--Additionalcolumnvaluestoinclude

      请注意,创建复合索引应当包含少数几个列,并且这些列经常在select查询里使用。在复合索引里包含太多的列不仅不会给你带来太多好处。而且由于使用相当多的内存来存储复合索引的列的值,其后果是内存溢出和性能降低。

      当创建复合索引的时候,尽量使用DatabaseTuningAdvisor(数据库优化顾问)的帮助。

      我们知道,一旦一个SQL开始运行,SQLSERVER引擎优化器基于以下几点动态的产生不同的检索计划。

      数据量

      统计

      索引变化

      TSQL的参数值

      服务器的负载

      这意味着:对于一个特殊的SQL语句,在产品服务器上的执行计划可能和在测试服务器上的执行计划不近相同,甚至表和索引结构一样。这同样也表明,一个在测试服务器上创建的索引可能会加速测试服务器上的性能,但是在产品服务器上的同样的索引可能不会带给你任何益处。为什么?因为在测试环境下的SQLSEVVER执行计划可能使用创建的索引,因此给你很好的性能,但是,在产品服务器上的执行计划可能出于下列的原因而根本不使用新创建的索引。例如:一个非聚焦索引列在产品服务器上不是高选择性列,而在测试服务器上是高选择性列.

      所以,当创建索引的时候,我们需要弄明白这一点:索引是执行引擎用来提高速度的。但是我们该如何去做呢?

      答案是我们必须在测试服务器上模拟产品服务器的负载,接着创建索引,以及测试他们。只有这样,在测试服务器上能提高性能的索引,才能更有可能在产品服务器上提高性能。

      这么做应该很困难,但幸运的是,我们有一些好用的工具去实现它,请跟随下面的指导:

      1:使用SQLprofiler捕获产品服务器上的痕迹。使用Tuningtemplate(我知道,有人建议不要在产品服务器上使用SQLprofiler,但有些时候,你不得不在产品服务器上诊断性能问题的时候使用它),如果你不熟悉这个工具,或者你想了解更多的关于SQLprofiler的知识,请阅读http://msdn.microsoft.com/en-us/library/ms181091.aspx

      2.利用上一步产生的跟踪文件,用数据库优化顾问在测试数据库创建相似的负载,从优化顾问得到一些建议,特别是创建索引的建议,你很可能从优化顾问那里获得比较实际的建议。因为优化顾问使用产品服务器产生的跟踪文件来装载测试服务器,所以能产生最可能好的索引建议。如果你不熟悉优化顾问工具,或者你想了解更多的关于使用优化顾问的的资料,请阅读:http://msdn.microsoft.com/en-us/library/ms166575.aspx.

    第三步:如果有碎片发生,重新整理它

      到了这里,如果你已经在表里创建了所有正确的索引,但是,你可能还没有获得所希望的良好的性能。什么原因呢?有一种可能是出现了索引碎片。

      1、什么是索引碎片

      索引碎片是这样一种情形:由于在表里大量的插入、修改、删除操作而使索引页分裂。如果索引有了高的碎片,有两种情况,一种情况是扫描索引需要花费很多的时间,另一种情况是在查询的时候索引根本不使用索引,都会导致性能降低。

      有2种类型的碎片:

      内部破碎:由于索引页里的数据插入或修改操作而发生,以数据作为稀疏矩阵的形式的分布而结束,这将导致数据页的增加,从而增加查询时间。

      外部破碎:由于索引/数据页的数据插入或修改而发生,以页码分离和在文件系统里不连贯的新的索引页的分配而结束,数据库服务器不能利用预读操作的优点,因为:下一个相关联的数据页不临近,而且这些相关连的下面的页码可能在数据文件的任何地方。

      2、如何知道索引破碎是否已经发生?

      在数据库执行下面的SQL语句(下面的语句在SQLserver2005及以后的版本运行正常,以你的目标数据库的名字取代AdventureWorks’)


      SELECTobject_name(dt.object_id)Tablename,si.name
      IndexName,dt.avg_fragmentation_in_percentAS
      ExternalFragmentation,dt.avg_page_space_used_in_percentAS
      InternalFragmentation
      FROM
      (
      SELECTobject_id,index_id,avg_fragmentation_in_percent,avg_page_space_used_in_percent
      FROMsys.dm_db_index_physical_stats(db_id('AdventureWorks'),null,null,null,'DETAILED'
      )
      WHEREindex_id<>0)ASdtINNERJOINsys.indexessiONsi.object_id=dt.object_id
      ANDsi.index_id=dt.index_idANDdt.avg_fragmentation_in_percent>10
      ANDdt.avg_page_space_used_in_percent<75ORDERBYavg_fragmentation_in_percentDESC

    分析上面的结果,你就能发现在哪里出现了索引碎片,应用下面的规则:

      ExternalFragmentation的值>10,预示对应的索引出现外部碎片。InternalFragmentation的值<75,预示对应的索引出现内部碎片

      3、怎样重新整理索引碎片

      有2种方式:

      索引重组:执行下面的命令:

      ALTERINDEXALLONTableNameRECOGNIZE

      索引重建:

      ALTERINDEXALLONTableNameREBUILDWITH(FILLFACTOR=90,ONLINE=ON)

      通过使用具体索引的名字代替ALL,你能重组或重建单个的索引。你也可以使用数据库控制台来重建/重组索引

      SQL Server使用索引实现数据访问优化

      4、什么时候重组和重建索引?

      当外部碎片的值在10-15,内部碎片的值在60-75,对于这样的索引,你应该重组索引。否则,你应该重建索引。

      关于索引重建的一个重要的事情是:一旦在一个特定的表上重建索引,表就会被锁定(重组的时候不会发生)。所以,对于一个产品数据库的一个大的表,因为在一个大表上的索引重建往往需要花费数个小时,我们不希望这种锁定。幸运的是,在SQL2005有一个解决方法,你可以在重建一个表的索引的时候,把ONLINE选项的值设为ON,这样会使重建索引和表上的数据事务同样进行。

      四、实现数据访问结束语

      在数据表里的所有适合创建索引的字段上创建索引,这是非常诱惑人的。但是如果你正在从事一个事务数据库工作,在每个字段上创建索引并不是每次都是需要的。事实上,在一个OLTP系统上创建大量的索引可能会降低数据库的性能。(因为当很多操作是更新操作的时候,更新数据意味着更新索引)

      一个首要的规则建议如下:

      如果你在从事一个事务性数据库,平均不要在一个表上创建超过5个索引,另外,如果你在从事数据仓库,平均最高可在一个表上创建10个索引。

    转载:http://hi.baidu.com/yuleboxcn/blog/item/dd0c4dd1bbf96f87a1ec9c54.html
  • 虚拟化技术 VMotion实时迁移详解

    2009-07-20 12:08:12

    转载地址:http://smb.pconline.com.cn/zxpc/0906/1693468.html 

      虚拟化正在改变人们对计算机的认识,说起虚拟化,VMotion估计是给人印象深刻的诸多亮点中的一个。VMware公司一直在虚拟化技术中占据领先的地位。因此VMware VMotion就好像站在了VMware这个巨人的肩膀上一样,在实时迁移技术领域,立于高峰之巅。

    VMware VMotion概述

      VMware VMotion能够在两台正在运行的服务器之间进行实时迁移,具有零停机性能,能够大幅度提高了服务器的可用性,保证交易数据的完整性。VMotion是创建动态,自动优化数据中心的关键因素,对完善服务器虚拟化,存储器虚拟化和网络虚拟化等技术产生重大的影响。

    Vmotion step by step
    VMware VMotion的迁移示意图

    VMware VMotion的功能

      对于服务器管理员来说,VMotion允许管理员:1、在资源库中不断地自动分配虚拟机;2、在不中断业务运作的情况下进行各项维修工作,从而令服务器获得最高的可用性。

      对于用户来说,VMotion允许用户:1、自动优化和分配资源库,从而大大地提高了硬件的利用率,灵活性和可用性。2、进行定期的硬件设备维护操作,但却不需要预先设定停机时间。3、在服务器发生故障或者表现不佳之前,进行迁移。

    VMotion中运用的技术

      VMotion从一台物理服务器将虚拟机迁移到另外一台虚拟机要用到下述三项技术:

      1. 虚拟机的全部状态信息被压缩在一套存储于共享存储器的文件中。作为载体的存储器类型可以是光纤通道(Fibre Channel),iSCSI存储区域网络(iSCSI Storage Area Network,SAN)或者网络附加存储器(Network Attached Storage,NAS)。VMware的群集虚拟机系统(VMFS)允许多台ESX服务器同时访问同一个虚拟机文件。

      2. 虚拟机的动态内存和执行状态在一个高速的网络上进行快速传输,允许虚拟机即时地在源ESX服务器和目标ESX服务器之间进行信息交换。在迁移过程中,VMotion只是在点阵图里对信息交换进行监控,所以整个转移过程对用户来说是透明的。一旦整个内存和系统状态全部复制到目标ESX服务器中,VMotion就会自动终止源虚拟机,同时将点阵图转移到目标ESX服务器中,并在目标ESX服务器中重新启动虚拟机。上述整个操作假如是在一个千兆以太网络中进行,那么不用两秒的时间就可以完成。

      3. 虚拟机使用的网络同样也会被目标ESX服务器虚拟化,确保在实时迁移之后,虚拟机的网络身份和连接能够得到保留。VMotion将MAC地址作为进程的一部分来进行管理。一旦目标机被激活,VMotion会检查网络路由器来确保它能识别虚拟机MAC地址新的物理位置。由于虚拟机使用VMotion来进行实时迁移,它的执行状态,网络身份和动态链接都能够得到保护,所以对于用户来说,整个迁移过程并没有引起服务器停机或者网络中断。

    VMware VMotion的关键特点

      可靠性:自从2004年推出了该产品之后,在成千上万的用户的支持下,VMotion一直不断地为最可靠的实时迁移性能调整标准。

      高可用性:最终用户无法觉察到实时迁移所带来的服务器的停机。CPU和网络资源的最大利用确保了实时迁移迅速和有效地进行。

      互操作性:无论虚拟机运行在什么操作系统上,实时迁移都可以在任何类型的硬件设备和网络上进行,只要VMware ESX服务器支持该设备和网络。支持由管线通信连接的存储区域网络(SAN)。实行的实时迁移的虚拟机利用带宽高达4GB的光纤通道连接的存储区域网络系统(SAN)。

      支持网络附属存储(NAS)和iSCSI的存储区域网络(SAN)。实行实时迁移的虚拟机花费更低的成本,使用更容易管理的存储器。可自定义的CPU兼容性设置。确保虚拟机可以在不同版本的硬件设备上进行迁移,以便虚拟机可以永远处于最新的CPU革新浪潮之中。

      易操作:迁移向导。通过迁移向导提供的即时信息,可以为一台虚拟机快速辨别最好的转移对象。

      多个并行迁移。在整个IT工作环境中,进行多个并行迁移,来持续不断的优化虚拟机的布局。

      优先等级。为每一个实时迁移操作分配一个优先等级,确保当前最需要进行的迁移可以及时反问它们所需要的资源。

      安排迁移任务。在每个预定好的时间点上,不需要管理员在场启动,迁移就能够自发进行。

      迁移检查追踪。每次迁移都有一份详细的操作报告,包括日期/时间和管理程序初始化迁移的回复信息。

    VMotion的具体操作

      使用VMotion进行实时迁移允许虚拟机在不中断工作进程的情况下进行。虚拟机的所有状态信息连同它的配置文件都会被迁移到新的主机上。然而与之相连接的虚拟磁盘将会保留在两主机共享的存储器中。在虚拟机的状态信息全部钱一到替换的主机上之后,虚拟机就可以在新的主机上运行了。

      需要迁移的状态信息包括当前的内存内容以及所有能够定义和识别该虚拟机的信息。其中,内存信息包括交换数据,操作系统的位数以及存储在内存中的应用程序。而虚拟机的定义和识别信息包括所有映射到虚拟机硬件上的数据,比如BIOS,设备,CPU, 网卡的MAC地址 ,芯片的设置状态等。另外,作为替换的主机还必须满足兼容性要求。

      使用VMotion来进行实时迁移一般要经历下述三个步骤:

        1. 当VMotion收到实时迁移的请求时,vCenter服务器就会检查当前主机上的虚拟机是否处于稳定的状态。

        2. 假如VMotion通过了实时迁移请求,那么虚拟机的所有状态信息(包括内存,注册表和网络连接)就会被复制到目标主机上。

        3. 信息复制完毕之后,虚拟机将在新的主机上重新启动,投入运作。

    Vmotion step by step
    VMware VMotion操作界面

      如果在迁移过程中发生了错误,那么虚拟机将会自动恢复到原来的状态和位置。

    Vmotion step by step
    VMware VMotion错误提示界面

     vSphere 4中的VMotion

      近日,VMware公布了新一代服务器虚拟化软件,其产品名称由VMware Infrastructure 3改为VMware vSphere 4,这表明了VMware对于服务器虚拟化已经从一个虚拟化的基础平台,走向一个由虚拟化建构起来的资料中心。VMotion在vSphere 4中也得到了很大的改进。最明显的特点就是能够将一台正在运行的虚拟机从一台物理ESX主机上迁移到一台虚拟ESX主机上。

    Vmotion step by step
    物理ESX主机和虚拟ESX主机之间的迁移

      从ESX 3.5升级到vSphere 4的过程中,ESX 3.5的VMotion可以不需要做任何改变就也可适用于vSphere 4。但是,如果使用的是不同的处理器芯片,并且还需要开启以太网虚连接(EVC),那么就需要做一点小变动,而且EVC的连接可能还会有停机的危险。另外,vSphere 4的VMotion却无法兼容ESX 3.5版本的主机。

    Storage VMotion

      Storage VMotion功能只存在于ESX 3.5和vCenter 2.5以及以上版本。是ESX系列的一个重要的改进。很到人可能会以为Storage VMotion是VMotion中的一项功能,事实上并非如此,两者其实是并行的。VMotion针对的是服务器中虚拟机的迁移,而Storage VMotion针对的是虚拟机中存储信息的迁移,主要是移动虚拟机的个人主目录,配置文件(vmx),日志,交换文件(VSWP),快照,磁盘或者逻辑硬盘(vmdk),操作系统磁盘,数据盘以及所有跟该虚拟机相关的文件。

    Vmotion step by step
    Storage VMotion操作示意图

    Storage VMotion的性能要求

      Storage VMotion的性能要求要比VMotion严格得多:

      安装带有VMware VMotion 许可证的VMware vCenter;VMware VMotion在ESX服务器上必须被激活并且进行了适当的配置(可以参考VMware管理员基础指南)。

      1. 虚拟机不能使用任何VMotion禁用的设备(比如软盘,CD-ROM)。

      2. Storage VMotion并不要求一定要连接上物理网络。

      ESX服务器必须拥有足够的资源来完成Storage Vmotion的完整操作。

      虚拟机的磁盘必须通过快找技术创建一个子磁盘,用来将原有磁盘的数据复制到新的节点上。如果没有这项功能,Storage VMotion将无法正常工作。

      ESX服务器必须能够访问员服务器和目标服务器的存储器。

      Storage VMotion一次最多可以在同一个数据存储器中同时执行四个迁移操作。

      只支持光纤通道和iSCSI存储序列。

      虚拟机要求Storage VMotion不能与内部虚拟交换机的网络相连接。

      虚拟机要求Storage VMotion不能跟其他虚拟机有群级关系,特别是使用微软群集服务器或者Sun群集器的时候。

      在同一台虚拟机上不允许同时使用Storage VMotion和VMotion。一台虚拟机的数据存储中心必须先使用Storage VMotion搬移到目标服务器的存储器中。然后虚拟机才可以使用VMotion迁移到目标ESX服务器上。两者的迁移顺序并没有限制。

    Storage VMotion的操作步骤

      1. 复制虚拟机的个人主目录到新的节点。这个步骤使用近距离无线通信技术(NFC)复制器来将文件复制的到新的节点上。

    Vmotion step by step
    虚拟机主目录拷贝

      2. 自我迁移(Self-VMotion)到新的虚拟机主目录上。Self-VMotion的进程跟正常的VMotion是一样的。这一步使用新的转换文件,并重新打开其他复制文件,比如虚拟机配置文件以及其他类似的文件。

    Vmotion step by step
    自我迁移

    3. 对磁盘进行快照处理。这一步骤创建了一个子磁盘,用来记录所有虚拟机数据上的变化。

    Vmotion step by step
    子磁盘的创建

      4. 复制虚拟机磁盘到目标服务器。

    Vmotion step by step
    虚拟机磁盘的拷贝

      5. 将步骤四创建的子磁盘整合进拷贝磁盘中。

    Vmotion step by step
    子磁盘的结合

      6. 删除原来虚拟机的主目录和磁盘,并将新的拷贝磁盘的状态设置为可读。

    Vmotion step by step
    移除源虚拟机

    vSphere 4中的Storage VMotion

      在vSphere 4中可以使用图形用户界面(GUI)来运行Storage VMotion。整个操作过程因为可视化的操作界面而变得非常简单。Storage VMotion的所有功能都集成在vCenter中,不需要任何外部插件。

    Vmotion step by step
    Storage VMotion操作界面

      在第一个界面中选择修改数据存储(Change datastore)。值得注意的是,选项一是用于虚拟机之间的VMotion,选项三只能在虚拟机的电源被断开之后才可用。

    Vmotion step by step
    Storage VMotion操作界面

      选择合适的数据存储中心来迁移你的信息,并且点击继续。

    Vmotion step by step
    Storage VMotion操作界面

      确认前已成功之后,就选择你所需要的选项。第一个选项是用来保留虚拟机之前的配置。第二个选项是进入thin provisioned模式。点击下一步(next),开始进行Storage VMotion操作。对于管理员来说,这个功能可以大大地简化Storage VMotion的进程。

  • Adsl猫+Dlink无线路由设置

    2009-06-18 23:46:25

    猫开路由后(猫内的DHCP关掉,直接设置后级路由为静态IP),再设置后级路由dlink为静态ip

    具体配置:

    ip192.168.1.1
    路由器外网设置:

    IP地址:192.168.1.2

    子网掩码:255.255.255.0

    缺省网关:192.168.1.1(路由器为猫的下级设备,网关设为猫的IP

    路由器网关设为猫IP192.168.1.1
    路由器内网设置保持不变(路由器IPDHCP等设置)

    上网计算机IP:全部自动获取就可以

541/3123>
Open Toolbar