2017-01-07 11 views
0

私は自分の心を補うことができない状況にあります。私はWebホスティング、vpsを販売するために当社が使用するクライアント管理システム(Whmcs)を持っています...現時点では、WHMCSのAPIを使用してクライアントの詳細、請求書、サポートを取得する新しいスタンドアロンクライアントインターフェイスを作成しています。チケットと商品。他のすべてのロジックは、これらのAPIリクエストは、プライベートネットワーク上で起こる、速度がここでの問題ではありませんAPIリクエストを保存するデータベースとmemcached

(請求書を払って、製品の設定、...)新しいアプリケーションで行われます。しかし、私はこれらの要求を最小限に抑えるためMemcachedまたは別のデータベースに格納したいと考えています。私は、データベースで作業する場合

、私は、ユーザーが新しい請求書を持っているときWHMCSは、例えば、場合呼び出すウェブフックのいくつかの種類で動作します。これはwebhookに送信され、データベースはWHMCSの何かが変更された場合にのみ更新されます。私がここで見ている唯一の欠点は、データの一部が2つのシステム上に存在し、これを達成するために多くのイベントとウェブフックが書き込まれなければならないことです。

他のソリューションは、私たちのmemcachedのクラスタを使用して、そこに必要なAPIリクエストを格納しているユーザがログインする場合、必要とされているデータは、memcachedの中に保存された後、返されます。この方法では、何かが変更されるまで1つの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

最終的に、私は解決策を考え出しました。この考え方は、顧客データとアプリケーションデータを別々のデータベースに保存することです。 Appデータベースには、基本的なユーザー情報、ブログ投稿、フォーラムデータなどが保存されています... 2番目のデータベースはWHMCSデータベースで、請求書、製品、サポートチケットなどの必要なデータをすべて取り出します。

Any WHMCS(請求書の支払い、製品のアップグレードなど)に送信する必要がある更新は、APIを通じて行われます。この方法では、WHMCSは入力データで独自のロジックを実行できます。私が実装した

第二部では、当社のインフラストラクチャに作られたAPIのクエリを制限堅牢、カスタム・キャッシング・システムです。 (Openstack、cPanel、...)アイデアはかなりシンプルです。アプリのバックエンドは、__callメソッドで関数名に含まれるCreate、Update、Read、Deleteを待ち受けます。例えば

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

Cpanel::listAddonDomain($data); 

これは、すべてのアドオンは、ユーザーがcPanelの中​​で自分のホスティングアカウントに追加したドメイン一覧表示されます。要求の量を減らすにはユーザーが変更を行ったり、ログアウトしたりするまでキャッシュする必要があります。

最初に、ユーザーがcPanelアカウントを所有しているかどうかをチェックし、listAddondomainsを配列に分割します。最初のキーがlist, read or getに等しい場合、データが属するユーザーを定義するタグでデータがキャッシュされます。 to:

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アカウントに対してキャッシュがフラッシュされます。

私は1週間これを試してきましたが、それは魅力的です。キャッシュを有効にしてWHMCSデータベースから直接データを取得すると、ページの読み込み時間が大幅に減ることがわかりました。

次のストップは、すべてのラーバルビューをスタンドアロンの角度アプリに書き換えます。

0

WHMCSの新しいクライアントインターフェイスontopを作成する興味深いアイデア!

フック付きの2つのシステムでデータを持つ最初のルートはありません。遅かれ早かれシステムが同期しなくなり、データベースのデータを信頼できなくなるという感覚があります。

最適化とキャッシングを開始する前に、「真実のソース」のAPIを常に使用してみましたか?データが必要なたびにAPIを使用しても、アプリケーションの処理速度は十分ですか?

この場合、アプリケーションは非常に単純になり、キャッシュデータのキャッシュと無効化について心配する必要はありません。たとえば、請求書の情報を30分間キャッシュしたとします。請求書は、WHMCS内の管理者または自己のシステムによって変更されます。請求書が変更されたことがわからないため、アプリケーションの同期が30分間に合うようになりました。

+0

先週、WHMCSデータベースに新しいクライアントインターフェイスを直接フックする方法を試しました。これは素晴らしい作品です!しかし、laravelアプリケーションはデータベースへの書き込みを行わず、読み込みのみを行います。これらのクエリはmem :: Cache :: remember()関数でmemcachedに格納されます。すべての書き込みは、WHMCSが競合を避けるためにすべての書き込みを処理できるように、WHMCS APIを介して行われます。 laravelアプリケーションには、基本的なユーザー情報とすべてのフォーラム/コミュニティのデータを格納するために対話する独自のデータベースがあります。この設定により、私は速く働くことができ、以前はWHMCSを使用していなかったすべての自由を持っています。 –

関連する問題