目前核心框架單元測試的覆蓋率(高達(dá)90%以上!??!此處應(yīng)該有掌聲~):
注意,此測試截圖并不是最新的,但我們一直都在致力堅持單元測試。
這一點(diǎn),你可以在單元測試的代碼中找到證明。
無論如何,都應(yīng)該走自動化發(fā)布流程,避免人工地打包、上傳、解壓、改生產(chǎn)配置這些重復(fù)性的人工操作。
在自動化發(fā)布中,Phing是個不錯的嘗試。
以下是我某個項(xiàng)目中的使用配置,出于對項(xiàng)目的保護(hù),部分?jǐn)?shù)據(jù)已刪除,但仍然可以參考。
主要的操作有:
<?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>
主要操作:
<?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>
可以通過以下的腳本來進(jìn)行,使用示例:
$ ./autobench.sh
Usage: ./autobench.sh <host> <uri>
- ./autobench.sh www.baidu.com /index.php
參數(shù)可以自行調(diào)整。
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
#!/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
xhprof是一個不錯的內(nèi)部性能分析工具,這里不過多的講述此工具的特點(diǎn)和使用,但會以對PhalApi進(jìn)行的一個性能測試展示它的分析效果。
http://api.phalapi.com /demo/?service=Default.Index&username=test
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
Function Name | Calls | Calls% | Incl. Wall Time(microsec) | IWall%(microsec) | Excl. Wall Time | EWall% |
---|---|---|---|---|---|---|
PhalApi_Loader::loadClass | 10 | 3.00% | 3,020 | 38.40% | 1,038 | 13.20% |
PhalApi_Loader::loadClass1 | 4 | 1.20% | 785 | 10.00% | 398 | 5.10% |
run_init::Public/init.php | 1 | 0.30% | 3,915 | 49.70% | 327 | 4.20% |
file_exists | 18 | 5.30% | 249 | 3.20% | 249 | 3.20% |
main() | 1 | 0.30% | 7,873 | 100.00% | 248 | 3.20% |
load::zh_cn/common.php | 2 | 0.60% | 237 | 3.00% | 237 | 3.00% |
PhalApi_Loader::load | 9 | 2.70% | 3,380 | 42.90% | 226 | 2.90% |
PhalApi_DI::get | 9 | 2.70% | 1,268 | 16.10% | 223 | 2.80% |
PhalApi_Translator::addMessage | 2 | 0.60% | 522 | 6.60% | 136 | 1.70% |
DI | 15 | 4.40% | 645 | 8.20% | 134 | 1.70% |
class_exists | 11 | 3.30% | 1,383 | 17.60% | 130 | 1.70% |
load::Config/sys.php | 1 | 0.30% | 120 | 1.50% | 120 | 1.50% |
對應(yīng)的圖表如下:
從中可以看出,主要的耗時途徑在于文件的加載,下面將進(jìn)一步探討。
所加載的文件如下:
PhalApi從來不會隱藏自己的設(shè)計,當(dāng)然,我們也不會隱藏我們內(nèi)部的各個細(xì)節(jié)以及存在的問題。
但和其他隱藏了技術(shù)債務(wù)的框架相比,PhalApi敢于展示自己的靜態(tài)代碼分析報告,并且它也是做得相當(dāng)出色的。
以下截圖來自 GIT@OSC 上的靜態(tài)代碼分析:
當(dāng)你的項(xiàng)目很重要時,也可以使用Jenkis或者Sonar進(jìn)行靜態(tài)代碼的分析。
不要個人主觀地覺得你的代碼風(fēng)格寫得好,而是交由專業(yè)的分析工具進(jìn)行解剖,并理解各個數(shù)據(jù)報表背后的含義,然后改進(jìn)之。
#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=
以下是針對本框架核心代碼所做的分析報告:
PS:從報告的評估可以看出,我們的框架明顯具有相當(dāng) 高的可維護(hù)性。
更多建議: