ホームページ  >  記事  >  バックエンド開発  >  マルチレベル配信ドッキングサードパーティ API データ取得システムの最適化

マルチレベル配信ドッキングサードパーティ API データ取得システムの最適化

WBOY
WBOYオリジナル
2016-08-08 09:20:201293ブラウズ

最近、Youzan をベースにしたマルチレベルの配信管理システムに取り組んでいます。すべてのメンバーの店舗は Youzan モールにあり、パフォーマンスを取得するために Youzan の API を使用しています。しかし、Youzan は 1 つのレベルの配信しか提供していないため、このシステムを作成しました。ワークロードを軽減し、階層関係を明確にするために、データベースとテーブルを基本クラス、配布メンバー、ストアフロント、その他の継承テーブルにカプセル化する OOP 設計手法が採用されました。

ただし、販売レポートとディストリビュータをリストするときに重大なパフォーマンスの問題が発生しました。ディストリビュータのパフォーマンス報酬はその下位のディストリビュータにリンクされているため、データベースをカプセル化するときに、すべてのディストリビュータの結果を取得するために DFS トラバーサルが実行されました。ただし、売上レポートをリストする場合、DFS は PHP 言語に多くの時間を費やすため、ページを開くのに 10 秒以上かかるため、最初のステップとして DFS スイッチを設定して最適化します。データベースのカプセル化関数内:

これは Database クラスの部分的な実装であり、一部の機密データが隠されています。

<?php
namespace System;
require_once(&#39;KdtApiClient.php&#39;);
class Database
{
	const db_adr="";
	const db_usr="";
	const db_pwd="";
	const db_db="";
	public $member=array();
	public function init($dfs=true,$store=true)
	{
		$mysqli=new \mysqli(self::db_adr,self::db_usr,self::db_pwd,self::db_db);
		if($mysqli->connect_error) throw new Exception('Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error);
		$result=$mysqli->query("select `id` from member_new");
		$row=$result->fetch_array();		
		$i=0;
		while($row)
		{
			$this->member[$i]=new Member($row[0],$dfs,$store);
			$row=$result->fetch_array();
			$i++;
		}
		$mysqli->close();
	}
	static public function doQuery($string)
	{
		$mysqli=new \mysqli(self::db_adr,self::db_usr,self::db_pwd,self::db_db);
		if($mysqli->connect_error) throw new Exception('Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error);
		return $mysqli->query($string);
	}
	static public function querySell($start,$end)
        {}
}

メンバー クラスは Table から継承されます。

class Table
{
	public $data=array();
	protected $table_name;
	public function __construct($id)
	{
		$this->data['id']=$id;
		$mysqli=new \mysqli(Database::db_adr,Database::db_usr,Database::db_pwd,Database::db_db);
		if($mysqli->connect_error) throw new Exception('Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error);
		$result=$mysqli->query("select * from ".$this->table_name." where `id`=$id");
		$row=$result->fetch_assoc();
		$this->data=$row;
		$mysqli->close();
	}
	public function updateAll()				//Do NOT CHANGE ID!!!
	{
		reset($this->data);
		while($data=each($this->data))
		{
			$querystring="update ".$this->table_name." set `".$data[0]."`='$data[1]' where `id`='".$this->data['id']."'";
			Database::doQuery($querystring);
		}
		reset($this->data);
	}
	public function update($key)
	{
		$querystring="update ".$this->table_name." set `$key`='".$this->data[$key]."' where `id`='".$this->data['id']."'";
		Database::doQuery($querystring);
	}
	public function set($key,$data)		//recommended
	{
		$this->data[$key]=$data;
		$this->update($key);
	}
	public function get($key)				//recommended
	{
		return $this->data[$key];
	}

}

はテーブルの基本操作をカプセル化するため、以下のメンバー クラスのコンストラクターはスイッチ パラメーターを追加した後に DFS 関数を完了できます。場合によっては、DFS を使用せずに効率が大幅に向上します:

class Member extends Table
{
	protected $table_name="member_new";
	public $infer=array();
	public $store=array();
	public function __construct($id,$dfs=true,$store=true)
	{
		parent::__construct($id);
		$mysqli=new \mysqli(Database::db_adr,Database::db_usr,Database::db_pwd,Database::db_db);
		if($mysqli->connect_error) throw new Exception('Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error);
		if($dfs){
			$result=$mysqli->query("select `id` from ".$this->table_name." where `super`=".$this->data['id']);
			if($result){
				$row=$result->fetch_array();
				$i=0;
				while($row)
				{
					$this->infer[$i]=new Member($row[0]);
					$row=$result->fetch_array();
					$i++;
				}
			}
		}
		if($store)
		{
			$result=$mysqli->query("select `id` from store_new where `member`=".$this->data['id']);
			if($result){
				$row=$result->fetch_array();
				$i=0;
				while($row)
				{
					$this->store[$i]=new Store($row[0]);
					$row=$result->fetch_array();
					$i++;
				}
			}
		}
		$mysqli->close();
	}

(一部の機密機能は隠されています)

さらに、フロントエンドに応答する PHP スクリプトにキャッシュのサポートが追加されますAJAX は、Youzan の API 呼び出し速度が遅いため、ただし、この種の配信モールのデータはリアルタイム性の要件がそれほど高くないため、Youzan との通信による速度の低下を軽減するためにサーバー キャッシュが使用されます。ローカライズされたオブジェクトは、リモート データベースからの読み取り情報を置き換え、データベースへのクエリのコストも削減します。 Cache オブジェクトの実装は次のとおりで、オブジェクトのシリアル化コードをサーバー上にローカルに保存します。 AJAX 応答ページは、Cache クラスのフィードバックに基づいてローカル データを取得するか、サーバーの更新を要求するかを選択します。 ローカル データ:

<?php
	namespace System;
    class Cache
    {
        public function __construct()
        {
        }
        
        static public function readCache($string)
        {
			error_reporting(1);
            $file=fopen($string.".ser","r");
            if(!$file)return false;
            $ser=fread($file,filesize($string.".ser"));
            fclose($file);
            $array=array();
            $array=unserialize($ser);
            if(time()-$array[&#39;time&#39;]>3600*24)return false;
            return $array['data'];
        }

        static public function updateCache($string,$data)
        {
            $array=array();
            $array['time']=time();
            $array['data']=$data;
            $file=fopen($string.".ser","w");
            fwrite($file,serialize($array));
            fclose($file);
        }
    }

上記の最適化後、元々は約 15 秒だったページの応答時間は、約 0.5 秒になりました。



著作権声明: この記事はブロガーによるオリジナルの記事であり、ブロガーの許可なく複製することはできません。

上記では、サードパーティ API データ取得システムをドッキングしたマルチレベルのディストリビューションの最適化について、内容の側面も含めて紹介しました。PHP チュートリアルに興味のある友人の参考になれば幸いです。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。