Ankündigung

Einklappen
Keine Ankündigung bisher.

Downloadverbindungsanzahl geöffnet geschlossen stimmt nicht überrein

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Downloadverbindungsanzahl geöffnet geschlossen stimmt nicht überrein

    Hallo zusammen,

    Ich möchte die Anzahl der Verbindungen zu einem Download zählen.
    Das Problem ist nun, dass die Anzahl der geöffneten Verbindungen, laut DB, kleiner ist als die, der geschlossenen Verbindungen und ich habe ehrlich gesagt keine Ahnung woran das liegen kann.

    Jeder Download hat eine eindeutige ID um den Download in der Datenbank wiederfinden zu können.

    Um einen Download starten zu können, muss die /download.php?id=ID aufgerufen werden. Hier wird zuerst die Connection um eins nach oben gezählt.
    (Default-value = 0)
    PHP-Code:
    $connections intval($info['connection']) + 1;
    $success $mysqli->Update('download', array('connection' => $connections), array('id' => urlencode(ID))); 
    Ich bin der Ansicht das dies auch funktioniert, da mindestens eine offene Verbindung besteht.

    Vorher wird noch überprüft, ob die ID existiert und gleichzeitig die Anzahl der offenen Verbindungen aus der DB geholt. "connection" ist in der DB ein Feld vom Typ int.

    Um nun zu schauen ob die Verbindung geschlossen wurde, lasse ich per Crontab ein Script laufen, dass überprüft ob in der Access.log die /download.php?id=ID drinnen steht, wenn dies der Fall ist soll die Anzahl der Verbindungen in der DB um 1 hochgezählt werden.
    PHP-Code:
    foreach($lines as $line_num => $line){
    $arr getArrayFromString($line);
            
    // Überprüfe ob download_start aufgerufen wurde
            
    if(preg_match('/download.php/'$arr['request_uri'])){
                
    $query parse_url($line);
                
    // _ entfernen, stammt von parse_url
                // 0 key, 1 value
                
    $id explode("="preg_replace("/_/"""$query['query']));
                
                
    // Überprüfe ob key vorhanden
                
    $exist $mysqli->Select('download', array('id' => $id[1]), true);
                
                if(
    $mysqli->affected==1){
                    
    // Downloadid existiert
                    
    $closedConnections intval($exist['closedconnections']) + 1;
                    
    $mysqli->Update('download', array('closedconnections' => $closedConnections), array('id' => $id[1]));
                }

    Syntax von Update: Update("table", SetArray, WhereArray);
    Ich kopiere vorher den gesamten Inhalt der access.log in eine tmp-file und leere die access.log, damit sich die access.log bereits füllen kann, wenn das Script die tmpfile noch bearbeitet.

    Nun ist es aber oft der Fall, dass die Anzahl der geschlossenen in der Datenbank höher sind, als die der geöffneten Verbindungen und ich habe ehrlich gesagt keine Ahnung woran das liegen kann.
    Es muss ja jedes mal die /download.php aufgerufen werden bevor die Datei geladen wird, und sich somit die Zugriffe in der access.log mit den tatsächlichen decken müssten, oder irre ich mich in dem Punkt?

    Hoffe ihr könnt mir helfen, stehe wirklich auf dem Schlauch :/

    Gruß
    prophet


  • #2
    Wann reduzierst du die Anzahl der Connections in der DB denn wieder? Ich bin mir derzeit nicht so ganz sicher, dass dein Text inhaltlich wirklich Sinn ergibt.

    (Edit: Ah, einmal erhöhst du Connections und einmal closed Connections. Sorry, hatte ich übersehen.)

    Auf mich wirkt die Lösung zudem sehr umständlich. Du möchtest zählen, wie viele Downloads gerade aktiv sind?

    Vielleicht hilft das hier: http://stackoverflow.com/questions/2...er-download-it (Dann eben noch eine DB-Query machen, statt zu löschen.)

    Ich habe so was aber noch nie versucht.

    Kommentar


    • #3
      Ich verringere die Anzahl an geschlossenen Verbindungen nicht, ich zähle die geschlossenen Verbindungen hoch.
      Wenn die Zahl bei offenen und geschlossenen übereinstimmt, dann müsste der Download fertig ist.
      Für mich ergibt er Sinn, bin aber bemüht unklarheiten zu beseitigen

      Ist zwar ein Ansatz, aber hilft mir nicht konkret weiter, da es sein kann, dass das script hinter download.php schon beendet ist, bevor die Datei beim User angekommen ist.

      Kommentar


      • #4
        Um nun zu schauen ob die Verbindung geschlossen wurde, lasse ich per Crontab ein Script laufen, dass überprüft ob in der Access.log die /download.php?id=ID drinnen steht, wenn dies der Fall ist soll die Anzahl der Verbindungen in der DB um 1 hochgezählt werden.
        Vermutlich zählst du die Verbindungen nochmal mit, die bereits geschlossen waren und schon mal gezählt wurden... oder leerst du die Logdatei nach dem Zählen?
        Über 90% aller Gewaltverbrechen passieren innerhalb von 24 Stunden nach dem Konsum von Brot.

        Kommentar


        • #5
          Ich kopiere die access.log in eine tmp file, leere die access.log, lasse das script über die tmpfile laufen und leere im Anschluss die tmpfile.
          Also ja leere die Logdatei.

          Kommentar


          • #6
            Ganz blöd gefragt: Klappt das Leeren der Logdatei auch wirklich [und immer]?

            Log doch mal separat, welche ID's du aus der Logdatei verarbeitet hast, dazu erstell eine Sicherheitskopie der verarbeiteten Datei (Dateipfad ebenfalls ins separate Log schreiben).
            Über 90% aller Gewaltverbrechen passieren innerhalb von 24 Stunden nach dem Konsum von Brot.

            Kommentar


            • #7
              Das ist eine gute Frage!

              Ich mache es mit folgendem Befehl:
              PHP-Code:
              $tmpfile "/tmp/tmpfile";
              system("cat /dev/null > $tmpfile"); 
              Oder gibt es einen besseren hierfür?
              Aber an sich müsste es gehen, werde deine Idee aber mal umsetzen und schauen was dabei rauskommt!

              Kommentar


              • #8
                Das Logfile könnte durch den Webserverprozeß gesperrt sein... dann kannst du es nicht einfach so löschen oder speichern (dann müsste der Webserver erst angehalten werden)

                Du kannst es ja vielleicht nebenher beobachten, wenn du direkt per Konsole drankommt... Filegröße nach dem Löschen müsste ja auf 0 zurückgehen.
                Über 90% aller Gewaltverbrechen passieren innerhalb von 24 Stunden nach dem Konsum von Brot.

                Kommentar


                • #9
                  Das ist mir bewusst das ich diese nicht löschen kann, deswegen leere ich diese auch und kopiere den Inhalt vorher in eine extra Datei damit es da keine Probleme mit den Rechten gibt. Die Filegröße geht nach dem leeren auf 0 zurück.

                  Kommentar


                  • #10
                    Zitat von prophet Beitrag anzeigen
                    Das ist eine gute Frage!

                    Ich mache es mit folgendem Befehl:
                    PHP-Code:
                    $tmpfile "/tmp/tmpfile";
                    system("cat /dev/null > $tmpfile"); 
                    Wenn ich mich nicht täusche, löschst du damit dein temp file, aber nicht die access.log
                    Könnte es das sein?
                    Über 90% aller Gewaltverbrechen passieren innerhalb von 24 Stunden nach dem Konsum von Brot.

                    Kommentar


                    • #11
                      Deine Temp-Datei kannst du doch theoretisch via "unlink" löschen?
                      Das Apache-Logfile müsstest du mit folgendem Befehl leeren können auch während der Webserver läuft:
                      Code:
                      echo "" > /var/log/apache2/access.log
                      Gruß,
                      SebTM

                      Kommentar


                      • #12
                        Zu meinem Link aus #2 (http://stackoverflow.com/questions/2...er-download-it):

                        Zitat von prophet Beitrag anzeigen
                        Ist zwar ein Ansatz, aber hilft mir nicht konkret weiter, da es sein kann, dass das script hinter download.php schon beendet ist, bevor die Datei beim User angekommen ist.
                        Du hast aber gesehen, dass es in der verlinkten Frage darum geht, die Datei zu löschen, nachdem der Download beendet ist? Ich weiß nicht genau, wie exakt du jetzt „angekommen“ meinst, aber grundsätzlich wäre es halt keine gute Idee, die Datei zu löschen, bevor sie vollständig übertragen wurde. Das scheint also grundsätzlich zu funktionieren. Da hätte sich sonst sicher schon jemand bemerkbar beschwert.

                        Deine jetzige Vorgehensweise hat eben (selbst dann, wenn sie funktionieren würde) einige Nachteile. Hauptsächlich wird das Access-Log für andere Nutzung unbrauchbar, weil es ständig gelöscht wird. Das ist nicht unbedingt das, was man will.

                        Kommentar


                        • #13
                          @lstegelitz
                          Könnte es das sein?
                          Nein könnte nicht, da ja dann gar keine Einträge bearbeitet würden. Das ist nur um zu zeigen wie ich die tmpfile vor jedem Durchgang leere.

                          @SebTM
                          Ich möchte aber keine Datei löschen und das leeren klappt ohne Probleme.

                          @mermshaus
                          Du hast aber gesehen, dass es in der verlinkten Frage darum geht, die Datei zu löschen, nachdem der Download beendet ist? Ich weiß nicht genau, wie exakt du jetzt „angekommen“ meinst, [...]die Datei zu löschen, [...].
                          Ja das habe ich gesehen. Mit "angekommen" meine ich die Bytes die vom Webserver, in meinem Fall nginx, gesendet wurden. Dies überprüfe ich mit dem Parameter $bytes_sent in der access.log.
                          Wie kommt Ihr alle gerade auf die Idee das ich die geladene Datei löschen möchte? O.o Davon habe ich nie was geschrieben
                          Das scheint also grundsätzlich zu funktionieren.
                          An sich funktioniert es, nur sind aus irgendeinem, mir nicht ersichtlichen, Grund, die Anzahl der closedConnections höher als die der geöffneten.

                          Deine jetzige Vorgehensweise hat eben (selbst dann, wenn sie funktionieren würde) einige Nachteile. Hauptsächlich wird das Access-Log für andere Nutzung unbrauchbar, weil es ständig gelöscht wird. Das ist nicht unbedingt das, was man will.
                          Ich habe für diesen Zweck extra eine zweite Logfile mit einem anderen Format angelegt, damit der Hauptzweck der log-datei bestehen bleibt.
                          Was wäre denn eine bessere Vorgehensweise?

                          Kommentar


                          • #14
                            Das ist nur um zu zeigen wie ich die tmpfile vor jedem Durchgang leere.
                            Ich rede aber vom access.log!
                            Das hast du uns nämlich nicht gezeigt, es wäre aber elementar wichtig, damit dein Prozeß richtig arbeitet.

                            Wird das access.log geleert oder nicht?
                            Über 90% aller Gewaltverbrechen passieren innerhalb von 24 Stunden nach dem Konsum von Brot.

                            Kommentar


                            • #15
                              Das ist im wesentlichen das Script:
                              PHP-Code:
                              foreach($logfile as $log){
                                  
                              // In Tmp kopieren
                                  
                              system("cp $log $tmpfile;");
                                  
                              // logfile leeren
                                  
                              system("cat /dev/null > $log");
                                  
                              // Alle Einträge aus der datei holen
                                  
                              $lines file($tmpfile);
                                  
                              // Über alle Einträge iterieren
                                  
                              foreach($lines as $line_num => $line){
                                      
                              // Überprüfe ob download_start aufgerufen wurde
                                      
                              if(preg_match('/download.php/'$arr['request_uri'])){
                                          
                              $query parse_url($line);
                                          
                              // _ entfernen, stammt von parse_url
                                          // 0 key, 1 value
                                          
                              $id explode("="preg_replace("/_/"""$query['query']));
                                          
                                                      
                              // Hier connection um 1 hochstufen, wenn id gefunden wurde
                                      
                              }
                                  }
                                  
                              // Tmp File leeren
                                  
                              system("cat /dev/null > $tmpfile");

                              Ja die access.log wird geleert!

                              Kommentar

                              Lädt...
                              X