更多工具:精英項(xiàng)目和團(tuán)隊建設(shè)

2018-11-21 21:21 更新

2.22.1 PHPUnit:自動化單元測試

目前核心框架單元測試的覆蓋率(高達(dá)90%以上!??!此處應(yīng)該有掌聲~): a pic

注意,此測試截圖并不是最新的,但我們一直都在致力堅持單元測試。
這一點(diǎn),你可以在單元測試的代碼中找到證明。

2.22.2 Phing:一鍵部署、快速發(fā)布

無論如何,都應(yīng)該走自動化發(fā)布流程,避免人工地打包、上傳、解壓、改生產(chǎn)配置這些重復(fù)性的人工操作。

在自動化發(fā)布中,Phing是個不錯的嘗試。

以下是我某個項(xiàng)目中的使用配置,出于對項(xiàng)目的保護(hù),部分?jǐn)?shù)據(jù)已刪除,但仍然可以參考。

(1)發(fā)布配置 - build.xml

主要的操作有:

    1. 備份當(dāng)前代碼,并刪除一天前的備份
    1. 從SVN簽出最新的發(fā)布代碼
    1. 執(zhí)行配置檢測腳本
    1. 代碼發(fā)布切換,并替換使用線上配置文件
    1. 移除單元測試初始化文件,以免誤執(zhí)行
<?xml version="1.0" encoding="UTF-8"?>

<!-- ============================================  -->
<!-- PhalApi                       -->
<!-- @dogstar 20141221                             -->
<!-- ============================================  -->

<project name="demo.phalapi.com" default="build">

    <property 
        name="backup_path" 
        value="/home/apps/backup/demo.phalapi.com" 
        override="true" />
    <property 
        name="backup_prefix" 
        value="demo.phalapi.com_phing_backup_" 
        override="true" />
    <property 
        name="svn_todir" 
        value="/home/apps/svn/demo.phalapi.com" 
        override="true" />

    <!-- ============================================  -->
    <!-- Target: prepare                               -->
    <!-- ============================================  -->
    <target name="prepare">
        <mkdir dir="./Runtime" />
        <mkdir dir="${svn_todir}" />
        <mkdir dir="${backup_path}" />
    </target>

    <!-- ============================================  -->
    <!-- Target: svn checkout                          -->
    <!-- ============================================  -->
    <target name="svncheckout">
        <svncheckout 
            repositoryurl="svn://127.0.0.1/PhalApi/demo/release" 
            username="test"
            password="123456"
            nocache="true"
            todir="${svn_todir}" />
    </target>

    <!-- ============================================  -->
    <!-- Target: svn update                            -->
    <!-- ============================================  -->
    <target name="svnup" depends="svncheckout">
        <svnupdate 
            repositoryurl="svn://127.0.0.1/PhalApi/demo/release" 
            username="test"
            password="123456"
            nocache="true"
            todir="${svn_todir}" />
    </target>

    <!-- ============================================  -->
    <!-- Target: check config                          -->
    <!-- ============================================  -->
    <target name="checkconfig">
    <php expression="include('${svn_todir}/Tools/check_config.php')" />
        <php 
            function="checkProd" 
            class="Tools_Check_Config" 
            returnProperty="checkProdErrorMsg" />

        <fail msg="${checkProdErrorMsg}" if="checkProdErrorMsg" />
    </target>

    <!-- ============================================  -->
    <!-- Target: backup                                -->
    <!-- ============================================  -->
    <target name="backup">
        <php 
            expression="date('Ymd', strtotime('-1 day'))" 
            returnProperty="backup_version_yesterday" />
        <php 
            expression="date('Ymd')" 
            returnProperty="backup_version_today" />
        <delete>
            <fileset dir="${backup_path}">
                <exclude name="${backup_prefix}${backup_version_yesterday}*" />
                <exclude name="${backup_prefix}${backup_version_today}*" />
            </fileset>
        </delete>

        <php 
            expression="date('YmdHis')" 
            returnProperty="backup_version" />
        <zip destfile="${backup_path}/${backup_prefix}${backup_version}.zip" basedir="." >
            <fileset dir=".">
                <include name="**/**" />

                <exclude name="./Runtime" />
                <exclude name="./Runtime/**" />
                <exclude name="./.svn" />
                <exclude name="./.svn/**" />
            </fileset>
        </zip>
        <copy 
            file="${backup_path}/${backup_prefix}${backup_version}.zip" 
            tofile="${backup_path}/${backup_prefix}lastest.zip" 
            overwrite="true" />
    </target>

    <!-- ============================================  -->
    <!-- Target: build                                 -->
    <!-- ============================================  -->
    <target name="build" depends="prepare,svnup,checkconfig,backup">
        <copy todir="." overwrite="true" >
            <fileset dir="${svn_todir}">
                <include name="**/**" />

                <exclude name="${svn_todir}/Config/dbs.php" />
                <exclude name="${svn_todir}/Config/sys.php" />
                <exclude name="${svn_todir}/Test" />
                <exclude name="${svn_todir}/Test/**" />
            </fileset>
        </copy>

        <copy 
            file="./Config/dbs.php.prod" 
            tofile="./Config/dbs.php" 
            overwrite="true" />
        <copy 
            file="./Config/sys.php.prod" 
            tofile="./Config/sys.php" 
            overwrite="true" />

        <!-- 避免在生產(chǎn)環(huán)境執(zhí)行PHPUnit,故把測試環(huán)境的初始文件移開 -->
        <move 
            file="./Test/test_env.php"
            tofile="./Test/test_env.php.bak" 
            overwrite="true"/>
    </target>

</project>

(2)回滾配置 - rollback.xml

主要操作:

    1. 回滾到上一個版本
<?xml version="1.0" encoding="UTF-8"?>

<!-- ============================================  -->
<!-- PhalApi                       -->
<!-- @dogstar 20141222 冬至                        -->
<!-- ============================================  -->

<project name="demo.phalapi.com" default="rollback">

    <property 
        name="backup_path" 
        value="/home/apps/backup/demo.phalapi.com" 
        override="true" />
    <property 
        name="backup_prefix" 
        value="demo.phalapi.com_phing_backup_" 
        override="true" />
    <property 
        name="svn_todir" 
        value="./__svn__" 
        override="true" />

    <!-- ============================================  -->
    <!-- Target: rollback                              -->
    <!-- ============================================  -->
    <target name="rollback" >
        <unzip file="${backup_path}/${backup_prefix}lastest.zip" todir="." >
            <fileset dir=".">
                <include name="*.zip"/>
            </fileset>
        </unzip>
    </target>

</project>

2.22.3 autobench:接口壓力測試與可視化圖表

可以通過以下的腳本來進(jìn)行,使用示例:

$ ./autobench.sh
Usage: ./autobench.sh <host> <uri>

 - ./autobench.sh www.baidu.com /index.php

參數(shù)可以自行調(diào)整。

(1)利用bench2graph生成可視化圖表

純PHP訪問 - 入口歡迎接口

a pic

mysql訪問 - 事件獲取接口

a pic

帶MC緩存的訪問 - 應(yīng)用入口 - 帶緩存的身份token驗(yàn)證

a pic

(2)詳細(xì)的數(shù)據(jù)報表

dem_req_rate    req_rate_demo.phalapi.com     con_rate_demo.phalapi.com     min_rep_rate_demo.phalapi.com avg_rep_rate_demo.phalapi.com    max_rep_rate_demo.phalapi.com stddev_rep_rate_demo.phalapi.com      resp_time_demo.phalapi.com       net_io_demo.phalapi.com       errors_demo.phalapi.com
5       5.0     5.0     4.8     5.0     5.2     0.1     22.4    2.9     0
25      25.0    25.0    25.0    25.0    25.0    0.0     21.6    14.3    0
45      45.0    45.0    45.0    45.0    45.0    0.0     22.3    25.7    0
65      64.9    64.9    64.7    64.7    64.7    0.0     25.4    37.0    0
85      84.8    84.8    84.6    84.6    84.6    0.0     28.6    48.3    0
105     104.6   104.6   0.0     0.0     0.0     0.0     34.4    59.7    0
125     124.0   124.0   0.0     0.0     0.0     0.0     42.2    70.7    0
145     143.8   143.8   0.0     0.0     0.0     0.0     59.2    82.0    0
165     147.4   147.4   0.0     0.0     0.0     0.0     262.9   84.1    0
185     151.1   151.1   0.0     0.0     0.0     0.0     429.7   86.2    0

(3)附腳本

#!/bin/bash

if [ $# -eq 0 ]; then
    echo "Usage: $0 <host> <uri>"
    echo ""
    echo " - $0 www.baidu.com /index.php"
    echo ""
    exit
fi

DM=$1
URL=$2

#--signle_host 只測單機(jī)
#--host1 測試主機(jī)地址
#--uri1 host1 測試URI
#--quiet 安靜模式
#--low_rate 測試時最低請求數(shù)(指 httperf)
#--hight_rate 測試時最高請求數(shù)
#--rate_step 每次測試請求數(shù)增加步長
#--num-call 每連接中發(fā)起聯(lián)接數(shù),一般是1
#--num_conn 測試聯(lián)接數(shù)
#--file 測試結(jié)果輸出的 tsv文件

autobench \
--single_host \
--host1=$DM \
--port1=80 \
--uri1=$URL \
--low_rate=5 \
--high_rate=200 \
--rate_step=20 \
--num_call=1 \
--num_conn=500 \
--timeout=10 \
--file ./$DM.tsv

2.22.4 xhprof:性能分析工具

xhprof是一個不錯的內(nèi)部性能分析工具,這里不過多的講述此工具的特點(diǎn)和使用,但會以對PhalApi進(jìn)行的一個性能測試展示它的分析效果。

(1)測試的接口服務(wù)

http://api.phalapi.com /demo/?service=Default.Index&username=test

(2)Overall Summary

Total Incl. Wall Time (microsec):     7,873 microsecs
Total Incl. CPU (microsecs):    7,999 microsecs
Total Incl. MemUse (bytes):    304,456 bytes
Total Incl. PeakMemUse (bytes):    306,616 bytes
Number of Function Calls:        338

(3)Top 10耗時

Function NameCallsCalls%Incl. Wall Time(microsec)IWall%(microsec)Excl. Wall TimeEWall%
PhalApi_Loader::loadClass103.00%3,02038.40%1,03813.20%
PhalApi_Loader::loadClass141.20%78510.00%3985.10%
run_init::Public/init.php10.30%3,91549.70%3274.20%
file_exists185.30%2493.20%2493.20%
main()10.30%7,873100.00%2483.20%
load::zh_cn/common.php20.60%2373.00%2373.00%
PhalApi_Loader::load92.70%3,38042.90%2262.90%
PhalApi_DI::get92.70%1,26816.10%2232.80%
PhalApi_Translator::addMessage20.60%5226.60%1361.70%
DI154.40%6458.20%1341.70%
class_exists113.30%1,38317.60%1301.70%
load::Config/sys.php10.30%1201.50%1201.50%

對應(yīng)的圖表如下:
a pic
從中可以看出,主要的耗時途徑在于文件的加載,下面將進(jìn)一步探討。

(4)Top 1耗時深入

a pic

所加載的文件如下:
a pic

2.22.5 Jenkis和Sonar:持續(xù)集成和靜態(tài)代碼分析

PhalApi從來不會隱藏自己的設(shè)計,當(dāng)然,我們也不會隱藏我們內(nèi)部的各個細(xì)節(jié)以及存在的問題。
但和其他隱藏了技術(shù)債務(wù)的框架相比,PhalApi敢于展示自己的靜態(tài)代碼分析報告,并且它也是做得相當(dāng)出色的。

以下截圖來自 GIT@OSC 上的靜態(tài)代碼分析: a pic

當(dāng)你的項(xiàng)目很重要時,也可以使用Jenkis或者Sonar進(jìn)行靜態(tài)代碼的分析。
不要個人主觀地覺得你的代碼風(fēng)格寫得好,而是交由專業(yè)的分析工具進(jìn)行解剖,并理解各個數(shù)據(jù)報表背后的含義,然后改進(jìn)之。

2.22.6 Git/SVN:更多的版本控制

2.22.7 WIKI:團(tuán)隊溝通與文檔交流

(1)markdown接口模板

#3.2 接口文檔模板
##1、功能說明
_請在這里放置簡短的接口功能說明。_  

##2、接口URL
/?service= _接口服務(wù)名稱_  + 公共參數(shù)(是否免登錄態(tài)?)

##3、接口參數(shù) [跳轉(zhuǎn)](http://demo.phalapi.com/demo/checkApiParams.php?service=) 

參數(shù)|必須|默認(rèn)值|說明
---|---|---|---
user_id|1||用戶id

##4、返回結(jié)果

###返回字段
參數(shù)|類型|說明
---|---|---
data.username|string|用戶名

###結(jié)果示例
{
    "ret": 200,
    "data": {
       ....  //更多結(jié)果的說明

        "msg": ""
    },
    "msg": ""
}

###請求示例
_請放置一個接口請求的鏈接。_

http://demo.phalapi.com/demo/?service=

2.22.8 靜態(tài)代碼分析工具 - phpmetrics

以下是針對本框架核心代碼所做的分析報告:

a pic
a pic

PS:從報告的評估可以看出,我們的框架明顯具有相當(dāng) 高的可維護(hù)性。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號