ホームページ >バックエンド開発 >PHPチュートリアル >PHP は同時実行性の問題を解決します

PHP は同時実行性の問題を解決します

伊谢尔伦
伊谢尔伦オリジナル
2017-01-24 13:09:5917157ブラウズ

通常、Web システムのスループット レートを測定する指標は QPS (Query Per Second、1 秒あたりに処理されるリクエストの数) です。この指標は、1 秒あたり数万回の同時実行性の高いシナリオを解決するために非常に重要です。たとえば、ビジネス リクエストを処理するための平均応答時間が 100 ミリ秒であると仮定します。同時に、システム内に 20 台の Apache Web サーバーがあり、MaxClients が 500 (Apache 接続の最大数を示す) に設定されているとします。

すると、私たちのWebシステムの理論上のピークQPSは(理想的な計算方法):

20*500/0.1 = 100000 (100,000 QPS)

え?私たちのシステムは非常に強力なようで、1 秒間に 100,000 件のリクエストを処理できます。5w/s のフラッシュセールは「紙の虎」のようです。もちろん、実際の状況はそれほど理想的ではありません。実際の同時実行性の高いシナリオでは、マシンは高負荷にさらされており、この時点で平均応答時間は大幅に増加します。

通常の p4 サーバーは、1 日あたり最大約 100,000 の IP をサポートできます。アクセス数が 10W を超える場合、問題を解決するには専用のサーバーが必要です。ハードウェアが強力でなければ、ソフトウェアがどんなに最適化されていても、問題は解決されません。役に立ちません。サーバーの速度に影響を与える主な要因は、ネットワーク - ハードディスクの読み取りおよび書き込み速度 - メモリ サイズ - CPU の処理速度です。

Web サーバーに関する限り、Apache が開く接続プロセスが増えるほど、CPU が処理する必要があるコンテキスト スイッチが増え、CPU 消費量が増加し、平均応答時間の増加に直接つながります。したがって、上記の MaxClient の数は、CPU やメモリなどのハードウェア要因に基づいて考慮する必要があります。多いほど良いというわけではありません。 Apache 独自のアベンチを通じてテストし、適切な値を取得できます。次に、メモリ操作レベルでのストレージとして Redis を選択します。同時実行性が高い状態では、ストレージの応答時間が重要になります。ネットワーク帯域幅も要因ですが、このような要求パケットは一般に比較的小さいため、要求のボトルネックになることはほとんどありません。負荷分散がシステムのボトルネックになることはほとんどないため、ここでは説明しません。

次に問題は、私たちのシステムが 5w/s の高い同時実行状態にあると仮定すると、平均応答時間が 100 ミリ秒から 250 ミリ秒に変化する (実際の状況ではさらに多くなります):

20*500/0.25 = 40000 (4) 10,000 QPS)

つまり、1 秒あたり 50,000 のリクエストに直面すると、システムには 40,000 QPS が残ることになります。その差は 10,000 QPS です。

例えば、高速道路の交差点では、1秒間に5台の車が行き来し、高速道路の交差点は通常通り動作します。突然、この交差点は1秒間に4台しか通過できなくなり、交通量は変わらないため、間違いなく渋滞が発生します。 (5レーンが突然4レーンになったような感じです)

同様に、ある秒間では20*500の利用可能な接続プロセスがフル稼働していますが、まだ10,000の新規リクエストがあり、利用可能な接続プロセスが存在しないことが予想されます。システムが異常な状態に陥ります。

PHP は同時実行性の問題を解決します 実際、同時実行性が高くない通常のビジネス シナリオでも、特定のビジネス リクエスト インターフェイスに問題があり、Web リクエスト全体の応答時間が非常に遅くなることがあります。が非常に長く、Web は徐々に減少し、サーバー上で使用可能な接続の数がいっぱいになり、他の通常のビジネス リクエストに使用できる接続プロセスがなくなりました。

さらに恐ろしい問題は、ユーザーの行動特性です。システムが利用できなくなると、ユーザーがクリックする頻度が高まり、最終的には「雪崩」が発生します (Web マシンの 1 つがハングアップし、トラフィックが停止します)。他の正常に動作しているマシンに分散され、通常のマシンもハングアップし、Web システム全体がダウンするという悪循環が発生します。

3. 再起動と過負荷保護

システムで「雪崩」が発生した場合、むやみにサービスを再起動しても問題は解決しません。最も多い現象は、起動してもすぐにハングアップしてしまうことです。現時点では、イングレス層でトラフィックを拒否してから再起動することをお勧めします。 redis/memcacheなどのサービスもダウンしている場合は、再起動時の「ウォームアップ」に注意が必要で、時間がかかる場合があります。

フラッシュ セールやラッシュ セールのシナリオでは、トラフィックがシステムの準備や想像を超えることがよくあります。このとき、過負荷保護が必要です。リクエストの拒否は、システムのフル負荷状態が検出された場合の保護手段でもあります。フロントエンドでフィルタリングを設定するのが最も簡単な方法ですが、このアプローチはユーザーから「批判」される動作です。より適切なのは、顧客からの直接リクエストを迅速に返すために、CGI エントリー層で過負荷保護を設定することです

高い同時実行下でのデータセキュリティ

複数のスレッドが同じファイルに書き込む場合、「スレッド」は「安全」として表示されることがわかっています。問題 (複数のスレッドが同じコード部分を同時に実行します。各実行の結果が単一スレッドの実行の結果と同じで、結果が期待どおりであれば、スレッドセーフです)。 MySQL データベースの場合は、独自のロック メカニズムを使用して問題を解決できます。ただし、大規模な同時実行シナリオでは、MySQL はお勧めできません。フラッシュ セールやラッシュ セールのシナリオでは、「過剰送信」という別の問題が発生します。この点を慎重に制御しないと、過剰な送信が発生します。一部の電子商取引会社では、購入者が写真撮影に成功した後、販売者が注文が有効であると認識せず、商品の配送を拒否する行為を行っていると聞いています。ここでの問題は、必ずしも販売業者が不正であるということではなく、システムの技術レベルでの過剰発行のリスクによって引き起こされる可能性があります。

1. 過剰な毛の成長の理由

ある急ぎ購入シナリオで、合計 100 個の製品しかなく、最後の瞬間に 99 個の製品を消費し、最後の 1 個だけが残ったとします。このとき、システムは複数のリクエストを同時に送信し、それらのリクエストによって読み取られた商品残高はすべて 99 であり、すべてがこの残高判定を通過し、最終的に過剰発行につながりました。 (記事内で前述したシーンと同じです)

PHP は同時実行性の問題を解決します

上の図では、同時ユーザー B も「購入に成功」し、さらに 1 人が商品を入手できるようになりました。このシナリオは、同時実行性が高い状況で非常に発生しやすくなります。

最適化計画 1: 在庫フィールド番号フィールドを unsigned に設定します。在庫が 0 の場合、フィールドは負の数値にすることができないため、false が返されます

<?php
//优化方案1:将库存字段number字段设为unsigned,当库存为0时,因为字段不能为负数,将会返回false
include(&#39;./mysql.php&#39;);
$username = &#39;wang&#39;.rand(0,1000);
//生成唯一订单
function build_order_no(){
  return date(&#39;ymd&#39;).substr(implode(NULL, array_map(&#39;ord&#39;, str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
}
//记录日志
function insertLog($event,$type=0,$username){
    global $conn;
    $sql="insert into ih_log(event,type,usernma)
    values(&#39;$event&#39;,&#39;$type&#39;,&#39;$username&#39;)";
    return mysqli_query($conn,$sql);
}
function insertOrder($order_sn,$user_id,$goods_id,$sku_id,$price,$username,$number)
{
      global $conn;
      $sql="insert into ih_order(order_sn,user_id,goods_id,sku_id,price,username,number)
      values(&#39;$order_sn&#39;,&#39;$user_id&#39;,&#39;$goods_id&#39;,&#39;$sku_id&#39;,&#39;$price&#39;,&#39;$username&#39;,&#39;$number&#39;)";
     return  mysqli_query($conn,$sql);
}
//模拟下单操作
//库存是否大于0
$sql="select number from ih_store where goods_id=&#39;$goods_id&#39; and sku_id=&#39;$sku_id&#39; ";
$rs=mysqli_query($conn,$sql);
$row = $rs->fetch_assoc();
  if($row[&#39;number&#39;]>0){//高并发下会导致超卖
      if($row[&#39;number&#39;]<$number){
        return insertLog(&#39;库存不够&#39;,3,$username);
      }
      $order_sn=build_order_no();
      //库存减少
      $sql="update ih_store set number=number-{$number} where sku_id=&#39;$sku_id&#39; and number>0";
      $store_rs=mysqli_query($conn,$sql);
      if($store_rs){
          //生成订单
          insertOrder($order_sn,$user_id,$goods_id,$sku_id,$price,$username,$number);
          insertLog(&#39;库存减少成功&#39;,1,$username);
      }else{
          insertLog(&#39;库存减少失败&#39;,2,$username);
      }
  }else{
      insertLog(&#39;库存不够&#39;,3,$username);
  }
?>

2。解決すべきアイデアはたくさんあります。スレッド セーフティ、から始めることができます。 「悲観的ロック」の方向性が議論され始めました。

悲観的ロック、つまり、データを変更するときに、外部リクエストからの変更を除外するためにロック状態が採用されます。ロック状態になった場合は、待機する必要があります。

PHP は同時実行性の問題を解決します上記の解決策はスレッドの安全性の問題を解決しますが、私たちのシナリオは「高い同時実行性」であることを忘れないでください。言い換えれば、そのような変更リクエストが多数あり、各リクエストは「ロック」を待つ必要があるため、一部のスレッドはこの「ロック」を取得する機会がなく、そのようなリクエストはそこで終了します。同時に、そのようなリクエストが多数発生し、システムの平均応答時間が即座に増加します。その結果、使用可能な接続の数が枯渇し、システムが例外に陥ります。

最適化計画 2: MySQL トランザクションを使用して操作の行をロックする

<?php
//优化方案2:使用MySQL的事务,锁住操作的行
include(&#39;./mysql.php&#39;);
//生成唯一订单号
function build_order_no(){
  return date(&#39;ymd&#39;).substr(implode(NULL, array_map(&#39;ord&#39;, str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
}
//记录日志
function insertLog($event,$type=0){
    global $conn;
    $sql="insert into ih_log(event,type)
    values(&#39;$event&#39;,&#39;$type&#39;)";
    mysqli_query($conn,$sql);
}
//模拟下单操作
//库存是否大于0
mysqli_query($conn,"BEGIN");  //开始事务
$sql="select number from ih_store where goods_id=&#39;$goods_id&#39; and sku_id=&#39;$sku_id&#39; FOR UPDATE";//此时这条记录被锁住,其它事务必须等待此次事务提交后才能执行
$rs=mysqli_query($conn,$sql);
$row=$rs->fetch_assoc();
if($row[&#39;number&#39;]>0){
    //生成订单
    $order_sn=build_order_no();
    $sql="insert into ih_order(order_sn,user_id,goods_id,sku_id,price)
    values(&#39;$order_sn&#39;,&#39;$user_id&#39;,&#39;$goods_id&#39;,&#39;$sku_id&#39;,&#39;$price&#39;)";
    $order_rs=mysqli_query($conn,$sql);
    //库存减少
    $sql="update ih_store set number=number-{$number} where sku_id=&#39;$sku_id&#39;";
    $store_rs=mysqli_query($conn,$sql);
    if($store_rs){
      echo &#39;库存减少成功&#39;;
        insertLog(&#39;库存减少成功&#39;);
        mysqli_query($conn,"COMMIT");//事务提交即解锁
    }else{
      echo &#39;库存减少失败&#39;;
        insertLog(&#39;库存减少失败&#39;);
    }
}else{
  echo &#39;库存不够&#39;;
    insertLog(&#39;库存不够&#39;);
    mysqli_query($conn,"ROLLBACK");
}
?>

3. FIFO キューのアイデア

それでは、上記のシナリオを少し変更して、リクエストをキューに直接入れ、FIFO (First Input First) を使用してみましょう。出力、先入れ先出し)、この場合、一部のリクエストがロックを取得しないことはありません。これを見ると、マルチスレッドを強制的にシングルスレッドにするような感じでしょうか?

PHP は同時実行性の問題を解決しますこれでロックの問題は解決され、すべてのリクエストは「先入れ先出し」キューで処理されます。さらに、同時実行性が高いシナリオでは、リクエストが多数あるため、キュー メモリが瞬時に「爆発」し、システムが再び異常状態に陥る可能性があります。または、巨大なメモリ キューを設計することも解決策です。ただし、システムがキュー内のリクエストを処理する速度は、キューへの異常な流入の数と比較することはできません。つまり、キュー内のリクエストの数はますます蓄積され、最終的には Web システムの平均応答時間は依然として大幅に低下し、システムは依然として例外に陥ってしまいます。

4. ファイルロックの考え方

1 日あたりの IP が高くない、または同時実行数がそれほど多くないアプリケーションの場合、通常、これを考慮する必要はありません。通常のファイル操作方法では全く問題ありません。しかし、同時実行性が高い場合、ファイルの読み書き時に複数のプロセスが次のファイルに対して動作する可能性が高く、その時点でファイルへのアクセスが排他的でない場合、データ損失が発生しやすくなります

。プラン 4: ノンブロッキング ファイル排他ロックを使用する

<?php
//优化方案4:使用非阻塞的文件排他锁
include (&#39;./mysql.php&#39;);
//生成唯一订单号
function build_order_no(){
  return date(&#39;ymd&#39;).substr(implode(NULL, array_map(&#39;ord&#39;, str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
}
//记录日志
function insertLog($event,$type=0){
    global $conn;
    $sql="insert into ih_log(event,type)
    values(&#39;$event&#39;,&#39;$type&#39;)";
    mysqli_query($conn,$sql);
}
$fp = fopen("lock.txt", "w+");
if(!flock($fp,LOCK_EX | LOCK_NB)){
    echo "系统繁忙,请稍后再试";
    return;
}
//下单
$sql="select number from ih_store where goods_id=&#39;$goods_id&#39; and sku_id=&#39;$sku_id&#39;";
$rs =  mysqli_query($conn,$sql);
$row = $rs->fetch_assoc();
if($row[&#39;number&#39;]>0){//库存是否大于0
    //模拟下单操作
    $order_sn=build_order_no();
    $sql="insert into ih_order(order_sn,user_id,goods_id,sku_id,price)
    values(&#39;$order_sn&#39;,&#39;$user_id&#39;,&#39;$goods_id&#39;,&#39;$sku_id&#39;,&#39;$price&#39;)";
    $order_rs =  mysqli_query($conn,$sql);
    //库存减少
    $sql="update ih_store set number=number-{$number} where sku_id=&#39;$sku_id&#39;";
    $store_rs =  mysqli_query($conn,$sql);
    if($store_rs){
      echo &#39;库存减少成功&#39;;
        insertLog(&#39;库存减少成功&#39;);
        flock($fp,LOCK_UN);//释放锁
    }else{
      echo &#39;库存减少失败&#39;;
        insertLog(&#39;库存减少失败&#39;);
    }
}else{
  echo &#39;库存不够&#39;;
    insertLog(&#39;库存不够&#39;);
}
fclose($fp);
 ?>

5. 楽観的ロックのアイデア

この時点で、「楽観的ロック」のアイデアについて議論できます。楽観的ロックは「悲観的ロック」に比べて緩いロック機構を採用しており、その多くはバージョンアップを利用します。実装では、このデータに対するすべてのリクエストが変更可能ですが、データのバージョン番号は一貫したバージョン番号を持つもののみが正常に取得され、その他のリクエストは失敗に返されます。この場合、キューの問題を考慮する必要はありませんが、CPU の計算オーバーヘッドが増加します。ただし、全体的には、これはより良い解決策です。

PHP は同時実行性の問題を解決します「楽観的ロック」機能をサポートするソフトウェアやサービスは数多くあり、Redis の watch もその 1 つです。この実装により、データのセキュリティが確保されます。

最適化プラン 5: Redis で見る

<?php
$redis = new redis();
 $result = $redis->connect(&#39;127.0.0.1&#39;, 6379);
 echo $mywatchkey = $redis->get("mywatchkey");
/*
  //插入抢购数据
 if($mywatchkey>0)
 {
     $redis->watch("mywatchkey");
  //启动一个新的事务。
    $redis->multi();
   $redis->set("mywatchkey",$mywatchkey-1);
   $result = $redis->exec();
   if($result) {
      $redis->hSet("watchkeylist","user_".mt_rand(1,99999),time());
      $watchkeylist = $redis->hGetAll("watchkeylist");
        echo "抢购成功!<br/>"; 
        $re = $mywatchkey - 1;   
        echo "剩余数量:".$re."<br/>";
        echo "用户列表:<pre class="brush:php;toolbar:false">";
        print_r($watchkeylist);
   }else{
      echo "手气不好,再抢购!";exit;
   }  
 }else{
     // $redis->hSet("watchkeylist","user_".mt_rand(1,99999),"12");
     //  $watchkeylist = $redis->hGetAll("watchkeylist");
        echo "fail!<br/>";    
        echo ".no result<br/>";
        echo "用户列表:<pre class="brush:php;toolbar:false">";
      //  var_dump($watchkeylist);  
 }*/
$rob_total = 100;   //抢购数量
if($mywatchkey<=$rob_total){
    $redis->watch("mywatchkey");
    $redis->multi(); //在当前连接上启动一个新的事务。
    //插入抢购数据
    $redis->set("mywatchkey",$mywatchkey+1);
    $rob_result = $redis->exec();
    if($rob_result){
         $redis->hSet("watchkeylist","user_".mt_rand(1, 9999),$mywatchkey);
        $mywatchlist = $redis->hGetAll("watchkeylist");
        echo "抢购成功!<br/>";
     
        echo "剩余数量:".($rob_total-$mywatchkey-1)."<br/>";
        echo "用户列表:<pre class="brush:php;toolbar:false">";
        var_dump($mywatchlist);
    }else{
          $redis->hSet("watchkeylist","user_".mt_rand(1, 9999),&#39;meiqiangdao&#39;);
        echo "手气不好,再抢购!";exit;
    }
}
?>

PHP は Web サイトのビッグデータ、大量のトラフィック、高い同時実行性の問題を解決します

まず最初に、データベースは適切な構造でなければなりません。頻繁なクエリには * を使用しないようにし、非順次アクセスを置き換えるにはソートを使用してください。条件が許せば、一般的には Linux オペレーティング システムに簡単にインストールできる MySQL サーバーが最適です。 Apache と nginx については、同時実行性が高い状況では nginx を使用することをお勧めします。Ginx は Apache サーバーの代替として適しています。 nginx はメモリ消費量が少なく、公式テストでは 50,000 の同時接続をサポートできますが、実際の運用環境では、同時接続の数は 20,000 ~ 30,000 に達する可能性があります。 PHP の不要なモジュールをできるだけ閉じて、memcached を使用します。Memcached は、データベースを使用せずにメモリから直接データを転送するため、速度が大幅に向上します。 . Web サイトを最適化し、Web サイトのコンテンツを圧縮して、Web サイトのトラフィックを大幅に節約します。 2 番目に、外部ホットリンクは禁止されています。 外部 Web サイトからの画像やファイルのホットリンクは、多くの場合負荷がかかるため、自分自身の画像やファイルへの外部ホットリンクは厳しく制限されるべきです。幸いなことに、現時点では、Apache を使用するだけでホットリンクを自動的に制御できます。 IIS には、同じ機能を実現できるサードパーティの ISAPI もいくつかあります。もちろん、偽の紹介を使用してコードを介してホットリンクを実現することもできますが、現時点では意図的に偽の紹介をホットリンクに設定する人は多くありません。今のところ無視することも、ウォーターマークを追加するなどの非技術的な手段を使用して解決することもできます。写真に。

3 番目に、大きなファイルのダウンロードを制御します。

大きなファイルをダウンロードすると大量のトラフィックが消費され、非 SCSI ハードドライブの場合、大量のファイルをダウンロードすると

CPU が消費され、ウェブサイトの応答性が低下します。したがって、2M を超える大きなファイルのダウンロードは提供しないようにしてください。提供する必要がある場合は、別のサーバーに大きなファイルを配置することをお勧めします。

4 番目に、メインのトラフィックを迂回するために別のホストを使用します

ファイルを別のホストに配置し、ユーザーがダウンロードできるように別のイメージを提供します。たとえば、RSS ファイルが大量のトラフィックを消費していると感じる場合は、FeedBurner や FeedSky などのサービスを使用して、RSS 出力を他のホストに配置します。この方法では、他の人のアクセスによるトラフィックの圧力のほとんどが集中します。 FeedBurner のホストと RSS はあまり多くのリソースを占有しません

5 番目に、メインのトラフィックを迂回するために別のホストを使用します

ファイルを別のホストに配置し、ユーザーがダウンロードできるように別の画像を提供します。たとえば、RSS ファイルが大量のトラフィックを消費していると感じる場合は、FeedBurner や FeedSky などのサービスを使用して、RSS 出力を他のホストに配置します。この方法では、他の人のアクセスによるトラフィックの圧力のほとんどが集中します。 FeedBurner のホストと RSS は、あまり多くのリソースを占有しません。


6番目、トラフィック分析および統計ソフトウェアを使用します。
ウェブサイトにトラフィック分析と統計のソフトウェアをインストールすると、どこで大量のトラフィックが消費されているか、どのページを最適化する必要があるかがすぐにわかります。そのため、トラフィックの問題を解決するには、正確な統計分析が必要です。例: Google アナリティクス。

高同時実行性と高負荷の制約: ハードウェア、デプロイメント、オペレーティング システム、Web サーバー、PHP、MySQL、テスト

デプロイメント: サーバーの分離、データベース クラスターとライブラリ テーブルのハッシュ、ミラーリング、ロード バランシング

ロード バランシングの分類: 1 )、DNS ラウンド ロビン 2) プロキシ サーバーのロード バランシング 3) アドレス変換ゲートウェイのロード バランシング 4) NAT ロード バランシング 5) リバース プロキシ ロード バランシング 6) ハイブリッド ロード バランシング

導入計画 1:

適用範囲: 静的 Web サイトとアプリケーションコンテンツを本体とするシステム、より高いシステムセキュリティ要件が要求される Web サイトおよびアプリケーションシステム。


メインサーバー: メインサーバー

は、プログラムの主要な動作圧力を担い、Webサイトまたはアプリケーションシステムでの動的リクエストを処理します。

は、静的ページを複数の公開サーバーにプッシュします。

は、添付ファイルをファイルサーバーにプッシュします。

セキュリティ要件が高く、主に静的な Web サイトの場合、サーバーを内部ネットワークに配置して、外部ネットワークからのアクセスをブロックできます。

DB サーバー: データベース サーバー

はデータベースの読み取りと書き込みの負荷を負います。

はメイン サーバーとのデータ量の交換のみを行い、外部ネットワーク アクセスをブロックします。

ファイル/ビデオ サーバー: ファイル/ビデオ サーバー

システム内の大規模なシステム リソースと帯域幅リソースを占有するデータ ストリームを伝送します。

大規模な添付ファイルのストレージおよび読み取り/書き込みの倉庫として機能します。自動ビデオ処理機能が搭載されます。

公開サーバー グループ:

は静的ページの公開のみを担当し、Web リクエストの大部分を処理します。

は Nginx を通じて負荷分散デプロイメントを実行します。

導入計画 2:

適用範囲: 動的インタラクティブ コンテンツを主体とする Web サイトまたはアプリケーション システム、負荷が高く十分な予算がある Web サイトまたはアプリケーション システム

Web サーバー グループ:

所有者のない Web サービスこの関係は、並列冗長設計です。

フロントエンド負荷分散装置または Nginx リバース プロキシを通じて負荷分散を実現します。

専用のファイル サーバー/ビデオ サーバーを分割して、軽量バスと重量バスを効果的に分離します。 pass DEC すべてのデータベースを接続し、マスターとスレーブを同時に分割できます。

データベース サーバー グループ:

は比較的バランスのとれたデータベースの読み取りおよび書き込みの負荷に耐えます。

はデータベースの物理ファイルのマッピングを通じて複数のデータベースのデータ同期を実現します。

共有ディスク/ディスクアレイ

データ物理ファイルの統合読み取りおよび書き込みに使用されます

大規模な添付ファイルのストレージ倉庫に使用されます

独自の物理ディスクのバランスと冗長性により、システム全体の IO 効率とデータのセキュリティを確保します

機能ソリューションの概要:

フロントエンドの負荷分散、Web 負荷の合理的な分散

ファイル/ビデオ サーバーと通常の Web サーバーの分離による、軽いデータ フローと重いデータ フローの合理的な分散

データベース サーバー グループによる、データベース IO プレッシャーの合理的な分散

各 Web サーバーは通常、データベース サーバーに接続するだけで、DEC のハートビート検出によって自動的に冗長データベース サーバーに切り替わります

ディスク アレイの導入は、システムを大幅に改善するだけではありません。 IO 効率だけでなく、データのセキュリティも大幅に強化されます。

Web サーバー:

通常の状況では、Web サーバーのリソース使用量の大部分は、Apache によって生成される負荷です。同時接続数が多い場合には、Nginx が適切な代替手段となります。 Apacheサーバー。 Nginx (「エンジン x」) は、ロシアで作成された高性能 HTTP およびリバース プロキシ サーバーです。中国では、Sina、Sohu Pass、NetEase News、NetEase Blog、Kingsoft Xiaoyao.com、Kingsoft iPowerWord、Xiaonei.com、YUPOO Photo Album、Douban、Xunlei Kankan などの多くの Web サイトやチャネルが Nginx サーバーを使用しています。

Nginx の利点:

高い同時接続: 公式テストでは 50,000 の同時接続をサポートできますが、実際の運用環境では、同時接続の数は 20,000 ~ 30,000 に達します。

低メモリ消費量: 30,000 の同時接続の下で、10 個の Nginx プロセスが起動しても、メモリの消費量はわずか 150M (15M*10=150M) です。

組み込みのヘルスチェック機能: Nginx プロキシのバックエンドの Web サーバーがダウンしても、フロントエンドのアクセスは影響を受けません。

戦略: 古い Apache と比較して、リソース使用量が少なく、負荷容量が高い Web サーバーである Lighttpd と Nginx を選択します。

Mysql:

MySQL 自体は強力な負荷容量を備えています。MySQL の最適化には、最終的にはシステムの最適化についての十分な理解が必要となるため、非常に複雑なタスクです。データベース作業には、プログラム開発中に注意を払う必要があるインデックス作成やクエリ効率の向上などのソフトウェア開発テクニックに加えて、短期間のクエリ、読み取りと書き込みが大量に含まれ、主に MySQL の実行効率に影響を与えることは誰もが知っています。ハードウェア機能の観点からは、検索、ディスク IO レベル、CPU サイクル、メモリ帯域幅が影響します。

サーバー上のハードウェアとソフトウェアの条件に基づいてMySQlの最適化を実行します。 MySQL 最適化の中核はシステム リソースの割り当てにあります。これは、より多くのリソースを無制限に MySQL に割り当てることを意味するものではありません。 MySQL 設定ファイルには、最も注目すべきパラメーターがいくつか導入されています:

インデックス バッファーの長さを変更する (key_buffer)

テーブルの長さを変更する (read_buffer_size)

開いているテーブルの最大数を設定する (table_cache)

Right Set低速で長いクエリに対する時間制限 (long_query_time)

条件が許せば、一般に MySQL サーバーを FreeBSD ではなく Linux オペレーティング システムにインストールするのが最善です。
戦略: MySQL の最適化には、ビジネス システムのデータベース読み取りおよび書き込み特性とサーバー ハードウェア構成に基づいてさまざまな最適化計画を策定する必要があり、必要に応じて MySQL のマスター/スレーブ構造をデプロイできます。

PHP:

1. できるだけ少ないモジュールをロードします。

2. Windows プラットフォームの場合は、通常使用する Apache を置き換えて、アクセラレータをインストールします。 PHP コードのプリコンパイル結果とデータベース結果をキャッシュして、PHP コードの実行速度を向上させます)

eAccelerator、eAccelerator は、動的コンテンツを最適化してキャッシュし、PHP スクリプトのパフォーマンスを向上させ、PHP スクリプトをコンパイルできる無料のオープンソース PHP アクセラレータです。より高速になる この状態では、サーバーのオーバーヘッドがほぼ完全に排除されます。


Apc: Alternative PHP Cache (APC) は、無料で公開されている、PHP 用に最適化されたコード キャッシュです。これは、PHP 中間コードをキャッシュおよび最適化するための、無料でオープンかつ堅牢なフレームワークを提供するために使用されます。

memcache: Memcache は、Danga Interactive によって開発された高性能の分散メモリ オブジェクト キャッシング システムであり、データベースの負荷を軽減し、動的アプリケーションでのアクセス速度を向上させるために使用されます。主なメカニズムは、メモリ内に統合された巨大なハッシュ テーブルを維持することです。

Xcache: 中国人によって開発されたキャッシュです。戦略: PHP 用のアクセラレータをインストールします。

プロキシ サーバー (キャッシュ サーバー):

Squid Cache (略して Squid) は、人気のあるフリー ソフトウェア (GNU General Public License) プロキシ サーバーおよび Web キャッシュ サーバーです。 Squid は、Web サーバーのフロントエンド キャッシュ サーバーとして機能し、関連するリクエストをキャッシュして Web サーバーの速度を向上させることから、World Wide Web、ドメイン ネーム システム、およびグループのその他の Web 検索をキャッシュすることまで、幅広い用途に使用できます。ネットワーク リソースを共有し、トラフィックをフィルタリングしてネットワークを保護し、プロキシ ネットワークを介して LAN に接続します。 Squid は主に Unix ライクなシステム上で動作するように設計されています。

戦略: Squid リバース プロキシ サーバーをインストールすると、サーバーの効率が大幅に向上します。

ストレス テスト: ストレス テストは、すべての重要なソフトウェア テスト作業の一部である基本的な品質保証動作です。ストレス テストの基本的な考え方はシンプルです。通常の条件下で手動または自動テストを実行するのではなく、コンピューターの数が少ない、またはシステム リソースが不足している条件下でテストを実行します。通常、ストレス テストが行​​われるリソースには、内部メモリ、CPU 可用性、ディスク容量、ネットワーク帯域幅が含まれます。同時実行性は通常、ストレス テストに使用されます。
ストレス テスト ツール: Webbench、ApacheBench など。

脆弱性テスト: システムの脆弱性には主に、SQL インジェクションの脆弱性、XSS クロスサイト スクリプティング攻撃などが含まれます。セキュリティには、オペレーティング システムの脆弱性、mysql、Apache の脆弱性などのシステム ソフトウェアも含まれますが、これらは通常、アップグレードによって解決できます。

脆弱性テストツール: Acunetix Web Vulnerability Scanner

関連コンテンツが見つかりません。

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