การจัดการธุรกิจที่ช้า
บางครั้งเราจำเป็นต้องจัดการธุรกิจที่ช้า เพื่อหลีกเลี่ยงไม่ให้ธุรกิจที่ช้ากระทบต่อการจัดการคำขออื่น ๆ ของ webman ซึ่งธุรกิจเหล่านี้สามารถใช้วิธีการจัดการที่แตกต่างกันตามสถานการณ์
แผนการที่หนึ่ง ใช้ข้อความคิว
ข้อดี
สามารถรับมือกับคำขอการจัดการธุรกิจจำนวนมากอย่างรวดเร็ว
ข้อเสีย
ไม่สามารถส่งผลลัพธ์กลับไปยังไคลเอนต์ได้โดยตรง หากต้องการส่งผลลัพธ์จะต้องใช้บริการอื่นร่วม เช่น การใช้ webman/push เพื่อส่งผลลัพธ์การจัดการ
แผนการที่สอง เพิ่มพอร์ต HTTP
เพิ่มพอร์ต HTTP สำหรับจัดการคำขอที่ช้า คำขอที่ช้าจะเข้ามายังกลุ่มกระบวนการเฉพาะผ่านการเข้าถึงพอร์ตนี้ หลังจากที่จัดการเสร็จแล้วจะส่งผลลัพธ์กลับไปยังไคลเอนต์โดยตรง
ข้อดี
สามารถส่งข้อมูลกลับไปยังไคลเอนต์ได้โดยตรง
ข้อเสีย
ไม่สามารถรับมือกับคำขอจำนวนมหาศาลที่เกิดขึ้นอย่างกระทันหัน
ขั้นตอนการดำเนินการ
เพิ่มการตั้งค่าดังต่อไปนี้ใน config/process.php
return [
// ... การตั้งค่าอื่นถูกละเว้น ...
'task' => [
'handler' => \Webman\App::class,
'listen' => 'http://0.0.0.0:8686',
'count' => 8, // จำนวนกระบวนการ
'user' => '',
'group' => '',
'reusePort' => true,
'constructor' => [
'requestClass' => \support\Request::class, // การตั้งค่า request class
'logger' => \support\Log::channel('default'), // ตัวอย่างบันทึก
'appPath' => app_path(), // ตำแหน่งของโฟลเดอร์ app
'publicPath' => public_path() // ตำแหน่งของโฟลเดอร์ public
]
]
];
ด้วยวิธีนี้ อินเทอร์เฟซที่ช้าจะสามารถใช้กลุ่มกระบวนการที่ http://127.0.0.1:8686/
โดยไม่กระทบต่อการจัดการธุรกิจของกระบวนการอื่น
เพื่อให้ส่วนหน้ารู้สึกไม่แตกต่างในการเข้าถึงพอร์ต สามารถเพิ่มพร็อกซี่ไปยังพอร์ต 8686 ใน nginx สมมุติว่าคำขอสำหรับอินเทอร์เฟซที่ช้าทั้งหมดเริ่มต้นด้วย /tast
การตั้งค่า nginx ทั้งหมดจะมีลักษณะดังนี้:
upstream webman {
server 127.0.0.1:8787;
keepalive 10240;
}
# เพิ่ม upstream สำหรับ 8686
upstream task {
server 127.0.0.1:8686;
keepalive 10240;
}
server {
server_name webman.com;
listen 80;
access_log off;
root /path/webman/public;
# คำขอที่เริ่มต้นด้วย /tast จะไปที่พอร์ต 8686 โปรดเปลี่ยน /tast เป็นคำนำหน้าที่คุณต้องการตามสถานการณ์จริง
location /tast {
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;
}
# คำขออื่น ๆ จะไปที่พอร์ต 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;
}
}
}
เมื่อไคลเอนต์เข้าถึง โดเมน.com/tast/xxx
จะส่งไปยังพอร์ต 8686 โดยเฉพาะ โดยไม่กระทบต่อการจัดการคำขอที่พอร์ต 8787
แผนการที่สาม ใช้ http chunked ส่งข้อมูลแบบอะซิงโครนัสทีละส่วน
ข้อดี
สามารถส่งข้อมูลกลับไปยังไคลเอนต์ได้โดยตรง
ติดตั้ง 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('')); // ส่ง chunk ว่างเพื่อบ่งบอกว่าการตอบกลับสิ้นสุด
});
// ส่ง HTTP header ก่อน และส่งข้อมูลที่เหลือผ่านการส่งแบบอะซิงโครนัส
return response()->withHeaders([
"Transfer-Encoding" => "chunked",
]);
}
}
提示
ในตัวอย่างนี้ใช้workerman/http-client
สำหรับการดึงผลลัพธ์ HTTP แบบอะซิงโครนัสและส่งข้อมูลคืน นอกจากนี้ยังสามารถใช้ไคลเอนต์อะซิงโครนัสอื่น ๆ เช่น AsyncTcpConnection ได้ด้วย