Langsame Geschäftsverarbeitung
Manchmal müssen wir langsame Geschäftsprozesse bewältigen. Um zu vermeiden, dass langsame Geschäftsprozesse andere Anfrageverarbeitungen in webman beeinträchtigen, können je nach Situation unterschiedliche Verarbeitungslösungen eingesetzt werden.
Lösung 1: Verwendung von Nachrichten-Warteschlangen
Siehe Redis-Warteschlange Stomp-Warteschlange
Vorteile
Kann plötzliche Flut von Geschäftsverarbeitungsanfragen bewältigen
Nachteile
Ergebnisse können nicht direkt an den Client zurückgegeben werden. Wenn Ergebnisse übertragen werden müssen, ist die Zusammenarbeit mit anderen Diensten erforderlich, z. B. die Verwendung von webman/push zum Versenden der Verarbeitungsergebnisse.
Lösung 2: Hinzufügen eines neuen HTTP-Ports
Hinzufügen eines neuen HTTP-Ports zur Verarbeitung langsamer Anfragen. Diese langsamen Anfragen werden durch Zugriff auf diesen Port von einer bestimmten Gruppe von Prozessen verarbeitet, und die Ergebnisse werden nach der Verarbeitung direkt an den Client zurückgegeben.
Vorteile
Daten können direkt an den Client zurückgegeben werden
Nachteile
Kann plötzliche Flut von Anfragen nicht bewältigen
Implementierungsschritte
Fügen Sie die folgende Konfiguration in config/process.php hinzu.
return [
// ... Andere Konfigurationen sind hier ausgelassen ...
'task' => [
'handler' => \Webman\App::class,
'listen' => 'http://0.0.0.0:8686',
'count' => 8, // Anzahl der Prozesse
'user' => '',
'group' => '',
'reusePort' => true,
'constructor' => [
'requestClass' => \support\Request::class, // Einstellung der Request-Klasse
'logger' => \support\Log::channel('default'), // Logger-Instanz
'appPath' => app_path(), // Speicherort des App-Verzeichnisses
'publicPath' => public_path() // Speicherort des public-Verzeichnisses
]
]
];
So können langsame Schnittstellen über die Prozessgruppe unter http://127.0.0.1:8686/ laufen, ohne die Geschäftsverarbeitung anderer Prozesse zu beeinträchtigen.
Damit das Frontend den Portunterschied nicht bemerkt, können Sie in nginx einen Proxy zum Port 8686 hinzufügen. Wenn die Pfade der langsamen Schnittstellenanfragen alle mit /task beginnen, sieht die nginx-Konfiguration ähnlich wie folgt aus:
upstream webman {
server 127.0.0.1:8787;
keepalive 10240;
}
# Neuen 8686-Upstream hinzufügen
upstream task {
server 127.0.0.1:8686;
keepalive 10240;
}
server {
server_name webman.com;
listen 80;
access_log off;
root /path/webman/public;
# Anfragen, die mit /task beginnen, gehen an Port 8686; ändern Sie /task bei Bedarf in Ihr gewünschtes Präfix
location /task {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_pass http://task;
}
# Andere Anfragen gehen an den ursprünglichen Port 8787
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_set_header Connection "";
if (!-f $request_filename){
proxy_pass http://webman;
}
}
}
So wird beim Client-Zugriff auf domain.com/task/xxx die Anfrage über den separaten Port 8686 verarbeitet, ohne die Anfrageverarbeitung auf Port 8787 zu beeinträchtigen.
Lösung 3: Nutzung von HTTP Chunked für asynchrone segmentierte Datenubertragung
Vorteile
Daten können direkt an den Client zurückgegeben werden
Installation von workerman/http-client
composer require workerman/http-client
app/controller/IndexController.php
<?php
namespace app\controller;
use support\Request;
use support\Response;
use Workerman\Protocols\Http\Chunk;
class IndexController
{
public function index(Request $request)
{
$connection = $request->connection;
$http = new \Workerman\Http\Client();
$http->get('https://example.com/', function ($response) use ($connection) {
$connection->send(new Chunk($response->getBody()));
$connection->send(new Chunk('')); // Leeren Chunk senden, um Ende der Antwort zu signalisieren
});
// Zuerst HTTP-Header senden, Daten werden asynchron nachgeliefert
return response()->withHeaders([
"Transfer-Encoding" => "chunked",
]);
}
}
Hinweis
Dieses Beispiel verwendet denworkerman/http-client, um HTTP-Ergebnisse asynchron abzurufen und zurückzugeben. Sie können auch andere asynchrone Clients verwenden, z. B. AsyncTcpConnection.