1

私は独学のAS3/Flex / AIR開発者であり、オンラインFlexアプリからのリモートコンテンツ管理を使用して、AIR上で実行されるタッチスクリーンキオスクのシステムを構築しました。

サーバーサイドの作業を行うのはこれが初めてなので、必要に応じて質問を修正してください。

AIRアプリとFlexアプリの両方がmysqlデータベースに接続して、phpスクリプトとZendフレームワークを使用した簡単なCRUD操作を行います。キオスクは30秒ごとにサーバーを呼び出して更新します。

これらの単純なサーバー側のphpスクリプトはすべて、FlashBuilderのデータウィザードによって自動生成されました。簡単な調整(gateway.php、amf_config.ini、mysqli接続パラメーター)を実行し、すべてをクライアントのサーバーにデプロイしました。これは共有サーバータイプです。

これで、システムが機能します。しかし、それはゆっくりと動作します。それぞれの作成/読み取り/更新/削除操作は機能しますが、はるかに高速であるはずです。また、これらの操作はサーバーのCPUに大きな負荷をかけます。ホスティング担当者によると、このシステムは、サーバーのCPUパワーの40%を占めるphp-cgiプロセスを開きます。そうすることで、サーバー自体とそのサーバーでホストされている他のサイトの速度が低下します。

私の質問は次のとおりです。

まず第一に、そもそも問題がありますか、それともこのパフォーマンスはZendフレームワークから拡張されていますか?Flash Builderによって作成された自動生成されたスクリプトは、適切に作成されておらず、最適化できますか?この種のシステムは共有ホストサーバーにとどまることができますか?パフォーマンスを向上させるためにVPSサーバーに移行する必要がありますか?phpmyadminを使用してmysqlデータベースに作成したテーブルが最適に構築されていなかった場合、パフォーマンスにこの種の影響を与える可能性はありますか?

私はphpまたはmysqlを知りません。どんな種類の助けも大いに活用されるでしょう。

サール

FlashBuilderによって作成されたスクリプトは次のとおりです。何も追加していません。接続パラメーターを変更しただけです。

<?php

class KiosksService {

   var $username = "--------";
   var $password = "--------";
   var $server = "--------";
   var $port = "3306";
   var $databasename = "--------";
   var $tablename = "kiosks";

   var $connection;

   /**
    * The constructor initializes the connection to database. Everytime a request is 
    * received by Zend AMF, an instance of the service class is created and then the
    * requested method is invoked.
    */
   public function __construct() {
        $this->connection = mysqli_connect(
                          $this->server,  
                          $this->username,  
                          $this->password, 
                          $this->databasename,
                          $this->port
                       );

      $this->throwExceptionOnError($this->connection);
   }

   /**
    * Returns all the rows from the table.
    *
    * Add authroization or any logical checks for secure access to your data 
    *
    * @return array
    */
   public function getAllKiosks() {

      $stmt = mysqli_prepare($this->connection, "SELECT * FROM $this->tablename");      
      $this->throwExceptionOnError();

      mysqli_stmt_execute($stmt);
      $this->throwExceptionOnError();

      $rows = array();

      mysqli_stmt_bind_result($stmt, $row->KioskID, $row->Station, $row->Branch, $row->Chain, $row->Pingdate, $row->Layout, $row->Online, $row->Clips, $row->Extra);

       while (mysqli_stmt_fetch($stmt)) {
         $row->Pingdate = new DateTime($row->Pingdate);
         $rows[] = $row;
         $row = new stdClass();
         mysqli_stmt_bind_result($stmt, $row->KioskID, $row->Station, $row->Branch, $row->Chain, $row->Pingdate, $row->Layout, $row->Online, $row->Clips, $row->Extra);
       }

      mysqli_stmt_free_result($stmt);
       mysqli_close($this->connection);

       return $rows;
   }

   /**
    * Returns the item corresponding to the value specified for the primary key.
    *
    * Add authorization or any logical checks for secure access to your data 
    *
    * 
    * @return stdClass
    */
   public function getKiosksByID($itemID) {

      $stmt = mysqli_prepare($this->connection, "SELECT * FROM $this->tablename where KioskID=?");
      $this->throwExceptionOnError();

      mysqli_stmt_bind_param($stmt, 'i', $itemID);      
      $this->throwExceptionOnError();

      mysqli_stmt_execute($stmt);
      $this->throwExceptionOnError();

      mysqli_stmt_bind_result($stmt, $row->KioskID, $row->Station, $row->Branch, $row->Chain, $row->Pingdate, $row->Layout, $row->Online, $row->Clips, $row->Extra);

      if(mysqli_stmt_fetch($stmt)) {
         $row->Pingdate = new DateTime($row->Pingdate);
         return $row;
      } else {
         return null;
      }
   }

   /**
    * Returns the item corresponding to the value specified for the primary key.
    *
    * Add authorization or any logical checks for secure access to your data 
    *
    * 
    * @return stdClass
    */
   public function createKiosks($item) {

      $stmt = mysqli_prepare($this->connection, "INSERT INTO $this->tablename (Station, Branch, Chain, Pingdate, Layout, Online, Clips, Extra) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
      $this->throwExceptionOnError();

      mysqli_stmt_bind_param($stmt, 'sssssisi', $item->Station, $item->Branch, $item->Chain, $item->Pingdate->toString('YYYY-MM-dd HH:mm:ss'), $item->Layout, $item->Online, $item->Clips, $item->Extra);
      $this->throwExceptionOnError();

      mysqli_stmt_execute($stmt);      
      $this->throwExceptionOnError();

      $autoid = mysqli_stmt_insert_id($stmt);

      mysqli_stmt_free_result($stmt);      
      mysqli_close($this->connection);

      return $autoid;
   }

   /**
    * Updates the passed item in the table.
    *
    * Add authorization or any logical checks for secure access to your data 
    *
    * @param stdClass $item
    * @return void
    */
   public function updateKiosks($item) {

      $stmt = mysqli_prepare($this->connection, "UPDATE $this->tablename SET Station=?, Branch=?, Chain=?, Pingdate=?, Layout=?, Online=?, Clips=?, Extra=? WHERE KioskID=?");      
      $this->throwExceptionOnError();

      mysqli_stmt_bind_param($stmt, 'sssssisii', $item->Station, $item->Branch, $item->Chain, $item->Pingdate->toString('YYYY-MM-dd HH:mm:ss'), $item->Layout, $item->Online, $item->Clips, $item->Extra, $item->KioskID);      
      $this->throwExceptionOnError();

      mysqli_stmt_execute($stmt);      
      $this->throwExceptionOnError();

      mysqli_stmt_free_result($stmt);      
      mysqli_close($this->connection);
   }

   /**
    * Deletes the item corresponding to the passed primary key value from 
    * the table.
    *
    * Add authorization or any logical checks for secure access to your data 
    *
    * 
    * @return void
    */
   public function deleteKiosks($itemID) {

      $stmt = mysqli_prepare($this->connection, "DELETE FROM $this->tablename WHERE KioskID = ?");
      $this->throwExceptionOnError();

      mysqli_stmt_bind_param($stmt, 'i', $itemID);
      mysqli_stmt_execute($stmt);
      $this->throwExceptionOnError();

      mysqli_stmt_free_result($stmt);      
      mysqli_close($this->connection);
   }


   /**
    * Returns the number of rows in the table.
    *
    * Add authorization or any logical checks for secure access to your data 
    *
    * 
    */
   public function count() {
      $stmt = mysqli_prepare($this->connection, "SELECT COUNT(*) AS COUNT FROM $this->tablename");
      $this->throwExceptionOnError();

      mysqli_stmt_execute($stmt);
      $this->throwExceptionOnError();

      mysqli_stmt_bind_result($stmt, $rec_count);
      $this->throwExceptionOnError();

      mysqli_stmt_fetch($stmt);
      $this->throwExceptionOnError();

      mysqli_stmt_free_result($stmt);
      mysqli_close($this->connection);

      return $rec_count;
   }


   /**
    * Returns $numItems rows starting from the $startIndex row from the 
    * table.
    *
    * Add authorization or any logical checks for secure access to your data 
    *
    * 
    * 
    * @return array
    */
   public function getKiosks_paged($startIndex, $numItems) {

      $stmt = mysqli_prepare($this->connection, "SELECT * FROM $this->tablename LIMIT ?, ?");
      $this->throwExceptionOnError();

      mysqli_stmt_bind_param($stmt, 'ii', $startIndex, $numItems);
      mysqli_stmt_execute($stmt);
      $this->throwExceptionOnError();

      $rows = array();

      mysqli_stmt_bind_result($stmt, $row->KioskID, $row->Station, $row->Branch, $row->Chain, $row->Pingdate, $row->Layout, $row->Online, $row->Clips, $row->Extra);

       while (mysqli_stmt_fetch($stmt)) {
         $row->Pingdate = new DateTime($row->Pingdate);
         $rows[] = $row;
         $row = new stdClass();
         mysqli_stmt_bind_result($stmt, $row->KioskID, $row->Station, $row->Branch, $row->Chain, $row->Pingdate, $row->Layout, $row->Online, $row->Clips, $row->Extra);
       }

      mysqli_stmt_free_result($stmt);      
      mysqli_close($this->connection);

      return $rows;
   }


   /**
    * Utility function to throw an exception if an error occurs 
    * while running a mysql command.
    */
   private function throwExceptionOnError($link = null) {
      if($link == null) {
         $link = $this->connection;
      }
      if(mysqli_error($link)) {
         $msg = mysqli_errno($link) . ": " . mysqli_error($link);
         throw new Exception('MySQL Error - '. $msg);
      }      
   }
}

?>
4

2 に答える 2

0

Zend フレームワークではパフォーマンスが少し問題になる可能性がありますが、例には zend フレームワーク コードはありません。

このシステムは 6 つの php-cgi プロセスを開きます

操作ごとに?それはありそうもない。この主張を裏付けるために提供された証拠とともに、典型的なトランザクションを示すアクセス ログのサンプルを提供していただけると助かります。

CGI 経由で php を実行するのは、パフォーマンス (またはサーバー ルームの温度) を少しでも気にしている場合は、非常に悪い考えです。mod_php や php-fpm、さらには fcgi 経由の php とオペコード キャッシュを併用すると、実行時間が 75% 以上短縮されます。

コードを見ると、getKiosks_paged を除いて、明らかに悪い点はありません。明示的な ORDER BY なしで行範囲選択を行うのは非常にずさんです。

作成/読み取り/更新/削除の各操作は機能しますが、もっと高速にする必要があると思います

どれくらい速いですか?websrver でのリクエストの長さ、実行されるクエリは? 彼らはどのくらいかかりますか?データベースの構造はどのようなものですか? クエリの説明計画はどのように見えますか?

于 2012-12-28T14:59:11.613 に答える
0

Zend フレームワークは使用したことがないため、コメントできません。

CGI は、Fast CGI や、さらに良いことに、mod_php などよりも常に遅くなります。CGI を使用すると、インタープリターが開始されるたびに、スクリプトの完了後にすべてが破棄されます。

代わりに Fast CGI または PHP モジュールを使用すると、Web サーバー モジュールは、呼び出し間でデータベース接続などの状態を維持できます。

于 2012-12-28T14:59:57.600 に答える