国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

PHPer的月工作總結之構建抽獎工具

W_BinaryTree / 3214人閱讀

摘要:這個月的計劃本來是對基礎的數(shù)據(jù)結構做一個沉淀,但是,但是,但是這個月的的狀態(tài)就是工作工作既然這樣就總結下這個月的工作吧。

前言

目標是每個月寫一篇文章,對從事編程開發(fā)的基礎知識做一個學習總結。這個月的計劃本來是對基礎的數(shù)據(jù)結構做一個沉淀,但是,但是,但是......這個月的的狀態(tài)就是工作工作...既然這樣就總結下這個月的工作吧。

工作內(nèi)容

促銷活動的抽獎工具,具備如下功能:

根據(jù)不同的訂單金額抽獎,可設置最高訂單金額限制

根據(jù)不同的抽獎次數(shù)抽獎,可設置積分消耗限制

根據(jù)不同的時間段抽獎,可設置積分消耗限制

建模

一看到上面的需求,很顯然的我們會想到策略模式,制定三種不同的策略實體類:

按訂單抽獎策略:LotteryOrderStrategy

按次數(shù)抽獎策略:LotteryTimesStrategy

時間段抽獎策略:LotteryTimeScopeStrategy

建立了具體的三個策略實體類之后,由于不同的抽獎策略其實有很多的相似行為,我們開始進行抽象,最后整個的抽獎行為如下:

活動參與條件驗證: check[抽象方法]

讀取規(guī)則信息: getRule[具體方法]

匹配符合的規(guī)則區(qū)間: getNodeByRule[抽象方法]

活動參與次數(shù)驗證: checkTimes[具體方法]

活動規(guī)則限制驗證: checkJoinLimit[抽象方法]

消費積分: consumePoints[抽象方法]

讀取該規(guī)則對應的所有獎品: getPrize[具體方法]

抽獎: draw[具體方法]

組裝獎品信息: packagePrizeInfo[具體方法]

接著,建立抽象類:LotteryAbstract。抽象完成以后:

相同的邏輯: 不同抽獎實體類直接繼承使用即可

不同的邏輯: 不同抽獎實體類具體實現(xiàn)即可

具體抽象類如下:

abstract class LotteryAbstract
{
    abstract protected function check();

    protected function getRule()
    {
        # code...
    }

    abstract protected function getNodeByRule();

    protected function checkTimes()
    {
        # code...
    }

    abstract protected function checkJoinLimit();

    abstract protected function consumePoints();

    protected function getPrize()
    {
        # code...
    }

    protected function draw()
    {
        # code...
    }

    protected function packagePrizeInfo()
    {
        # code...
    }
}

接著我們發(fā)現(xiàn)其實不同的抽獎策略的抽獎流程基本一致,這樣我們就聯(lián)想到了設計模式的“模板模式”,我們對抽象類做些小的調(diào)整,我們把抽獎的算法調(diào)用流程實現(xiàn)在抽象類中,最后抽象類就構成了一個抽獎類的模板。以后我們增加新的抽象方式,只需要實現(xiàn)抽獎模板的抽象方法即可,變更后的抽象類如下:

abstract class LotteryAbstract
{
    /**
     * 抽獎算法
     */
    public function run ()
    {
        $this->check();
        $this->getRule();
        $this->getNodeByRule();
        $this->checkTimes();
        $this->checkJoinLimit();
        $this->consumePoints();
        $this->getPrize();
        $this->draw();
        $this->packagePrizeInfo();
    }

    abstract protected function check();

    protected function getRule()
    {
        # code...
    }

    abstract protected function getNodeByRule();

    protected function checkTimes()
    {
        # code...
    }

    abstract protected function checkJoinLimit();

    abstract protected function consumePoints();

    protected function getPrize()
    {
        # code...
    }

    protected function draw()
    {
        # code...
    }

    protected function packagePrizeInfo()
    {
        # code...
    }
}
并發(fā)

建模完成后,還存一個并發(fā)的問題:并發(fā)下對獎品領取數(shù)量的變更問題。當然可能都會想到加鎖,讓并發(fā)的過程變成串行的過程,這樣就不會存在問題了。一是使用mysql的悲觀鎖(for update),但是考慮到這個去抽獎的過程有在類似秒殺的場景中使用,所以我就考慮用redis的悲觀鎖實現(xiàn),畢竟內(nèi)存的io性能比磁盤要高的多,所以開始的方案一如下:

redis悲觀鎖

本地ab -c 100 -n 1000 壓測正常。

然后上線就出問題了,順時redis大量的操作,遠遠的超過了以前的峰值。然后方案二出來了,搶不到鎖,睡5毫秒,降低搶鎖的頻率,方案如下:

偽代碼:

do {
    搶鎖...
    if (! 失敗) {
        usleep(5000);
    }
} while (! 失敗);

上面的方案有效的降低了峰值,但是又造成了499的請求,接著方案三出來了,具體方案如下:

由于redis是單線程的利用redis的decr自減,保證獎品庫存的準確性

活動開始前注入獎品庫存到redis

定時同步庫存到mysql(減少了直接從mysql中減少庫存的主庫壓力)

通過這個方案,redis,mysql主庫的壓力基本減輕。

問題

接著來說說這段時間工作中遇到的一些問題:

個人問題:

錯誤的使用redis的悲觀鎖,搶鎖失敗沒有進行睡眠,導致線上redis瞬時大量的操作(本地壓測未發(fā)現(xiàn)問題),后期會對這塊進行深度的研究

沒有從頭到尾認真的進行code review(項目開發(fā)時間過于緊急)

項目排期混亂:每年定期搞的活動,卻只預留了5天開發(fā)時間

接口文檔:老式的wiki文檔,沒有返回值的示例,沒有返回值的類型說明。增加了前后端開發(fā)成本,低效率。

前端依賴:前端重度的依賴后端數(shù)據(jù)進行調(diào)試

測試低效:純手工的測試,也缺乏對一些基礎工具的使用

低效的后臺項目項目代碼:基本不具備代碼復用能力的代碼,組織混亂

各個環(huán)境的使用:目前我們開發(fā)測試灰度環(huán)境,每次使用前都靠“吼”,經(jīng)常會出現(xiàn)代碼被別人覆蓋的問題

svn問題

同事本地代碼丟失

代碼發(fā)布的分支,發(fā)布通過合并trunk,導致線上緊急修復分支被阻塞

代碼發(fā)布的分支,經(jīng)常導致忘記合并回trunk

每次發(fā)布前需要到專門的線上代碼diff機器進行代碼diff

解決方案

提出了問題,當然得給出對應的解決方案:

個人問題:

繼續(xù)對基礎知識進行深度學習,目前對于nginx,linux,redis,mysql,mongo我都還需要大力的去學習。

有質(zhì)量的code review是必須的

項目排期混亂:對產(chǎn)品和上級反饋希望我們能從中挖掘出原因,避免和減少同樣的事情的發(fā)生

接口文檔:內(nèi)部推動試行api blueprint,和對snowboard,swagger等這樣工具的使用,目前從我做起。

前端依賴:推動前端同事自行打斷點調(diào)試和api mock

測試低效:推動至少目前對簡單代理工具的使用

低效的后臺項目項目代碼:有可能推動內(nèi)部使用yii2開發(fā)后臺,個人覺著開發(fā)后臺gii還是蠻有效率

各個環(huán)境的使用: 有空寫一個簡單的頁面,使用對應環(huán)境的機器checkbox選中即可,一目了然,完全避免以前的問題

svn問題

推動內(nèi)部轉(zhuǎn)向git

git stash 本地暫存未提交的代碼,從而避免丟代碼問題

緊急的修補分支,采用git workflow的熱補丁分之隨時上線即可

git workflow的工作流可以避免我們目前的使用svn代碼經(jīng)常忘記合并到trunk問題

git 本地diff分支代碼即可 提高了效率

經(jīng)驗

寫代碼前一定要盡可能的弄清楚要做什么

寫代碼前進行必要的抽象過程,這樣通常可以寫出易于閱讀和擴展的代碼(不過,脫離業(yè)務的代碼是耍流氓哦,哈哈~)

code review 必不可少,慢慢養(yǎng)成習慣吧,騷年們

壓測,對我們寫完的代碼進行壓測,簡單的可以使用ab,siege

項目完成后的總結和沉淀

文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/22882.html

相關文章

  • PHP相關

    摘要:的機器學習庫的機器學習庫,包括算法交叉驗證神經(jīng)網(wǎng)絡等內(nèi)容。在即將到來的大會上,她將和大家分享在機器學習領域的全新可能。入門總結入門相關,如安裝配置基本使用等。 基于 Swoole 開發(fā) PHP 擴展 Swoole-1.9.7 增加了一個新特性,可以基于 Swoole 使用 C++ 語言開發(fā)擴展模塊,在擴展模塊中可以注冊 PHP 內(nèi)置函數(shù)和類。現(xiàn)在可以基于 Swoole 來編寫 PHP ...

    lewinlee 評論0 收藏0
  • 八年phper的高級工程師面試

    摘要:它們的用處都是用來能讓數(shù)據(jù)正常插入到數(shù)據(jù)庫中,并防止注入,但是并不能做到防止注入。進來抽獎的用戶使用原子加鎖,實現(xiàn)抽獎次數(shù)自增,當抽獎次數(shù)到達時,返回不中獎。 轉(zhuǎn)載于:https://zhuanlan.zhihu.com/p/...答案并非標準,是作者經(jīng)驗之談,僅供參考 mysql_real_escape_string mysql_escape_string有什么本質(zhì)的區(qū)別,有什么用處...

    韓冰 評論0 收藏0
  • Javascript五十問——從源頭細說Webpack與Gulp

    摘要:前言與是目前圈子內(nèi)比較活躍的前端構建工具。對于初學者來說,對這二者往往容易認識不清,今天,就從事件的源頭,說清楚與。它可以將許多松散的模塊按照依賴和規(guī)則打包成符合生產(chǎn)環(huán)境部署的前端資源。打包后形成的文件出口。 前言:Webpack 與 gulp是目前圈子內(nèi)比較活躍的前端構建工具。網(wǎng)上有很多二者比較的文章,面試中也會經(jīng)常遇到gulp,Webpack的區(qū)別這樣的問題。對于初學者來說,對這二...

    lwx12525 評論0 收藏0
  • PHPer工作總結觀察者&裝飾器模式

    摘要:我們可以把取消發(fā)貨單和取消訂單看成一個被觀察或被訂閱的類實例的對象,一旦發(fā)生取消行為,我們立即通知各個觀察者做出相對應的行為。裝飾器模式裝飾器思想,不管以前業(yè)務邏輯,甚至不去讀,調(diào)用之前的接口裝飾上新的數(shù)據(jù),達到自己的目的。 前言 還是每月的目標至少寫一篇文章,一晃八月份就要過去了,這個月依然沒有什么產(chǎn)出,毫無疑問最近的狀態(tài)就是不停的工作,不停的加班。所以還是把最近工作進行一個總結,首...

    MadPecker 評論0 收藏0

發(fā)表評論

0條評論

W_BinaryTree

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<