• 发货服务化的工程质量实践


    概述###

    要构建高质量软件工程,需要构建两个关键步骤:(1)持续自动化的开发与部署流程,能够将开发、测试、部署、验收等重要环节流畅地串联起来,并增强自动化和可靠性;(2)持续增强每个环节的质量。 推荐阅读: 《持续交付:发布可靠软件的系统方法》

    为方便起见,发货服务化工程简称为D,项目结构遵循标准 Java Maven 结构。

    D
       src/main/java
       src/main/resources
       src/test/java
       src/test/resources
       pom.xml    
    

    持续集成####

    代码开发(包括添加相应单测) -> 提交前自动运行单测,单测不通过不能提交 -> 单测全部通过【覆盖率达标】 -> Push到代码库(触发持续集成环境单测全部通过) -> 代码Reivew通过 -> 成功构建和部署到QA环境 -> 自动触发QA验收测试(接口测试与业务场景测试) -> QA验收测试全部通过 -> 成功构建和部署到预发环境 -> 预发验收测试通过 -> 发布到正式生产环境 -> 生产环境验收通过。

    代码开发###

    代码开发应该注意两个基本点:(1) 可复用性; (2) 将潜在变化与不变分离出来,适当使用设计模式。

    代码开发可适当考虑 TDD 开发。 对于提交结果而言, 新增方法一定要添加相应单测。 最好能有自动检测是否有相应单测增加工具。

    单元测试###

    更好地编写单测####

    参考: 深入探究单测编写

    提交前自动运行单测####

    开发同学常常忘了运行单测, 其实只要一个小技巧即可:在 ~/.bash_profile 文件末尾增加一行 alias gp="mvn test && git push origin" 。 当运行 gp 分支名时, 会自动运行单测, 单测不通过是不能提交的。

    单测覆盖率####

    pom.xml 里配置单测覆盖率maven插件, 然后在项目根目录下运行
    mvn clean && mvn cobertura:cobertura && cat /target/site/cobertura/coverage.xml | grep "<coverage"

    <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>cobertura-maven-plugin</artifactId>
        <version>2.7</version>
        <configuration>
            <formats>
                <format>xml</format>
            </formats>
        </configuration>
        <executions>
            <execution>
                <phase>package</phase>
                <goals>
                    <goal>cobertura</goal>
                </goals>
            </execution>
        </executions>
    </plugin>
    

    这是发货服务化工程的单测覆盖率结果:

    即使核心代码单测覆盖率达到100%,从整体上也难以达到指定指标, 这主要是由于一些“无需测试的方法比如getter/setter”的存在,以及一些 utils , 缺乏单测的复杂业务方法的存在。如何达到指定单测率而且保证质量呢? 首先建立若干准则:
    (1) 核心主流程经过的所有方法的行覆盖率应该达到 100%;
    (2) 非核心主流程的方法,只要程序会运行到且有一定逻辑,行覆盖率 90%;
    (3) Utils 的未用到的方法,要么删除,要么加上单测;
    (4) 无需测试的方法, 可以生成单测允许通过,但不必过多考虑。

    查看单测覆盖率报告,看看是哪些地方覆盖率低,重要性如何。 在重要性相对较高、覆盖率低的地方添加单测。

    代码Review###

    在持续集成环境中, 当代码 push 到代码库后,应当自动触发持续集成环境的单元测试(防止开发同学本地忘了运行单测), 单测不通过将在 CodeReview 里增加一个明显的错误标识。一般单测不通过是不允许进入人工代码 Review 的。

    在代码库工具平台上创建代码Review , 并将链接发送到相关Review同学。根据代码Review 意见改善代码后提交,直到单测全部通过、代码Review全部通过后进入下一步。

    CodeReview实践与总结

    QA验收测试###

    构建和部署到QA测试环境####

    理想情况下, 当 git push 到代码库后,应当自动触发发布系统将指定分支的代码部署到QA环境,然后运行接口测试用例。

    验收测试####

    验收测试主要是针对业务场景的测试。可以包括单接口测试和组合接口测试。由于发货是单个接口完成,因此,可以只验收单接口测试。单接口测试必须覆盖各种场景的发货。比如普通单商品发货、普通多商品发货、送礼发货、分销发货、批量发货、有退款维权的发货、非合法发货返回的错误码。

    运行接口测试用例####

    发货服务化的接口测试用例放在工程 service-test 的 DeliveryServiceDubboTest 和 DeliveryServiceHttpTest 测试类里。 方便起见, 最好将 service-test 放置在与 java 工程同级目录下,即 work/java/D, work/java/service-test。先将环境切换到 QA host ; 然后在 service-test 项目根目录下, 运行 mvn test -Dtest=DeliveryService*Test 即可。

    预发布及验收测试###

    在发布系统选择预发布, 部署工程到预发布环境; 然后在测试店铺验证普通发货、送礼发货、分销发货、批量发货均正常。

    正式发布及验收测试###

    在发布系统选择正式发布, 部署工程到正式环境; 然后登录测试店铺验证普通发货、送礼发货、分销发货、批量发货均正常。

    一个简单的集成脚本###

    在推送代码到代码库时使用: ./push.sh 分支名

    #!/bin/bash
    #-----------------------------------------
    # add line below to ~/.bash_profile
    # alias gp="mvn test && git push origin "
    #------------------------------------------
    alias gp="mvn clean test && git push origin "
    shopt -s expand_aliases
    if [ x$1 != x ]
    then
        echo "git push origin $1"
        gp $1
    else
        gp
    fi
    echo "code review passed ?"
    read answer
    if [ "$answer"x != "y"x -a "$answer"x != "Y"x ]
    then
        echo "code review not pass, please fix and recommit"
        exit 1
    fi
    echo "deploy to qa ?"
    read answer
    if [ "$answer"x != "y"x -a "$answer" != "Y"x ]
    then
        echo "not deploy to qa not pass, please fix and recommit"
        exit 1
    fi
    # set qa enviroment
    echo "switch qa environment."
    sudo python ./tools/switchhost.py qa
    echo "run interface tests."
    cd ../service-test
    mvn test -Dtest=DeliveryService*Test
    

    使用 SwitchHost 工具时自动切换 HOST 的脚本

    #!/usr/bin/python
    #_*_encoding:utf-8_*_
    #------------------------------------------------------
    # switchhost.py  automatically switch hosts managed by SwitchHosts tools
    # usages: sudo python switchhost.py [qa] [q] [local] [l] [pre] [p] [online] [o] [c]
    #------------------------------------------------------
    
    import json
    import os
    import sys
    homedir = os.environ['HOME']
    hostcodemap = {"local": "My Hosts", "l": "My Hosts", "qa": "qa", "q": "qa", "online":"online", "o": "online", "pre":"pre", "p": "pre", "c": "camen-dev"}
    
    def switch(env):
        with open(homedir+'/.Switchhosts/data.json') as data_file:
            hostobj = json.load(data_file)
            hostmap = {}
            for host in hostobj['list']:
                hostmap[host['title']] = host['content']
            content = hostmap[env]
            with open('/etc/hosts', 'w') as hostfile:
                hostfile.write(content)
                hostfile.close()
    
    def getEnv():
        if len(sys.argv) == 1:
            return "online"
        if len(sys.argv) > 1:
            env = sys.argv[1]
            env = hostcodemap[env]
            if env is None:
                env = "online"
        return env
    if __name__ == '__main__':
        switch(getEnv())
    

    发货服务化的分流心得###

    严格代码质量####

    使用设计模式确保代码组织的可扩展性, 并严格进行代码 Review 。

    1. 使用模板方法模式,确保通用的发货流程模板,以及不同的发货流程之间的解耦(普通发货、送礼发货、分销发货、批量发货);
    2. 确保业务方法只做一件事;

    双重护航测试####

    QA 提测之前,编写发货工程的单测及服务接口的可重复自动化测试用例(检测到数据库字段级别)尽可能覆盖到业务流程、方法及工具类,并确保全部通过。双重护航保证每一行代码改动都能快速回归有效;开发必须对自己的代码质量负最主要责任;

    发布谨慎平滑####

    分流步骤严格循序渐进,按“除TOP20外 0.001, 0.005, 0.01, 0.05, 0.1, 0.3, 0.5, 0.7, 1.0, TOP20加入”平滑进行,切忌贪急求快。每一次发布要谨慎:

    1. 登录服务器查看启动日志service.log , 确保发布后是服务正常启动的;
    2. 到测试店铺进行验证发货是否正常;
    3. 查看发货日志是否正常;查看监控是否正常。

    变更回归测试####

    1. 每一行代码改动,都必须运行单测及接口自动测试用例,保证全部通过;
    2. 每个BUG修复,都要增加相应的单测和接口测试用例覆盖;
    3. 分流接口也要增加接口测试用例,并同步运行测试用例;

    全天覆盖监控####

    打开Grafana服务器监控、日志平台与服务接口监控平台,全天候不定时刷新日志和监控曲线:

    1. 关注CPU/内存/IO/网络流量是否正常及报警;
    2. 评估和解决发货日志其中出现的错误和警告;
    3. 关注发货接口的调用次数和失败次数。

    日志分级统计####

    日志分级,便于排查真正的系统问题。

    1. 非系统级别,比如参数不合法等,使用警告级别,不必加入错误统计中;
    2. 系统错误,必须使用错误级别,加入错误统计;

    局部升级####

    若在分流中需要模块升级、字段升级、配置改动等,尽量保持小的改动(否则要进行全量回归测试);协调好发布顺序和时机;控制好服务工程与外部依赖的边界,保持边界兼容即可;

    不放过测试用例的失败####

    当服务接口的可重复自动化测试用例运行失败,要仔细排查问题的原因所在。在common-model升级后,发现发货测试用例运行失败,经仔细排查后,发现有两个代码上的小问题,存在潜在风险,并及时修复了这两个问题。

    不放过Error日志和Warn日志####

    Error 日志通常是系统有潜在问题的表现, 比如排查一个发货没有插入发货数据库表的问题,就发现商品传空的时候就有问题,甚至发现之前的事务引用修复分支并没有合并到master 分支发布(发布遗漏); Warn 日志通常是用户使用不当导致的, 就需要跟商家进行沟通,停掉这种无用的浪费资源的行为。

  • 相关阅读:
    delphi TreeView 从数据库添加节点的四种方法
    mac攻略(3) -- brew使用
    mac攻略(2) -- apache站点配置
    mac攻略(1) -- 简单配置php开发环境
    Mac通过brew安装reds、memcached
    golang urlencode
    golang GET 出现 x509: certificate signed by unknown authority
    git取消文件跟踪
    golang使用http client发起get和post请求示例
    PHP判断SQL语句是否合法:mysqli_error()
  • 原文地址:https://www.cnblogs.com/lovesqcc/p/6367598.html
Copyright © 2020-2023  润新知