Hướng dẫn nâng cấp 1.5
Trước khi nâng cấp, vui lòng sao lưu và thực hiện lệnh sau:
composer require workerman/webman-framework ^1.5 -W && composer require webman/console ^1.2.12 && php webman install
Tính năng và thay đổi
Hỗ trợ workerman v5 coroutines
Lưu ý
workerman v5 yêu cầu PHP>=8.1
Lệnh nâng cấp workermancomposer require workerman/workerman ^5.0.0 -W
Fiber coroutines cần cài đặtcomposer require revolt/event-loop ^1.0.0
Ví dụ
Phản hồi trễ
<?php
namespace app\controller;
use support\Request;
use Workerman\Timer;
class TestController
{
public function index(Request $request)
{
// Ngủ 1.5 giây
Timer::sleep(1.5);
return $request->getRemoteIp();
}
}
Timer::sleep()
tương tự như hàm sleep()
có sẵn trong PHP, khác biệt là Timer::sleep()
không chặn tiến trình.
Gửi yêu cầu HTTP
Chú ý
Cần cài đặtcomposer require workerman/http-client ^2.0.0
<?php
namespace app\controller;
use support\Request;
use Workerman\Http\Client;
class TestController
{
public function index(Request $request)
{
static $client;
$client = $client ?: new Client();
$response = $client->get('http://example.com'); // Gửi yêu cầu bất đồng bộ ở dạng đồng bộ
return $response->getBody()->getContents();
}
}
Tương tự, yêu cầu $client->get()
là không chặn, điều này có thể được sử dụng để xử lý yêu cầu HTTP không chặn trong webman, nâng cao hiệu suất.
Xem thêm tại workerman/http-client
Thêm lớp support\Context
Lớp support\Context được sử dụng để lưu trữ dữ liệu liên quan đến yêu cầu; khi yêu cầu hoàn tất, dữ liệu ngữ cảnh tương ứng sẽ tự động xóa. Nghĩa là tuổi thọ của dữ liệu ngữ cảnh tuần tự với tuổi thọ của yêu cầu.
Ô nhiễm biến toàn cục
Môi trường coroutine cấm lưu trữ thông tin trạng thái liên quan đến yêu cầu trong biến toàn cục hoặc biến tĩnh, vì điều này có thể dẫn đến ô nhiễm biến toàn cục, ví dụ
<?php
namespace app\controller;
use support\Request;
use Workerman\Timer;
class TestController
{
protected static $name = '';
public function index(Request $request)
{
static::$name = $request->get('name');
Timer::sleep(5);
return static::$name;
}
}
Thiết lập số tiến trình là 1, khi chúng ta gửi liên tiếp hai yêu cầu
http://127.0.0.1:8787/test?name=lilei
http://127.0.0.1:8787/test?name=hanmeimei
Chúng ta mong đợi kết quả trả về từ hai yêu cầu lần lượt là lilei
và hanmeimei
, nhưng thực tế, cả hai kết quả đều là hanmeimei
.
Điều này xảy ra vì yêu cầu thứ hai ghi đè biến tĩnh $name
, khi yêu cầu đầu tiên kết thúc ngủ, biến tĩnh $name
đã trở thành hanmeimei
.
Cách làm đúng là sử dụng ngữ cảnh lưu trữ dữ liệu trạng thái yêu cầu
<?php
namespace app\controller;
use support\Request;
use support\Context;
use Workerman\Timer;
class TestController
{
public function index(Request $request)
{
Context::set('name', $request->get('name'));
Timer::sleep(5);
return Context::get('name');
}
}
Biến cục bộ không gây ô nhiễm dữ liệu
<?php
namespace app\controller;
use support\Request;
use support\Context;
use Workerman\Timer;
class TestController
{
public function index(Request $request)
{
$name = $request->get('name');
Timer::sleep(5);
return $name;
}
}
Vì $name
là biến cục bộ, các coroutine không thể truy cập vào biến cục bộ của coroutine khác, vì vậy sử dụng biến cục bộ là an toàn cho coroutine.
Về coroutine
Coroutine không phải là giải pháp tối ưu, sử dụng coroutine đồng nghĩa với việc cần chú ý đến vấn đề ô nhiễm biến toàn cục/biến tĩnh và cần thiết lập ngữ cảnh. Hơn nữa, gỡ lỗi trong môi trường coroutine phức tạp hơn so với lập trình chặn.
Lập trình chặn trong webman thực sự đủ nhanh, dựa trên dữ liệu kiểm tra từ techempower.com, trong vòng ba năm qua, hiệu suất xử lý cơ sở dữ liệu của webman vượt gấp đôi so với framework web go gin, echo, gần 40 lần so với framework truyền thống Laravel.
Khi cả cơ sở dữ liệu và redis đều nằm trong mạng nội bộ, lập trình chặn có thể thường cao hơn so với coroutine, điều này là do khi cơ sở dữ liệu, redis đủ nhanh, chi phí tạo, lên lịch và huỷ coroutine có thể lớn hơn chi phí chuyển đổi tiến trình. Do đó, việc triển khai coroutine không nhất thiết làm cho hiệu suất nổi bật.
Khi nào sử dụng coroutine
Khi doanh nghiệp có yêu cầu trả chậm, ví dụ như khi doanh nghiệp cần truy cập vào API bên thứ ba, có thể sử dụng workerman/http-client để gửi yêu cầu HTTP bất đồng bộ theo cách coroutine, nâng cao khả năng xử lý đồng thời của ứng dụng.