php集成PHystrix

PHystrix 參照了 Netflix的項(xiàng)目 Hystrix。我們叫豪豬。豪豬的作用。

部署hystrix-dashboard界面工具。

作為一個(gè)壓根不懂java的程序員。跑java程序當(dāng)然不是難事。

打war包

wiki中有教你的。../gradlew jettyRun。但也許實(shí)際上會(huì)遇到一些問(wèn)題。比如,我用gradlew 會(huì)提示我下載安裝對(duì)應(yīng)的gradle。結(jié)果沒(méi)下載下來(lái)。尷尬啊。在了解了什么是gradlew(會(huì)指定對(duì)應(yīng)的版本)之后。我用brew intall gradle 下載了比較新的版本。然后直接用gradle jettyRun運(yùn)行。默認(rèn)是跑得 是 7979端口。不用打包就可以跑。

war包

gradle build 執(zhí)行。war包在 /hystrix-dashboard/build/libs 下

部署到tomcat下

下載一個(gè)tomcat。bin目錄下點(diǎn)擊運(yùn)行文件直接運(yùn)行(linux有start_up.sh)。這玩意兒比nginx簡(jiǎn)單。一個(gè)war包扔到 webapps目錄下就執(zhí)行了。

瀏覽器輸入:http://localhost:8080/hystrix-dashboard

PHystrix的準(zhǔn)備

需要準(zhǔn)備好 apc模塊。php7及以上安裝 apcu。

pecl 的方式安裝。

可以通過(guò)運(yùn)行 apc.php文件,看apc使用情況。

apc.png

具體的操作配置,看下面的參考。這里注意你的php版本。

參考鏈接: 《PHP之APC緩存詳細(xì)介紹http://www.cnblogs.com/Alight/archive/2013/06/06/3121000.html

phystrix-dashboard 代碼,為java的dashboard工具提供數(shù)據(jù)流

文檔中的代碼即可

$config = new Zend\Config\Config(array(/* ... */));
 $metricsPoller = new \Odesk\PhystrixDashboard\MetricsEventStream\ApcMetricsPoller($config);
 $metricsServer = new \Odesk\PhystrixDashboard\MetricsEventStream\MetricsServer($metricsPoller);
 $metricsServer->run();

我們創(chuàng)建一個(gè)控制器 叫做 DashBoard,寫(xiě)個(gè)方法叫Log。我們請(qǐng)求這個(gè)方法。

驚喜的發(fā)現(xiàn) 數(shù)據(jù)流出來(lái)了。 ok,我們打開(kāi)dashBoard的界面。然后,開(kāi)心的填入鏈接。添加監(jiān)聽(tīng)觀察。然后開(kāi)始不開(kāi)心了。

參考鏈接: https://github.com/upwork/phystrix-dashboard

PHP豪豬集成遇到的問(wèn)題。

不開(kāi)心的地方在于。dashboard 展示出現(xiàn)死循環(huán)。滿屏的 PhystrixCommand\UnReadCntCommand。愣是沒(méi)出現(xiàn)圖形的東東。看下圖。

死循環(huán).png

于是,開(kāi)始郁悶。為什么會(huì)出現(xiàn)死循環(huán)。我對(duì)比了別人寫(xiě)的demo。跑了下,沒(méi)有死循環(huán),顯示正常。我摘了端數(shù)據(jù)流。compare了下,感覺(jué)沒(méi)什么差異。那就奇怪了。既然數(shù)據(jù)格式一樣。問(wèn)題只能在js端排查。

于是開(kāi)始找循環(huán)的前端代碼。
hystrixCommand.js文件中搜self.eventSourceMessageListener,在這個(gè)方法中。獲取數(shù)據(jù)并解析。我對(duì)比了正常的data跟我的data。格式一樣。那么問(wèn)題。還不是出現(xiàn)數(shù)據(jù)結(jié)構(gòu)上。

那么開(kāi)始找展示的html(通過(guò)id搜索下)。中間展示圖形html代碼在hystrixCircuitContainer.html中。

<div class="monitor" id="CIRCUIT_<%= name + '_' + index %>" style="position:relative;">

發(fā)現(xiàn)界面死循環(huán),會(huì)產(chǎn)生多個(gè)相同的id值。那么我懷疑id是不起作用的,所以數(shù)據(jù)無(wú)法填充。導(dǎo)致圖形界面出不來(lái)。進(jìn)一步驗(yàn)證。$("#CIRCUIT_PhystrixCommand\UnReadCntCommand_0").length。打印出來(lái)是0 ,逆天了。

那么在js文件中,肯定有相關(guān)的操作。比如定位id填充數(shù)據(jù)的操作。于是,在hystrixCommand.js代碼中找到如下這個(gè)函數(shù)displayCircuit。這個(gè)函數(shù)中有對(duì)長(zhǎng)度進(jìn)行判斷,然后進(jìn)行相關(guān)的數(shù)據(jù)渲染操作。

if(!$('#CIRCUIT_' + data.escapedName).length) {
    // args for display
    if(self.args.includeDetailIcon != undefined && self.args.includeDetailIcon) {
        data.includeDetailIcon = true;
    }else {
        data.includeDetailIcon = false;
    }
    
    // it doesn't exist so add it
    var html = tmpl(hystrixTemplateCircuitContainer, data);
    console.log('#CIRCUIT_' + data.escapedName);
    console.log("3333333333330000");
    // remove the loading thing first
    $('#' + containerId + ' span.loading').remove();
    // now create the new data and add it
    $('#' + containerId + '').append(html);
    
    // add the default sparkline graph
    d3.selectAll('#graph_CIRCUIT_' + data.escapedName + ' svg').append("svg:path");
    
    // remember this is new so we can trigger a sort after setting data
    addNew = true;
}

既然發(fā)現(xiàn)問(wèn)題。如何解決。key中帶\所以id元素length為0。那么就在數(shù)據(jù)渲染之前,把escapedName中的\替換成空字符串。

找到了這個(gè)方法preProcessData(UI展示錢的數(shù)據(jù)處理),找到了如下代碼。

 data.escapedName = data.name.replace(/([ !"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g,'\\$1') + '_' + data.index;

于是在這行代碼上面加了一行 data.name = data.name.replace("\\", '');。問(wèn)題就這么解決了。

字符串替換.png

但,這樣結(jié)束真的好嗎?

我們?yōu)槭裁床辉趯?xiě)緩存的時(shí)候,用不帶\的Key呢?

在文件AbstractCommand中,有一個(gè)屬性 protected $commandKey。在我們的文件繼承中。我們?cè)O(shè)置這個(gè)屬性即可。我們?cè)陬?code>PhystrixCommand\UnReadCntCommand中。繼承這個(gè)屬性把key設(shè)置成UnReadCntCommand即可。

看來(lái)都是命名空間惹的禍。為什么存的key是命名空間的呢?那一定是調(diào)用的時(shí)候,內(nèi)部存到了APC里面。在文件AbstractCommand有這個(gè)代碼。代碼很容易明白,你不指定commandKey。那么通過(guò)class名字當(dāng)做key。于是,才有了命名空間的key。

    public function getCommandKey()
    {
        if ($this->commandKey) {
            return $this->commandKey;
        } else {
            // If the command key hasn't been defined in the class we use the current class name
            return get_class($this);
        }
    }
繼承屬性.png

參考資料:

Hystrix入門(mén)http://fobject.iteye.com/blog/2337582

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容