Heim Backend-Entwicklung PHP-Tutorial Analyse der Verarbeitungsschritte mit hoher Parallelität beim Lesen und Schreiben von PHP-Dateien

Analyse der Verarbeitungsschritte mit hoher Parallelität beim Lesen und Schreiben von PHP-Dateien

May 17, 2018 pm 01:49 PM
php 处理 操作步骤

Dieses Mal werde ich Ihnen eine Analyse der Betriebsschritte der hohen gleichzeitigen Verarbeitung von PHP-Lese- und Schreibdateien geben. Was sind die Vorsichtsmaßnahmen für die hohe Parallelität der Verarbeitung von PHP-Lese- und Schreibdateien? Das Folgende ist ein praktischer Fall.

Seit kurzem muss die Spieleentwicklung des Unternehmens die Abwanderungsrate beim Laden von Spielen kennen. Weil wir Webspiele machen. Jeder, der schon einmal Webspiele gespielt hat, weiß, dass man einige Ressourcen laden muss, bevor man mit dem Spiel beginnen kann. Schließlich gelangen Sie zur Spieloberfläche zum Erstellen eines Charakters. Eine unserer Anforderungen besteht darin, die Anzahl der Benutzer zu zählen, die verloren gehen, bevor während des Ladevorgangs die Benutzeroberfläche zur Charaktererstellung erreicht wird.

Wir zählen die Anzahl der Personen zu Beginn des Ladevorgangs und erfassen dann die Anzahl der Personen, nachdem der Ladevorgang abgeschlossen ist. Auf diese Weise wird die Anzahl der Personen nach erfolgreicher Verladung von der Anzahl der Personen vor der Verladung abgezogen. Kennen Sie einfach die Abwanderungsrate beim Laden. Sie können erkennen, ob das Spiel den Ladevorgang weiter optimieren und die Benutzerladerate des Spiels reduzieren muss.

Weil unser Traffic aus den meisten Mainstream-Kooperationsmedien importiert wird. Daher ist die Parallelität sehr hoch und sollte nach groben Berechnungen etwa 1.000 Parallelitäten pro Sekunde erreichen können.

Die Anzahl der Personen vor dem Laden sollte ursprünglich auf der Caching-Plattform im Spiel platziert werden. Die Kollegen im Spiele-Backend befürchten jedoch, dass die Parallelität zu hoch ist und unnötige Ressourcenverschwendung entsteht. Weil auf die Speicherfreigabe nicht in Echtzeit reagiert wird. Legen Sie daher die gezählte Personenzahl auf einen anderen Server: den Statistikserver.

Die Lösung, die ich gerade verwendet habe, ist wie folgt:

Durch PHPs <a href="http://www.php.cn/wiki/1311.html" target=" _blank">file_get_contents<p style="text-align: left;">()</p></a> und <a href="http://www.php.cn/wiki/1312.html" target="_blank">file_put_contents<code><a href="http://www.php.cn/wiki/1311.html" target="_blank">file_get_contents</a>()( ) Lesen und schreiben. Schreiben Sie beim ersten Lesen und Schreiben 1 in die Datei, fügen Sie beim zweiten Laden 1 zum Original hinzu und so weiter. Mit dieser Ideenfolge gibt es kein Problem. Das Problem liegt darin, dass unser Server nicht sequentiell sein kann. <a href="http://www.php.cn/wiki/1312.html" target="_blank">file_put_contents</a>()Um genau zu sein, ist der gleichzeitige Zugriff nicht sequentiell. Wenn Spieler A das Spiel lädt und die Zahl 100 in der Datei liest (vorausgesetzt, es ist zu diesem Zeitpunkt 100), liest Spieler B auch 100. Zu diesem Zeitpunkt addiert der Thread verarbeitende Spieler A 1 zu 100, um 101 zu erhalten. wird 101 schreiben zur Datei.

Der Thread-Verarbeitungsspieler B erhält ebenfalls das gleiche Ergebnis und schreibt 101 in die Datei. Zu diesem Zeitpunkt tritt das Problem auf? Spieler B hat das Spiel nach Spieler A geladen, daher sollte er ein Berechnungsergebnis von 102 erhalten.

Dies ist das Problem, das durch Parallelität verursacht wird. Zu diesem Zeitpunkt dachte ich darüber nach, die Datei mit

zu öffnen und mit fopen() eine Schreibsperre hinzuzufügen. Jeder wird definitiv denken, dass es keine Probleme verursachen wird, wenn diese Methode gesperrt ist. Tatsächlich ist es auch falsch. flock()

Weil unser Problem nicht das Schreiben ist. Stattdessen führt es dazu, dass die Daten beim Lesen nicht synchron sind. OK. Zum jetzigen Zeitpunkt komme ich mit Baidu und Google wirklich nicht klar.

Als meine Hoffnungen auf die PHP-Funktion selbst gesetzt waren und meine Träume zerplatzten, konnte ich nur einen anderen Weg finden. Raus damit. Also dachte ich an den Map-Mapping-Mechanismus der *-Sprache. Ähnlich wie bei unserem PHP-Array füge ich dem Array bei jedem Laden ein Element hinzu. Auf diese Weise muss ich am Ende nur

auf das Array klicken, um zu erfahren, wie viele Spieler das Spiel geladen haben. count()

Allerdings gibt es ein Problem bei der Verwendung von Arrays. Sogar

PHP-Variablen sind weiterhin Konstanten und werden nach der Ausführung des Skripts gelöscht. Also habe ich darüber nachgedacht, wie man Dateien speichert.

Die endgültige mögliche Lösung lautet wie folgt:

Verwenden Sie fopen, um eine Datei im schreibgeschützten Modus zu öffnen. Dann Schreibsperre. Jedes Mal, wenn ein Spieler lädt, schreibe ich eine Zahl 1 in die Datei. Der endgültige Dateiinhalt wird sofort über

ausgelesen und dann wird die Länge mit file_get_contents() berechnet, um zu erfahren, wie viele Spieler das Spiel geladen haben. strlen()

Ich habe gehört, dass die Funktion

gesperrt wird, was dazu führt, dass die Systemressourcen für lange Zeit ansteigen. Daher habe ich die von allen verwendete Methode übernommen und die Mikrosekunden-Timeout-Technologie verwendet, um dieses Problem zu lösen. Wenn ich aus dieser Zeit herauskomme, werde ich es wegwerfen. Der spezifische Code lautet wie folgt: flock()

// loadcount.func.php 函数文件。
/**
 * 获取某来源和某服务器ID的游戏加载次数。
 *
 * @param string $fromid 来源标识。
 * @param int $serverid 服务器ID编号。
 *
 * @return int
 */
function getLoadCount($fromid, $serverid)
{
    global $g_global;
    $serverid = (int) $serverid;
    $fromid  = md5($fromid);
    $filename = $fromid . $serverid . &#39;.txt&#39;;
    $data = file_get_contents($filename);
    return strlen($data);
}
/**
 * 获取某来源所有服务器的游戏加载次数。
 *
 * @param string $fromid 来源标识。
 *
 * @return int
 */
function getAllLoadCount($fromid)
{
    global $g_global;
    $fromid  = md5($fromid);
    $count = 0;
    foreach (glob("{$fromid}*.txt") as $filename)
    {
        $file_content = file_get_contents($filename);
        $count += strlen($file_content);
    }
    return $count;
}
/**
 * 清空所有的加载数据。
 *
 * @return void
 */
function clearLoadCount()
{
    foreach (glob("*.txt") as $filename) {
      unlink($filename);
    }
    return true;
}
/**
 * 延迟更新游戏加载次数中间件。
 *
 * 使用此函数来延迟更新数据,原理:当不足1000次的时候,不更新数据库,超过1000就更新到数据库里面去。
 *
 * @param string $fromid 来源标识。
 * @param int $serverid 服务器ID编号。
 */
function delayAddLoadCount($fromid, $serverid)
{
    // 使用MD5生成文件名记录缓存次数。
    $fromid  = md5($fromid);
    $filename = $fromid . $serverid . &#39;.txt&#39;;
    if($fp = fopen($filename, &#39;a&#39;))
    {
        $startTime = microtime();
        do {
            $canWrite = flock($fp, LOCK_EX);
            if(!$canWrite)
            {
                usleep(round(mt_rand(0, 100)*1000));
            }
        }
        while ( ( !$canWrite ) && ( ( microtime()- $startTime ) < 1000 ) );
        if ($canWrite)
        {
            fwrite($fp, "1");
        }
        fclose($fp);
    }
    return true;
}
Nach dem Login kopieren

Das Folgende ist die Datei, in der ich die obige Methode aufgerufen habe:

< ?php
/**
 * @describe 平台用户加载游戏次数统计接口入口。
 * @date 2012.12.17
 */
include_once &#39;./loadcount.func.php&#39;;
// 测试用。
// $_GET[&#39;fromid&#39;]  = &#39;4399&#39;;
// $_GET[&#39;serverid&#39;] = mt_rand(0, 5);
// 添加加载次数。
if ( $_GET[&#39;action&#39;] == &#39;addcount&#39; )
{
    $fromid  = $_GET[&#39;fromid&#39;];  // 来源标识。
    $serverid = $_GET[&#39;serverid&#39;]; // 服务器ID编号。
    $return = delayAddLoadCount($fromid, $serverid);
    $return = $return ? 1 : 0;
    ob_clean();
    echo json_encode($return);
    exit;
}
// 取加载次数。
elseif ( $_GET[&#39;action&#39;] == &#39;getcount&#39; )
{
    $fromid = $_GET[&#39;fromid&#39;];  // 来源标识。
    if ( !isset( $_GET[&#39;serverid&#39;] ) ) // 有服务器编号 ID则取来源对应的服务器加载次数。
    {
        $count = getAllLoadCount($fromid);
    }
    else // 加载对应来源的次数。
    {
        $serverid = $_GET[&#39;serverid&#39;]; // 服务器ID编号。
        $count = getLoadCount($fromid, $serverid);
    }
    ob_clean();
    header(&#39;Content-Type:text/html;charset=UTF-8&#39;);
    $serverid = strlen($serverid) ? $serverid : &#39;无&#39;;
    echo "来源:{$fromid},服务器ID:{$serverid},游戏加载次数:" . $count;
    exit;
}
// 清除加载次数。
elseif ( $_GET[&#39;action&#39;] == &#39;clearcount&#39; )
{
    header(&#39;Content-Type:text/html;charset=UTF-8&#39;);
    $return = clearLoadCount();
    if ($return)
    {
        echo "清除成功!";
    }
    else
    {
        echo "清除失败!";
    }
}
Nach dem Login kopieren

Das ist eine verdammte Lektion, also muss ich sie aufzeichnen. Damit andere in Zukunft daraus lernen können.

Bei diesem Artikel handelt es sich um den Code, den der Autor Han Bing vor einem Jahr geschrieben hat, als er bei 4399 Game Studio für die Datenanalyse verantwortlich war. Ich hoffe, es hilft allen.

PHP数据库操作之高并发实例

高并发下PHP写文件日志丢失

<?php
/**
 * Created by PhpStorm.
 * User: andyfeng
 * Date: 2015/6/24
 * Time: 13:31
 */
class LogFileUtil {
  public static $fileHandlerCache;
  private static $initFlag = false;
  private static $MAX_LOOP_COUNT = 3;
  private static function init() {
    self::$initFlag = true;
    register_shutdown_function(array("LogFileUtil", "shutdown_func"));
  }
  /**
   * 输出到文件日志
   * @param $filePath 文件路径
   * @param $msg 日志信息
   * @return int
   */
  public static function out($filePath, $msg) {
    if (!self::$initFlag) {
      self::init();
    }
    return self::internalOut($filePath, $msg);
  }
  /**
   * @param $filePath
   * @param $msg
   * @param $loop
   * @return int
   */
  private static function internalOut($filePath, $msg, $loop = 0) {
    //以防一直添加失败造成死循环
    if ($loop > self::$MAX_LOOP_COUNT) {
      $result = 0;
    } else {
      $loop++;
      $fp = self::$fileHandlerCache["$filePath"];
      if (empty($fp)) {
        $fp = fopen($filePath, "a+");
        self::$fileHandlerCache[$filePath] = $fp;
      }
      if (flock($fp, LOCK_EX)) {
        $result = fwrite($fp, $msg);
        flock($fp, LOCK_UN);
      } else {
        $result = self::internalOut($filePath, $msg, $loop);
      }
    }
    return $result;
  }
  function shutdown_func() {
    if (!empty(LogFileUtil::$fileHandlerCache)) {
      if (is_array(LogFileUtil::$fileHandlerCache)) {
        foreach (LogFileUtil::$fileHandlerCache as $k => $v) {
          if (is_resource($v))
            //file_put_contents("close.txt",$k);
            fclose($v);
        }
      }
    }
  }
}
Nach dem Login kopieren

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

PHP动态创建XML文档步骤详解

php怎样快速生成无限级分类(附代码)

Das obige ist der detaillierte Inhalt vonAnalyse der Verarbeitungsschritte mit hoher Parallelität beim Lesen und Schreiben von PHP-Dateien. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Wie man alles in Myrise freischaltet
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

PHP 8.4 Installations- und Upgrade-Anleitung für Ubuntu und Debian PHP 8.4 Installations- und Upgrade-Anleitung für Ubuntu und Debian Dec 24, 2024 pm 04:42 PM

PHP 8.4 bringt mehrere neue Funktionen, Sicherheitsverbesserungen und Leistungsverbesserungen mit einer beträchtlichen Menge an veralteten und entfernten Funktionen. In dieser Anleitung wird erklärt, wie Sie PHP 8.4 installieren oder auf PHP 8.4 auf Ubuntu, Debian oder deren Derivaten aktualisieren. Obwohl es möglich ist, PHP aus dem Quellcode zu kompilieren, ist die Installation aus einem APT-Repository wie unten erläutert oft schneller und sicherer, da diese Repositorys in Zukunft die neuesten Fehlerbehebungen und Sicherheitsupdates bereitstellen.

CakePHP Datum und Uhrzeit CakePHP Datum und Uhrzeit Sep 10, 2024 pm 05:27 PM

Um in cakephp4 mit Datum und Uhrzeit zu arbeiten, verwenden wir die verfügbare FrozenTime-Klasse.

Besprechen Sie CakePHP Besprechen Sie CakePHP Sep 10, 2024 pm 05:28 PM

CakePHP ist ein Open-Source-Framework für PHP. Es soll die Entwicklung, Bereitstellung und Wartung von Anwendungen erheblich vereinfachen. CakePHP basiert auf einer MVC-ähnlichen Architektur, die sowohl leistungsstark als auch leicht zu verstehen ist. Modelle, Ansichten und Controller gu

CakePHP-Datei hochladen CakePHP-Datei hochladen Sep 10, 2024 pm 05:27 PM

Um am Datei-Upload zu arbeiten, verwenden wir den Formular-Helfer. Hier ist ein Beispiel für den Datei-Upload.

CakePHP erstellt Validatoren CakePHP erstellt Validatoren Sep 10, 2024 pm 05:26 PM

Der Validator kann durch Hinzufügen der folgenden zwei Zeilen im Controller erstellt werden.

CakePHP-Protokollierung CakePHP-Protokollierung Sep 10, 2024 pm 05:26 PM

Die Anmeldung bei CakePHP ist eine sehr einfache Aufgabe. Sie müssen nur eine Funktion verwenden. Sie können Fehler, Ausnahmen, Benutzeraktivitäten und von Benutzern durchgeführte Aktionen für jeden Hintergrundprozess wie Cronjob protokollieren. Das Protokollieren von Daten in CakePHP ist einfach. Die Funktion log() wird bereitgestellt

So richten Sie Visual Studio-Code (VS-Code) für die PHP-Entwicklung ein So richten Sie Visual Studio-Code (VS-Code) für die PHP-Entwicklung ein Dec 20, 2024 am 11:31 AM

Visual Studio Code, auch bekannt als VS Code, ist ein kostenloser Quellcode-Editor – oder eine integrierte Entwicklungsumgebung (IDE) –, die für alle gängigen Betriebssysteme verfügbar ist. Mit einer großen Sammlung von Erweiterungen für viele Programmiersprachen kann VS Code c

CakePHP-Kurzanleitung CakePHP-Kurzanleitung Sep 10, 2024 pm 05:27 PM

CakePHP ist ein Open-Source-MVC-Framework. Es erleichtert die Entwicklung, Bereitstellung und Wartung von Anwendungen erheblich. CakePHP verfügt über eine Reihe von Bibliotheken, um die Überlastung der häufigsten Aufgaben zu reduzieren.

See all articles