exists() – 永夜 https://www.shuijingwanwq.com 没有不值得去解决的问题,也没有不值得去学习的技术! Fri, 17 May 2024 08:43:19 +0000 zh-Hans hourly 1 https://wordpress.org/?v=7.0 在 TortoiseGit 中拉取时,报错:error: some local refs could not be updated; try running ‘git remote prune origin’ to remove any old, conflicting branches https://www.shuijingwanwq.com/2024/05/17/8586/ https://www.shuijingwanwq.com/2024/05/17/8586/#respond Fri, 17 May 2024 08:42:46 +0000 https://www.shuijingwanwq.com/?p=8586 Post Views: 146 1、在 TortoiseGit 中拉取时,报错:error: some local refs could not be updated; try running ‘git remote prune origin’ to remove any old, conflicting branches。如图1
在 TortoiseGit 中拉取时,报错:error: some local refs could not be updated; try running 'git remote prune origin' to remove any old, conflicting branches。

图1



git.exe pull --progress -v --no-rebase "origin"
POST git-upload-pack (165 bytes)
From https://git.xxx.com/object/frontend
= [up to date]          develop                 -> origin/develop
= [up to date]          0.22.0-hotfix           -> origin/0.22.0-hotfix
= [up to date]          antd5                   -> origin/antd5
= [up to date]          hotfix/outbound-order   -> origin/hotfix/outbound-order
= [up to date]          master                  -> origin/master
= [up to date]          od/feat/batch-merge-order -> origin/od/feat/batch-merge-order
= [up to date]          od/feat/count           -> origin/od/feat/count
= [up to date]          od/feat/dispute         -> origin/od/feat/dispute
= [up to date]          od/feat/download-order  -> origin/od/feat/download-order
= [up to date]          od/feat/merge-order-optimize -> origin/od/feat/merge-order-optimize
= [up to date]          od/feat/return          -> origin/od/feat/return
= [up to date]          od/feat/status          -> origin/od/feat/status
= [up to date]          od/feat/warehouse-matching -> origin/od/feat/warehouse-matching
= [up to date]          opt/virtual-table       -> origin/opt/virtual-table
= [up to date]          pdc/feat/add-sort-field -> origin/pdc/feat/add-sort-field
= [up to date]          pdc/feat/image-center   -> origin/pdc/feat/image-center
= [up to date]          pdc/feat/sku-form       -> origin/pdc/feat/sku-form
= [up to date]          pdc/feat/spu-export     -> origin/pdc/feat/spu-export
= [up to date]          pdc/feat/track          -> origin/pdc/feat/track
= [up to date]          sc/1688-opt-test        -> origin/sc/1688-opt-test
= [up to date]          sc/appendix-upload      -> origin/sc/appendix-upload
= [up to date]          sc/feat/purchase-order-ui -> origin/sc/feat/purchase-order-ui
error: cannot lock ref 'refs/remotes/origin/sc/fix/to-be-merged-table-scroller': 'refs/remotes/origin/sc/fix' exists; cannot create 'refs/remotes/origin/sc/fix/to-be-merged-table-scroller'
! [new branch]          sc/fix/to-be-merged-table-scroller -> origin/sc/fix/to-be-merged-table-scroller  (unable to update local ref)
= [up to date]          sc/fixs                 -> origin/sc/fixs
= [up to date]          sc/manual-marking       -> origin/sc/manual-marking
= [up to date]          sc/old-out-of-stock     -> origin/sc/old-out-of-stock
= [up to date]          sc/purchase-list-opt    -> origin/sc/purchase-list-opt
= [up to date]          stage                   -> origin/stage
= [up to date]          test                    -> origin/test
= [up to date]          wh/feat/all-order-export -> origin/wh/feat/all-order-export
= [up to date]          wh/feat/deactivated-warehouse -> origin/wh/feat/deactivated-warehouse
= [up to date]          wh/feat/delivery        -> origin/wh/feat/delivery
= [up to date]          wh/feat/examine         -> origin/wh/feat/examine
= [up to date]          wh/feat/hot-outbound    -> origin/wh/feat/hot-outbound
= [up to date]          wh/feat/in-order        -> origin/wh/feat/in-order
= [up to date]          wh/feat/in-outbound-order-batch-add-custom-sku -> origin/wh/feat/in-outbound-order-batch-add-custom-sku
= [up to date]          wh/feat/modify-position-sku-custom-code -> origin/wh/feat/modify-position-sku-custom-code
= [up to date]          wh/feat/multi-position  -> origin/wh/feat/multi-position
= [up to date]          wh/feat/opt-log         -> origin/wh/feat/opt-log
= [up to date]          wh/feat/order-batch_no  -> origin/wh/feat/order-batch_no
= [up to date]          wh/feat/outbound-order-api -> origin/wh/feat/outbound-order-api
= [up to date]          wh/feat/quick-multi-class-outbound -> origin/wh/feat/quick-multi-class-outbound
= [up to date]          wh/feat/quick-outbound  -> origin/wh/feat/quick-outbound
= [up to date]          wh/feat/quick-single-deliver -> origin/wh/feat/quick-single-deliver
= [up to date]          wh/feat/storage-in-log-export -> origin/wh/feat/storage-in-log-export
= [up to date]          wh/feat/transfer-export -> origin/wh/feat/transfer-export
= [up to date]          wh/feat/transfer-import -> origin/wh/feat/transfer-import
= [up to date]          wh/feat/warehouse-order -> origin/wh/feat/warehouse-order
= [up to date]          wh/fix/custom-text-table -> origin/wh/fix/custom-text-table
= [up to date]          wh/fix/order-selected-keys -> origin/wh/fix/order-selected-keys
error: some local refs could not be updated; try running
'git remote prune origin' to remove any old, conflicting branches


git 未能顺利结束 (退出码 1) (5328 ms @ 2024/04/30 10:09:10)



2、仔细查看提示信息,发现存在:error: cannot lock ref ‘refs/remotes/origin/sc/fix/to-be-merged-table-scroller’: ‘refs/remotes/origin/sc/fix’ exists; cannot create ‘refs/remotes/origin/sc/fix/to-be-merged-table-scroller’ 。如图2
仔细查看提示信息,发现存在:error: cannot lock ref 'refs/remotes/origin/sc/fix/to-be-merged-table-scroller': 'refs/remotes/origin/sc/fix' exists; cannot create 'refs/remotes/origin/sc/fix/to-be-merged-table-scroller'

图2

3、参考:在 TortoiseGit 中拉取时,报错:error: cannot lock ref ‘refs/remotes/origin/sc/fix’: ‘refs/remotes/origin/sc/fix/to-be-merge-order’ exists; cannot create ‘refs/remotes/origin/sc/fix’ https://www.shuijingwanwq.com/2024/03/30/8496/ 。得以解决。 4、在 Git Bash 中执行命令:git update-ref -d refs/remotes/origin/sc/fix/to-be-merged-table-scroller。


Lenovo@DESKTOP-QLPK8QM MINGW64 /e/wwwroot/object (develop)
$ git update-ref -d refs/remotes/origin/sc/fix/to-be-merged-table-scroller
error: cannot lock ref 'refs/remotes/origin/sc/fix/to-be-merged-table-scroller': 'refs/remotes/origin/sc/fix' exists; cannot create 'refs/remotes/origin/sc/fix/to-be-merged-table-scroller'
Lenovo@DESKTOP-QLPK8QM MINGW64 /e/wwwroot/object (develop)
$ git update-ref -d refs/remotes/origin/sc/fix



5、再次在 TortoiseGit 中拉取,不再报错,拉取成功]]>
https://www.shuijingwanwq.com/2024/05/17/8586/feed/ 0
在 TortoiseGit 中拉取时,报错:error: cannot lock ref ‘refs/remotes/origin/sc/fix’: ‘refs/remotes/origin/sc/fix/to-be-merge-order’ exists; cannot create ‘refs/remotes/origin/sc/fix’ https://www.shuijingwanwq.com/2024/03/30/8496/ https://www.shuijingwanwq.com/2024/03/30/8496/#respond Sat, 30 Mar 2024 02:38:26 +0000 https://www.shuijingwanwq.com/?p=8496 Post Views: 94 1、在 TortoiseGit 中拉取时,报错:error: cannot lock ref ‘refs/remotes/origin/sc/fix’: ‘refs/remotes/origin/sc/fix/to-be-merge-order’ exists; cannot create ‘refs/remotes/origin/sc/fix’。如图1
在 TortoiseGit 中拉取时,报错:error: cannot lock ref 'refs/remotes/origin/sc/fix': 'refs/remotes/origin/sc/fix/to-be-merge-order' exists; cannot create 'refs/remotes/origin/sc/fix'

图1

2、参考:error: cannot lock ref.. ‘refs/tags’ exists; cannot create ‘refs/tags/  。 3、在 Git Bash 中执行命令:git update-ref -d refs/remotes/origin/sc/fix/to-be-merge-order。如图2
在 Git Bash 中执行命令:git update-ref -d refs/remotes/origin/sc/fix/to-be-merge-order

图2



Lenovo@DESKTOP-QLPK8QM MINGW64 /e/wwwroot/xxx-frontend (develop)
$ git update-ref -d refs/remotes/origin/sc/fix/to-be-merge-order


4、再次在 TortoiseGit 中拉取,不再报错,拉取成功。如图3
再次在 TortoiseGit 中拉取,不再报错,拉取成功

图3

]]>
https://www.shuijingwanwq.com/2024/03/30/8496/feed/ 0
在 Laravel 6、LightHouse 5、Module 中使用 @rules 指令时,应用 exists 规则时的本地化实现 https://www.shuijingwanwq.com/2022/04/29/6354/ https://www.shuijingwanwq.com/2022/04/29/6354/#respond Fri, 29 Apr 2022 01:12:38 +0000 https://www.shuijingwanwq.com/?p=6354 Post Views: 107 1、当语言区域为 en 时,当验证的参数不存在时,响应:The selected theme id is invalid.。如图1
当语言区域为 en 时,当验证的参数不存在时,响应:The selected theme id is invalid.

图1



{
  "errors": [
    {
      "message": "Validation failed for the field [onlineStoreThemeEditorSessionCreate].",
      "extensions": {
        "validation": {
          "themeId": [
            "The selected theme id is invalid."
          ]
        },
        "category": "validation"
      },
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "onlineStoreThemeEditorSessionCreate"
      ],
      "trace": ...
    }
  ],
  "data": {
    "onlineStoreThemeEditorSessionCreate": null
  }
}


2、当语言区域为 zh_CN 时,当验证的参数不存在时,响应:所选的theme id无效。预期为:所选的主题ID无效。如图2
当语言区域为 zh_CN 时,当验证的参数不存在时,响应:所选的theme id无效。预期为:所选的主题ID无效。

图2



{
  "errors": [
    {
      "message": "Validation failed for the field [onlineStoreThemeEditorSessionCreate].",
      "extensions": {
        "validation": {
          "themeId": [
            "所选的theme id无效。"
          ]
        },
        "category": "validation"
      },
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "onlineStoreThemeEditorSessionCreate"
      ],
      "trace": ...
    }
  ],
  "data": {
    "onlineStoreThemeEditorSessionCreate": null
  }
}


3、查看 GraphQL 代码实现,/Modules/ThemeStore/Resources/graphql/theme_editor.graphql


extend type Mutation {
    "创建主题编辑会话"
    onlineStoreThemeEditorSessionCreate(themeId: ID! @rules(apply: ["exists:theme_asset,theme_id"])): ThemeEditorSessionCreatePayload @field(resolver: "Modules\\ThemeStore\\Resolver\\ThemeEditor\\CreateThemeEditorSessionResolver")
}

type ThemeEditorSessionCreatePayload
{
    "会话"
    session: Session!
}




4、查看 语言文件 ,/Modules/ThemeStore/Resources/lang/zh_CN/validation.php,已经指定了 theme_id 的自定义属性名称,但是,并未生效
<pre class="wp-block-syntaxhighlighter-code">

<?php

return [

    'attributes' => [
        'theme_id' => '主题ID',
    ],
];


</pre>
5、即使将此配置放至语言文件 /resources/lang/zh_CN/validation.php 中,仍然未生效,响应:所选的theme_id无效。但是,其默认是使用的此语言文件的配置。将验证规则消息放在任何语言的 validation.php 中名为 attributes 的键中,验证消息的 :attribute 部分不会被翻译(模块上下文)。
<pre class="wp-block-syntaxhighlighter-code">

<?php

return [

	'exists' => '所选的:attribute无效。',

    'attributes' => [
        'theme_id' => '主题ID',
    ],
];


</pre>
6、在 Laravel v8.7.90、nwidart/laravel-modules 8.2.0 中,编辑 /resources/lang/zh_CN/validation.php ,attributes 会生效。


    /**
     * 显示创建博客文章的表单
     *
     * @return Response
     */
    public function create(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'theme_id' => 'required|exists:users,id',
        ]);

        if ($validator->fails()) {
            dd($validator->errors());
        }

        // 保存博客文章…

        return view('blog::post.create');
    }


<pre class="wp-block-syntaxhighlighter-code">

<?php
return [
    'exists' => '所选的:attribute无效。resources',

    'attributes' => [
        'theme_id' => '主题ID',
    ],
];


</pre>


Illuminate\Support\MessageBag {#361 ▼
  #messages: array:1 [▼
    "theme_id" => array:1 [▼
      0 => "所选的主题ID无效。resources"
    ]
  ]
  #format: ":message"
}


7、决定在当前版本:Laravel v6.20.43、nwidart/laravel-modules 7.3.0 中,模拟步骤6的实现。以确定是否与框架、模块包的版本有关,进而导致在应用的根目录中,attributes 不生效的问题。确定是无关的。那么原因在于 LightHouse 5。
<pre class="wp-block-syntaxhighlighter-code">

<?php
return [
    'array' => ':attribute必须是一个数组。',

    'attributes' => [
        'filter' => '过滤器'
    ],
];


</pre>


{
  "message": "The given data was invalid.",
  "errors": {
    "filter": [
      "过滤器必须是一个数组。"
    ]
  },
  "status_code": 422,
  "debug": {
    "line": 385,
    "file": "E:\\wwwroot\\object\\vendor\\laravel\\framework\\src\\Illuminate\\Validation\\Validator.php",
    "class": "Illuminate\\Validation\\ValidationException",
    "trace": ...
  }
}


8、参考:https://github.com/nuwave/lighthouse/issues/1773 ,虽然已经在 @rules 指令上实现了翻译功能,但是实现得不够彻底。即验证属性未支持。开发者建议:https://lighthouse-php.com/master/security/validation.html#validator-classes 。支持通过任意 PHP 代码定义规则。 9、暂时不准备编写一个自定义规则。决定在非英语环境下,属性名未翻译为对应的语言,暂且接受。且语言文件在根目录下,不在对应的模块目录下。  ]]>
https://www.shuijingwanwq.com/2022/04/29/6354/feed/ 0
在 Laravel 6、Module、Lighthouse 中实现 安全 验证 的流程(使用 @rules 指令,使用 Exists 规则) https://www.shuijingwanwq.com/2022/04/20/6312/ https://www.shuijingwanwq.com/2022/04/20/6312/#respond Wed, 20 Apr 2022 01:10:33 +0000 https://www.shuijingwanwq.com/?p=6312 Post Views: 93 1、当请求响应成功时的结构。如图1
当请求响应成功时的结构

图1




mutation {
  onlineStoreThemePreviewCodeGenerate(themeId: "vogue") {
    themePreviewCode
  }
}





{
  "data": {
    "onlineStoreThemePreviewCodeGenerate": {
      "themePreviewCode": "eyJpdiI6IjZlZ3RpZzlyZmp6S3BzQWJcL0N1NVR3PT0iLCJ2YWx1ZSI6IkNGdVwvdGJMZFI2MWJPRXFMbTNhdmVOUVVCVDhzb1ZnSzFNQzd2Y1RoSElGMmw4VkxOWFppbnlNbmtjaFNnbG9FXC9Oa1hYSndRU1hlcmpFMktneFNkQmVoMjhENnoxb3dQY0lxNHZnemJrNXlLTlpNKzJmbEU4RTFXNnFza2dyVG4iLCJtYWMiOiI0NzcwZjllYjIxZDliOGFkMTU2OTdiZmVmYWViN2I2OTI5NWE0ZDFjOTBmOGU1MGMyZjI3MzBjNTQxMWE3ODQ2In0="
    }
  }
}


2、但是,现阶段并未针对请求参数进行安全验证。参考:https://lighthouse-php.com/master/security/validation.html#single-arguments 。Lighthouse 允许您在查询和变更中使用 Laravel 的验证。 3、此 GraphQL API 的变更仅有一个请求参数,即 themeId,仅需要验证此字段是否在表中存在即可。 4、利用内置验证规则的最简单方法是使用 @rules 指令。使用 Exists 规则


extend type Mutation {
    "生成主题预览代码"
    onlineStoreThemePreviewCodeGenerate(themeId: ID! @rules(apply: ["exists:theme_asset,theme_id"])): OnlineStoreThemePreviewCodeGeneratePayload @field(resolver: "Modules\\ThemeStore\\Resolver\\ThemePreview\\GenerateThemePreviewCodeResolver")
}


5、测试验证规则是否有效,确定有效。如图2
测试验证规则是否有效,确定有效

图2




mutation {
  onlineStoreThemePreviewCodeGenerate(themeId: "vogue1") {
    themePreviewCode
  }
}





{
  "errors": [
    {
      "message": "Validation failed for the field [onlineStoreThemePreviewCodeGenerate].",
      "extensions": {
        "validation": {
          "themeId": [
            "The selected theme id is invalid."
          ]
        },
        "category": "validation"
      },
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "onlineStoreThemePreviewCodeGenerate"
      ],
      "trace": ...
    }
  ],
  "data": {
    "onlineStoreThemePreviewCodeGenerate": null
  }
}


6、查看 Laravel Telescope 中请求中的 SQL 语句。


select
  count(*) as aggregate
from
  `theme_asset`
where
  `theme_id` = 'vogue1'


7、但是,现阶段还存在一个问题,因为表名称的前缀恰好是 ”,如果设置为 ‘object_’,可能会有问题。再次请求,发现报错,符合预期。说明验证规则中会自动读取表前缀的。无需要调整。如图3
但是,现阶段还存在一个问题,因为表名称的前缀恰好是 '',如果设置为 'object_',可能会有问题。再次请求,发现报错,符合预期。说明验证规则中会自动读取表前缀的。无需要调整

图3



        'mysql' => [
            ...
            'prefix' => 'object_',
        ],




{
  "errors": [
    {
      "debugMessage": "SQLSTATE[42S02]: Base table or view not found: 1146 Table 'object_store.object_theme_asset' doesn't exist (SQL: select count(*) as aggregate from `object_theme_asset` where `theme_id` = vogue1)",
      "message": "Internal server error",
      "extensions": {
        "category": "internal"
      },
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "onlineStoreThemePreviewCodeGenerate"
      ],
      "trace": [
        ...
      ]
    }
  ],
  "data": {
    "onlineStoreThemePreviewCodeGenerate": null
  }
}


]]>
https://www.shuijingwanwq.com/2022/04/20/6312/feed/ 0
在 Yii 2.0 中,核心验证器:unique (唯一性) 支持多个模型与变量的实现 https://www.shuijingwanwq.com/2020/02/05/3918/ https://www.shuijingwanwq.com/2020/02/05/3918/#respond Wed, 05 Feb 2020 10:32:50 +0000 getRequest()]]> params]]> https://www.shuijingwanwq.com/?p=3918 Post Views: 135 1、涉及至第 1 张表,企鹅号的文章:cpa_qq_article,需要验证其字段:title 的唯一性,表结构如图1
涉及至第 1 张表,企鹅号的文章:cpa_qq_article,需要验证其字段:title 的唯一性,表结构

图1

2、涉及至第 2 张表,渠道的应用的任务:cpa_channel_app_task,字段:task_id 与 企鹅号的文章的字段:task_id 存在关联关系(多对一),字段:channel_app_source_uuid 为条件(变量、请求参数),字段:status 为条件(常量),表结构如图2
涉及至第 2 张表,渠道的应用的任务:cpa_channel_app_task,字段:task_id 与 企鹅号的文章的字段:task_id 存在关联关系(多对一),字段:channel_app_source_uuid 为条件(变量、请求参数),字段:status 为条件(常量),表结构

图2

3、filter:用于检查输入值唯一性必然会进行数据库查询,而该属性为用于进一步筛选该查询的过滤条件。样式为 function ($query) 的匿名函数, $query 参数为你希望在该函数内进行修改的 Query 对象。模型中的验证规则声明如下:


    /**
     * {@inheritdoc}
     */
    public function scenarios()
    {
        $scenarios = parent::scenarios();
        $scenarios[self::SCENARIO_CREATE] = ['group_id', 'article_category_id', 'title', 'author', 'source_article_id'];

        return $scenarios;
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        $rules = [
            ['title', 'unique', 'filter' => function ($query) {
                /* @var $query ChannelAppTaskQuery */
                $query->joinWith('channelAppTask', false)->andWhere([ChannelAppTask::tableName() . '.status' => ChannelAppTask::STATUS_PLATFORM_PUBLISHED]);
            }, 'on' => self::SCENARIO_CREATE],
        ];
        $parentRules = parent::rules();

        return ArrayHelper::merge($rules, $parentRules);
    }

    /*
     * 声明了一个渠道的应用的任务关联
     */
    public function getChannelAppTask()
    {
        return $this->hasOne(ChannelAppTask::className(), ['task_id' => 'task_id']);
    }


4、验证请求参数时,生成的 SQL 如下:


SELECT EXISTS(SELECT `cpa_qq_article`.* FROM `cpa_qq_article` LEFT JOIN `cpa_channel_app_task` ON `cpa_qq_article`.`task_id` = `cpa_channel_app_task`.`task_id` WHERE (`cpa_qq_article`.`title`='未来 10 年,“星光中国芯工程”计划投资 100 亿元用于芯片研发及大规模产业化。') AND (`cpa_channel_app_task`.`status`=6))


5、请求参数中,存在 channel_app_source_uuids 字段,其值为数组:[“8d72b7cc2ac911eab85a54ee75d2ebc1”, “18cf06d22ac911eaa31854ee75d2ebc1”],需要将 channel_app_source_uuids 的值做为条件应用于唯一性验证的查询条件中。在执行模型的验证之前,赋值给应用的全局参数变量 Yii::$app->params。如图3
请求参数中,存在 channel_app_source_uuids 字段,其值为数组:["8d72b7cc2ac911eab85a54ee75d2ebc1", "18cf06d22ac911eaa31854ee75d2ebc1"],需要将 channel_app_source_uuids 的值做为条件应用于唯一性验证的查询条件中。在执行模型的验证之前,赋值给应用的全局参数变量 Yii::$app->params。

图3



$requestParams = Yii::$app->getRequest()->getBodyParams();
Yii::$app->params['channelAppSourceUuids'] = $requestParams['channel_app_source_uuids'];


6、现在可在验证规则中使用 Yii::$app->params,模型中的验证规则声明调整如下:


    /**
     * @inheritdoc
     */
    public function rules()
    {
        $rules = [
            ['title', 'unique', 'filter' => function ($query) {
                /* @var $query ChannelAppTaskQuery */
                $query->joinWith('channelAppTask', false)->andWhere(['and', ['in', ChannelAppTask::tableName() . '.channel_app_source_uuid', Yii::$app->params['channelAppSourceUuids']], [ChannelAppTask::tableName() . '.status' => ChannelAppTask::STATUS_PLATFORM_PUBLISHED]]);
            }, 'on' => self::SCENARIO_CREATE],
        ];
        $parentRules = parent::rules();

        return ArrayHelper::merge($rules, $parentRules);
    }


7、验证请求参数时,生成的 SQL 如下,请求参数已经应用于查询条件中,符合预期


SELECT EXISTS(SELECT `cpa_qq_article`.* FROM `cpa_qq_article` LEFT JOIN `cpa_channel_app_task` ON `cpa_qq_article`.`task_id` = `cpa_channel_app_task`.`task_id` WHERE (`cpa_qq_article`.`title`='未来 10 年,“星光中国芯工程”计划投资 100 亿元用于芯片研发及大规模产业化。') AND ((`cpa_channel_app_task`.`channel_app_source_uuid` IN ('8d72b7cc2ac911eab85a54ee75d2ebc1', '18cf06d22ac911eaa31854ee75d2ebc1')) AND (`cpa_channel_app_task`.`status`=6)))


8、核心验证器:unique (唯一性) 支持多个模型与变量的实现,验证失败时,响应如下,如图4
核心验证器:unique (唯一性) 支持多个模型与变量的实现,验证失败时,响应如下

图4



{
    "code": 226004,
    "message": "数据验证失败:标题的值\"未来 10 年,“星光中国芯工程”计划投资 100 亿元用于芯片研发及大规模产业化。\"已经被占用了。"
}


]]>
https://www.shuijingwanwq.com/2020/02/05/3918/feed/ 0
基于 Yii 2 的 ActiveRecord,在运行期间,Redis的CPU使用率为100%的分析、解决 https://www.shuijingwanwq.com/2017/07/17/1679/ https://www.shuijingwanwq.com/2017/07/17/1679/#respond Mon, 17 Jul 2017 10:27:13 +0000 http://www.shuijingwanwq.com/?p=1679 Post Views: 160

1、在2017-06-18 19:36:00,即比赛开始的时候,应用的响应时间为51.8ms,响应时间正常,如图1

在2017-06-18 19:36:00,即比赛开始的时候,应用的响应时间为51.8ms,响应时间正常

图1

2、在整个足球比赛期间,响应时间呈线性不断增加,在2017-06-18 20:30:00 至 2017-06-18 20:40:00,响应时间下降,是因为此时比赛处于中场休息期间,基本上发送至服务器的比赛数据无变化,因此处理逻辑简单,如图2

在整个足球比赛期间,响应时间呈线性不断增加,在2017-06-18 20:30:00 至 2017-06-18 20:40:00,响应时间下降,是因为此时比赛处于中场休息期间,基本上发送至服务器的比赛数据无变化,因此处理逻辑简单

图2

3、在2017-06-18 21:25:00,即比赛即将结束的时候,应用的响应时间为2320ms,业务目标所要求的平均响应时间为150ms,因此性能无法满足业务要求,如图3

在2017-06-18 21:25:00,即比赛即将结束的时候,应用的响应时间为2320ms,业务目标所要求的平均响应时间为150ms,因此性能无法满足业务要求

图3

4、在APM的Transaction trace中,可以发现在一次响应时间为5710 ms的请求中,Redis相关的操作就消耗了4390 ms,占用的比例为77%,httpclient是调用了另一个接口,其接口中也使用了Redis的,因此,分析结果为Redis为性能瓶颈所在,如图4

在APM的Transaction trace中,可以发现在一次响应时间为5710 ms的请求中,Redis相关的操作就消耗了4390 ms,占用的比例为77%,httpclient是调用了另一个接口,其接口中也使用了Redis的,因此,分析结果为Redis为性能瓶颈所在

图4

5、在APM的Transaction trace的 Trace details中,发现 shujujiexi\models\redis\GamePlayerData::gamePlayerDataByShuJuJieXi 所消耗时间占用的比例为 57.25%,如图5

在APM的Transaction trace的 Trace details中,发现 shujujiexi\models\redis\GamePlayerData::gamePlayerDataByShuJuJieXi 所消耗时间占用的比例为 57.25%

图5

6、继续展开,直到无法展开为止,发现 yii\redis\Connection::parseResponse ,需要分析其运行机制,如图6

继续展开,直到无法展开为止,发现 yii\redis\Connection::parseResponse ,需要分析其运行机制

图6

7、在阿里云监控中,在2017-06-18 19:36:00,即比赛开始的时候,Redis的CPU使用率为1.9%,如图7

在阿里云监控中,在2017-06-18 19:36:00,即比赛开始的时候,Redis的CPU使用率为1.9%

图7

8、在整个足球比赛期间,在阿里云监控中,Redis的CPU使用率呈线性不断增加,在2017-06-18 20:30:00 至 2017-06-18 20:40:00,Redis的CPU使用率下降,是因为此时比赛处于中场休息期间,基本上发送至服务器的比赛数据无变化,因此处理逻辑简单,整个曲线与响应时间完全成正比关系,如图8

在整个足球比赛期间,在阿里云监控中,Redis的CPU使用率呈线性不断增加,在2017-06-18 20:30:00 至 2017-06-18 20:40:00,Redis的CPU使用率下降,是因为此时比赛处于中场休息期间,基本上发送至服务器的比赛数据无变化,因此处理逻辑简单,整个曲线与响应时间完全成正比关系

图8

9、在阿里云监控中,在2017-06-18 21:27:00,即比赛即将结束的时候,Redis的CPU使用率为100%,如图9

在阿里云监控中,在2017-06-18 21:27:00,即比赛即将结束的时候,Redis的CPU使用率为100%

图9

10、在阿里云监控中,在2017-06-18 21:28:00,即比赛即将结束的时候,Redis的已用连接数为54个,达到峰值,如图10

在阿里云监控中,在2017-06-18 21:28:00,即比赛即将结束的时候,Redis的已用连接数为54个,达到峰值

图10

11、现在需要分析究竟是何原因导致Redis的CPU使用率为100%了,在APM的Transaction trace中,发现 yii\redis\ActiveRecord::deleteAll 所消耗时间占用的比例为 78%,如图11

现在需要分析究竟是何原因导致Redis的CPU使用率为100%了,在APM的Transaction trace中,发现 yii\redis\ActiveRecord::deleteAll 所消耗时间占用的比例为 78%

图11

12、在APM的Transaction trace的 Trace details中,发现 Application code (in yii\redis\ActiveRecord::deleteAll) 最为消耗时间,基本上可以确定ActiveRecord相关的操作为导致Redis的CPU使用率为100%的根本原因了,如图12

在APM的Transaction trace的 Trace details中,发现 Application code (in yii\redis\ActiveRecord::deleteAll) 最为消耗时间,基本上可以确定ActiveRecord相关的操作为导致Redis的CPU使用率为100%的根本原因了

图12

13、在pro环境,准备实现一个典型请求的2个版本,第1个版本的ActiveRecord相关的操作基本上为查询、修改,第2个版本的ActiveRecord相关的操作基本上为查询、插入,以便于确认当某个ActiveRecord模型中的key数量过多时,是否会提升Redis的CPU使用率,先清空Redis,之后定时任务所生成的Redis数据,key的数量为3170,如图13

在pro环境,准备实现一个典型请求的2个版本,第1个版本的ActiveRecord相关的操作基本上为查询、修改,第2个版本的ActiveRecord相关的操作基本上为查询、插入,以便于确认当某个ActiveRecord模型中的key数量过多时,是否会提升Redis的CPU使用率,先清空Redis,之后定时任务所生成的Redis数据,key的数量为3170

图13

14、在pro环境,请求的第1个版本运行2个小时之后,Redis数据,key的数量为3220,仅增加了50个key,如图14

在pro环境,请求的第1个版本运行2个小时之后,Redis数据,key的数量为3220,仅增加了50个key

图14

15、在pro环境,在整个典型请求的运行期间,在阿里云监控中,Redis的CPU使用率最高为2.6%,在 2017-06-27 16:50:00 之后,Redis的CPU使用率维持在0.6%,是因为此时,基本上发送至服务器的比赛数据无变化,因此处理逻辑简单,如图15

在pro环境,在整个典型请求的运行期间,在阿里云监控中,Redis的CPU使用率最高为2.6%,在 2017-06-27 16:50:00 之后,Redis的CPU使用率维持在0.6%,是因为此时,基本上发送至服务器的比赛数据无变化,因此处理逻辑简单

图15

16、在pro环境,在整个典型请求的运行期间,响应时间基本上保持稳定,最大响应时间为266ms,此请求的业务目标在生产环境上所要求的平均响应时间为200ms,因此性能满足业务要求,在 2017-06-27 16:50:00 之后,响应时间下降,是因为此时,基本上发送至服务器的比赛数据无变化,因此处理逻辑简单,如图16

在pro环境,在整个典型请求的运行期间,响应时间基本上保持稳定,最大响应时间为266ms,此请求的业务目标在生产环境上所要求的平均响应时间为200ms,因此性能满足业务要求,在 2017-06-27 16:50:00 之后,响应时间下降,是因为此时,基本上发送至服务器的比赛数据无变化,因此处理逻辑简单

图16

17、先清空Redis,之后定时任务所生成的Redis数据,key的数量为2909,如图17

先清空Redis,之后定时任务所生成的Redis数据,key的数量为2909

图17

18、在pro环境,请求的第2个版本运行2个小时之后,Redis数据,key的数量为89840,增加了86931个key,如图18

在pro环境,请求的第2个版本运行2个小时之后,Redis数据,key的数量为89840,增加了86931个key

图18

19、请求的第2个版本所操作的Redis模型的key的数量为79527,如图19

请求的第2个版本所操作的Redis模型的key的数量为79527

图19

20、在pro环境,请求的第2个版本,在整个典型请求的运行期间,在阿里云监控中,Redis的CPU使用率最高为66.8%,如图20

在pro环境,请求的第2个版本,在整个典型请求的运行期间,在阿里云监控中,Redis的CPU使用率最高为66.8%

图20

21、基于当前分析结果,已经可以确定当ActiveRecord操作的某个模型的key的数量过大时,Redis的CPU使用率会大幅度提升,不过是由于查询还是插入导致的,需要进一步确认,代码,如图21

基于当前分析结果,已经可以确定当ActiveRecord操作的某个模型的key的数量过大时,Redis的CPU使用率会大幅度提升,不过是由于查询还是插入导致的,需要进一步确认,代码

图21

22、修改查询方案,将count(‘id’)调整为exists(),即查询模型中满足条件的所有key调整为查询模型中满足条件的1个key,代码,如图22

修改查询方案,将count('id')调整为exists(),即查询模型中满足条件的所有key调整为查询模型中满足条件的1个key,代码

图22

23、不清空Redis,在pro环境,请求的第3个版本所操作的Redis模型的key的数量为81277,如图23

不清空Redis,在pro环境,请求的第3个版本所操作的Redis模型的key的数量为81277

图23

24、在pro环境,请求的第3个版本,在整个典型请求的运行期间,在阿里云监控中,Redis的CPU使用率最高为11.8%,如图24

在pro环境,请求的第3个版本,在整个典型请求的运行期间,在阿里云监控中,Redis的CPU使用率最高为11.8%

图24

25、基于当前分析结果,已经可以确定当ActiveRecord操作的某个模型的key的数量过大时,Redis的CPU使用率会大幅度提升,并且是与查询的关联性最大,不过查询与插入的性能对比,需要进一步确认,代码,注释掉查询,只保留插入操作,如图25

基于当前分析结果,已经可以确定当ActiveRecord操作的某个模型的key的数量过大时,Redis的CPU使用率会大幅度提升,并且是与查询的关联性最大,不过查询与插入的性能对比,需要进一步确认,代码,注释掉查询,只保留插入操作

图25

26、不清空Redis,在pro环境,请求的第4个版本所操作的Redis模型的key的数量为81947,如图26

不清空Redis,在pro环境,请求的第4个版本所操作的Redis模型的key的数量为81947

图26

27、在pro环境,请求的第4个版本,在整个典型请求的运行期间,在阿里云监控中,Redis的CPU使用率最高为2.2%,如图27

在pro环境,请求的第4个版本,在整个典型请求的运行期间,在阿里云监控中,Redis的CPU使用率最高为2.2%

图27

28、将count()调整为exists()以提升查询性能,如图28

将count()调整为exists()以提升查询性能

图28

29、将一些ActiveRecord实现重构为Redis原生命令实现,在整个足球比赛期间,在阿里云监控中,Redis的CPU使用率最高为21.1%,因此响应时间正常,如图29

将一些ActiveRecord实现重构为Redis原生命令实现,在整个足球比赛期间,在阿里云监控中,Redis的CPU使用率最高为21.1%,因此响应时间正常

图29

30、总结:Yii 2 的 ActiveRecord,相关方法对于Redis的CPU计算压力排行:insert() < one()/exists() < count()/all(),当某个Redis模型的key的数量超出10000后,如果要执行查询(有where条件)操作,建议不要使用ActiveRecord,如图30

总结:Yii 2 的 ActiveRecord,相关方法对于Redis的CPU计算压力排行:insert() < one()/exists() < count()/all(),当某个Redis模型的key的数量超出10000后,如果要执行查询(有where条件)操作,建议不要使用ActiveRecord

图30

]]>
https://www.shuijingwanwq.com/2017/07/17/1679/feed/ 0