webman的request的一些问题

dgkerry

问题描述

我使用webman并开启协程(Workerman\Events\Swoole::class),使用1个进程跑,我在support\Request上加了一个getRequestId()和_requestId()的方法,这样每次请求进来,就可以生成一个对应的请求id(request_id),这样我可以在日志上查找关于某个请求(request_id)究竟发生了什么事情,然后我做了以下测试(写在后面),为何会有不同的结果?

support\Request代码

namespace support;

/**
 * Class Request
 * @package support
 */
class Request extends \Webman\Http\Request
{
    public function getRequestId(){
        if(!isset($this->data['request_id'])){
            $this->data['request_id']=self::_requestId();
        }
        return $this->data['request_id'];
    }
    private static function _requestId(){
        //这里生成固定格式的xxxx-xxxxxxxx-xxxx-xxxx字符串
        $characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $randomPart = '';
        $length = 20;
        for ($i = 0; $i < $length; $i++) {
            $randomPart .= $characters[rand(0, strlen($characters) - 1)];
        }
        $request_id = sprintf('%s-%s-%s-%s', 
            substr($randomPart, 0, 4), 
            substr($randomPart, 4, 8), 
            substr($randomPart, 12, 4), 
            substr($randomPart, 16, 4)
        );
        return $request_id;
    }
}

控制器代码

namespace app\controller;
use support\Log;
class IndexController{
    public function test(Request $request){
        $log = Log::channel('log2');
        $id = $request->get('id');
        $log->useLoggingLoopDetection(false);//取消日志深度检测
        sleep(3);
        $log->info($request->getRequestId().'请求进来['.$id.']');
        return json(array('ok5'));
        }
}

测试

1.1、通过网址方式刷新同一个url 10次(https://网址/test?id=0),log记录如下,对应的request_id全部都是同一个(A4YW-7LIEBMUC-NPPM-RY4V

[2025-03-05 11:31:30]log2.INFO: A4YW-7LIEBMUC-NPPM-RY4V请求进来[0]
[2025-03-05 11:31:37]log2.INFO: A4YW-7LIEBMUC-NPPM-RY4V请求进来[0]
[2025-03-05 11:43:24]log2.INFO: A4YW-7LIEBMUC-NPPM-RY4V请求进来[0]
[2025-03-05 11:43:25]log2.INFO: A4YW-7LIEBMUC-NPPM-RY4V请求进来[0]
[2025-03-05 11:43:26]log2.INFO: A4YW-7LIEBMUC-NPPM-RY4V请求进来[0]
[2025-03-05 11:43:27]log2.INFO: A4YW-7LIEBMUC-NPPM-RY4V请求进来[0]
[2025-03-05 11:43:27]log2.INFO: A4YW-7LIEBMUC-NPPM-RY4V请求进来[0]
[2025-03-05 11:43:28]log2.INFO: A4YW-7LIEBMUC-NPPM-RY4V请求进来[0]
[2025-03-05 11:43:28]log2.INFO: A4YW-7LIEBMUC-NPPM-RY4V请求进来[0]
[2025-03-05 11:43:28]log2.INFO: A4YW-7LIEBMUC-NPPM-RY4V请求进来[0]

(浏览器也没有说长连接)
截图
1.1、通过网址方式刷新同一个url,但不同的传参(https://网址/test?id=xxx) 10次(id=1~10),log记录如下,每一个请求的request_id都不一样

[2025-03-05 11:53:13]log2.INFO: VTJD-9Y534GN6-7970-LCB6请求进来[0]
[2025-03-05 11:54:18]log2.INFO: A4YW-7LIEBMUC-NPPM-RY4V请求进来[1]
[2025-03-05 11:54:21]log2.INFO: MFAC-HMRQUSA9-XMOR-HBFO请求进来[2]
[2025-03-05 11:55:05]log2.INFO: T95Q-12Q526TB-6P13-LM05请求进来[3]
[2025-03-05 11:55:11]log2.INFO: KU9G-3DMFRHSE-188W-Q27P请求进来[4]
[2025-03-05 11:55:13]log2.INFO: 6YP6-AYWWTF7J-DWD3-ZU1C请求进来[5]
[2025-03-05 11:55:16]log2.INFO: TLVQ-B9YEOCUK-L829-J8FL请求进来[6]
[2025-03-05 11:55:17]log2.INFO: AJVA-J0F9DAUT-W5Z3-PW0M请求进来[7]
[2025-03-05 11:55:19]log2.INFO: XM02-KIGW5L6E-AB9I-IN23请求进来[8]
[2025-03-05 11:55:22]log2.INFO: YQ7F-Y0ZRGNQQ-V05H-DR4B请求进来[8]
[2025-03-05 11:55:23]log2.INFO: 9FN1-64QRUGPY-U8OV-M2RU请求进来[9]
[2025-03-05 11:55:26]log2.INFO: DC6Y-K5WAXRFT-2F22-JMAY请求进来[10]

2、通过php的异步请求方式(GuzzleHttp\Client、GuzzleHttp\Promise)请求10次

[2025-03-05 11:47:01] log2.INFO: EH1E-ULZO34ZF-P0PK-Y484请求进来[1]
[2025-03-05 11:47:01] log2.INFO: GWC6-WX7IQOIW-7HAH-FN41请求进来[4]
[2025-03-05 11:47:01] log2.INFO: TSI6-YI5HDMFC-U34A-5DO9请求进来[3]
[2025-03-05 11:47:01] log2.INFO: 0OF3-NYRENBZM-IRP9-I8AA请求进来[2]
[2025-03-05 11:47:01] log2.INFO: V002-5QEY865H-D4EF-KRJW请求进来[5]
[2025-03-05 11:47:01] log2.INFO: SLM9-I8Y0B5GV-KN0J-QZCB请求进来[7]
[2025-03-05 11:47:01] log2.INFO: 2BQ7-HXZN2RBK-BERA-9ZRI请求进来[8]
[2025-03-05 11:47:01] log2.INFO: VOJG-4FWBYMD8-SGTH-VTWC请求进来[6]
[2025-03-05 11:47:01] log2.INFO: LQ2N-LL6YZJV4-VNQ4-EP1M请求进来[9]
[2025-03-05 11:47:01] log2.INFO: JPPW-CXY8O1ZU-HVTP-KCWN请求进来[0]
226 3 1
3个回答

用 $this->requestId 来记录 requestId,不要用 $this->data['request_id'])来记录。$this->data 不适合用来存储于请求相关的状态数据。

  • dgkerry 7天前

    你这个办法的确可行,谢谢啦

SillyDog

使用context也比较合适

  • walkor 7天前

    放context里就更好了,一个原则,请求相关的状态数据放到context里。

qq7467466

使用Context上下文获取就不会出问题

// 设置数据
Context::set('trace_id', 'XXXX-XXXX');
// 读取数据
Context::get('trace_id')
  • dgkerry 6天前

    这样写,可以在任意地方获取到吗?如在控制器下、实例某个类后在这个类的某个方法下

  • qq7467466 6天前

    在整个生命周期里面都是可以获取到的, trace_id一般都是在中间件设置的, 然后其他地方读取

×
🔝