2017-01-07 108 views
0

我處於一種我無法下定決心的情況。我有一個客戶管理系統(Whmcs),我們公司用來出售虛擬主機,vps,...現在我正在編寫一個新的獨立客戶端界面,它使用WHMCS的API檢索客戶的詳細信息,發票,支持,門票和產品。所有其他邏輯發生在新應用程序(配置產品,支付發票,...)存儲API請求數據庫vs memcached

這些API請求發生在專用網絡上,速度在這裏不是問題。但是,我想將它們存儲在Memcached或單獨的數據庫中,以將這些請求減少到最低限度。

如果我使用數據庫,我會使用WHMCS將調用的某種webhook,例如,當用戶有新發票時。這將發送到webhook,並且數據庫只有在WHMCS中發生變化時纔會更新。我在這裏看到的唯一缺點是一些數據存在於兩個系統上,並且必須編寫大量事件和webhook才能實現。

另一種解決方案是使用我們的memcached集羣並在那裏存儲所需的API請求,如果用戶登錄,則需要的數據將返回並存儲在memcached中。這種方式只會有一個API請求,直到有些事情發生了變化。這種方式相對容易實現,例如:

public function getInvoices($status = null) 
    { 
     if (!Cache::has('invoices_' . $status . $this->id)){ 
      $data = $this->fetchInvoices($this->id, $status); 
      Cache::put('invoices_' . $status . $this->id, $data, 30); 
     } 

     $data = Cache::get('invoices_' . $status . $this->id); 

     //Check if user owns the invoices 
     if (Gate::denies('owns-data', $this->id)){ 
      abort(401); 
     } 

     return $data; 
    } 

對此,最佳方法是什麼?

回答

0

最終,我想出了一個解決方案。這個想法是將客戶數據和應用程序數據保存在不同的數據庫中。應用程序數據庫包含一些基本的用戶信息,博客文章,論壇數據......第二個數據庫是WHMCS數據庫本身,我提取所有發票,產品,支持票據所需的數據...

任何需要發送給WHMCS的更新(發票支付,產品升級......)通過API發生。這樣WHMCS就可以對輸入數據執行自己的邏輯。

我已經實現的第二部分是一個健壯的自定義緩存系統,它限制了對我們基礎設施進行的API查詢。 (Openstack,cPanel,...)這個想法非常簡單:應用程序的後端用__call方法偵聽包含在函數名稱中的創建,更新,讀取和刪除。

例如:

$data = array(
    'hostname' => $r['host'], 
    'username' => $r['username'], 
); 

Cpanel::listAddonDomain($data); 

這將列出所有的插件域用戶已添加到他們的cPanel託管帳戶。減少請求數量這需要緩存,直到用戶進行了更改或者他已經註銷爲止。

首先,有一些邏輯來檢查,如果用戶擁有的cPanel帳戶然後它分裂向上listAddondomains到一個數組,如果第一密鑰等於list, read or get得到的數據與定義該數據所屬的用戶標籤緩存到:

public function __call($name, $arguments) 
{ 
    // Check if the user owns the account 
    if(Gate::denies('owns-data', $this->search($this->getProducts(), 'username', $arguments['username'])[0]['clientid'])) 
    { 
     if ($request == 'api'){ 
      return Api::respondNotAllowed('Not Allowed!'); 
     } 

     abort(404); 
    } 

    $nameSplit = preg_split('/(?=\p{Lu})/u', $name); 

    // Check for arguments to flush the cache 
    if($nameSplit[0] == 'create' || $nameSplit[0] == 'delete' || $nameSplit[0] == 'add' || $nameSplit[0] == 'install') 
    { 
     Cache::tags(['cpanel', $arguments['username']]) 
      ->flush(); 
    } 

    // If is already present in cache 
    if(Cache::tags(['cpanel', $arguments['username']])->get($name . '_' . Auth::user()->id)) 
    { 
     return Cache::tags(['cpanel', $arguments['username']]) 
      ->get($name . '_' . Auth::user()->id); 
    } 

    // Do the query 
    try{ 

     $data = $this->send($arguments, $this->getClass($nameSplit), $name); 
     $response = Api::respondSuccess($data); 

    }catch (Exception $e){ 
     return Api::respondInternalError($e); 
    } 

    Cache::tags(['cpanel', $arguments['username']]) 
     ->put($name . '_' . Auth::user()->id, $response, $this->cacheTime); 

    return $response; 
} 

private function send($arguments, $className, $functionName) 
{ 
    $do = new $className($arguments); 
    return $do->$functionName(); 
} 

上面的代碼被降低到最低限度。張貼在這裏太長了,但你會得到這張照片。

現在怎麼樣在正確的時間清除緩存?假設用戶創建一個新的插件域,則需要清除現有的緩存。

$data = array(
    'hostname' => $r['host'], 
    'username' => $r['username'], 
    'domain' => $r['domain'] 
); 

Cpanel::createAddonDomain($data); 

$nameSplit = preg_split('/(?=\p{Lu})/u', 'createAddonDomain'); 

if($nameSplit[0] == 'create' || $nameSplit[0] == 'delete' || $nameSplit[0] == 'add' || $nameSplit[0] == 'install') 
{ 
    Cache::tags(['cpanel', $arguments['username']]) 
     ->flush(); 
} 

如果插件域創建成功,緩存將爲該cPanel帳戶刷新。

我已經測試了一個星期了,它的功能就像一個魅力。我已經看到啓用了緩存的頁面加載時間很長,並直接從WHMCS數據庫獲取數據。

下一站,將所有laravel視圖重寫爲獨立的Angular應用程序。

0

有趣的想法,以創建一個新的客戶端界面上WHMCS!

我不會走帶鉤子的第一條路線,並在兩個系統中有數據。感覺是遲早系統會出現同步,你不能相信數據庫中的數據。

在開始優化和緩存之前,您是否嘗試過將API始終用於「真相源」?每次需要數據時,即使您點擊API,您的應用程序也可能足夠快。

在這種情況下,您的應用程序將非常簡單,無需擔心緩存和無效緩存數據。例如,如果您將發票的信息緩存了30分鐘,會發生什麼情況。然後發票由WHMCS內部的管理員或系統自行更改。現在您的應用程序將在30分鐘內不同步,因爲它不知道發票已更改。

+0

上週我已經開始嘗試用新的客戶端界面直接掛接WHMCS數據庫。這很好用!然而,laravel應用程序不會寫入數據庫,只能讀取。這些查詢通過Cache :: remember()函數存儲在memcached中。所有寫入都通過WHMCS api發生,以便WHMCS可以處理所有寫入操作以避免衝突。 laravel應用程序擁有自己的數據庫,可與之交互以存儲基本用戶信息和所有論壇/社區數據。這種設置使我能夠快速工作,並擁有使用WHMCS之前所沒有的自由。 –