PHP 7.2 – 永夜 https://www.shuijingwanwq.com 没有不值得去解决的问题,也没有不值得去学习的技术! Sun, 31 May 2026 03:52:39 +0000 zh-Hans hourly 1 https://wordpress.org/?v=7.0 Composer detected issues in your platform:Your Composer dependencies require a PHP version “>= 7.3.0”. https://www.shuijingwanwq.com/2021/10/22/5390/ https://www.shuijingwanwq.com/2021/10/22/5390/#respond Fri, 22 Oct 2021 06:35:11 +0000 = 7.3.0]]> https://www.shuijingwanwq.com/?p=5390 浏览量: 205 1、Composer detected issues in your platform:Your Composer dependencies require a PHP version “>= 7.3.0”.。Composer 在您的平台中检测到问题:您的 Composer 依赖项需要 PHP 版本 “>= 7.3.0″。如图1
Composer detected issues in your platform:Your Composer dependencies require a PHP version ">= 7.3.0".。Composer 在您的平台中检测到问题:您的 Composer 依赖项需要 PHP 版本 ">= 7.3.0"。

图1



[root@payment-7865946b4-v88ld /]# curl http://payment.cmc/check-status
Composer detected issues in your platform:

Your Composer dependencies require a PHP version ">= 7.3.0". 



2、根源在于,需要将程序部署在华为云的ARM (鲲鹏)架构的云服务器上,因此,基础镜像换为一个支持 ARM 的镜像,进而 PHP 版本变化为:PHP 7.2.20。AArch64是Armv8-A架构中引入的64位状态。如图2
根源在于,需要将程序部署在华为云的ARM (鲲鹏)架构的云服务器上,因此,基础镜像换为一个支持 ARM 的镜像,进而 PHP 版本变化为:PHP 7.2.20。AArch64是Armv8-A架构中引入的64位状态。

图2



[root@payment-7865946b4-v88ld /]# cat /etc/redhat-release
CentOS Linux release 7.8.2003 (AltArch)
[root@payment-7865946b4-v88ld /]# cat /proc/version
Linux version 4.18.0-80.7.2.el7.aarch64 (mockbuild@aarch64-01.bsys.centos.org) (gcc version 8.3.1 20190311 (Red Hat 8.3.1-3) (GCC)) #1 SMP Thu Sep 12 16:13:20 UTC 2019
[root@payment-7865946b4-v88ld /]# arch
aarch64
[root@payment-7865946b4-v88ld /]# php -v
PHP 7.2.20 (cli) (built: Aug 12 2020 19:02:44) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.2.20, Copyright (c) 1999-2018, by Zend Technologies
[root@payment-7865946b4-v88ld /]# 


3、查看 composer.json。”php”: “>=7.3.0”,。如图3
查看 composer.json。"php": ">=7.3.0",。

图3

4、由于 /vendor 已经放入 Git 仓库中。编辑 composer.json:”php”: “>=7.2.0”,。如图4
由于 /vendor 已经放入 Git 仓库中。编辑 composer.json:"php": ">=7.2.0",。

图4



    "require": {
        "php": ">=7.2.0",
    },


5、将本地 Windows 环境的 PHP 版本切换至:7.2.14,与生产环境的镜像的 PHP 大版本:7.2.20 保持一致。如图5
将本地 Windows 环境的 PHP 版本切换至:7.2.14,与生产环境的镜像的 PHP 大版本:7.2.20 保持一致。

图5



PS C:\WINDOWS\system32> php -v
PHP 7.2.14 (cli) (built: Jan  9 2019 22:23:26) ( ZTS MSVC15 (Visual C++ 2017) x64 )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies


6、删除目录:/vendor ,删除:composer.lock,重新执行:composer install。如图6
删除目录:/vendor ,删除:composer.lock,重新执行:composer install。

图6

7、运行健康检查程序,一个 PHP 脚本,响应 200,未再报错。问题解决。如图7
运行健康检查程序,一个 PHP 脚本,响应 200,未再报错。问题解决。

图7



[root@payment-7d74df5689-cfckp /]# curl http://payment.cmc/check-status
200[root@payment-7d74df5689-cfckp /]# 


]]>
https://www.shuijingwanwq.com/2021/10/22/5390/feed/ 0
在 K8s 中,已经安装 PHP 代码缓存组件:Zend Opcache,修改 PHP 文件,让其立即生效的流程(在 CentOS 中批量 kill php 进程) https://www.shuijingwanwq.com/2020/11/05/4599/ https://www.shuijingwanwq.com/2020/11/05/4599/#respond Thu, 05 Nov 2020 03:20:52 +0000 https://www.shuijingwanwq.com/?p=4599 浏览量: 114 1、在 K8s 中,容器无重启选项,如图1
在 K8s 中,容器无重启选项

图1

2、在非 K8s 中,容器有重启选项,之前修改 PHP 文件,容器重启后自动生效。如图2
在非 K8s 中,容器有重启选项,之前修改 PHP 文件,容器重启后自动生效。

图2

3、编辑 PHP 文件,输出一些信息,如图3
编辑 PHP 文件,输出一些信息

图3



print_r($domain);
print_r($cooike_domain);
exit;


4、刷新页面,发现没有立即生效,如图4
刷新页面,发现没有立即生效

图4

5、在 CentOS 中批量 kill php 进程,执行命令。管道符“|”用来隔开两个命令,管道符左边命令的输出会作为管道符右边命令的输入。下面说说用管道符联接起来的几个命令: “ps – ef”是 Red Hat 里查看所有进程的命令。这时检索出的进程将作为下一条命令“grep LOCAL=NO”的输入。 “grep php”的输出结果是,所有含有关键字“LOCAL=NO”的进程。 “grep -v grep”是在列出的进程中去除含有关键字“grep”的进程。 “cut -c 9-15”是截取输入行的第 9 个字符到第 15 个字符,而这正好是进程号 PID。 “xargs kill -9”中的 xargs 命令是用来把前面命令的输出结果 (PID) 作为“kill -9”命令的参数,并执行该命令。 “kill -9”会强行杀掉指定进程,这样就成功清除了 php 所有进程。如图5
在 CentOS 中批量 kill php 进程,执行命令。

图5



[root@cmcp-front-7f96bbb58-rknvt cmcp-front2]# ps -ef|grep php|grep -v grep|cut -c 9-15|xargs kill -9
[root@cmcp-front-7f96bbb58-rknvt cmcp-front2]# 


6、再次刷新页面,发现立即生效,符合预期。如图6
再次刷新页面,发现立即生效,符合预期。

图6

]]>
https://www.shuijingwanwq.com/2020/11/05/4599/feed/ 0
在 Yii 2.0 中,控制台命令行,添加参数的实现 https://www.shuijingwanwq.com/2020/05/29/4196/ https://www.shuijingwanwq.com/2020/05/29/4196/#respond Fri, 29 May 2020 08:14:57 +0000 https://www.shuijingwanwq.com/?p=4196 浏览量: 122 1、CmcConsoleUser/actionSync,现有实现,参考:https://www.shuijingwanwq.com/2020/03/02/3964/ ,现在需要添加参数:租户ID 2、参数将传递给请求的子命令对应的动作方法。设置参数 $groupId 的默认值为 null


public function actionSync($groupId = null)


3、判断 $groupId 是否为空,如果不为空,且在 $httpCmcApiGroupIds 中不存在,则成功退出


        /* 判断 $groupId 是否为空,如果不为空,且在 $httpCmcApiGroupIds 中不存在,则成功退出 */
        if (!empty($groupId) && !in_array($groupId, $httpCmcApiGroupIds)) {
            return ExitCode::OK;
        }


4、基于上次同步时间顺序排列,赋值给:$sortCmcApiGroupIds,打印排序前后的数组


        // 基于上次同步时间顺序排列,赋值给:$sortCmcApiGroupIds
        $sortCmcApiGroupIds = $cmcApiGroupIds;
        print_r($sortCmcApiGroupIds);
        ArrayHelper::multisort($sortCmcApiGroupIds, 'cmc_console_user_last_synced_at', SORT_ASC);
        print_r($sortCmcApiGroupIds);
        exit;




PS E:\wwwroot\pcs-api> ./yii cmc-console-user/sync
Array
(
    [0] => Array
        (
            [group_id] => c10e87f39873512a16727e17f57456a5
            [cmc_console_user_last_synced_at] => 1590649259
        )

    [1] => Array
        (
            [group_id] => 015ce30b116ce86058fa6ab4fea4ac63
            [cmc_console_user_last_synced_at] => 0
        )

    [2] => Array
        (
            [group_id] => 4fd58ceba1fbc537b5402302702131eb
            [cmc_console_user_last_synced_at] => 0
        )

    [3] => Array
        (
            [group_id] => f53df1a8d46108afc8ae9eeb3f0e1f0e
            [cmc_console_user_last_synced_at] => 0
        )

    [4] => Array
        (
            [group_id] => e774bfcf8fc4cfe2ce57ac875a266e94
            [cmc_console_user_last_synced_at] => 0
        )

    [5] => Array
        (
            [group_id] => b28312e46044da2682e540d1fb838c67
            [cmc_console_user_last_synced_at] => 0
        )

)
Array
(
    [0] => Array
        (
            [group_id] => 015ce30b116ce86058fa6ab4fea4ac63
            [cmc_console_user_last_synced_at] => 0
        )

    [1] => Array
        (
            [group_id] => 4fd58ceba1fbc537b5402302702131eb
            [cmc_console_user_last_synced_at] => 0
        )

    [2] => Array
        (
            [group_id] => f53df1a8d46108afc8ae9eeb3f0e1f0e
            [cmc_console_user_last_synced_at] => 0
        )

    [3] => Array
        (
            [group_id] => e774bfcf8fc4cfe2ce57ac875a266e94
            [cmc_console_user_last_synced_at] => 0
        )

    [4] => Array
        (
            [group_id] => b28312e46044da2682e540d1fb838c67
            [cmc_console_user_last_synced_at] => 0
        )

    [5] => Array
        (
            [group_id] => c10e87f39873512a16727e17f57456a5
            [cmc_console_user_last_synced_at] => 1590649259
        )

)


5、现在需要基于参数 $groupId 的值,来同步此租户下的用户,即需要让此租户排在第一位。才能够满足需求。先销毁 $sortCmcApiGroupIds 中的 $groupId,再插入至开头。打印排序前后的数组。符合预期。如图1
现在需要基于参数 $groupId 的值,来同步此租户下的用户,即需要让此租户排在第一位。才能够满足需求。先销毁 $sortCmcApiGroupIds 中的 $groupId,再插入至开头。打印排序前后的数组。符合预期

图1



        // 基于上次同步时间顺序排列,赋值给:$sortCmcApiGroupIds
        $sortCmcApiGroupIds = $cmcApiGroupIds;
        print_r($sortCmcApiGroupIds);
        ArrayHelper::multisort($sortCmcApiGroupIds, 'cmc_console_user_last_synced_at', SORT_ASC);
        print_r($sortCmcApiGroupIds);

        /* 判断 $groupId 是否为空,如果不为空 */
        if (!empty($groupId)) {
            // 销毁 $sortCmcApiGroupIds 中的 $groupId
            foreach ($sortCmcApiGroupIds as $sortCmcApiGroupIdKey => $sortCmcApiGroupId) {
                if ($sortCmcApiGroupId['group_id'] == $groupId) {
                    unset($sortCmcApiGroupIds[$sortCmcApiGroupIdKey]);
                    break;
                }
            }
            print_r($sortCmcApiGroupIds);
            // 将 $groupId 插入至 $sortCmcApiGroupIds 的开头
            array_unshift($sortCmcApiGroupIds, [
                'group_id' => $groupId,
                'cmc_console_user_last_synced_at' => 0, //上次同步时间
            ]);
        }

        print_r($sortCmcApiGroupIds);
        exit;




PS E:\wwwroot\pcs-api> ./yii cmc-console-user/sync b28312e46044da2682e540d1fb838c67
Array
(
    [0] => Array
        (
            [group_id] => c10e87f39873512a16727e17f57456a5
            [cmc_console_user_last_synced_at] => 1590649259
        )

    [1] => Array
        (
            [group_id] => 015ce30b116ce86058fa6ab4fea4ac63
            [cmc_console_user_last_synced_at] => 0
        )

    [2] => Array
        (
            [group_id] => 4fd58ceba1fbc537b5402302702131eb
            [cmc_console_user_last_synced_at] => 0
        )

    [3] => Array
        (
            [group_id] => f53df1a8d46108afc8ae9eeb3f0e1f0e
            [cmc_console_user_last_synced_at] => 0
        )

    [4] => Array
        (
            [group_id] => e774bfcf8fc4cfe2ce57ac875a266e94
            [cmc_console_user_last_synced_at] => 0
        )

    [5] => Array
        (
            [group_id] => b28312e46044da2682e540d1fb838c67
            [cmc_console_user_last_synced_at] => 0
        )

)
Array
(
    [0] => Array
        (
            [group_id] => 015ce30b116ce86058fa6ab4fea4ac63
            [cmc_console_user_last_synced_at] => 0
        )

    [1] => Array
        (
            [group_id] => 4fd58ceba1fbc537b5402302702131eb
            [cmc_console_user_last_synced_at] => 0
        )

    [2] => Array
        (
            [group_id] => f53df1a8d46108afc8ae9eeb3f0e1f0e
            [cmc_console_user_last_synced_at] => 0
        )

    [3] => Array
        (
            [group_id] => e774bfcf8fc4cfe2ce57ac875a266e94
            [cmc_console_user_last_synced_at] => 0
        )

    [4] => Array
        (
            [group_id] => b28312e46044da2682e540d1fb838c67
            [cmc_console_user_last_synced_at] => 0
        )

    [5] => Array
        (
            [group_id] => c10e87f39873512a16727e17f57456a5
            [cmc_console_user_last_synced_at] => 1590649259
        )

)
Array
(
    [0] => Array
        (
            [group_id] => 015ce30b116ce86058fa6ab4fea4ac63
            [cmc_console_user_last_synced_at] => 0
        )

    [1] => Array
        (
            [group_id] => 4fd58ceba1fbc537b5402302702131eb
            [cmc_console_user_last_synced_at] => 0
        )

    [2] => Array
        (
            [group_id] => f53df1a8d46108afc8ae9eeb3f0e1f0e
            [cmc_console_user_last_synced_at] => 0
        )

    [3] => Array
        (
            [group_id] => e774bfcf8fc4cfe2ce57ac875a266e94
            [cmc_console_user_last_synced_at] => 0
        )

    [5] => Array
        (
            [group_id] => c10e87f39873512a16727e17f57456a5
            [cmc_console_user_last_synced_at] => 1590649259
        )

)
Array
(
    [0] => Array
        (
            [group_id] => b28312e46044da2682e540d1fb838c67
            [cmc_console_user_last_synced_at] => 0
        )

    [1] => Array
        (
            [group_id] => 015ce30b116ce86058fa6ab4fea4ac63
            [cmc_console_user_last_synced_at] => 0
        )

    [2] => Array
        (
            [group_id] => 4fd58ceba1fbc537b5402302702131eb
            [cmc_console_user_last_synced_at] => 0
        )

    [3] => Array
        (
            [group_id] => f53df1a8d46108afc8ae9eeb3f0e1f0e
            [cmc_console_user_last_synced_at] => 0
        )

    [4] => Array
        (
            [group_id] => e774bfcf8fc4cfe2ce57ac875a266e94
            [cmc_console_user_last_synced_at] => 0
        )

    [5] => Array
        (
            [group_id] => c10e87f39873512a16727e17f57456a5
            [cmc_console_user_last_synced_at] => 1590649259
        )

)


6、最终的代码实现


        // 设置同步标识的缓存键
        $redisCache = Yii::$app->redisCache;

        // HTTP 请求,获取开通有效服务的租户ID列表
        $httpCmcApiGroupIds = CmcApiGroupService::httpGetGroupIds();

        /* 判断 $httpCmcApiGroupIds 是否为空,如果为空,则成功退出 */
        if (empty($httpCmcApiGroupIds)) {
            // 延缓执行 60 * 60 秒
            // sleep(Yii::$app->params['cmcConsoleUser']['isEmptyYesSleepTime']);

            return ExitCode::OK;
        }

        /* 判断 $groupId 是否为空,如果不为空,且在 $httpCmcApiGroupIds 中不存在,则成功退出 */
        if (!empty($groupId) && !in_array($groupId, $httpCmcApiGroupIds)) {
            return ExitCode::OK;
        }

        // 设置租户ID列表的缓存键
        $redisCacheGroupIdsKey = 'cmc_api_group_ids';

        // 从缓存中取回租户ID列表
        $redisCacheGroupIdsData = $redisCache[$redisCacheGroupIdsKey];

        // 是否设置租户ID列表的缓存,默认:否
        $isSetRedisCacheGroupIds = false;

        if ($redisCacheGroupIdsData === false) {
            $cmcApiGroupIds = [];
            foreach ($httpCmcApiGroupIds as $httpCmcApiGroupId) {
                $cmcApiGroupIds[] = [
                    'group_id' => $httpCmcApiGroupId,
                    'cmc_console_user_last_synced_at' => 0, //上次同步时间
                ];
            }
            // 是否设置租户ID列表的缓存:是
            $isSetRedisCacheGroupIds = true;
        } else {
            // 获取 group_id 值列表
            $redisCacheGroupIds = ArrayHelper::getColumn($redisCacheGroupIdsData, 'group_id');
            $cmcApiGroupIds = $redisCacheGroupIdsData;

            /* 删除出现在 $cmcApiGroupIds 中但是未出现在 $httpCmcApiGroupIds 中的租户 */
            foreach ($cmcApiGroupIds as $cmcApiGroupIdKey => $cmcApiGroupId) {
                if (!in_array($cmcApiGroupId['group_id'], $httpCmcApiGroupIds)) {
                    unset($cmcApiGroupIds[$cmcApiGroupIdKey]);
                    // 是否设置租户ID列表的缓存:是
                    $isSetRedisCacheGroupIds = true;
                }
            }

            foreach ($httpCmcApiGroupIds as $httpCmcApiGroupId) {
                if (!in_array($httpCmcApiGroupId, $redisCacheGroupIds)) {
                    $cmcApiGroupIds[] = [
                        'group_id' => $httpCmcApiGroupId,
                        'cmc_console_user_last_synced_at' => 0, //上次同步时间
                    ];
                    // 是否设置租户ID列表的缓存:是
                    $isSetRedisCacheGroupIds = true;
                }
            }
        }

        // 判断是否设置租户ID列表的缓存
        if ($isSetRedisCacheGroupIds) {
            // 将 $cmcApiGroupIds 存放到缓存供下次使用,将数据在缓存中永久保留
            $redisCache->set($redisCacheGroupIdsKey, $cmcApiGroupIds);
        }


        // 基于上次同步时间顺序排列,赋值给:$sortCmcApiGroupIds
        $sortCmcApiGroupIds = $cmcApiGroupIds;
        ArrayHelper::multisort($sortCmcApiGroupIds, 'cmc_console_user_last_synced_at', SORT_ASC);

        /* 判断 $groupId 是否为空,如果不为空 */
        if (!empty($groupId)) {
            // 销毁 $sortCmcApiGroupIds 中的 $groupId
            foreach ($sortCmcApiGroupIds as $sortCmcApiGroupIdKey => $sortCmcApiGroupId) {
                if ($sortCmcApiGroupId['group_id'] == $groupId) {
                    unset($sortCmcApiGroupIds[$sortCmcApiGroupIdKey]);
                    break;
                }
            }
            // 将 $groupId 插入至 $sortCmcApiGroupIds 的开头
            array_unshift($sortCmcApiGroupIds, [
                'group_id' => $groupId,
                'cmc_console_user_last_synced_at' => 0, //上次同步时间
            ]);
        }



 ]]>
https://www.shuijingwanwq.com/2020/05/29/4196/feed/ 0
在 Yii 2.0 中,Redis ActiveRecord 出现主键 ID 重复的情况的分析解决 https://www.shuijingwanwq.com/2020/05/27/4178/ https://www.shuijingwanwq.com/2020/05/27/4178/#respond Wed, 27 May 2020 07:17:23 +0000 https://www.shuijingwanwq.com/?p=4178 浏览量: 123

1、请求接口,响应参数中资源总数量为 30 个。包含 id 等于 37918 的资源是重复的。总计为 2 个。如图1

请求接口,响应参数中资源总数量为 30 个。包含 id 等于 37918 的资源是重复的。总计为 2 个。

图1


{
  "code": 10000,
  "message": "获取 CMC 用户列表成功",
  "data": {
    "items": [
      {
        "user_birthday": "1990-01-01",
        "login_name": "xianwanzhou",
        "add_time": "2020-03-31 09:41:07",
        "user_email": "",
        "group_id": "643d80843ae23bcfa95b75bae30a7656",
        "id": "37918",
        "user_pic": "http://uploads.cmc.lzgbdst.com/uploads/cmc_user_avatar/default_header.png",
        "update_time": "2020-03-31 09:43:16",
        "is_open": "1",
        "user_nick": "鲜万州",
        "user_mobile": "15208396209",
        "user_token": "6a1de11e594d61790963eaaf1d9bee8d",
        "user_chat_id": "f98e3b834f577cc3d83d74323cd3094d",
        "user_type": "2",
        "user_sex": "2"
      },
      {
        "user_birthday": "1990-01-01",
        "login_name": "xianwanzhou",
        "add_time": "2020-03-31 09:41:07",
        "user_email": "",
        "group_id": "643d80843ae23bcfa95b75bae30a7656",
        "id": "37918",
        "user_pic": "http://uploads.cmc.lzgbdst.com/uploads/cmc_user_avatar/default_header.png",
        "update_time": "2020-03-31 09:43:16",
        "is_open": "1",
        "user_nick": "鲜万州",
        "user_mobile": "15208396209",
        "user_token": "6a1de11e594d61790963eaaf1d9bee8d",
        "user_chat_id": "f98e3b834f577cc3d83d74323cd3094d",
        "user_type": "2",
        "user_sex": "2"
      }
    ],
    "_links": {
      "self": {
        "href": "http://pcsapi.cmc.lzgbdst.com/v1/cmc-users?login_id=7309cba1c93fc0a80663007612b784b8&login_tid=25f49c543b8ec31c6d905def0ad99913&per-page=30&page=1"
      }
    },
    "_meta": {
      "totalCount": 30,
      "pageCount": 1,
      "currentPage": 1,
      "perPage": 30
    }
  }
}


2、查看模型类,/common/models/redis/cmc_console/User.php

<?php
 
namespace common\models\redis\cmc_console;
 
use Yii;
use common\components\redis\ActiveRecord;
 
/**
 * This is the model class for table "{{%user}}".
 *
 * @property string $id
 * @property string $group_id
 * @property string $login_name
 * @property string $user_token
 * @property string $user_nick
 * @property string $user_pic
 * @property string $user_mobile
 * @property string $user_email
 * @property string $user_sex
 * @property string $user_birthday
 * @property string $user_type
 * @property string $user_chat_id
 * @property string $is_open
 * @property string $add_time
 * @property string $update_time
 */
class User extends ActiveRecord
{
    /**
     * @return array the list of attributes for this record
     */
    public function attributes()
    {
        return ['id', 'group_id', 'login_name', 'user_token', 'user_nick', 'user_pic', 'user_mobile', 'user_email', 'user_sex', 'user_birthday', 'user_type', 'user_chat_id', 'is_open', 'add_time', 'update_time'];
    }
     
    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['id', 'group_id', 'login_name', 'user_token', 'user_nick', 'user_pic', 'user_mobile', 'user_email', 'user_sex', 'user_birthday', 'user_type', 'user_chat_id', 'is_open', 'add_time', 'update_time'], 'safe'],
        ];
    }
     
    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'id' => Yii::t('model/redis/cmc-console/user', 'ID'),
            'group_id' => Yii::t('model/redis/cmc-console/user', 'Group ID'),
            'login_name' => Yii::t('model/redis/cmc-console/user', 'Login Name'),
            'user_token' => Yii::t('model/redis/cmc-console/user', 'User Token'),
            'user_nick' => Yii::t('model/redis/cmc-console/user', 'User Nick'),
            'user_pic' => Yii::t('model/redis/cmc-console/user', 'User Pic'),
            'user_mobile' => Yii::t('model/redis/cmc-console/user', 'User Mobile'),
            'user_email' => Yii::t('model/redis/cmc-console/user', 'User Email'),
            'user_sex' => Yii::t('model/redis/cmc-console/user', 'User Sex'),
            'user_type' => Yii::t('model/redis/cmc-console/user', 'User Type'),
            'user_birthday' => Yii::t('model/redis/cmc-console/user', 'User Birthday'),
            'user_chat_id' => Yii::t('model/redis/cmc-console/user', 'User Chat Id'),
            'is_open' => Yii::t('model/redis/cmc-console/user', 'Is Open'),
            'add_time' => Yii::t('model/redis/cmc-console/user', 'Add Time'),
            'update_time' => Yii::t('model/redis/cmc-console/user', 'Update Time'),
        ];
    }
}
 
 

3、查看 /common/components/redis/ActiveRecord.php ,定义了前缀,适用于所有 AR 键。

<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/02/05
 * Time: 9:47
 */
 
namespace common\components\redis;
 
use Yii;
 
class ActiveRecord extends \yii\redis\ActiveRecord
{
    /**
     * Declares prefix of the key that represents the keys that store this records in redis.
     * By default this method returns the class name as the table name by calling [[Inflector::camel2id()]].
     * For example, 'Customer' becomes 'customer', and 'OrderItem' becomes
     * 'order_item'. You may override this method if you want different key naming.
     * @return string the prefix to apply to all AR keys
     */
    public static function keyPrefix()
    {
        return Yii::$app->params['redisActiveRecord']['keyPrefix'] . parent::keyPrefix();
    }
}
 

4、打开 RedisDesktopManager,查看 用户 总数,确定为 29 个,如图2

打开 RedisDesktopManager,查看 用户 总数,确定为 29 个

图2

5、打开 RedisDesktopManager,确定主键值为 37918 的记录为 1 个,并未重复。如图3

打开 RedisDesktopManager,确定主键值为 37918 的记录为 1 个,并未重复。

图3

6、查看 pa:ar:user 的值,发现行 29、30 的值皆为 37918。由此确定,是此键的值导致了 id 等于 37918 的资源数等于 2 个。如图4

查看 pa:ar:user 的值,发现行 29、30 的值皆为 37918。由此确定,是此键的值导致了 id 等于 37918 的资源数等于 2 个。

图4

7、删除 pa:ar:user 的第 30 行,如图5

删除 pa:ar:user 的第 30 行

图5

8、再次请求接口,响应参数中资源总数量为 29 个。包含 id 等于 37918 的资源未重复。仅剩下 1 个。


{
  "code": 10000,
  "message": "获取 CMC 用户列表成功",
  "data": {
    "items": [
      {
        "user_birthday": "1990-01-01",
        "login_name": "xianwanzhou",
        "add_time": "2020-03-31 09:41:07",
        "user_email": "",
        "group_id": "643d80843ae23bcfa95b75bae30a7656",
        "id": "37918",
        "user_pic": "http://uploads.cmc.lzgbdst.com/uploads/cmc_user_avatar/default_header.png",
        "update_time": "2020-03-31 09:43:16",
        "is_open": "1",
        "user_nick": "鲜万州",
        "user_mobile": "15208396209",
        "user_token": "6a1de11e594d61790963eaaf1d9bee8d",
        "user_chat_id": "f98e3b834f577cc3d83d74323cd3094d",
        "user_type": "2",
        "user_sex": "2"
      }
    ],
    "_links": {
      "self": {
        "href": "http://pcsapi.cmc.lzgbdst.com/v1/cmc-users?login_id=7309cba1c93fc0a80663007612b784b8&login_tid=25f49c543b8ec31c6d905def0ad99913&per-page=29&page=1"
      }
    },
    "_meta": {
      "totalCount": 29,
      "pageCount": 1,
      "currentPage": 1,
      "perPage": 29
    }
  }
}


9、准备在本地环境复现一下 ID 主键重复的情况。请求接口,响应参数中资源总数量为 13 个。ID 主键未重复。如图6

准备在本地环境复现一下 ID 主键重复的情况。请求接口,响应参数中资源总数量为 13 个。ID 主键未重复。

图6


{
  "code": 10000,
  "message": "获取 CMC 用户列表成功",
  "data": {
    "items": [
      {
        "login_name": "13281105967",
        "update_time": "2019-12-11 14:28:26",
        "group_id": "015ce30b116ce86058fa6ab4fea4ac63",
        "user_nick": "13281105967",
        "user_sex": "2",
        "user_mobile": "13281105967",
        "user_type": "1",
        "is_open": "1",
        "user_chat_id": "ede7616c5e4232896453202cd0c3f7ec",
        "user_pic": "https://pgcupload.flydev.chinamcloud.cn/uploads/cmc_user_avatar/20190219/1550570817-4LLQJJ.png",
        "id": "3",
        "add_time": "2018-04-26 10:05:28",
        "user_birthday": "1990-01-01",
        "user_email": "13281105967@chinamcloud.com",
        "user_token": "fb46626f0e71e423ca8ab4c750620a85"
      },
      {
        "login_name": "test10",
        "update_time": "2019-12-11 15:00:38",
        "group_id": "015ce30b116ce86058fa6ab4fea4ac63",
        "user_nick": "test10",
        "user_sex": "2",
        "user_mobile": "13980074657",
        "user_type": "2",
        "is_open": "1",
        "user_chat_id": "ce524778954bd10d5a0ff65dadc0354b",
        "user_pic": "https://pgcupload.flydev.chinamcloud.cn/uploads/cmc_user_avatar/default_header.png",
        "id": "4",
        "add_time": "2019-12-11 14:55:07",
        "user_birthday": "1990-01-01",
        "user_email": "",
        "user_token": "bc8daab7ba8620c132cdf4e5de1d4758"
      },
      {
        "login_name": "jmj12130003",
        "update_time": "2019-12-13 14:41:55",
        "group_id": "015ce30b116ce86058fa6ab4fea4ac63",
        "user_nick": "jmj1213",
        "user_sex": "2",
        "user_mobile": "18412130003",
        "user_type": "2",
        "is_open": "1",
        "user_chat_id": "84e1bb32ffa895e56d950bbfa24fefc7",
        "user_pic": "https://pgcupload.flydev.chinamcloud.cn/uploads/cmc_user_avatar/default_header.png",
        "id": "49",
        "add_time": "2019-12-13 14:41:55",
        "user_birthday": "1990-01-01",
        "user_email": "",
        "user_token": "ba0ca65da7c3048fd9d449bb0d21a39b"
      },
      {
        "login_name": "test11",
        "update_time": "2019-12-17 11:14:53",
        "group_id": "015ce30b116ce86058fa6ab4fea4ac63",
        "user_nick": "test11",
        "user_sex": "2",
        "user_mobile": "13980074650",
        "user_type": "2",
        "is_open": "1",
        "user_chat_id": "bc1650a6834fc490de65a4527dfc8ae5",
        "user_pic": "https://pgcupload.flydev.chinamcloud.cn/uploads/cmc_user_avatar/default_header.png",
        "id": "64",
        "add_time": "2019-12-17 11:14:53",
        "user_birthday": "1990-01-01",
        "user_email": "",
        "user_token": "04532bb62deb99bf229698c9e1a81da1"
      },
      {
        "login_name": "test12",
        "update_time": "2019-12-17 11:15:14",
        "group_id": "015ce30b116ce86058fa6ab4fea4ac63",
        "user_nick": "test12",
        "user_sex": "2",
        "user_mobile": "13980074651",
        "user_type": "2",
        "is_open": "1",
        "user_chat_id": "fa154673421e5a3731991498397d712d",
        "user_pic": "https://pgcupload.flydev.chinamcloud.cn/uploads/cmc_user_avatar/default_header.png",
        "id": "65",
        "add_time": "2019-12-17 11:15:14",
        "user_birthday": "1990-01-01",
        "user_email": "",
        "user_token": "bcdc9e3781180b7bc18bc0e38777a467"
      },
      {
        "login_name": "test13",
        "update_time": "2019-12-17 11:15:35",
        "group_id": "015ce30b116ce86058fa6ab4fea4ac63",
        "user_nick": "test13",
        "user_sex": "2",
        "user_mobile": "13980074652",
        "user_type": "2",
        "is_open": "1",
        "user_chat_id": "35ce7075c1c57bb6c66d0f67a7840383",
        "user_pic": "https://pgcupload.flydev.chinamcloud.cn/uploads/cmc_user_avatar/default_header.png",
        "id": "66",
        "add_time": "2019-12-17 11:15:35",
        "user_birthday": "1990-01-01",
        "user_email": "",
        "user_token": "633cae769e274cabd4441acb7be1c5a1"
      },
      {
        "login_name": "test14",
        "update_time": "2019-12-17 11:15:55",
        "group_id": "015ce30b116ce86058fa6ab4fea4ac63",
        "user_nick": "test14",
        "user_sex": "2",
        "user_mobile": "13980074654",
        "user_type": "2",
        "is_open": "1",
        "user_chat_id": "3190c55b297b51b38463da4eae6bbd95",
        "user_pic": "https://pgcupload.flydev.chinamcloud.cn/uploads/cmc_user_avatar/default_header.png",
        "id": "67",
        "add_time": "2019-12-17 11:15:55",
        "user_birthday": "1990-01-01",
        "user_email": "",
        "user_token": "84c5871da19f7a489234af73c491f74f"
      },
      {
        "login_name": "test15",
        "update_time": "2019-12-17 11:16:16",
        "group_id": "015ce30b116ce86058fa6ab4fea4ac63",
        "user_nick": "test15",
        "user_sex": "2",
        "user_mobile": "13980074655",
        "user_type": "2",
        "is_open": "1",
        "user_chat_id": "fd072f598ec1a978f5fb968dfa386f0d",
        "user_pic": "https://pgcupload.flydev.chinamcloud.cn/uploads/cmc_user_avatar/default_header.png",
        "id": "68",
        "add_time": "2019-12-17 11:16:16",
        "user_birthday": "1990-01-01",
        "user_email": "",
        "user_token": "5bb37b4045e9ad6eb1cc398d3170d33e"
      },
      {
        "login_name": "test16",
        "update_time": "2019-12-17 11:16:36",
        "group_id": "015ce30b116ce86058fa6ab4fea4ac63",
        "user_nick": "test16",
        "user_sex": "2",
        "user_mobile": "13980074656",
        "user_type": "2",
        "is_open": "1",
        "user_chat_id": "88178648656ae259bae213ee00ccb4c7",
        "user_pic": "https://pgcupload.flydev.chinamcloud.cn/uploads/cmc_user_avatar/default_header.png",
        "id": "69",
        "add_time": "2019-12-17 11:16:36",
        "user_birthday": "1990-01-01",
        "user_email": "",
        "user_token": "2926796eb8e990aa8bd726e121cb91e8"
      },
      {
        "login_name": "test17",
        "update_time": "2019-12-17 11:17:07",
        "group_id": "015ce30b116ce86058fa6ab4fea4ac63",
        "user_nick": "test17",
        "user_sex": "2",
        "user_mobile": "13980074653",
        "user_type": "2",
        "is_open": "1",
        "user_chat_id": "b03d6e7b4db061d52b3d420844a5dde8",
        "user_pic": "https://pgcupload.flydev.chinamcloud.cn/uploads/cmc_user_avatar/default_header.png",
        "id": "70",
        "add_time": "2019-12-17 11:17:07",
        "user_birthday": "1990-01-01",
        "user_email": "",
        "user_token": "bf028bc0353bf8ff070bfd62490ae284"
      },
      {
        "login_name": "test18",
        "update_time": "2019-12-17 11:17:25",
        "group_id": "015ce30b116ce86058fa6ab4fea4ac63",
        "user_nick": "test18",
        "user_sex": "2",
        "user_mobile": "13980074658",
        "user_type": "2",
        "is_open": "1",
        "user_chat_id": "c1eddd55f8efcec8da1e0cc6fc1a5624",
        "user_pic": "https://pgcupload.flydev.chinamcloud.cn/uploads/cmc_user_avatar/default_header.png",
        "id": "71",
        "add_time": "2019-12-17 11:17:25",
        "user_birthday": "1990-01-01",
        "user_email": "",
        "user_token": "4adbe2313b7e4967ac518e4e0a73f5c9"
      },
      {
        "login_name": "test19",
        "update_time": "2019-12-17 11:17:41",
        "group_id": "015ce30b116ce86058fa6ab4fea4ac63",
        "user_nick": "test19",
        "user_sex": "2",
        "user_mobile": "13980074659",
        "user_type": "2",
        "is_open": "1",
        "user_chat_id": "5bf1e9f7e4bf9aa2d8a633eddf628710",
        "user_pic": "https://pgcupload.flydev.chinamcloud.cn/uploads/cmc_user_avatar/default_header.png",
        "id": "72",
        "add_time": "2019-12-17 11:17:41",
        "user_birthday": "1990-01-01",
        "user_email": "",
        "user_token": "dd7ab3f1fb3e8651b35ba070d10594c7"
      },
      {
        "login_name": "15708495493",
        "update_time": "2020-03-02 14:31:36",
        "group_id": "015ce30b116ce86058fa6ab4fea4ac63",
        "user_nick": "clover",
        "user_sex": "2",
        "user_mobile": "15708495493",
        "user_type": "2",
        "is_open": "1",
        "user_chat_id": "251f91338781d5354e08c1351ca3342d",
        "user_pic": "https://pgcupload.flydev.chinamcloud.cn/uploads/cmc_user_avatar/default_header.png",
        "id": "166",
        "add_time": "2020-03-02 14:31:36",
        "user_birthday": "1990-01-01",
        "user_email": "",
        "user_token": "ff94d3f7b1dafada193ae7d6a82fa628"
      }
    ],
    "_links": {
      "self": {
        "href": "http://api.pcs-api.localhost/v1/cmc-users?login_id=2e368664c41b8bf511bcc9c65d86dbc3&login_tid=efda7e64b7747f8c4360b29aa9c18f77&per-page=13&page=1"
      }
    },
    "_meta": {
      "totalCount": 13,
      "pageCount": 1,
      "currentPage": 1,
      "perPage": 13
    }
  }
}


10、在程序执行过程中,插入数据至 Redis 中时,会判断 ID 是否存在,存在则更新,不存在则插入。初步怀疑是在并发请求的情况下。皆执行了插入的操作。


            $redisCmcConsoleUser = new RedisCmcConsoleUser();
            $redisCmcConsoleUserResult = $redisCmcConsoleUser->initSync(['group_id' => $groupInfo['group_id']], $loginId, $loginTid);
            if ($redisCmcConsoleUserResult === false) {
                throw new NotFoundHttpException(Yii::t('error', Yii::t('error', Yii::t('error', '201041'), ['id' => $loginId])), 201041);
            }

            $redisCmcConsoleUserItem = $redisCmcConsoleUser::find()->where(['id' => $userInfo['id'], 'group_id' => Yii::$app->params['groupId']])->one();

            /* 如果资源不存在,则插入;否则更新 */
            $redisCmcConsoleUserAttributes = [
                'id' => $userInfo['id'],
                'group_id' => $groupInfo['group_id'],
                'login_name' => $userInfo['login_name'],
                'user_token' => $userInfo['user_token'],
                'user_nick' => $userInfo['user_nick'],
                'user_pic' => $userInfo['user_pic'],
                'user_mobile' => $userInfo['user_mobile'] ? $userInfo['user_mobile'] : '',
                'user_email' => $userInfo['user_email'] ? $userInfo['user_email'] : '',
                'user_sex' => $userInfo['user_sex'],
                'user_type' => $userInfo['user_type'],
                'user_birthday' => $userInfo['user_birthday'],
                'user_chat_id' => $userInfo['user_chat_id'] ? $userInfo['user_chat_id'] : '',
                'is_open' => $userInfo['is_open'],
                'add_time' => $userInfo['add_time'],
                'update_time' => $userInfo['update_time'],
            ];
            if (!isset($redisCmcConsoleUserItem)) {
                $redisCmcConsoleUser->attributes = $redisCmcConsoleUserAttributes;
                $redisCmcConsoleUser->insert();
                // 设置用户身份为已认证
                Yii::$app->user->setIdentity($redisCmcConsoleUser);
            } else {
                $redisCmcConsoleUserItem->attributes = $redisCmcConsoleUserAttributes;
                $redisCmcConsoleUserItem->save();
                // 设置用户身份为已认证
                Yii::$app->user->setIdentity($redisCmcConsoleUserItem);
            }


11、在程序执行过程中,插入数据至 Redis 中时,不论 ID 是否存在,皆插入。请求接口,响应参数中资源总数量为 14 个。包含 id 等于 3 的资源是重复的。总计为 2 个。如图7

在程序执行过程中,插入数据至 Redis 中时,不论 ID 是否存在,皆插入。请求接口,响应参数中资源总数量为 14 个。包含 id 等于 3 的资源是重复的。总计为 2 个。

图7


            if (!isset($redisCmcConsoleUserItem)) {
                $redisCmcConsoleUser->attributes = $redisCmcConsoleUserAttributes;
                $redisCmcConsoleUser->insert();
                // 设置用户身份为已认证
                Yii::$app->user->setIdentity($redisCmcConsoleUser);
            } else {
                $redisCmcConsoleUserItem->attributes = $redisCmcConsoleUserAttributes;
                $redisCmcConsoleUserItem->insert();
                // 设置用户身份为已认证
                Yii::$app->user->setIdentity($redisCmcConsoleUserItem);
            }



{
  "code": 10000,
  "message": "获取 CMC 用户列表成功",
  "data": {
    "items": [
      {
        "login_name": "13281105967",
        "update_time": "2019-12-11 14:28:26",
        "group_id": "015ce30b116ce86058fa6ab4fea4ac63",
        "user_nick": "13281105967",
        "user_sex": "2",
        "user_mobile": "13281105967",
        "user_type": "1",
        "is_open": "1",
        "user_chat_id": "ede7616c5e4232896453202cd0c3f7ec",
        "user_pic": "https://pgcupload.flydev.chinamcloud.cn/uploads/cmc_user_avatar/20190219/1550570817-4LLQJJ.png",
        "id": "3",
        "add_time": "2018-04-26 10:05:28",
        "user_birthday": "1990-01-01",
        "user_email": "13281105967@chinamcloud.com",
        "user_token": "fb46626f0e71e423ca8ab4c750620a85"
      },
      {
        "login_name": "13281105967",
        "update_time": "2019-12-11 14:28:26",
        "group_id": "015ce30b116ce86058fa6ab4fea4ac63",
        "user_nick": "13281105967",
        "user_sex": "2",
        "user_mobile": "13281105967",
        "user_type": "1",
        "is_open": "1",
        "user_chat_id": "ede7616c5e4232896453202cd0c3f7ec",
        "user_pic": "https://pgcupload.flydev.chinamcloud.cn/uploads/cmc_user_avatar/20190219/1550570817-4LLQJJ.png",
        "id": "3",
        "add_time": "2018-04-26 10:05:28",
        "user_birthday": "1990-01-01",
        "user_email": "13281105967@chinamcloud.com",
        "user_token": "fb46626f0e71e423ca8ab4c750620a85"
      }
    ],
    "_links": {
      "self": {
        "href": "http://api.pcs-api.localhost/v1/cmc-users?login_id=2e368664c41b8bf511bcc9c65d86dbc3&login_tid=efda7e64b7747f8c4360b29aa9c18f77&per-page=14&page=1"
      }
    },
    "_meta": {
      "totalCount": 14,
      "pageCount": 1,
      "currentPage": 1,
      "perPage": 14
    }
  }
}


12、由此可以确认,Redis ActiveRecord 不能够确保主键 ID 的唯一性的。现阶段有 2 种方案,第 1 种方案是插入记录时基于 Redis 实现唯一性的锁定。第 2 种方案是查询时去重。决定采用第 2 种方案。由于 redis 不支持 SQL 查询,因此查询 API 仅限于以下方法: where(),limit(),offset(),orderBy() 和 indexBy()。 (orderBy() 尚未实现:#1305)。基于 indexBy()。请求接口,响应参数中资源总数量为 13 个。ID 主键未重复。但是,totalCount 的值为 14。统计错误。如图8

由此可以确认,Redis ActiveRecord 不能够确保主键 ID 的唯一性的。现阶段有 2 种方案,第 1 种方案是插入记录时基于 Redis 实现唯一性的锁定。第 2 种方案是查询时去重。决定采用第 2 种方案。由于 redis 不支持 SQL 查询,因此查询 API 仅限于以下方法: where(),limit(),offset(),orderBy() 和 indexBy()。 (orderBy() 尚未实现:#1305)。基于 indexBy()。请求接口,响应参数中资源总数量为 13 个。ID 主键未重复。但是,totalCount 的值为 14。统计错误。

图8


        // 查询当前用户所属租户 ID 下的 CMC 的用户模型(Redis)
        $query = $modelClass::find()
            ->where([
                'group_id' => $identity->group_id,
                'is_open' => $modelClass::STATUS_ENABLED
            ])
            ->indexBy('id');



{
  "code": 10000,
  "message": "获取 CMC 用户列表成功",
  "data": {
    "items": [
      {
        "login_name": "13281105967",
        "update_time": "2019-12-11 14:28:26",
        "group_id": "015ce30b116ce86058fa6ab4fea4ac63",
        "user_nick": "13281105967",
        "user_sex": "2",
        "user_mobile": "13281105967",
        "user_type": "1",
        "is_open": "1",
        "user_chat_id": "ede7616c5e4232896453202cd0c3f7ec",
        "user_pic": "https://pgcupload.flydev.chinamcloud.cn/uploads/cmc_user_avatar/20190219/1550570817-4LLQJJ.png",
        "id": "3",
        "add_time": "2018-04-26 10:05:28",
        "user_birthday": "1990-01-01",
        "user_email": "13281105967@chinamcloud.com",
        "user_token": "fb46626f0e71e423ca8ab4c750620a85"
      }
    ],
    "_links": {
      "self": {
        "href": "http://api.pcs-api.localhost/v1/cmc-users?login_id=2e368664c41b8bf511bcc9c65d86dbc3&login_tid=efda7e64b7747f8c4360b29aa9c18f77&per-page=14&page=1"
      }
    },
    "_meta": {
      "totalCount": 14,
      "pageCount": 1,
      "currentPage": 1,
      "perPage": 14
    }
  }
}


13、因此,尝试采用第 1 种方案。不过由于 此处程序实现 是所有请求皆会执行到的流程,担心锁定实现降低程序性能,最终决定,放弃插入,仅做更新。如果 Redis 中用户不存在,则插入;否则更新。调整为:如果 Redis 中用户不存在,则响应 404;否则更新。


            /* 如果资源不存在,则响应 404 */
            if (!isset($redisCmcConsoleUserItem)) {
                throw new NotFoundHttpException(Yii::t('error', Yii::t('error', Yii::t('error', '201011'), ['user_nick' => $userInfo['user_nick']])), 201011);
            }

            /* 更新 */
            $redisCmcConsoleUserItem->attributes = $redisCmcConsoleUserAttributes;
            $redisCmcConsoleUserItem->save();
            // 设置用户身份为已认证
            Yii::$app->user->setIdentity($redisCmcConsoleUserItem);


14、如果 Redis 中用户不存在,则响应 404。如图9

如果 Redis 中用户不存在,则响应 404。

图9

15、但是,此修复仅防止以后出现用户重复的问题,之前已经重复的用户,仍然是重复的。如果要去重,需要手动操作 Redis。且此修复会衍生出一个新的影响体验的问题,即在框架处新添加了一个用户 B 后,如果用户 B 在 Redis 中不存在,则用户 B 无法使用策划指挥。需要等待用户 B 同步至 Redis 后,才可使用。

 

]]>
https://www.shuijingwanwq.com/2020/05/27/4178/feed/ 0
在 Yii 2.0 中添加了多个 DB 应用组件时,Gii 的生成流程 https://www.shuijingwanwq.com/2020/05/20/4164/ https://www.shuijingwanwq.com/2020/05/20/4164/#respond Wed, 20 May 2020 06:27:07 +0000 https://www.shuijingwanwq.com/?p=4164 浏览量: 84 1、在 Yii 2.0 中添加了多个数据库连接组件时


    'components' => [
        'db' => [
            'class' => 'yii\db\Connection',
            'dsn' => 'mysql:host=62.234.135.47;dbname=pcs_api',
            'username' => 'sq_pcs',
            'password' => '',
            'tablePrefix' => 'pa_',
            'charset' => 'utf8mb4',
            'enableSchemaCache' => false,
            'schemaCacheDuration' => 3600,
            'schemaCache' => 'redisCache',
        ],
        'statDb' => [
            'class' => 'yii\db\Connection',
            'dsn' => 'mysql:host=62.234.135.47;dbname=pcs_stat',
            'username' => 'sq_pcs',
            'password' => '',
            'tablePrefix' => 'ps_',
            'charset' => 'utf8mb4',
        ],
    ],


2、数据库连接ID选择 statDb 时,表名的下拉列表中,仅会出现 statDb 下的数据表,如图1
数据库连接ID选择 statDb 时,表名的下拉列表中,仅会出现 statDb 下的数据表

图1

3、当生成 statDb 下的模型文件时,会额外生成 getDb() ,如图2
当生成 statDb 下的模型文件时,会额外生成 getDb()

图2



    /** 
     * @return \yii\db\Connection the database connection used by this AR class. 
     */ 
    public static function getDb() 
    { 
        return Yii::$app->get('statDb'); 
    } 


4、数据库连接ID选择 db 时,表名的下拉列表中,未出现 db 下的数据表,因此,需要手动填写相应的信息。如图3
数据库连接ID选择 db 时,表名的下拉列表中,未出现 db 下的数据表,因此,需要手动填写相应的信息。

图3

5、当生成 db 下的模型文件时,不会生成 getDb() ,因为 db 是默认的。如图4
当生成 db 下的模型文件时,不会生成 getDb() ,因为 db 是默认的。

图4

6、当 Preview 或者 Generate 后,数据库连接ID选择 db 时,表名的下拉列表中,仅会出现 db 下的数据表。如图5
当 Preview 或者 Generate 后,数据库连接ID选择 db 时,表名的下拉列表中,仅会出现 db 下的数据表。

图5

]]>
https://www.shuijingwanwq.com/2020/05/20/4164/feed/ 0
Nginx + php-fpm 在 Windows 10、CentOS 8 下的串行、并行支持与否的分析测试与解决 https://www.shuijingwanwq.com/2020/03/26/4043/ https://www.shuijingwanwq.com/2020/03/26/4043/#respond Thu, 26 Mar 2020 08:06:18 +0000 https://www.shuijingwanwq.com/?p=4043 浏览量: 119 1、Nginx + php-fpm 在 Windows 10 下的情况表现,当在一个请求(http://api.channel-pub-api.localhost)中 CURL 另一个请求(http://api.channel-pub-api.localhost)时,报错:fopen(http://api.channel-pub-api.localhost/qq/v1/articles/standard?group_id=015ce30b116ce86058fa6ab4fea4ac63): failed to open stream: HTTP request failed! 。如图1
Nginx + php-fpm 在 Windows 10 下的情况表现,当在一个请求(http://api.channel-pub-api.localhost)中 CURL 另一个请求(http://api.channel-pub-api.localhost)时,报错:fopen(http://api.channel-pub-api.localhost/qq/v1/articles/standard?group_id=015ce30b116ce86058fa6ab4fea4ac63): failed to open stream: HTTP request failed! 。

图1



{
    "name": "HTTP Client Exception",
    "message": "fopen(http://api.channel-pub-api.localhost/qq/v1/articles/standard?group_id=015ce30b116ce86058fa6ab4fea4ac63): failed to open stream: HTTP request failed! ",
    "code": 2,
    "type": "yii\\httpclient\\Exception",
    "file": "E:\\wwwroot\\channel-pub-api-feature-task-group\\vendor\\yiisoft\\yii2-httpclient\\src\\StreamTransport.php",
    "line": 68,
    "stack-trace": [
        "#0 E:\\wwwroot\\channel-pub-api-feature-task-group\\vendor\\yiisoft\\yii2-httpclient\\src\\Transport.php(41): yii\\httpclient\\StreamTransport->send(Object(yii\\httpclient\\Request))",
        "#1 E:\\wwwroot\\channel-pub-api-feature-task-group\\vendor\\yiisoft\\yii2-httpclient\\src\\Client.php(259): yii\\httpclient\\Transport->batchSend(Array)",
        "#2 E:\\wwwroot\\channel-pub-api-feature-task-group\\common\\logics\\http\\channel_pub_api\\Article.php(55): yii\\httpclient\\Client->batchSend(Array)",
        "#3 E:\\wwwroot\\channel-pub-api-feature-task-group\\common\\services\\TaskGroupService.php(117): common\\logics\\http\\channel_pub_api\\Article->batchPostArticlesStandard('015ce30b116ce86...', Array)",
        "#4 E:\\wwwroot\\channel-pub-api-feature-task-group\\api\\filters\\TaskGroupFilter.php(45): common\\services\\TaskGroupService::createMultipleSync(Array)",
        "#5 E:\\wwwroot\\channel-pub-api-feature-task-group\\vendor\\yiisoft\\yii2\\base\\ActionFilter.php(92): api\\filters\\TaskGroupFilter->afterAction(Object(api\\rests\\task_group\\CreateAction), Array)",
        "#6 [internal function]: yii\\base\\ActionFilter->afterFilter(Object(yii\\base\\ActionEvent))",
        "#7 E:\\wwwroot\\channel-pub-api-feature-task-group\\vendor\\yiisoft\\yii2\\base\\Component.php(627): call_user_func(Array, Object(yii\\base\\ActionEvent))",
        "#8 E:\\wwwroot\\channel-pub-api-feature-task-group\\vendor\\yiisoft\\yii2\\base\\Controller.php(305): yii\\base\\Component->trigger('afterAction', Object(yii\\base\\ActionEvent))",
        "#9 E:\\wwwroot\\channel-pub-api-feature-task-group\\vendor\\yiisoft\\yii2\\rest\\Controller.php(76): yii\\base\\Controller->afterAction(Object(api\\rests\\task_group\\CreateAction), Array)",
        "#10 E:\\wwwroot\\channel-pub-api-feature-task-group\\vendor\\yiisoft\\yii2\\base\\Controller.php(159): yii\\rest\\Controller->afterAction(Object(api\\rests\\task_group\\CreateAction), Array)",
        "#11 E:\\wwwroot\\channel-pub-api-feature-task-group\\vendor\\yiisoft\\yii2\\base\\Module.php(528): yii\\base\\Controller->runAction('create', Array)",
        "#12 E:\\wwwroot\\channel-pub-api-feature-task-group\\vendor\\yiisoft\\yii2\\web\\Application.php(103): yii\\base\\Module->runAction('v1/task-group/c...', Array)",
        "#13 E:\\wwwroot\\channel-pub-api-feature-task-group\\vendor\\yiisoft\\yii2\\base\\Application.php(386): yii\\web\\Application->handleRequest(Object(yii\\web\\Request))",
        "#14 E:\\wwwroot\\channel-pub-api-feature-task-group\\api\\web\\index.php(17): yii\\base\\Application->run()",
        "#15 {main}"
    ],
    "previous": {
        "name": "PHP Warning",
        "message": "fopen(http://api.channel-pub-api.localhost/qq/v1/articles/standard?group_id=015ce30b116ce86058fa6ab4fea4ac63): failed to open stream: HTTP request failed! ",
        "code": 2,
        "type": "yii\\base\\ErrorException",
        "file": "E:\\wwwroot\\channel-pub-api-feature-task-group\\vendor\\yiisoft\\yii2-httpclient\\src\\StreamTransport.php",
        "line": 61,
        "stack-trace": [
            "#0 [internal function]: yii\\base\\ErrorHandler->handleError(2, 'fopen(http://ap...', 'E:\\\\wwwroot\\\\chan...', 61, Array)",
            "#1 E:\\wwwroot\\channel-pub-api-feature-task-group\\vendor\\yiisoft\\yii2-httpclient\\src\\StreamTransport.php(61): fopen('http://api.chan...', 'rb', false, Resource id #205)",
            "#2 E:\\wwwroot\\channel-pub-api-feature-task-group\\vendor\\yiisoft\\yii2-httpclient\\src\\Transport.php(41): yii\\httpclient\\StreamTransport->send(Object(yii\\httpclient\\Request))",
            "#3 E:\\wwwroot\\channel-pub-api-feature-task-group\\vendor\\yiisoft\\yii2-httpclient\\src\\Client.php(259): yii\\httpclient\\Transport->batchSend(Array)",
            "#4 E:\\wwwroot\\channel-pub-api-feature-task-group\\common\\logics\\http\\channel_pub_api\\Article.php(55): yii\\httpclient\\Client->batchSend(Array)",
            "#5 E:\\wwwroot\\channel-pub-api-feature-task-group\\common\\services\\TaskGroupService.php(117): common\\logics\\http\\channel_pub_api\\Article->batchPostArticlesStandard('015ce30b116ce86...', Array)",
            "#6 E:\\wwwroot\\channel-pub-api-feature-task-group\\api\\filters\\TaskGroupFilter.php(45): common\\services\\TaskGroupService::createMultipleSync(Array)",
            "#7 E:\\wwwroot\\channel-pub-api-feature-task-group\\vendor\\yiisoft\\yii2\\base\\ActionFilter.php(92): api\\filters\\TaskGroupFilter->afterAction(Object(api\\rests\\task_group\\CreateAction), Array)",
            "#8 [internal function]: yii\\base\\ActionFilter->afterFilter(Object(yii\\base\\ActionEvent))",
            "#9 E:\\wwwroot\\channel-pub-api-feature-task-group\\vendor\\yiisoft\\yii2\\base\\Component.php(627): call_user_func(Array, Object(yii\\base\\ActionEvent))",
            "#10 E:\\wwwroot\\channel-pub-api-feature-task-group\\vendor\\yiisoft\\yii2\\base\\Controller.php(305): yii\\base\\Component->trigger('afterAction', Object(yii\\base\\ActionEvent))",
            "#11 E:\\wwwroot\\channel-pub-api-feature-task-group\\vendor\\yiisoft\\yii2\\rest\\Controller.php(76): yii\\base\\Controller->afterAction(Object(api\\rests\\task_group\\CreateAction), Array)",
            "#12 E:\\wwwroot\\channel-pub-api-feature-task-group\\vendor\\yiisoft\\yii2\\base\\Controller.php(159): yii\\rest\\Controller->afterAction(Object(api\\rests\\task_group\\CreateAction), Array)",
            "#13 E:\\wwwroot\\channel-pub-api-feature-task-group\\vendor\\yiisoft\\yii2\\base\\Module.php(528): yii\\base\\Controller->runAction('create', Array)",
            "#14 E:\\wwwroot\\channel-pub-api-feature-task-group\\vendor\\yiisoft\\yii2\\web\\Application.php(103): yii\\base\\Module->runAction('v1/task-group/c...', Array)",
            "#15 E:\\wwwroot\\channel-pub-api-feature-task-group\\vendor\\yiisoft\\yii2\\base\\Application.php(386): yii\\web\\Application->handleRequest(Object(yii\\web\\Request))",
            "#16 E:\\wwwroot\\channel-pub-api-feature-task-group\\api\\web\\index.php(17): yii\\base\\Application->run()",
            "#17 {main}"
        ]
    }
}


2、编辑 Nginx 配置文件,复制 server:API 为 server:LOCALHOST API。调整 listen 81、server_name localhost、fastcgi_pass 127.0.0.1:9001。总计 3 项配置值。如图2、图3
编辑 Nginx 配置文件,复制 server:API 为 server:LOCALHOST API。调整 listen 81、server_name localhost

图2

 
编辑 Nginx 配置文件,复制 server:API 为 server:LOCALHOST API。调整 fastcgi_pass 127.0.0.1:9001

图3



## FRONTEND ##
server {
    charset utf-8;

	client_max_body_size 200m;
	client_body_buffer_size 1024k;

	fastcgi_read_timeout 180s;

    listen 80; ## listen for ipv4
    #listen [::]:80 default_server ipv6only=on; ## listen for ipv6

    server_name www.channel-pub-api.localhost www.channel-pub-api-localhost.chinamcloud.cn auth.channel-pub.wjdev.chinamcloud.cn;
    root        E:/wwwroot/channel-pub-api-feature-task-group/frontend/web;
    index       index.php;

    access_log  logs/www.channel-pub-api.localhost.access.log;
    error_log   logs/www.channel-pub-api.localhost.error.log;

	location / {
		# Redirect everything that isn't a real file to index.php
		try_files $uri $uri/ /index.php$is_args$args;
	}

	# uncomment to avoid processing of calls to non-existing static files by Yii
	#location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {
	#    try_files $uri =404;
	#}
	#error_page 404 /404.html;

	# deny accessing php files for the /assets directory
	location ~ ^/assets/.*\.php$ {
		deny all;
	}

	location ~ \.php$ {
		include fastcgi_params;
		fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
		fastcgi_pass 127.0.0.1:9000;
		#fastcgi_pass unix:/var/run/php5-fpm.sock;
		try_files $uri =404;
	}

	location ~* /\. {
		deny all;
	}
}

## API ##
server {
    charset utf-8;

	client_max_body_size 200m;
	client_body_buffer_size 1024k;

	fastcgi_read_timeout 180s;

    listen 80; ## listen for ipv4
    #listen [::]:80 default_server ipv6only=on; ## listen for ipv6

    server_name api.channel-pub-api.localhost api.channel-pub-api-localhost.chinamcloud.cn;

    root E:/wwwroot/channel-pub-api-feature-task-group;
    index index.php;

    access_log  logs/api.channel-pub-api.localhost.access.log;
    error_log   logs/api.channel-pub-api.localhost.error.log;

	location / {
        root E:/wwwroot/channel-pub-api-feature-task-group/api/web;
        try_files $uri $uri/ /api/web/index.php$is_args$args;

        # omit static files logging, and if they don't exist, avoid processing by Yii (uncomment if necessary)
        #location ~ ^/.+\.(css|js|ico|png|jpe?g|gif|svg|ttf|mp4|mov|swf|pdf|zip|rar)$ {
        #    log_not_found off;
        #    access_log off;
        #    try_files $uri =404;
        #}

        location ~ ^/assets/.+\.php(/|$) {
            deny all;
        }
    }

    location /baijia {
        alias E:/wwwroot/channel-pub-api-feature-task-group/baijia/web/;

        # redirect to the URL without a trailing slash (uncomment if necessary)
        #location = /baijia/ {
        #    return 301 /baijia;
        #}

        # prevent the directory redirect to the URL with a trailing slash
        location = /baijia {
            # if your location is "/baijia", try use "/baijia/baijia/web/index.php$is_args$args"
            # bug ticket: https://trac.nginx.org/nginx/ticket/97
            try_files $uri /baijia/baijia/web/index.php$is_args$args;
        }

        # if your location is "/baijia", try use "/baijia/baijia/web/index.php$is_args$args"
        # bug ticket: https://trac.nginx.org/nginx/ticket/97
        try_files $uri $uri/ /baijia/baijia/web/index.php$is_args$args;

        # omit static files logging, and if they don't exist, avoid processing by Yii (uncomment if necessary)
        #location ~ ^/baijia/.+\.(css|js|ico|png|jpe?g|gif|svg|ttf|mp4|mov|swf|pdf|zip|rar)$ {
        #    log_not_found off;
        #    access_log off;
        #    try_files $uri =404;
        #}

        location ~ ^/baijia/assets/.+\.php(/|$) {
            deny all;
        }
    }

	location /customize {
        alias E:/wwwroot/channel-pub-api-feature-task-group/customize/web/;

        # redirect to the URL without a trailing slash (uncomment if necessary)
        #location = /customize/ {
        #    return 301 /customize;
        #}

        # prevent the directory redirect to the URL with a trailing slash
        location = /customize {
            # if your location is "/customize", try use "/customize/customize/web/index.php$is_args$args"
            # bug ticket: https://trac.nginx.org/nginx/ticket/97
            try_files $uri /customize/customize/web/index.php$is_args$args;
        }

        # if your location is "/customize", try use "/customize/customize/web/index.php$is_args$args"
        # bug ticket: https://trac.nginx.org/nginx/ticket/97
        try_files $uri $uri/ /customize/customize/web/index.php$is_args$args;

        # omit static files logging, and if they don't exist, avoid processing by Yii (uncomment if necessary)
        #location ~ ^/customize/.+\.(css|js|ico|png|jpe?g|gif|svg|ttf|mp4|mov|swf|pdf|zip|rar)$ {
        #    log_not_found off;
        #    access_log off;
        #    try_files $uri =404;
        #}

        location ~ ^/customize/assets/.+\.php(/|$) {
            deny all;
        }
    }

	location /netease {
        alias E:/wwwroot/channel-pub-api-feature-task-group/netease/web/;

        # redirect to the URL without a trailing slash (uncomment if necessary)
        #location = /netease/ {
        #    return 301 /netease;
        #}

        # prevent the directory redirect to the URL with a trailing slash
        location = /netease {
            # if your location is "/netease", try use "/netease/netease/web/index.php$is_args$args"
            # bug ticket: https://trac.nginx.org/nginx/ticket/97
            try_files $uri /netease/netease/web/index.php$is_args$args;
        }

        # if your location is "/netease", try use "/netease/netease/web/index.php$is_args$args"
        # bug ticket: https://trac.nginx.org/nginx/ticket/97
        try_files $uri $uri/ /netease/netease/web/index.php$is_args$args;

        # omit static files logging, and if they don't exist, avoid processing by Yii (uncomment if necessary)
        #location ~ ^/netease/.+\.(css|js|ico|png|jpe?g|gif|svg|ttf|mp4|mov|swf|pdf|zip|rar)$ {
        #    log_not_found off;
        #    access_log off;
        #    try_files $uri =404;
        #}

        location ~ ^/netease/assets/.+\.php(/|$) {
            deny all;
        }
    }

    location /qq {
        alias E:/wwwroot/channel-pub-api-feature-task-group/qq/web/;

        # redirect to the URL without a trailing slash (uncomment if necessary)
        #location = /qq/ {
        #    return 301 /qq;
        #}

        # prevent the directory redirect to the URL with a trailing slash
        location = /qq {
            # if your location is "/qq", try use "/qq/qq/web/index.php$is_args$args"
            # bug ticket: https://trac.nginx.org/nginx/ticket/97
            try_files $uri /qq/qq/web/index.php$is_args$args;
        }

        # if your location is "/qq", try use "/qq/qq/web/index.php$is_args$args"
        # bug ticket: https://trac.nginx.org/nginx/ticket/97
        try_files $uri $uri/ /qq/qq/web/index.php$is_args$args;

        # omit static files logging, and if they don't exist, avoid processing by Yii (uncomment if necessary)
        #location ~ ^/qq/.+\.(css|js|ico|png|jpe?g|gif|svg|ttf|mp4|mov|swf|pdf|zip|rar)$ {
        #    log_not_found off;
        #    access_log off;
        #    try_files $uri =404;
        #}

        location ~ ^/qq/assets/.+\.php(/|$) {
            deny all;
        }
    }

	location /weibo {
        alias E:/wwwroot/channel-pub-api-feature-task-group/weibo/web/;

        # redirect to the URL without a trailing slash (uncomment if necessary)
        #location = /weibo/ {
        #    return 301 /weibo;
        #}

        # prevent the directory redirect to the URL with a trailing slash
        location = /weibo {
            # if your location is "/weibo", try use "/weibo/weibo/web/index.php$is_args$args"
            # bug ticket: https://trac.nginx.org/nginx/ticket/97
            try_files $uri /weibo/weibo/web/index.php$is_args$args;
        }

        # if your location is "/weibo", try use "/weibo/weibo/web/index.php$is_args$args"
        # bug ticket: https://trac.nginx.org/nginx/ticket/97
        try_files $uri $uri/ /weibo/weibo/web/index.php$is_args$args;

        # omit static files logging, and if they don't exist, avoid processing by Yii (uncomment if necessary)
        #location ~ ^/weibo/.+\.(css|js|ico|png|jpe?g|gif|svg|ttf|mp4|mov|swf|pdf|zip|rar)$ {
        #    log_not_found off;
        #    access_log off;
        #    try_files $uri =404;
        #}

        location ~ ^/weibo/assets/.+\.php(/|$) {
            deny all;
        }
    }

	location /wx {
        alias E:/wwwroot/channel-pub-api-feature-task-group/wx/web/;

        # redirect to the URL without a trailing slash (uncomment if necessary)
        #location = /wx/ {
        #    return 301 /wx;
        #}

        # prevent the directory redirect to the URL with a trailing slash
        location = /wx {
            # if your location is "/wx", try use "/wx/wx/web/index.php$is_args$args"
            # bug ticket: https://trac.nginx.org/nginx/ticket/97
            try_files $uri /wx/wx/web/index.php$is_args$args;
        }

        # if your location is "/wx", try use "/wx/wx/web/index.php$is_args$args"
        # bug ticket: https://trac.nginx.org/nginx/ticket/97
        try_files $uri $uri/ /wx/wx/web/index.php$is_args$args;

        # omit static files logging, and if they don't exist, avoid processing by Yii (uncomment if necessary)
        #location ~ ^/wx/.+\.(css|js|ico|png|jpe?g|gif|svg|ttf|mp4|mov|swf|pdf|zip|rar)$ {
        #    log_not_found off;
        #    access_log off;
        #    try_files $uri =404;
        #}

        location ~ ^/wx/assets/.+\.php(/|$) {
            deny all;
        }
    }

	location ~ ^/.+\.php(/|$) {
        rewrite (?!^/((api|baijia|customize|netease|qq|weibo|wx)/web|baijia|customize|netease|qq|weibo|wx))^ /api/web$uri break;
		rewrite (?!^/baijia/web)^/baijia(/.+)$ /baijia/web$1 break;
		rewrite (?!^/customize/web)^/customize(/.+)$ /customize/web$1 break;
        rewrite (?!^/netease/web)^/netease(/.+)$ /netease/web$1 break;
		rewrite (?!^/qq/web)^/qq(/.+)$ /qq/web$1 break;
		rewrite (?!^/weibo/web)^/weibo(/.+)$ /weibo/web$1 break;
		rewrite (?!^/wx/web)^/wx(/.+)$ /wx/web$1 break;

		include fastcgi_params;
		fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
		fastcgi_pass 127.0.0.1:9000;
		#fastcgi_pass unix:/var/run/php5-fpm.sock;
        try_files $fastcgi_script_name =404;
    }

    location ~ /\. {
        deny all;
    }
}

## LOCALHOST API ##
server {
    charset utf-8;

	client_max_body_size 200m;
	client_body_buffer_size 1024k;

	fastcgi_read_timeout 180s;

    listen 81; ## listen for ipv4
    #listen [::]:80 default_server ipv6only=on; ## listen for ipv6

    server_name localhost;

    root E:/wwwroot/channel-pub-api-feature-task-group;
    index index.php;

    access_log  logs/localhost.access.log;
    error_log   logs/localhost.error.log;

	location / {
        root E:/wwwroot/channel-pub-api-feature-task-group/api/web;
        try_files $uri $uri/ /api/web/index.php$is_args$args;

        # omit static files logging, and if they don't exist, avoid processing by Yii (uncomment if necessary)
        #location ~ ^/.+\.(css|js|ico|png|jpe?g|gif|svg|ttf|mp4|mov|swf|pdf|zip|rar)$ {
        #    log_not_found off;
        #    access_log off;
        #    try_files $uri =404;
        #}

        location ~ ^/assets/.+\.php(/|$) {
            deny all;
        }
    }

    location /baijia {
        alias E:/wwwroot/channel-pub-api-feature-task-group/baijia/web/;

        # redirect to the URL without a trailing slash (uncomment if necessary)
        #location = /baijia/ {
        #    return 301 /baijia;
        #}

        # prevent the directory redirect to the URL with a trailing slash
        location = /baijia {
            # if your location is "/baijia", try use "/baijia/baijia/web/index.php$is_args$args"
            # bug ticket: https://trac.nginx.org/nginx/ticket/97
            try_files $uri /baijia/baijia/web/index.php$is_args$args;
        }

        # if your location is "/baijia", try use "/baijia/baijia/web/index.php$is_args$args"
        # bug ticket: https://trac.nginx.org/nginx/ticket/97
        try_files $uri $uri/ /baijia/baijia/web/index.php$is_args$args;

        # omit static files logging, and if they don't exist, avoid processing by Yii (uncomment if necessary)
        #location ~ ^/baijia/.+\.(css|js|ico|png|jpe?g|gif|svg|ttf|mp4|mov|swf|pdf|zip|rar)$ {
        #    log_not_found off;
        #    access_log off;
        #    try_files $uri =404;
        #}

        location ~ ^/baijia/assets/.+\.php(/|$) {
            deny all;
        }
    }

	location /customize {
        alias E:/wwwroot/channel-pub-api-feature-task-group/customize/web/;

        # redirect to the URL without a trailing slash (uncomment if necessary)
        #location = /customize/ {
        #    return 301 /customize;
        #}

        # prevent the directory redirect to the URL with a trailing slash
        location = /customize {
            # if your location is "/customize", try use "/customize/customize/web/index.php$is_args$args"
            # bug ticket: https://trac.nginx.org/nginx/ticket/97
            try_files $uri /customize/customize/web/index.php$is_args$args;
        }

        # if your location is "/customize", try use "/customize/customize/web/index.php$is_args$args"
        # bug ticket: https://trac.nginx.org/nginx/ticket/97
        try_files $uri $uri/ /customize/customize/web/index.php$is_args$args;

        # omit static files logging, and if they don't exist, avoid processing by Yii (uncomment if necessary)
        #location ~ ^/customize/.+\.(css|js|ico|png|jpe?g|gif|svg|ttf|mp4|mov|swf|pdf|zip|rar)$ {
        #    log_not_found off;
        #    access_log off;
        #    try_files $uri =404;
        #}

        location ~ ^/customize/assets/.+\.php(/|$) {
            deny all;
        }
    }

	location /netease {
        alias E:/wwwroot/channel-pub-api-feature-task-group/netease/web/;

        # redirect to the URL without a trailing slash (uncomment if necessary)
        #location = /netease/ {
        #    return 301 /netease;
        #}

        # prevent the directory redirect to the URL with a trailing slash
        location = /netease {
            # if your location is "/netease", try use "/netease/netease/web/index.php$is_args$args"
            # bug ticket: https://trac.nginx.org/nginx/ticket/97
            try_files $uri /netease/netease/web/index.php$is_args$args;
        }

        # if your location is "/netease", try use "/netease/netease/web/index.php$is_args$args"
        # bug ticket: https://trac.nginx.org/nginx/ticket/97
        try_files $uri $uri/ /netease/netease/web/index.php$is_args$args;

        # omit static files logging, and if they don't exist, avoid processing by Yii (uncomment if necessary)
        #location ~ ^/netease/.+\.(css|js|ico|png|jpe?g|gif|svg|ttf|mp4|mov|swf|pdf|zip|rar)$ {
        #    log_not_found off;
        #    access_log off;
        #    try_files $uri =404;
        #}

        location ~ ^/netease/assets/.+\.php(/|$) {
            deny all;
        }
    }

    location /qq {
        alias E:/wwwroot/channel-pub-api-feature-task-group/qq/web/;

        # redirect to the URL without a trailing slash (uncomment if necessary)
        #location = /qq/ {
        #    return 301 /qq;
        #}

        # prevent the directory redirect to the URL with a trailing slash
        location = /qq {
            # if your location is "/qq", try use "/qq/qq/web/index.php$is_args$args"
            # bug ticket: https://trac.nginx.org/nginx/ticket/97
            try_files $uri /qq/qq/web/index.php$is_args$args;
        }

        # if your location is "/qq", try use "/qq/qq/web/index.php$is_args$args"
        # bug ticket: https://trac.nginx.org/nginx/ticket/97
        try_files $uri $uri/ /qq/qq/web/index.php$is_args$args;

        # omit static files logging, and if they don't exist, avoid processing by Yii (uncomment if necessary)
        #location ~ ^/qq/.+\.(css|js|ico|png|jpe?g|gif|svg|ttf|mp4|mov|swf|pdf|zip|rar)$ {
        #    log_not_found off;
        #    access_log off;
        #    try_files $uri =404;
        #}

        location ~ ^/qq/assets/.+\.php(/|$) {
            deny all;
        }
    }

	location /weibo {
        alias E:/wwwroot/channel-pub-api-feature-task-group/weibo/web/;

        # redirect to the URL without a trailing slash (uncomment if necessary)
        #location = /weibo/ {
        #    return 301 /weibo;
        #}

        # prevent the directory redirect to the URL with a trailing slash
        location = /weibo {
            # if your location is "/weibo", try use "/weibo/weibo/web/index.php$is_args$args"
            # bug ticket: https://trac.nginx.org/nginx/ticket/97
            try_files $uri /weibo/weibo/web/index.php$is_args$args;
        }

        # if your location is "/weibo", try use "/weibo/weibo/web/index.php$is_args$args"
        # bug ticket: https://trac.nginx.org/nginx/ticket/97
        try_files $uri $uri/ /weibo/weibo/web/index.php$is_args$args;

        # omit static files logging, and if they don't exist, avoid processing by Yii (uncomment if necessary)
        #location ~ ^/weibo/.+\.(css|js|ico|png|jpe?g|gif|svg|ttf|mp4|mov|swf|pdf|zip|rar)$ {
        #    log_not_found off;
        #    access_log off;
        #    try_files $uri =404;
        #}

        location ~ ^/weibo/assets/.+\.php(/|$) {
            deny all;
        }
    }

	location /wx {
        alias E:/wwwroot/channel-pub-api-feature-task-group/wx/web/;

        # redirect to the URL without a trailing slash (uncomment if necessary)
        #location = /wx/ {
        #    return 301 /wx;
        #}

        # prevent the directory redirect to the URL with a trailing slash
        location = /wx {
            # if your location is "/wx", try use "/wx/wx/web/index.php$is_args$args"
            # bug ticket: https://trac.nginx.org/nginx/ticket/97
            try_files $uri /wx/wx/web/index.php$is_args$args;
        }

        # if your location is "/wx", try use "/wx/wx/web/index.php$is_args$args"
        # bug ticket: https://trac.nginx.org/nginx/ticket/97
        try_files $uri $uri/ /wx/wx/web/index.php$is_args$args;

        # omit static files logging, and if they don't exist, avoid processing by Yii (uncomment if necessary)
        #location ~ ^/wx/.+\.(css|js|ico|png|jpe?g|gif|svg|ttf|mp4|mov|swf|pdf|zip|rar)$ {
        #    log_not_found off;
        #    access_log off;
        #    try_files $uri =404;
        #}

        location ~ ^/wx/assets/.+\.php(/|$) {
            deny all;
        }
    }

	location ~ ^/.+\.php(/|$) {
        rewrite (?!^/((api|baijia|customize|netease|qq|weibo|wx)/web|baijia|customize|netease|qq|weibo|wx))^ /api/web$uri break;
		rewrite (?!^/baijia/web)^/baijia(/.+)$ /baijia/web$1 break;
		rewrite (?!^/customize/web)^/customize(/.+)$ /customize/web$1 break;
        rewrite (?!^/netease/web)^/netease(/.+)$ /netease/web$1 break;
		rewrite (?!^/qq/web)^/qq(/.+)$ /qq/web$1 break;
		rewrite (?!^/weibo/web)^/weibo(/.+)$ /weibo/web$1 break;
		rewrite (?!^/wx/web)^/wx(/.+)$ /wx/web$1 break;

		include fastcgi_params;
		fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
		fastcgi_pass 127.0.0.1:9001;
		#fastcgi_pass unix:/var/run/php5-fpm.sock;
        try_files $fastcgi_script_name =404;
    }

    location ~ /\. {
        deny all;
    }
}

## MISC ##

### WWW Redirect ###
server {
    listen       80;
    server_name  channel-pub-api.localhost;
    return       301 http://www.channel-pub-api.localhost$request_uri;
}



3、新开 PowerShell 窗口,执行 php-cgi.exe -b 127.0.0.1:9001-c C:/php-7.2.14/php.ini,如图4
新开 PowerShell 窗口,执行 php-cgi.exe -b 127.0.0.1:9001-c C:/php-7.2.14/php.ini

图4

4、Nginx + php-fpm 在 Windows 10 下的情况表现,当在一个请求(http://api.channel-pub-api.localhost)中 CURL 另一个请求(http://localhost:81)时,响应成功,如图5
Nginx + php-fpm 在 Windows 10 下的情况表现,当在一个请求(http://api.channel-pub-api.localhost)中 CURL 另一个请求(http://localhost:81)时,响应成功

图5

5、查看具体的请求发起时间节点,虽然是并行请求,但是实际表现上却是串行的。即一个请求完毕后,再执行下一个请求。其总体响应时间长度为:21.75s。如图6
查看具体的请求发起时间节点,虽然是并行请求,但是实际表现上却是串行的。即一个请求完毕后,再执行下一个请求。其总体响应时间长度为:21.75s。

图6



10:37:26.340	info	yii\httpclient\StreamTransport::send	POST http://localhost:81/baijia/v1/articles/standard?group_id=015ce30b116ce86058fa6ab4fea4ac62
Content-Type: application/json; charset=UTF-8

10:37:29.461	info	yii\httpclient\StreamTransport::send	POST http://localhost:81/netease/v1/articles/standard?group_id=015ce30b116ce86058fa6ab4fea4ac62
Content-Type: application/json; charset=UTF-8

10:37:32.732	info	yii\httpclient\StreamTransport::send	POST http://localhost:81/weibo/v1/articles/toutiao?group_id=015ce30b116ce86058fa6ab4fea4ac62
Content-Type: application/json; charset=UTF-8

10:37:35.757	info	yii\httpclient\StreamTransport::send	POST http://localhost:81/qq/v1/articles/standard?group_id=015ce30b116ce86058fa6ab4fea4ac62
Content-Type: application/json; charset=UTF-8

10:37:38.533	info	yii\httpclient\StreamTransport::send	POST http://localhost:81/qq/v1/articles/standard?group_id=015ce30b116ce86058fa6ab4fea4ac62
Content-Type: application/json; charset=UTF-8

10:37:41.132	info	yii\httpclient\StreamTransport::send	POST http://localhost:81/wx/v1/wx-articles/article?group_id=015ce30b116ce86058fa6ab4fea4ac62
Content-Type: application/json; charset=UTF-8

10:37:44.207	info	yii\httpclient\StreamTransport::send	POST http://localhost:81/customize/v1/articles/standard?group_id=015ce30b116ce86058fa6ab4fea4ac62
Content-Type: application/json; charset=UTF-8


6、决定分析测试 Nginx + php-fpm 在 Windows 10 下的串行表现。新建 phpinfo.php(延时 30 秒写入日志)、phpinfo1.php(延时 5 秒写入日志),在浏览器中先打开 phpinfo.php、然后再迅速打开 phpinfo1.php,间隔时间约为 1 秒左右。 phpinfo.php
<pre class="wp-block-syntaxhighlighter-code">

<?php
sleep(30);
file_put_contents('E:/wwwroot/channel-pub-api/console/runtime/logs/sleep-0-' . time() . '.txt', time());
phpinfo();
?>

</pre>
phpinfo1.php
<pre class="wp-block-syntaxhighlighter-code">

<?php
sleep(5);
file_put_contents('E:/wwwroot/channel-pub-api/console/runtime/logs/sleep-1-' . time() . '.txt', time());
phpinfo();
?>

</pre>
7、在打开 phpinfo.php 后,其大约加载了 30 秒左右的时间长度。在打开 phpinfo1.php 后,其大约加载了 35 秒左右的时间长度(如果支持并行,则加载时间预计为 5 秒左右。如果不支持并行,仅支持串行,则加载时间预计为 35 秒左右,其中 30 秒为等待 phpinfo.php 运行结束的时间,只有当 phpinfo.php 运行结束后,9001 端口才可用,5 秒为 phpinfo1.php 自身运行的时间)。如图7
在打开 phpinfo.php 后,其大约加载了 30 秒左右的时间长度。在打开 phpinfo1.php 后,其大约加载了 35 秒左右的时间长度(如果支持并行,则加载时间预计为 5 秒左右。如果不支持并行,仅支持串行,则加载时间预计为 35 秒左右,其中 30 秒为等待 phpinfo.php 运行结束的时间,只有当 phpinfo.php 运行结束后,9001 端口才可用,5 秒为 phpinfo1.php 自身运行的时间)。

图7

8、分别查看生成的日志文件的创建时间。可以确定 phpinfo1.php 的日志文件的创建时间晚于 phpinfo.php 的日志文件的创建时间,精确为 5 秒钟。由此可以确定,Nginx + php-fpm 在 Windows 10 下,是仅支持串行请求的。如图8
分别查看生成的日志文件的创建时间。可以确定 phpinfo1.php 的日志文件的创建时间晚于 phpinfo.php 的日志文件的创建时间,精确为 5 秒钟。由此可以确定,Nginx + php-fpm 在 Windows 10 下,是仅支持串行请求的。

图8



sleep-0-1585200354.txt
sleep-1-1585200359.txt


9、开发环境的部署方案为:CentOS + Nginx + php-fpm。重复第 6、7、8 步骤。分别查看生成的日志文件的创建时间。可以确定 phpinfo1.php 的日志文件的创建时间早于 phpinfo.php 的日志文件的创建时间,精确为 23 秒钟,虽然其晚于 phpinfo.php 开始运行。由此可以确定,Nginx + php-fpm 在 CentOS 7 下,是支持并行请求的。如图9
开发环境的部署方案为:CentOS + Nginx + php-fpm。重复第 6、7、8 步骤。分别查看生成的日志文件的创建时间。可以确定 phpinfo1.php 的日志文件的创建时间早于 phpinfo.php 的日志文件的创建时间,精确为 23 秒钟,虽然其晚于 phpinfo.php 开始运行。由此可以确定,Nginx + php-fpm 在 CentOS 7 下,是支持并行请求的。

图9



sleep-0-1585202045.txt
sleep-1-1585202022.txt


10、编辑 Nginx 配置文件,修改 server_name 的值:api.channel-pub.wjdev.chinamcloud.cn localhost,以在一个请求(https://api.channel-pub.wjdev.chinamcloud.cn)中 CURL 另一个请求(http://localhost)(总计请求次数为 7),直接请求本机,以节省网络开销。其总体响应时间长度为:1956ms,2 秒左右,符合预期。如图10
编辑 Nginx 配置文件,修改 server_name 的值:api.channel-pub.wjdev.chinamcloud.cn localhost,以在一个请求(https://api.channel-pub.wjdev.chinamcloud.cn)中 CURL 另一个请求(http://localhost)(总计请求次数为 7),直接请求本机,以节省网络开销。其总体响应时间长度为:1956ms,2 秒左右,符合预期。

图10

11、直接请求本机,其并发请求数受限于 php-fpm.conf 中的 pm.max_children 值。现在默认设置为:40。子进程的数量固定为 40 个。当在一个请求(https://api.channel-pub.wjdev.chinamcloud.cn)中 CURL 另一个请求(http://localhost)的数量为 52 时,其总体响应时间长度为:6.00s。如图11
直接请求本机,其并发请求数受限于 php-fpm.conf 中的 pm.max_children 值。现在默认设置为:40。子进程的数量固定为 40 个。当在一个请求(https://api.channel-pub.wjdev.chinamcloud.cn)中 CURL 另一个请求(http://localhost)的数量为 52 时,其总体响应时间长度为:6.00s。

图11

12、当请求数量为 42 时,其总体响应时间长度为:4.73s。当请求数量为 35 时,其总体响应时间长度为:4.39s。当请求数量为 30 时,其总体响应时间长度为:3.79s。当请求数量为 25 时,其总体响应时间长度为:2.98s。当请求数量为 20 时,其总体响应时间长度为:2.85s。当请求数量为 15 时,其总体响应时间长度为:2.36s。当请求数量为 10 时,其总体响应时间长度为:2.21s。 13、在服务器上 curl,查看 php-fpm 的状态页。


[root@5b9088596e62 /]# curl http://127.0.0.1/status
pool:                 www
process manager:      static
start time:           26/Mar/2020:13:50:05 +0800
start since:          4603
accepted conn:        516
listen queue:         0
max listen queue:     0
listen queue len:     128
idle processes:       39
active processes:     1
total processes:      40
max active processes: 10
max children reached: 0
slow requests:        0


14、最后分析测试的结果: Windows + Nginx + php-fpm(串行)、CentOS + Nginx + php-fpm(并行)、MacOS + Nginx + php-fpm(并行)、MacOS + Apache(并行)。]]>
https://www.shuijingwanwq.com/2020/03/26/4043/feed/ 0
基于 Composer 安装:JamesHeinrich / getID3,提示 ( SSL:握手超时;无法启用加密;无法打开流:操作失败 ) 的解决 https://www.shuijingwanwq.com/2020/03/10/4009/ https://www.shuijingwanwq.com/2020/03/10/4009/#respond Tue, 10 Mar 2020 09:09:38 +0000 https://www.shuijingwanwq.com/?p=4009 浏览量: 104 1、getID3() 是一个 PHP 脚本,可从 MP3 和其他多媒体文件格式中提取有用的信息。打开网址:https://github.com/JamesHeinrich/getID3 2、基于 Composer 安装:JamesHeinrich / getID3。打开 PHP 软件包存储库的网址:https://packagist.org ,搜索:JamesHeinrich / getID3 ,得出搜索结果:james-heinrich/getid3,如图1
基于 Composer 安装:JamesHeinrich / getID3。打开 PHP 软件包存储库的网址:https://packagist.org ,搜索:JamesHeinrich / getID3 ,得出搜索结果:james-heinrich/getid3

图1

3、在 PowerShell 中,执行安装命令:composer require james-heinrich/getid3,提示 ( SSL:握手超时;无法启用加密;无法打开流:操作失败 ),如图2
在 PowerShell 中,执行安装命令:composer require james-heinrich/getid3,提示 ( SSL:握手超时;无法启用加密;无法打开流:操作失败 )

图2



PS E:\wwwroot\channel-pub-api> composer require james-heinrich/getid3
The "https://asset-packagist.org/packages.json" file could not be downloaded: SSL: Handshake timed out
Failed to enable crypto
failed to open stream: operation failed
https://asset-packagist.org could not be fully loaded, package information was loaded from the local cache and may be ou
t of date
Using version ^1.9 for james-heinrich/getid3
./composer.json has been updated
Loading composer repositories with package information
The "https://asset-packagist.org/packages.json" file could not be downloaded: failed to open stream: HTTP request failed
!
https://asset-packagist.org could not be fully loaded, package information was loaded from the local cache and may be ou
t of date
Updating dependencies (including require-dev)
^CTerminate batch job (Y/N)? Y


4、参考网址:https://www.shuijingwanwq.com/2019/12/28/3784/ ,在 cmd 中设置 HTTP 代理,再次执行安装命令,安装成功,如图3
参考网址:https://www.shuijingwanwq.com/2019/12/28/3784/ ,在 cmd 中设置 HTTP 代理,再次执行安装命令,安装成功

图3



E:\wwwroot>cd channel-pub-api

E:\wwwroot\channel-pub-api>set HTTP_PROXY=http://127.0.0.1:50999

E:\wwwroot\channel-pub-api>set HTTPS_PROXY=http://127.0.0.1:50999

E:\wwwroot\channel-pub-api>composer require james-heinrich/getid3
Using version ^1.9 for james-heinrich/getid3
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
  - Installing james-heinrich/getid3 (v1.9.19): Downloading (100%)
james-heinrich/getid3 suggests installing ext-com_dotnet (COM extension is required when loading files larger than 2GB on Windows.)
james-heinrich/getid3 suggests installing ext-dba (DBA extension is required to use the DBA database as a cache storage.)
james-heinrich/getid3 suggests installing ext-exif (EXIF extension is required for graphic modules.)
james-heinrich/getid3 suggests installing ext-mysql (MySQL extension is required to use the MySQL database as a cache storage (deprecated in PHP 5.5, removed in PHP >= 7.0, use `ext-mysqli` instead).)
james-heinrich/getid3 suggests installing ext-rar (RAR extension is required for RAR archive module.)
james-heinrich/getid3 suggests installing ext-SimpleXML (SimpleXML extension is required to analyze RIFF/WAV/BWF audio files (also requires `ext-libxml`).)
james-heinrich/getid3 suggests installing ext-sqlite3 (SQLite3 extension is required to use the SQLite3 database as a cache storage.)
Package codeception/base is abandoned, you should avoid using it. No replacement was suggested.
Writing lock file
Generating autoload files



]]>
https://www.shuijingwanwq.com/2020/03/10/4009/feed/ 0
在 Rancher 中实现集群的部署与测试 ( 负载均衡 与 命令行下的 Redis 锁定、性能提升 ) https://www.shuijingwanwq.com/2020/03/09/3998/ https://www.shuijingwanwq.com/2020/03/09/3998/#respond Mon, 09 Mar 2020 02:10:11 +0000 https://www.shuijingwanwq.com/?p=3998 浏览量: 92 1、在 Rancher 中,克隆已经存在的 Docker 容器 channel-pub-api-prev 为 channel-pub-api-prev-1、channel-pub-api-prev-2,如图1
在 Rancher 中,克隆已经存在的 Docker 容器 channel-pub-api-prev 为 channel-pub-api-prev-1、channel-pub-api-prev-2

图1

2、最终 3 个容器组成了一个集群,如图2
最终 3 个容器组成了一个集群

图2

3、在负载均衡中,添加服务规则,设置域名与目标容器的映射关系,如图3
在负载均衡中,添加服务规则,设置域名与目标容器的映射关系

图3

4、在 Postman 中执行了 2 次请求,第 1 次为 GET,第 2 次为 POST,最终在容器 channel-pub-api-prev 中有一条 GET 请求日志,在容器 channel-pub-api-prev-1 中有一条 POST 请求日志,在容器 channel-pub-api-prev-2 中无请求日志,负载均衡设置符合预期,如图4
在 Postman 中执行了 2 次请求,第 1 次为 GET,第 2 次为 POST,最终在容器 channel-pub-api-prev 中有一条 GET 请求日志,在容器 channel-pub-api-prev-1 中有一条 POST 请求日志,在容器 channel-pub-api-prev-2 中无请求日志,负载均衡设置符合预期

图4

5、在 3 个容器中,均在基于 Supervisor 监听队列,在队列所调用的服务中,输出日志至文件中,最终在容器 channel-pub-api-prev 中有一条服务日志,表明队列作业在容器 channel-pub-api-prev 中执行的。如图5
在 3 个容器中,均在基于 Supervisor 监听队列,在队列所调用的服务中,输出日志至文件中,最终在容器 channel-pub-api-prev 中有一条服务日志,表明队列作业在容器 channel-pub-api-prev 中执行的。

图5

6、查看 命令行下的 Redis 锁定日志,不仅存在 判断Redis模型的锁定是否存在(已存在),而且存在 Redis模型的锁定实现时失败的 日志。时间:14:58 – 14:50 = 9 分钟。锁定次数:29 + 31 + 10 = 70 。锁定频率:70 / 9 = 8,即每分钟 8 次。如图6
查看 命令行下的 Redis 锁定日志,不仅存在 判断Redis模型的锁定是否存在(已存在),而且存在 Redis模型的锁定实现时失败的 日志。时间:14:58 - 14:50 = 9 分钟。锁定次数:29 + 31 + 10 = 70 。锁定频率:70 / 9 = 8,即每分钟 8 次

图6



[root@7edbf272f55f logs]# ls -ltr
total 136
-rw-r--r-- 1 root root 16556 Mar  4 14:50 app.log
-rw-r--r-- 1 root root     1 Mar  4 14:51 qq-cw-transaction-article-sync-lock-2-1583304715.txt
-rw-r--r-- 1 root root     1 Mar  4 14:54 qq-cw-transaction-article-sync-is-lock-exist-2-1583304842.txt
-rw-r--r-- 1 root root     1 Mar  4 14:54 qq-cw-transaction-article-sync-is-lock-exist-2-1583304846.txt
-rw-r--r-- 1 root root     1 Mar  4 14:54 qq-cw-transaction-article-sync-is-lock-exist-2-1583304851.txt
-rw-r--r-- 1 root root     1 Mar  4 14:54 qq-cw-transaction-article-sync-is-lock-exist-2-1583304855.txt
-rw-r--r-- 1 root root     1 Mar  4 14:54 qq-cw-transaction-article-sync-is-lock-exist-2-1583304859.txt
-rw-r--r-- 1 root root     1 Mar  4 14:54 qq-cw-transaction-article-sync-is-lock-exist-2-1583304863.txt
-rw-r--r-- 1 root root     1 Mar  4 14:54 qq-cw-transaction-article-sync-is-lock-exist-2-1583304868.txt
-rw-r--r-- 1 root root     1 Mar  4 14:54 qq-cw-transaction-article-sync-is-lock-exist-2-1583304872.txt
-rw-r--r-- 1 root root     1 Mar  4 14:54 qq-cw-transaction-article-sync-is-lock-exist-2-1583304876.txt
-rw-r--r-- 1 root root     1 Mar  4 14:54 qq-cw-transaction-article-sync-is-lock-exist-2-1583304880.txt
-rw-r--r-- 1 root root     1 Mar  4 14:54 qq-cw-transaction-article-sync-is-lock-exist-2-1583304885.txt
-rw-r--r-- 1 root root     1 Mar  4 14:54 qq-cw-transaction-article-sync-is-lock-exist-2-1583304889.txt
-rw-r--r-- 1 root root     1 Mar  4 14:54 qq-cw-transaction-article-sync-is-lock-exist-2-1583304893.txt
-rw-r--r-- 1 root root     1 Mar  4 14:54 qq-cw-transaction-article-sync-is-lock-exist-2-1583304897.txt
-rw-r--r-- 1 root root     1 Mar  4 14:55 qq-cw-transaction-article-sync-is-lock-exist-2-1583304902.txt
-rw-r--r-- 1 root root     1 Mar  4 14:55 qq-cw-transaction-article-sync-is-lock-exist-2-1583304906.txt
-rw-r--r-- 1 root root     1 Mar  4 14:55 qq-cw-transaction-article-sync-is-lock-exist-2-1583304910.txt
-rw-r--r-- 1 root root     1 Mar  4 14:55 qq-cw-transaction-article-sync-is-lock-exist-2-1583304914.txt
-rw-r--r-- 1 root root     1 Mar  4 14:55 qq-cw-transaction-article-sync-is-lock-exist-2-1583304919.txt
-rw-r--r-- 1 root root     1 Mar  4 14:55 qq-cw-transaction-article-sync-is-lock-exist-2-1583304923.txt
-rw-r--r-- 1 root root     1 Mar  4 14:55 qq-cw-transaction-article-sync-is-lock-exist-2-1583304927.txt
-rw-r--r-- 1 root root     1 Mar  4 14:57 qq-cw-transaction-article-sync-is-lock-exist-2-1583305042.txt
-rw-r--r-- 1 root root     1 Mar  4 14:57 qq-cw-transaction-article-sync-is-lock-exist-2-1583305046.txt
-rw-r--r-- 1 root root     1 Mar  4 14:57 qq-cw-transaction-article-sync-is-lock-exist-2-1583305051.txt
-rw-r--r-- 1 root root     1 Mar  4 14:57 qq-cw-transaction-article-sync-is-lock-exist-2-1583305063.txt
-rw-r--r-- 1 root root     1 Mar  4 14:58 qq-cw-transaction-article-sync-is-lock-exist-2-1583305084.txt
-rw-r--r-- 1 root root     1 Mar  4 14:58 qq-cw-transaction-article-sync-is-lock-exist-2-1583305093.txt
-rw-r--r-- 1 root root     1 Mar  4 14:58 qq-cw-transaction-article-sync-is-lock-exist-2-1583305097.txt

[root@22f7ada2d88d logs]# ls -ltr
total 144
-rw-r--r-- 1 root root 16547 Mar  4 14:50 app.log
-rw-r--r-- 1 root root     1 Mar  4 14:50 qq-cw-transaction-article-sync-is-lock-exist-2-1583304652.txt
-rw-r--r-- 1 root root     1 Mar  4 14:51 qq-cw-transaction-article-sync-is-lock-exist-2-1583304665.txt
-rw-r--r-- 1 root root     1 Mar  4 14:51 qq-cw-transaction-article-sync-is-lock-exist-2-1583304669.txt
-rw-r--r-- 1 root root     1 Mar  4 14:51 qq-cw-transaction-article-sync-is-lock-exist-2-1583304673.txt
-rw-r--r-- 1 root root     1 Mar  4 14:51 qq-cw-transaction-article-sync-is-lock-exist-2-1583304677.txt
-rw-r--r-- 1 root root     1 Mar  4 14:51 qq-cw-transaction-article-sync-is-lock-exist-2-1583304682.txt
-rw-r--r-- 1 root root     1 Mar  4 14:51 qq-cw-transaction-article-sync-is-lock-exist-2-1583304686.txt
-rw-r--r-- 1 root root     1 Mar  4 14:51 qq-cw-transaction-article-sync-is-lock-exist-2-1583304690.txt
-rw-r--r-- 1 root root     1 Mar  4 14:51 qq-cw-transaction-article-sync-is-lock-exist-2-1583304694.txt
-rw-r--r-- 1 root root     1 Mar  4 14:51 qq-cw-transaction-article-sync-is-lock-exist-2-1583304699.txt
-rw-r--r-- 1 root root     1 Mar  4 14:51 qq-cw-transaction-article-sync-is-lock-exist-2-1583304703.txt
-rw-r--r-- 1 root root     1 Mar  4 14:51 qq-cw-transaction-article-sync-is-lock-exist-2-1583304707.txt
-rw-r--r-- 1 root root     1 Mar  4 14:51 qq-cw-transaction-article-sync-is-lock-exist-2-1583304711.txt
-rw-r--r-- 1 root root     1 Mar  4 14:52 qq-cw-transaction-article-sync-is-lock-exist-2-1583304720.txt
-rw-r--r-- 1 root root     1 Mar  4 14:53 qq-cw-transaction-article-sync-is-lock-exist-2-1583304816.txt
-rw-r--r-- 1 root root     1 Mar  4 14:54 qq-cw-transaction-article-sync-is-lock-exist-2-1583304846.txt
-rw-r--r-- 1 root root     1 Mar  4 14:54 qq-cw-transaction-article-sync-is-lock-exist-2-1583304851.txt
-rw-r--r-- 1 root root     1 Mar  4 14:54 qq-cw-transaction-article-sync-is-lock-exist-2-1583304855.txt
-rw-r--r-- 1 root root     1 Mar  4 14:54 qq-cw-transaction-article-sync-is-lock-exist-2-1583304859.txt
-rw-r--r-- 1 root root     1 Mar  4 14:54 qq-cw-transaction-article-sync-is-lock-exist-2-1583304864.txt
-rw-r--r-- 1 root root     1 Mar  4 14:54 qq-cw-transaction-article-sync-is-lock-exist-2-1583304868.txt
-rw-r--r-- 1 root root     1 Mar  4 14:55 qq-cw-transaction-article-sync-is-lock-exist-2-1583304949.txt
-rw-r--r-- 1 root root     1 Mar  4 14:55 qq-cw-transaction-article-sync-is-lock-exist-2-1583304954.txt
-rw-r--r-- 1 root root     1 Mar  4 14:55 qq-cw-transaction-article-sync-is-lock-exist-2-1583304958.txt
-rw-r--r-- 1 root root     1 Mar  4 14:56 qq-cw-transaction-article-sync-is-lock-exist-2-1583304962.txt
-rw-r--r-- 1 root root     1 Mar  4 14:56 qq-cw-transaction-article-sync-is-lock-exist-2-1583304988.txt
-rw-r--r-- 1 root root     1 Mar  4 14:56 qq-cw-transaction-article-sync-is-lock-exist-2-1583304996.txt
-rw-r--r-- 1 root root     1 Mar  4 14:57 qq-cw-transaction-article-sync-is-lock-exist-2-1583305055.txt
-rw-r--r-- 1 root root     1 Mar  4 14:57 qq-cw-transaction-article-sync-is-lock-exist-2-1583305060.txt
-rw-r--r-- 1 root root     1 Mar  4 14:57 qq-cw-transaction-article-sync-is-lock-exist-2-1583305072.txt
-rw-r--r-- 1 root root     1 Mar  4 14:58 qq-cw-transaction-article-sync-is-lock-exist-2-1583305081.txt

[root@54d07ee806e6 logs]# ls -ltr
total 60
-rw-r--r-- 1 root root 16556 Mar  4 14:53 app.log
-rw-r--r-- 1 root root     1 Mar  4 14:53 qq-cw-transaction-article-sync-is-lock-exist-2-1583304824.txt
-rw-r--r-- 1 root root     1 Mar  4 14:53 qq-cw-transaction-article-sync-is-lock-exist-2-1583304829.txt
-rw-r--r-- 1 root root     1 Mar  4 14:53 qq-cw-transaction-article-sync-is-lock-exist-2-1583304833.txt
-rw-r--r-- 1 root root     1 Mar  4 14:53 qq-cw-transaction-article-sync-is-lock-exist-2-1583304837.txt
-rw-r--r-- 1 root root     1 Mar  4 14:55 qq-cw-transaction-article-sync-is-lock-exist-2-1583304932.txt
-rw-r--r-- 1 root root     1 Mar  4 14:55 qq-cw-transaction-article-sync-is-lock-exist-2-1583304936.txt
-rw-r--r-- 1 root root     1 Mar  4 14:55 qq-cw-transaction-article-sync-is-lock-exist-2-1583304941.txt
-rw-r--r-- 1 root root     1 Mar  4 14:57 qq-cw-transaction-article-sync-is-lock-exist-2-1583305029.txt
-rw-r--r-- 1 root root     1 Mar  4 14:57 qq-cw-transaction-article-sync-is-lock-exist-2-1583305033.txt
-rw-r--r-- 1 root root     1 Mar  4 14:57 qq-cw-transaction-article-sync-is-lock-exist-2-1583305038.txt


7、锁定频率过高的根源应该在于命令行中仅有同一条任务在执行。决定模拟出 6 条任务,锁定频率应该会有所下降。时间:15:52 – 15:47 = 6 分钟。锁定次数:47 + 34 + 45 = 126 。锁定频率:126 / 6 = 9,即每分钟 20 次。不符合预期。


[root@7edbf272f55f logs]# ls -ltr
total 188
-rw-r--r-- 1 root root 1 Mar  4 15:47 qq-cw-transaction-video-sync-is-lock-exist-4-1583308059.txt
-rw-r--r-- 1 root root 1 Mar  4 15:47 qq-cw-transaction-video-sync-lock-5-1583308059.txt
-rw-r--r-- 1 root root 1 Mar  4 15:47 qq-cw-transaction-article-sync-is-lock-exist-6-1583308069.txt
-rw-r--r-- 1 root root 1 Mar  4 15:47 qq-cw-transaction-article-sync-is-lock-exist-8-1583308069.txt
-rw-r--r-- 1 root root 1 Mar  4 15:48 qq-cw-transaction-video-sync-is-lock-exist-9-1583308096.txt
-rw-r--r-- 1 root root 1 Mar  4 15:49 qq-cw-transaction-article-sync-is-lock-exist-7-1583308161.txt
-rw-r--r-- 1 root root 2 Mar  4 15:49 qq-cw-transaction-article-sync-is-lock-exist-11-1583308161.txt
-rw-r--r-- 1 root root 1 Mar  4 15:49 qq-cw-transaction-article-sync-is-lock-exist-6-1583308166.txt
-rw-r--r-- 1 root root 1 Mar  4 15:49 qq-cw-transaction-article-sync-is-lock-exist-8-1583308166.txt
-rw-r--r-- 1 root root 2 Mar  4 15:49 qq-cw-transaction-article-sync-is-lock-exist-12-1583308167.txt
-rw-r--r-- 1 root root 2 Mar  4 15:49 qq-cw-transaction-article-sync-is-lock-exist-11-1583308187.txt
-rw-r--r-- 1 root root 1 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-6-1583308222.txt
-rw-r--r-- 1 root root 1 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-8-1583308222.txt
-rw-r--r-- 1 root root 2 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-12-1583308222.txt
-rw-r--r-- 1 root root 1 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-6-1583308226.txt
-rw-r--r-- 1 root root 1 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-7-1583308226.txt
-rw-r--r-- 1 root root 2 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-11-1583308226.txt
-rw-r--r-- 1 root root 1 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-6-1583308230.txt
-rw-r--r-- 1 root root 1 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-7-1583308230.txt
-rw-r--r-- 1 root root 2 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-11-1583308230.txt
-rw-r--r-- 1 root root 2 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-12-1583308230.txt
-rw-r--r-- 1 root root 1 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-6-1583308234.txt
-rw-r--r-- 1 root root 1 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-7-1583308234.txt
-rw-r--r-- 1 root root 1 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-6-1583308239.txt
-rw-r--r-- 1 root root 1 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-7-1583308239.txt
-rw-r--r-- 1 root root 2 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-11-1583308239.txt
-rw-r--r-- 1 root root 2 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-12-1583308239.txt
-rw-r--r-- 1 root root 1 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-6-1583308243.txt
-rw-r--r-- 1 root root 1 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-8-1583308243.txt
-rw-r--r-- 1 root root 2 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-11-1583308243.txt
-rw-r--r-- 1 root root 1 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-6-1583308247.txt
-rw-r--r-- 1 root root 2 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-11-1583308248.txt
-rw-r--r-- 1 root root 2 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-11-1583308251.txt
-rw-r--r-- 1 root root 2 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-11-1583308256.txt
-rw-r--r-- 1 root root 2 Mar  4 15:51 qq-cw-transaction-article-sync-is-lock-exist-11-1583308260.txt
-rw-r--r-- 1 root root 2 Mar  4 15:51 qq-cw-transaction-article-sync-is-lock-exist-11-1583308264.txt
-rw-r--r-- 1 root root 2 Mar  4 15:51 qq-cw-transaction-article-sync-is-lock-exist-11-1583308268.txt
-rw-r--r-- 1 root root 2 Mar  4 15:51 qq-cw-transaction-article-sync-is-lock-exist-11-1583308272.txt
-rw-r--r-- 1 root root 2 Mar  4 15:51 qq-cw-transaction-article-sync-is-lock-exist-12-1583308277.txt
-rw-r--r-- 1 root root 2 Mar  4 15:51 qq-cw-transaction-article-sync-is-lock-exist-12-1583308281.txt
-rw-r--r-- 1 root root 2 Mar  4 15:51 qq-cw-transaction-article-sync-is-lock-exist-12-1583308290.txt
-rw-r--r-- 1 root root 2 Mar  4 15:51 qq-cw-transaction-article-sync-is-lock-exist-12-1583308294.txt
-rw-r--r-- 1 root root 2 Mar  4 15:51 qq-cw-transaction-article-sync-is-lock-exist-12-1583308303.txt
-rw-r--r-- 1 root root 2 Mar  4 15:51 qq-cw-transaction-article-sync-is-lock-exist-12-1583308307.txt
-rw-r--r-- 1 root root 2 Mar  4 15:51 qq-cw-transaction-article-sync-is-lock-exist-12-1583308311.txt
-rw-r--r-- 1 root root 2 Mar  4 15:52 qq-cw-transaction-article-sync-is-lock-exist-12-1583308332.txt
-rw-r--r-- 1 root root 2 Mar  4 15:52 qq-cw-transaction-article-sync-is-lock-exist-12-1583308344.txt

[root@22f7ada2d88d logs]# ls -ltr
total 136
-rw-r--r-- 1 root root 1 Mar  4 15:47 qq-cw-transaction-video-sync-is-lock-exist-5-1583308059.txt
-rw-r--r-- 1 root root 2 Mar  4 15:48 qq-cw-transaction-video-sync-is-lock-exist-10-1583308096.txt
-rw-r--r-- 1 root root 1 Mar  4 15:48 qq-cw-transaction-article-sync-is-lock-exist-8-1583308126.txt
-rw-r--r-- 1 root root 2 Mar  4 15:48 qq-cw-transaction-article-sync-is-lock-exist-11-1583308126.txt
-rw-r--r-- 1 root root 1 Mar  4 15:49 qq-cw-transaction-article-sync-is-lock-exist-6-1583308177.txt
-rw-r--r-- 1 root root 1 Mar  4 15:49 qq-cw-transaction-article-sync-is-lock-exist-6-1583308182.txt
-rw-r--r-- 1 root root 1 Mar  4 15:49 qq-cw-transaction-article-sync-is-lock-exist-8-1583308183.txt
-rw-r--r-- 1 root root 2 Mar  4 15:49 qq-cw-transaction-article-sync-is-lock-exist-12-1583308183.txt
-rw-r--r-- 1 root root 1 Mar  4 15:49 qq-cw-transaction-article-sync-is-lock-exist-6-1583308187.txt
-rw-r--r-- 1 root root 1 Mar  4 15:49 qq-cw-transaction-article-sync-is-lock-exist-6-1583308196.txt
-rw-r--r-- 1 root root 1 Mar  4 15:49 qq-cw-transaction-article-sync-is-lock-exist-8-1583308196.txt
-rw-r--r-- 1 root root 2 Mar  4 15:49 qq-cw-transaction-article-sync-is-lock-exist-12-1583308196.txt
-rw-r--r-- 1 root root 1 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-7-1583308206.txt
-rw-r--r-- 1 root root 1 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-7-1583308222.txt
-rw-r--r-- 1 root root 2 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-11-1583308222.txt
-rw-r--r-- 1 root root 1 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-6-1583308226.txt
-rw-r--r-- 1 root root 1 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-8-1583308226.txt
-rw-r--r-- 1 root root 2 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-12-1583308226.txt
-rw-r--r-- 1 root root 1 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-6-1583308230.txt
-rw-r--r-- 1 root root 1 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-8-1583308230.txt
-rw-r--r-- 1 root root 2 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-11-1583308230.txt
-rw-r--r-- 1 root root 1 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-7-1583308235.txt
-rw-r--r-- 1 root root 1 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-8-1583308235.txt
-rw-r--r-- 1 root root 2 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-12-1583308235.txt
-rw-r--r-- 1 root root 1 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-7-1583308239.txt
-rw-r--r-- 1 root root 1 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-8-1583308239.txt
-rw-r--r-- 1 root root 2 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-12-1583308239.txt
-rw-r--r-- 1 root root 1 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-7-1583308243.txt
-rw-r--r-- 1 root root 1 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-8-1583308243.txt
-rw-r--r-- 1 root root 2 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-12-1583308244.txt
-rw-r--r-- 1 root root 2 Mar  4 15:51 qq-cw-transaction-article-sync-is-lock-exist-12-1583308286.txt
-rw-r--r-- 1 root root 2 Mar  4 15:51 qq-cw-transaction-article-sync-is-lock-exist-12-1583308298.txt
-rw-r--r-- 1 root root 2 Mar  4 15:51 qq-cw-transaction-article-sync-is-lock-exist-12-1583308315.txt
-rw-r--r-- 1 root root 2 Mar  4 15:52 qq-cw-transaction-article-sync-is-lock-exist-12-1583308323.txt

[root@54d07ee806e6 logs]# ls -ltr
total 196
-rw-r--r-- 1 root root     1 Mar  4 15:47 qq-cw-transaction-video-sync-is-lock-exist-4-1583308059.txt
-rw-r--r-- 1 root root     1 Mar  4 15:47 qq-cw-transaction-article-sync-is-lock-exist-7-1583308069.txt
-rw-r--r-- 1 root root     1 Mar  4 15:48 qq-cw-transaction-article-sync-is-lock-exist-8-1583308087.txt
-rw-r--r-- 1 root root 17361 Mar  4 15:48 app.log
-rw-r--r-- 1 root root     2 Mar  4 15:48 qq-cw-transaction-video-sync-is-lock-exist-10-1583308096.txt
-rw-r--r-- 1 root root     1 Mar  4 15:49 qq-cw-transaction-article-sync-is-lock-exist-6-1583308160.txt
-rw-r--r-- 1 root root     1 Mar  4 15:49 qq-cw-transaction-article-sync-is-lock-exist-8-1583308161.txt
-rw-r--r-- 1 root root     2 Mar  4 15:49 qq-cw-transaction-article-sync-is-lock-exist-12-1583308161.txt
-rw-r--r-- 1 root root     1 Mar  4 15:49 qq-cw-transaction-article-sync-is-lock-exist-7-1583308166.txt
-rw-r--r-- 1 root root     2 Mar  4 15:49 qq-cw-transaction-article-sync-is-lock-exist-11-1583308167.txt
-rw-r--r-- 1 root root     1 Mar  4 15:49 qq-cw-transaction-article-sync-is-lock-exist-7-1583308177.txt
-rw-r--r-- 1 root root     1 Mar  4 15:49 qq-cw-transaction-article-sync-is-lock-exist-7-1583308182.txt
-rw-r--r-- 1 root root     2 Mar  4 15:49 qq-cw-transaction-article-sync-is-lock-exist-11-1583308183.txt
-rw-r--r-- 1 root root     1 Mar  4 15:49 qq-cw-transaction-article-sync-is-lock-exist-7-1583308187.txt
-rw-r--r-- 1 root root     1 Mar  4 15:49 qq-cw-transaction-article-sync-is-lock-exist-8-1583308187.txt
-rw-r--r-- 1 root root     2 Mar  4 15:49 qq-cw-transaction-article-sync-is-lock-exist-12-1583308187.txt
-rw-r--r-- 1 root root     1 Mar  4 15:49 qq-cw-transaction-article-sync-is-lock-exist-7-1583308196.txt
-rw-r--r-- 1 root root     2 Mar  4 15:49 qq-cw-transaction-article-sync-is-lock-exist-11-1583308196.txt
-rw-r--r-- 1 root root     1 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-6-1583308205.txt
-rw-r--r-- 1 root root     1 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-8-1583308206.txt
-rw-r--r-- 1 root root     1 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-7-1583308226.txt
-rw-r--r-- 1 root root     1 Mar  4 15:50 qq-cw-transaction-article-sync-lock-8-1583308226.txt
-rw-r--r-- 1 root root     1 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-7-1583308230.txt
-rw-r--r-- 1 root root     1 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-8-1583308230.txt
-rw-r--r-- 1 root root     2 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-12-1583308230.txt
-rw-r--r-- 1 root root     1 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-6-1583308234.txt
-rw-r--r-- 1 root root     1 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-8-1583308235.txt
-rw-r--r-- 1 root root     2 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-11-1583308235.txt
-rw-r--r-- 1 root root     1 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-6-1583308239.txt
-rw-r--r-- 1 root root     1 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-8-1583308239.txt
-rw-r--r-- 1 root root     2 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-11-1583308239.txt
-rw-r--r-- 1 root root     1 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-6-1583308243.txt
-rw-r--r-- 1 root root     1 Mar  4 15:50 qq-cw-transaction-article-sync-lock-7-1583308243.txt
-rw-r--r-- 1 root root     2 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-11-1583308243.txt
-rw-r--r-- 1 root root     2 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-12-1583308243.txt
-rw-r--r-- 1 root root     1 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-8-1583308248.txt
-rw-r--r-- 1 root root     2 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-12-1583308251.txt
-rw-r--r-- 1 root root     2 Mar  4 15:50 qq-cw-transaction-article-sync-is-lock-exist-12-1583308256.txt
-rw-r--r-- 1 root root     2 Mar  4 15:51 qq-cw-transaction-article-sync-is-lock-exist-12-1583308260.txt
-rw-r--r-- 1 root root     2 Mar  4 15:51 qq-cw-transaction-article-sync-is-lock-exist-12-1583308264.txt
-rw-r--r-- 1 root root     2 Mar  4 15:51 qq-cw-transaction-article-sync-is-lock-exist-12-1583308269.txt
-rw-r--r-- 1 root root     2 Mar  4 15:51 qq-cw-transaction-article-sync-is-lock-exist-12-1583308273.txt
-rw-r--r-- 1 root root     2 Mar  4 15:51 qq-cw-transaction-article-sync-is-lock-exist-11-1583308277.txt
-rw-r--r-- 1 root root     2 Mar  4 15:51 qq-cw-transaction-article-sync-is-lock-exist-11-1583308281.txt
-rw-r--r-- 1 root root     2 Mar  4 15:51 qq-cw-transaction-article-sync-is-lock-exist-11-1583308285.txt


8、决定调整 bash sleep 3 为 bash sleep 60,即命令行运行一次后,间隔 60 秒后再次运行,而不是 3 秒。重复第 7 步骤,不存在 Redis 锁定日志。符合预期。 9、基于同步时间、ID顺序排列(企鹅号的事务)。某一任务开始执行时,更新企鹅号的事务的同步时间为当前时间 ,以提升执行性能,且再次降低锁定频率。


        // 查询企鹅号的应用类型,cw:内容网站应用 && 类型,1:文章 && 状态,3:处理中 && 文章发布状态:审核中的5条记录,基于同步时间、ID顺序排列(企鹅号的事务)
        $qqTransactionArticleItems = QqTransaction::find()->where(['qq_app_type' => QqArticle::QQ_APP_TYPE_CW, 'type' => QqTransaction::TYPE_ARTICLE, 'article_pub_flag' => HttpQqApiTransaction::ARTICLE_PUB_FLAG_REVIEW])->isDeletedNo()->processing()->orderBy(['synced_at' => SORT_ASC, 'id' => SORT_ASC])->limit(5)->all();

        if ($qqTransactionArticleItems) {
            foreach ($qqTransactionArticleItems as $qqTransactionArticleItem) {
                /* 判断Redis模型的锁定是否存在 */
                $redisLockKeyName = 'qq_cw_transaction_article:sync:' . implode(':', ['id' => $qqTransactionArticleItem->id]);
                $redisLock = new RedisLock();
                $isLockExist = $redisLock->isLockExist($redisLockKeyName);
                // 返回 true,表示锁定存在,即已经被其他客户端锁定
                if ($isLockExist === true) {
                    continue;
                }

                /* Redis模型的锁定实现 */
                $lock = $redisLock->lock($redisLockKeyName, 600);
                // 返回 false,表示已经被其他客户端锁定
                if ($lock === false) {
                    continue;
                }

                // 基于ID查找单个数据模型(企鹅号的事务)
                $qqTransactionArticleItem = QqTransaction::findOne($qqTransactionArticleItem->id);

                // 更新企鹅号的事务的同步时间
                $qqTransactionArticleItem->synced_at = time();
                $qqTransactionArticleItem->update();
                file_put_contents('/mcloud/www/channel-pub-api/console/runtime/logs/qq-cw-transaction-article-sync-' . $qqTransactionArticleItem->id . '-' . time() . '.txt', $qqTransactionArticleItem->id);
            }
        }


10、模拟出 3 条任务。事务ID为 41、42、43 的同步时间(分钟)分别为:9、9、8 。事务ID为 41、42、43 的同步次数分别为:22、20、17 。事务ID为 41、42、43 的同步频率分别为:9 * 60 / 22 = 25、9 * 60 / 20 = 27、8 * 60 / 17 = 28。得出平均值:(25 + 27 + 28) / 3 = 27。理论上的计算公式,进一法取整(事务数量 / 5) / 容器数量 * 60。符合预期。如图7
模拟出 3 条任务。事务ID为 41、42、43 的同步时间(分钟)分别为:9、9、8 。事务ID为 41、42、43 的同步次数分别为:22、20、17 。事务ID为 41、42、43 的同步频率分别为:9 * 60 / 22 = 25、9 * 60 / 20 = 27、8 * 60 / 17 = 28。得出平均值:(25 + 27 + 28) / 3 = 27。理论上的计算公式,进一法取整(事务数量 / 5) / 容器数量 * 60。符合预期

图7



[root@21325d776096 logs]# ls -ltr
total 64
-rw-r--r-- 1 root root 2 Mar  5 17:04 qq-cw-transaction-article-sync-41-1583399050.txt
-rw-r--r-- 1 root root 2 Mar  5 17:04 qq-cw-transaction-article-sync-43-1583399050.txt
-rw-r--r-- 1 root root 2 Mar  5 17:05 qq-cw-transaction-article-sync-41-1583399112.txt
-rw-r--r-- 1 root root 2 Mar  5 17:05 qq-cw-transaction-article-sync-42-1583399112.txt
-rw-r--r-- 1 root root 2 Mar  5 17:06 qq-cw-transaction-article-sync-41-1583399173.txt
-rw-r--r-- 1 root root 2 Mar  5 17:06 qq-cw-transaction-article-sync-42-1583399174.txt
-rw-r--r-- 1 root root 2 Mar  5 17:07 qq-cw-transaction-article-sync-41-1583399235.txt
-rw-r--r-- 1 root root 2 Mar  5 17:07 qq-cw-transaction-article-sync-42-1583399235.txt
-rw-r--r-- 1 root root 2 Mar  5 17:07 qq-cw-transaction-article-sync-43-1583399236.txt
-rw-r--r-- 1 root root 2 Mar  5 17:08 qq-cw-transaction-article-sync-41-1583399297.txt
-rw-r--r-- 1 root root 2 Mar  5 17:08 qq-cw-transaction-article-sync-43-1583399298.txt
-rw-r--r-- 1 root root 2 Mar  5 17:09 qq-cw-transaction-article-sync-41-1583399359.txt
-rw-r--r-- 1 root root 2 Mar  5 17:09 qq-cw-transaction-article-sync-42-1583399359.txt
-rw-r--r-- 1 root root 2 Mar  5 17:10 qq-cw-transaction-article-sync-41-1583399421.txt
-rw-r--r-- 1 root root 2 Mar  5 17:10 qq-cw-transaction-article-sync-42-1583399421.txt
-rw-r--r-- 1 root root 2 Mar  5 17:11 qq-cw-transaction-article-sync-42-1583399483.txt

[root@e9565f71310d logs]# ls -ltr
total 100
-rw-r--r-- 1 root root 2 Mar  5 17:03 qq-cw-transaction-article-sync-41-1583399012.txt
-rw-r--r-- 1 root root 2 Mar  5 17:03 qq-cw-transaction-article-sync-42-1583399013.txt
-rw-r--r-- 1 root root 2 Mar  5 17:03 qq-cw-transaction-article-sync-43-1583399013.txt
-rw-r--r-- 1 root root 2 Mar  5 17:04 qq-cw-transaction-article-sync-41-1583399074.txt
-rw-r--r-- 1 root root 2 Mar  5 17:04 qq-cw-transaction-article-sync-42-1583399075.txt
-rw-r--r-- 1 root root 2 Mar  5 17:04 qq-cw-transaction-article-sync-43-1583399076.txt
-rw-r--r-- 1 root root 2 Mar  5 17:05 qq-cw-transaction-article-sync-41-1583399137.txt
-rw-r--r-- 1 root root 2 Mar  5 17:05 qq-cw-transaction-article-sync-42-1583399138.txt
-rw-r--r-- 1 root root 2 Mar  5 17:05 qq-cw-transaction-article-sync-43-1583399139.txt
-rw-r--r-- 1 root root 2 Mar  5 17:06 qq-cw-transaction-article-sync-41-1583399200.txt
-rw-r--r-- 1 root root 2 Mar  5 17:06 qq-cw-transaction-article-sync-42-1583399201.txt
-rw-r--r-- 1 root root 2 Mar  5 17:06 qq-cw-transaction-article-sync-43-1583399201.txt
-rw-r--r-- 1 root root 2 Mar  5 17:07 qq-cw-transaction-article-sync-41-1583399263.txt
-rw-r--r-- 1 root root 2 Mar  5 17:07 qq-cw-transaction-article-sync-42-1583399264.txt
-rw-r--r-- 1 root root 2 Mar  5 17:07 qq-cw-transaction-article-sync-43-1583399264.txt
-rw-r--r-- 1 root root 2 Mar  5 17:08 qq-cw-transaction-article-sync-41-1583399325.txt
-rw-r--r-- 1 root root 2 Mar  5 17:08 qq-cw-transaction-article-sync-42-1583399326.txt
-rw-r--r-- 1 root root 2 Mar  5 17:08 qq-cw-transaction-article-sync-43-1583399326.txt
-rw-r--r-- 1 root root 2 Mar  5 17:09 qq-cw-transaction-article-sync-42-1583399388.txt
-rw-r--r-- 1 root root 2 Mar  5 17:09 qq-cw-transaction-article-sync-43-1583399388.txt
-rw-r--r-- 1 root root 2 Mar  5 17:09 qq-cw-transaction-article-sync-41-1583399388.txt
-rw-r--r-- 1 root root 2 Mar  5 17:10 qq-cw-transaction-article-sync-42-1583399450.txt
-rw-r--r-- 1 root root 2 Mar  5 17:10 qq-cw-transaction-article-sync-43-1583399451.txt
-rw-r--r-- 1 root root 2 Mar  5 17:10 qq-cw-transaction-article-sync-41-1583399451.txt
-rw-r--r-- 1 root root 2 Mar  5 17:11 qq-cw-transaction-article-sync-42-1583399512.txt

[root@7c7a4390ba3f logs]# ls -ltr
total 72
-rw-r--r-- 1 root root 2 Mar  5 17:04 qq-cw-transaction-article-sync-42-1583399050.txt
-rw-r--r-- 1 root root 2 Mar  5 17:04 qq-cw-transaction-article-sync-43-1583399050.txt
-rw-r--r-- 1 root root 2 Mar  5 17:04 qq-cw-transaction-article-sync-41-1583399050.txt
-rw-r--r-- 1 root root 2 Mar  5 17:05 qq-cw-transaction-article-sync-43-1583399112.txt
-rw-r--r-- 1 root root 2 Mar  5 17:05 qq-cw-transaction-article-sync-41-1583399112.txt
-rw-r--r-- 1 root root 2 Mar  5 17:06 qq-cw-transaction-article-sync-43-1583399174.txt
-rw-r--r-- 1 root root 2 Mar  5 17:06 qq-cw-transaction-article-sync-41-1583399174.txt
-rw-r--r-- 1 root root 2 Mar  5 17:06 qq-cw-transaction-article-sync-42-1583399174.txt
-rw-r--r-- 1 root root 2 Mar  5 17:07 qq-cw-transaction-article-sync-41-1583399236.txt
-rw-r--r-- 1 root root 2 Mar  5 17:07 qq-cw-transaction-article-sync-42-1583399236.txt
-rw-r--r-- 1 root root 2 Mar  5 17:08 qq-cw-transaction-article-sync-42-1583399298.txt
-rw-r--r-- 1 root root 2 Mar  5 17:08 qq-cw-transaction-article-sync-43-1583399298.txt
-rw-r--r-- 1 root root 2 Mar  5 17:08 qq-cw-transaction-article-sync-41-1583399298.txt
-rw-r--r-- 1 root root 2 Mar  5 17:09 qq-cw-transaction-article-sync-43-1583399360.txt
-rw-r--r-- 1 root root 2 Mar  5 17:09 qq-cw-transaction-article-sync-41-1583399360.txt
-rw-r--r-- 1 root root 2 Mar  5 17:10 qq-cw-transaction-article-sync-43-1583399421.txt
-rw-r--r-- 1 root root 2 Mar  5 17:10 qq-cw-transaction-article-sync-41-1583399422.txt
-rw-r--r-- 1 root root 2 Mar  5 17:11 qq-cw-transaction-article-sync-42-1583399483.txt


11、模拟出 5 条任务。事务ID为 47、48、49、52、53 的同步时间(分钟)分别为:4、11、4、5、5 。事务ID为 47、48、49、52、53 的同步次数分别为:10、20、10、9、10 。事务ID为 47、48、49、52、53 的同步频率分别为:4 * 60 / 10 = 24、11 * 60 / 20 = 33、4 * 60 / 10 = 24、5 * 60 / 9 = 33、5 * 60 / 10 = 30。得出平均值:(24 + 33 + 24 + 33 + 30) / 5 = 29。理论上的计算公式,进一法取整(事务数量 / 5) / 容器数量 * 60。符合预期。如图8
模拟出 5 条任务。事务ID为 47、48、49、52、53 的同步时间(分钟)分别为:4、11、4、5、5 。事务ID为 47、48、49、52、53 的同步次数分别为:10、20、10、9、10 。事务ID为 47、48、49、52、53 的同步频率分别为:4 * 60 / 10 = 24、11 * 60 / 20 = 33、4 * 60 / 10 = 24、5 * 60 / 9 = 33、5 * 60 / 10 = 30。得出平均值:(24 + 33 + 24 + 33 + 30) / 5 = 29。理论上的计算公式,进一法取整(事务数量 / 5) / 容器数量 * 60。符合预期

图8



[root@21325d776096 logs]# ls -ltr
total 88
-rw-r--r-- 1 root root 2 Mar  6 09:55 qq-cw-transaction-article-sync-47-1583459743.txt
-rw-r--r-- 1 root root 2 Mar  6 09:55 qq-cw-transaction-article-sync-48-1583459744.txt
-rw-r--r-- 1 root root 2 Mar  6 09:55 qq-cw-transaction-article-sync-49-1583459744.txt
-rw-r--r-- 1 root root 2 Mar  6 09:56 qq-cw-transaction-article-sync-52-1583459806.txt
-rw-r--r-- 1 root root 2 Mar  6 09:56 qq-cw-transaction-article-sync-47-1583459807.txt
-rw-r--r-- 1 root root 2 Mar  6 09:56 qq-cw-transaction-article-sync-48-1583459807.txt
-rw-r--r-- 1 root root 2 Mar  6 09:56 qq-cw-transaction-article-sync-49-1583459807.txt
-rw-r--r-- 1 root root 2 Mar  6 09:56 qq-cw-transaction-article-sync-53-1583459807.txt
-rw-r--r-- 1 root root 2 Mar  6 09:57 qq-cw-transaction-article-sync-47-1583459869.txt
-rw-r--r-- 1 root root 2 Mar  6 09:57 qq-cw-transaction-article-sync-48-1583459869.txt
-rw-r--r-- 1 root root 2 Mar  6 09:57 qq-cw-transaction-article-sync-52-1583459870.txt
-rw-r--r-- 1 root root 2 Mar  6 09:57 qq-cw-transaction-article-sync-49-1583459870.txt
-rw-r--r-- 1 root root 2 Mar  6 09:57 qq-cw-transaction-article-sync-53-1583459870.txt
-rw-r--r-- 1 root root 2 Mar  6 09:58 qq-cw-transaction-article-sync-48-1583459932.txt
-rw-r--r-- 1 root root 2 Mar  6 09:58 qq-cw-transaction-article-sync-52-1583459932.txt
-rw-r--r-- 1 root root 2 Mar  6 09:58 qq-cw-transaction-article-sync-53-1583459932.txt
-rw-r--r-- 1 root root 2 Mar  6 09:59 qq-cw-transaction-article-sync-48-1583459994.txt
-rw-r--r-- 1 root root 2 Mar  6 10:00 qq-cw-transaction-article-sync-48-1583460055.txt
-rw-r--r-- 1 root root 2 Mar  6 10:01 qq-cw-transaction-article-sync-48-1583460117.txt
-rw-r--r-- 1 root root 2 Mar  6 10:02 qq-cw-transaction-article-sync-48-1583460179.txt
-rw-r--r-- 1 root root 2 Mar  6 10:04 qq-cw-transaction-article-sync-48-1583460240.txt
-rw-r--r-- 1 root root 2 Mar  6 10:05 qq-cw-transaction-article-sync-48-1583460302.txt

[root@e9565f71310d logs]# ls -ltr
total 96
-rw-r--r-- 1 root root 2 Mar  6 09:55 qq-cw-transaction-article-sync-52-1583459751.txt
-rw-r--r-- 1 root root 2 Mar  6 09:55 qq-cw-transaction-article-sync-53-1583459752.txt
-rw-r--r-- 1 root root 2 Mar  6 09:55 qq-cw-transaction-article-sync-47-1583459752.txt
-rw-r--r-- 1 root root 2 Mar  6 09:55 qq-cw-transaction-article-sync-48-1583459752.txt
-rw-r--r-- 1 root root 2 Mar  6 09:55 qq-cw-transaction-article-sync-49-1583459752.txt
-rw-r--r-- 1 root root 2 Mar  6 09:56 qq-cw-transaction-article-sync-52-1583459813.txt
-rw-r--r-- 1 root root 2 Mar  6 09:56 qq-cw-transaction-article-sync-47-1583459813.txt
-rw-r--r-- 1 root root 2 Mar  6 09:56 qq-cw-transaction-article-sync-48-1583459814.txt
-rw-r--r-- 1 root root 2 Mar  6 09:56 qq-cw-transaction-article-sync-49-1583459814.txt
-rw-r--r-- 1 root root 2 Mar  6 09:56 qq-cw-transaction-article-sync-53-1583459814.txt
-rw-r--r-- 1 root root 2 Mar  6 09:57 qq-cw-transaction-article-sync-47-1583459876.txt
-rw-r--r-- 1 root root 2 Mar  6 09:57 qq-cw-transaction-article-sync-48-1583459877.txt
-rw-r--r-- 1 root root 2 Mar  6 09:57 qq-cw-transaction-article-sync-49-1583459877.txt
-rw-r--r-- 1 root root 2 Mar  6 09:57 qq-cw-transaction-article-sync-52-1583459878.txt
-rw-r--r-- 1 root root 2 Mar  6 09:57 qq-cw-transaction-article-sync-53-1583459878.txt
-rw-r--r-- 1 root root 2 Mar  6 09:59 qq-cw-transaction-article-sync-48-1583459940.txt
-rw-r--r-- 1 root root 2 Mar  6 09:59 qq-cw-transaction-article-sync-52-1583459940.txt
-rw-r--r-- 1 root root 2 Mar  6 09:59 qq-cw-transaction-article-sync-53-1583459941.txt
-rw-r--r-- 1 root root 2 Mar  6 10:00 qq-cw-transaction-article-sync-48-1583460002.txt
-rw-r--r-- 1 root root 2 Mar  6 10:01 qq-cw-transaction-article-sync-48-1583460063.txt
-rw-r--r-- 1 root root 2 Mar  6 10:02 qq-cw-transaction-article-sync-48-1583460125.txt
-rw-r--r-- 1 root root 2 Mar  6 10:03 qq-cw-transaction-article-sync-48-1583460187.txt
-rw-r--r-- 1 root root 2 Mar  6 10:04 qq-cw-transaction-article-sync-48-1583460248.txt
-rw-r--r-- 1 root root 2 Mar  6 10:05 qq-cw-transaction-article-sync-48-1583460310.txt

[root@7c7a4390ba3f logs]# ls -ltr
total 120
-rw-r--r-- 1 root root 17367 Mar  6 09:55 app.log
-rw-r--r-- 1 root root     2 Mar  6 09:55 qq-cw-transaction-article-sync-47-1583459731.txt
-rw-r--r-- 1 root root     2 Mar  6 09:55 qq-cw-transaction-article-sync-48-1583459732.txt
-rw-r--r-- 1 root root     2 Mar  6 09:55 qq-cw-transaction-article-sync-49-1583459732.txt
-rw-r--r-- 1 root root     2 Mar  6 09:56 qq-cw-transaction-article-sync-52-1583459793.txt
-rw-r--r-- 1 root root     2 Mar  6 09:56 qq-cw-transaction-article-sync-47-1583459794.txt
-rw-r--r-- 1 root root     2 Mar  6 09:56 qq-cw-transaction-article-sync-48-1583459794.txt
-rw-r--r-- 1 root root     2 Mar  6 09:56 qq-cw-transaction-article-sync-49-1583459794.txt
-rw-r--r-- 1 root root     2 Mar  6 09:56 qq-cw-transaction-article-sync-53-1583459795.txt
-rw-r--r-- 1 root root     2 Mar  6 09:57 qq-cw-transaction-article-sync-47-1583459856.txt
-rw-r--r-- 1 root root     2 Mar  6 09:57 qq-cw-transaction-article-sync-52-1583459857.txt
-rw-r--r-- 1 root root     2 Mar  6 09:57 qq-cw-transaction-article-sync-48-1583459857.txt
-rw-r--r-- 1 root root     2 Mar  6 09:57 qq-cw-transaction-article-sync-49-1583459858.txt
-rw-r--r-- 1 root root     2 Mar  6 09:57 qq-cw-transaction-article-sync-53-1583459859.txt
-rw-r--r-- 1 root root     2 Mar  6 09:58 qq-cw-transaction-article-sync-47-1583459920.txt
-rw-r--r-- 1 root root     2 Mar  6 09:58 qq-cw-transaction-article-sync-48-1583459921.txt
-rw-r--r-- 1 root root     2 Mar  6 09:58 qq-cw-transaction-article-sync-49-1583459922.txt
-rw-r--r-- 1 root root     2 Mar  6 09:58 qq-cw-transaction-article-sync-52-1583459922.txt
-rw-r--r-- 1 root root     2 Mar  6 09:58 qq-cw-transaction-article-sync-53-1583459922.txt
-rw-r--r-- 1 root root     2 Mar  6 09:59 qq-cw-transaction-article-sync-48-1583459984.txt
-rw-r--r-- 1 root root     2 Mar  6 10:00 qq-cw-transaction-article-sync-48-1583460045.txt
-rw-r--r-- 1 root root     2 Mar  6 10:01 qq-cw-transaction-article-sync-48-1583460107.txt
-rw-r--r-- 1 root root     2 Mar  6 10:02 qq-cw-transaction-article-sync-48-1583460169.txt
-rw-r--r-- 1 root root     2 Mar  6 10:03 qq-cw-transaction-article-sync-48-1583460231.txt
-rw-r--r-- 1 root root     2 Mar  6 10:04 qq-cw-transaction-article-sync-48-1583460293.txt
-rw-r--r-- 1 root root     2 Mar  6 10:05 qq-cw-transaction-article-sync-48-1583460355.txt


12、模拟出 8 条任务。事务ID为 57、58、59、63、64、65、68、69 的同步时间(分钟)分别为:11、12、13、12、11、12、11、12 。事务ID为 57、58、59、63、64、65、68、69 的同步次数分别为:21、22、22、19、17、5、17、17 。事务ID为 57、58、59、63、64、65、68、69 的同步频率分别为:11 * 60 / 21 = 31、12 * 60 / 22 = 33、13 * 60 / 22 = 35、12 * 60 / 19 = 38、11 * 60 / 17 = 39、12 * 60 / 5 = 144、11 * 60 / 17 = 39、12 * 60 / 17 = 42。得出平均值:(31 + 33 + 35 + 38 + 39 + 144 + 39 + 42) / 8 = 50。理论上的计算公式,进一法取整(事务数量 / 5) / 容器数量 * 60。符合预期。如图9
模拟出 8 条任务。事务ID为 57、58、59、63、64、65、68、69 的同步时间(分钟)分别为:11、12、13、12、11、12、11、12 。事务ID为 57、58、59、63、64、65、68、69 的同步次数分别为:21、22、22、19、17、5、17、17 。事务ID为 57、58、59、63、64、65、68、69 的同步频率分别为:11 * 60 / 21 = 31、12 * 60 / 22 = 33、13 * 60 / 22 = 35、12 * 60 / 19 = 38、11 * 60 / 17 = 39、12 * 60 / 5 = 144、11 * 60 / 17 = 39、12 * 60 / 17 = 42。得出平均值:(31 + 33 + 35 + 38 + 39 + 144 + 39 + 42) / 8 = 50。理论上的计算公式,进一法取整(事务数量 / 5) / 容器数量 * 60。符合预期

图9



[root@21325d776096 logs]# ls -ltr
total 220
-rw-r--r-- 1 root root     2 Mar  6 10:30 qq-cw-transaction-article-sync-57-1583461834.txt
-rw-r--r-- 1 root root     2 Mar  6 10:30 qq-cw-transaction-article-sync-58-1583461834.txt
-rw-r--r-- 1 root root     2 Mar  6 10:30 qq-cw-transaction-article-sync-59-1583461834.txt
-rw-r--r-- 1 root root     2 Mar  6 10:31 qq-cw-transaction-article-sync-68-1583461896.txt
-rw-r--r-- 1 root root     2 Mar  6 10:31 qq-cw-transaction-article-sync-69-1583461896.txt
-rw-r--r-- 1 root root     2 Mar  6 10:31 qq-cw-transaction-article-sync-57-1583461897.txt
-rw-r--r-- 1 root root     2 Mar  6 10:31 qq-cw-transaction-article-sync-58-1583461897.txt
-rw-r--r-- 1 root root     2 Mar  6 10:32 qq-cw-transaction-article-sync-63-1583461959.txt
-rw-r--r-- 1 root root     2 Mar  6 10:32 qq-cw-transaction-article-sync-64-1583461959.txt
-rw-r--r-- 1 root root     2 Mar  6 10:32 qq-cw-transaction-article-sync-68-1583461959.txt
-rw-r--r-- 1 root root     2 Mar  6 10:32 qq-cw-transaction-article-sync-69-1583461959.txt
-rw-r--r-- 1 root root     2 Mar  6 10:33 qq-cw-transaction-article-sync-58-1583462021.txt
-rw-r--r-- 1 root root     2 Mar  6 10:33 qq-cw-transaction-article-sync-59-1583462022.txt
-rw-r--r-- 1 root root     2 Mar  6 10:33 qq-cw-transaction-article-sync-63-1583462022.txt
-rw-r--r-- 1 root root     2 Mar  6 10:33 qq-cw-transaction-article-sync-57-1583462022.txt
-rw-r--r-- 1 root root     2 Mar  6 10:34 qq-cw-transaction-article-sync-68-1583462084.txt
-rw-r--r-- 1 root root     2 Mar  6 10:34 qq-cw-transaction-article-sync-58-1583462084.txt
-rw-r--r-- 1 root root     2 Mar  6 10:34 qq-cw-transaction-article-sync-69-1583462085.txt
-rw-r--r-- 1 root root     2 Mar  6 10:34 qq-cw-transaction-article-sync-59-1583462085.txt
-rw-r--r-- 1 root root 34566 Mar  6 10:35 app.log
-rw-r--r-- 1 root root     2 Mar  6 10:35 qq-cw-transaction-article-sync-63-1583462146.txt
-rw-r--r-- 1 root root     2 Mar  6 10:35 qq-cw-transaction-article-sync-64-1583462147.txt
-rw-r--r-- 1 root root     2 Mar  6 10:35 qq-cw-transaction-article-sync-68-1583462147.txt
-rw-r--r-- 1 root root     2 Mar  6 10:35 qq-cw-transaction-article-sync-57-1583462147.txt
-rw-r--r-- 1 root root     2 Mar  6 10:36 qq-cw-transaction-article-sync-59-1583462209.txt
-rw-r--r-- 1 root root     2 Mar  6 10:36 qq-cw-transaction-article-sync-63-1583462209.txt
-rw-r--r-- 1 root root     2 Mar  6 10:36 qq-cw-transaction-article-sync-69-1583462210.txt
-rw-r--r-- 1 root root     2 Mar  6 10:36 qq-cw-transaction-article-sync-57-1583462210.txt
-rw-r--r-- 1 root root     2 Mar  6 10:37 qq-cw-transaction-article-sync-64-1583462271.txt
-rw-r--r-- 1 root root     2 Mar  6 10:37 qq-cw-transaction-article-sync-68-1583462272.txt
-rw-r--r-- 1 root root     2 Mar  6 10:37 qq-cw-transaction-article-sync-59-1583462272.txt
-rw-r--r-- 1 root root     2 Mar  6 10:37 qq-cw-transaction-article-sync-57-1583462272.txt
-rw-r--r-- 1 root root     2 Mar  6 10:38 qq-cw-transaction-article-sync-63-1583462334.txt
-rw-r--r-- 1 root root     2 Mar  6 10:38 qq-cw-transaction-article-sync-64-1583462334.txt
-rw-r--r-- 1 root root     2 Mar  6 10:38 qq-cw-transaction-article-sync-69-1583462335.txt
-rw-r--r-- 1 root root     2 Mar  6 10:38 qq-cw-transaction-article-sync-57-1583462335.txt
-rw-r--r-- 1 root root     2 Mar  6 10:39 qq-cw-transaction-article-sync-59-1583462396.txt
-rw-r--r-- 1 root root     2 Mar  6 10:39 qq-cw-transaction-article-sync-63-1583462397.txt
-rw-r--r-- 1 root root     2 Mar  6 10:39 qq-cw-transaction-article-sync-68-1583462397.txt
-rw-r--r-- 1 root root     2 Mar  6 10:39 qq-cw-transaction-article-sync-57-1583462397.txt
-rw-r--r-- 1 root root     2 Mar  6 10:40 qq-cw-transaction-article-sync-59-1583462459.txt
-rw-r--r-- 1 root root     2 Mar  6 10:40 qq-cw-transaction-article-sync-64-1583462459.txt
-rw-r--r-- 1 root root     2 Mar  6 10:41 qq-cw-transaction-article-sync-69-1583462460.txt
-rw-r--r-- 1 root root     2 Mar  6 10:41 qq-cw-transaction-article-sync-65-1583462460.txt
-rw-r--r-- 1 root root     2 Mar  6 10:41 qq-cw-transaction-article-sync-58-1583462460.txt
-rw-r--r-- 1 root root     2 Mar  6 10:42 qq-cw-transaction-article-sync-69-1583462522.txt
-rw-r--r-- 1 root root     2 Mar  6 10:42 qq-cw-transaction-article-sync-59-1583462523.txt

[root@e9565f71310d logs]# ls -ltr
total 212
-rw-r--r-- 1 root root     2 Mar  6 10:30 qq-cw-transaction-article-sync-63-1583461842.txt
-rw-r--r-- 1 root root     2 Mar  6 10:30 qq-cw-transaction-article-sync-64-1583461842.txt
-rw-r--r-- 1 root root     2 Mar  6 10:30 qq-cw-transaction-article-sync-65-1583461843.txt
-rw-r--r-- 1 root root     2 Mar  6 10:31 qq-cw-transaction-article-sync-59-1583461905.txt
-rw-r--r-- 1 root root     2 Mar  6 10:31 qq-cw-transaction-article-sync-63-1583461905.txt
-rw-r--r-- 1 root root     2 Mar  6 10:31 qq-cw-transaction-article-sync-64-1583461906.txt
-rw-r--r-- 1 root root     2 Mar  6 10:31 qq-cw-transaction-article-sync-68-1583461906.txt
-rw-r--r-- 1 root root     2 Mar  6 10:32 qq-cw-transaction-article-sync-57-1583461968.txt
-rw-r--r-- 1 root root     2 Mar  6 10:32 qq-cw-transaction-article-sync-58-1583461968.txt
-rw-r--r-- 1 root root     2 Mar  6 10:32 qq-cw-transaction-article-sync-59-1583461969.txt
-rw-r--r-- 1 root root     2 Mar  6 10:32 qq-cw-transaction-article-sync-63-1583461969.txt
-rw-r--r-- 1 root root     2 Mar  6 10:33 qq-cw-transaction-article-sync-64-1583462030.txt
-rw-r--r-- 1 root root     2 Mar  6 10:33 qq-cw-transaction-article-sync-68-1583462031.txt
-rw-r--r-- 1 root root     2 Mar  6 10:33 qq-cw-transaction-article-sync-69-1583462032.txt
-rw-r--r-- 1 root root     2 Mar  6 10:33 qq-cw-transaction-article-sync-58-1583462032.txt
-rw-r--r-- 1 root root 33937 Mar  6 10:34 app.log
-rw-r--r-- 1 root root     2 Mar  6 10:34 qq-cw-transaction-article-sync-57-1583462093.txt
-rw-r--r-- 1 root root     2 Mar  6 10:34 qq-cw-transaction-article-sync-63-1583462094.txt
-rw-r--r-- 1 root root     2 Mar  6 10:34 qq-cw-transaction-article-sync-64-1583462094.txt
-rw-r--r-- 1 root root     2 Mar  6 10:34 qq-cw-transaction-article-sync-68-1583462094.txt
-rw-r--r-- 1 root root     2 Mar  6 10:35 qq-cw-transaction-article-sync-58-1583462155.txt
-rw-r--r-- 1 root root     2 Mar  6 10:35 qq-cw-transaction-article-sync-59-1583462156.txt
-rw-r--r-- 1 root root     2 Mar  6 10:35 qq-cw-transaction-article-sync-69-1583462156.txt
-rw-r--r-- 1 root root     2 Mar  6 10:35 qq-cw-transaction-article-sync-63-1583462156.txt
-rw-r--r-- 1 root root     2 Mar  6 10:36 qq-cw-transaction-article-sync-58-1583462218.txt
-rw-r--r-- 1 root root     2 Mar  6 10:36 qq-cw-transaction-article-sync-64-1583462218.txt
-rw-r--r-- 1 root root     2 Mar  6 10:36 qq-cw-transaction-article-sync-68-1583462218.txt
-rw-r--r-- 1 root root     2 Mar  6 10:36 qq-cw-transaction-article-sync-59-1583462219.txt
-rw-r--r-- 1 root root     2 Mar  6 10:38 qq-cw-transaction-article-sync-58-1583462280.txt
-rw-r--r-- 1 root root     2 Mar  6 10:38 qq-cw-transaction-article-sync-63-1583462281.txt
-rw-r--r-- 1 root root     2 Mar  6 10:38 qq-cw-transaction-article-sync-69-1583462281.txt
-rw-r--r-- 1 root root     2 Mar  6 10:38 qq-cw-transaction-article-sync-64-1583462281.txt
-rw-r--r-- 1 root root     2 Mar  6 10:39 qq-cw-transaction-article-sync-58-1583462343.txt
-rw-r--r-- 1 root root     2 Mar  6 10:39 qq-cw-transaction-article-sync-59-1583462344.txt
-rw-r--r-- 1 root root     2 Mar  6 10:39 qq-cw-transaction-article-sync-68-1583462344.txt
-rw-r--r-- 1 root root     2 Mar  6 10:39 qq-cw-transaction-article-sync-63-1583462344.txt
-rw-r--r-- 1 root root     2 Mar  6 10:40 qq-cw-transaction-article-sync-58-1583462406.txt
-rw-r--r-- 1 root root     2 Mar  6 10:40 qq-cw-transaction-article-sync-64-1583462406.txt
-rw-r--r-- 1 root root     2 Mar  6 10:40 qq-cw-transaction-article-sync-69-1583462406.txt
-rw-r--r-- 1 root root     2 Mar  6 10:40 qq-cw-transaction-article-sync-59-1583462406.txt
-rw-r--r-- 1 root root     2 Mar  6 10:41 qq-cw-transaction-article-sync-63-1583462468.txt
-rw-r--r-- 1 root root     2 Mar  6 10:41 qq-cw-transaction-article-sync-68-1583462468.txt
-rw-r--r-- 1 root root     2 Mar  6 10:41 qq-cw-transaction-article-sync-59-1583462469.txt
-rw-r--r-- 1 root root     2 Mar  6 10:41 qq-cw-transaction-article-sync-58-1583462469.txt
-rw-r--r-- 1 root root     2 Mar  6 10:41 qq-cw-transaction-article-sync-65-1583462470.txt

[root@7c7a4390ba3f logs]# ls -ltr
total 220
-rw-r--r-- 1 root root     2 Mar  6 10:30 qq-cw-transaction-article-sync-57-1583461824.txt
-rw-r--r-- 1 root root     2 Mar  6 10:30 qq-cw-transaction-article-sync-58-1583461825.txt
-rw-r--r-- 1 root root     2 Mar  6 10:30 qq-cw-transaction-article-sync-59-1583461825.txt
-rw-r--r-- 1 root root     2 Mar  6 10:31 qq-cw-transaction-article-sync-57-1583461886.txt
-rw-r--r-- 1 root root     2 Mar  6 10:31 qq-cw-transaction-article-sync-58-1583461886.txt
-rw-r--r-- 1 root root     2 Mar  6 10:31 qq-cw-transaction-article-sync-59-1583461886.txt
-rw-r--r-- 1 root root     2 Mar  6 10:31 qq-cw-transaction-article-sync-63-1583461887.txt
-rw-r--r-- 1 root root     2 Mar  6 10:31 qq-cw-transaction-article-sync-64-1583461887.txt
-rw-r--r-- 1 root root     2 Mar  6 10:32 qq-cw-transaction-article-sync-69-1583461948.txt
-rw-r--r-- 1 root root     2 Mar  6 10:32 qq-cw-transaction-article-sync-57-1583461949.txt
-rw-r--r-- 1 root root     2 Mar  6 10:32 qq-cw-transaction-article-sync-58-1583461949.txt
-rw-r--r-- 1 root root     2 Mar  6 10:32 qq-cw-transaction-article-sync-59-1583461949.txt
-rw-r--r-- 1 root root     2 Mar  6 10:33 qq-cw-transaction-article-sync-64-1583462011.txt
-rw-r--r-- 1 root root     2 Mar  6 10:33 qq-cw-transaction-article-sync-68-1583462011.txt
-rw-r--r-- 1 root root     2 Mar  6 10:33 qq-cw-transaction-article-sync-69-1583462011.txt
-rw-r--r-- 1 root root     2 Mar  6 10:33 qq-cw-transaction-article-sync-57-1583462011.txt
-rw-r--r-- 1 root root     2 Mar  6 10:34 qq-cw-transaction-article-sync-59-1583462073.txt
-rw-r--r-- 1 root root     2 Mar  6 10:34 qq-cw-transaction-article-sync-57-1583462074.txt
-rw-r--r-- 1 root root     2 Mar  6 10:34 qq-cw-transaction-article-sync-63-1583462074.txt
-rw-r--r-- 1 root root     2 Mar  6 10:34 qq-cw-transaction-article-sync-64-1583462074.txt
-rw-r--r-- 1 root root 17200 Mar  6 10:35 app.log
-rw-r--r-- 1 root root     2 Mar  6 10:35 qq-cw-transaction-article-sync-58-1583462136.txt
-rw-r--r-- 1 root root     2 Mar  6 10:35 qq-cw-transaction-article-sync-59-1583462136.txt
-rw-r--r-- 1 root root     2 Mar  6 10:35 qq-cw-transaction-article-sync-69-1583462136.txt
-rw-r--r-- 1 root root     2 Mar  6 10:35 qq-cw-transaction-article-sync-57-1583462136.txt
-rw-r--r-- 1 root root     2 Mar  6 10:36 qq-cw-transaction-article-sync-57-1583462198.txt
-rw-r--r-- 1 root root     2 Mar  6 10:36 qq-cw-transaction-article-sync-64-1583462199.txt
-rw-r--r-- 1 root root     2 Mar  6 10:36 qq-cw-transaction-article-sync-68-1583462199.txt
-rw-r--r-- 1 root root     2 Mar  6 10:36 qq-cw-transaction-article-sync-58-1583462199.txt
-rw-r--r-- 1 root root     2 Mar  6 10:37 qq-cw-transaction-article-sync-63-1583462261.txt
-rw-r--r-- 1 root root     2 Mar  6 10:37 qq-cw-transaction-article-sync-57-1583462261.txt
-rw-r--r-- 1 root root     2 Mar  6 10:37 qq-cw-transaction-article-sync-69-1583462261.txt
-rw-r--r-- 1 root root     2 Mar  6 10:37 qq-cw-transaction-article-sync-58-1583462261.txt
-rw-r--r-- 1 root root     2 Mar  6 10:38 qq-cw-transaction-article-sync-57-1583462323.txt
-rw-r--r-- 1 root root     2 Mar  6 10:38 qq-cw-transaction-article-sync-59-1583462324.txt
-rw-r--r-- 1 root root     2 Mar  6 10:38 qq-cw-transaction-article-sync-68-1583462324.txt
-rw-r--r-- 1 root root     2 Mar  6 10:38 qq-cw-transaction-article-sync-58-1583462324.txt
-rw-r--r-- 1 root root     2 Mar  6 10:39 qq-cw-transaction-article-sync-64-1583462386.txt
-rw-r--r-- 1 root root     2 Mar  6 10:39 qq-cw-transaction-article-sync-57-1583462386.txt
-rw-r--r-- 1 root root     2 Mar  6 10:39 qq-cw-transaction-article-sync-69-1583462386.txt
-rw-r--r-- 1 root root     2 Mar  6 10:39 qq-cw-transaction-article-sync-58-1583462386.txt
-rw-r--r-- 1 root root     2 Mar  6 10:40 qq-cw-transaction-article-sync-65-1583462448.txt
-rw-r--r-- 1 root root     2 Mar  6 10:40 qq-cw-transaction-article-sync-57-1583462448.txt
-rw-r--r-- 1 root root     2 Mar  6 10:40 qq-cw-transaction-article-sync-63-1583462449.txt
-rw-r--r-- 1 root root     2 Mar  6 10:40 qq-cw-transaction-article-sync-68-1583462449.txt
-rw-r--r-- 1 root root     2 Mar  6 10:40 qq-cw-transaction-article-sync-58-1583462449.txt
-rw-r--r-- 1 root root     2 Mar  6 10:41 qq-cw-transaction-article-sync-69-1583462511.txt
-rw-r--r-- 1 root root     2 Mar  6 10:41 qq-cw-transaction-article-sync-63-1583462511.txt
-rw-r--r-- 1 root root     2 Mar  6 10:41 qq-cw-transaction-article-sync-68-1583462512.txt
-rw-r--r-- 1 root root     2 Mar  6 10:41 qq-cw-transaction-article-sync-59-1583462512.txt
-rw-r--r-- 1 root root     2 Mar  6 10:41 qq-cw-transaction-article-sync-65-1583462512.txt


 ]]>
https://www.shuijingwanwq.com/2020/03/09/3998/feed/ 0
在 Yii 2.0 中,控制台命令的集群实现,Redis模型的锁定实现(以保证同一时间段内,即使多台服务器皆在运行命令行,但是每台服务器运行的任务是不重复的,以提升命令行的总体处理性能) https://www.shuijingwanwq.com/2020/03/02/3964/ https://www.shuijingwanwq.com/2020/03/02/3964/#respond Mon, 02 Mar 2020 05:54:25 +0000 https://www.shuijingwanwq.com/?p=3964 浏览量: 70 1、Docker 部署,基于 Supervisor 的 crontab (bash sleep) 的实现,以降低内存占用,参考:https://www.shuijingwanwq.com/2019/10/12/3555/ 。/console/controllers/CmcConsoleUserController.php
<pre class="wp-block-syntaxhighlighter-code">

<?php
/**
 * Created by PhpStorm.
 * User: Qiang Wang
 * Date: 2019/01/09
 * Time: 13:55
 */

namespace console\controllers;

use Yii;
use console\models\ConfigColumnUser;
use console\models\redis\cmc_console\User as RedisCmcConsoleUser;
use console\services\CmcApiGroupService;
use console\services\CmcConsoleUserService;
use yii\base\InvalidArgumentException;
use yii\console\Controller;
use yii\console\ExitCode;
use yii\helpers\ArrayHelper;
use yii\web\HttpException;
use yii\web\ServerErrorHttpException;

/**
 * 框架服务控制台的用户
 *
 * @author Qiang Wang <shuijingwanwq@163.com>
 * @since  1.0
 */
class CmcConsoleUserController extends Controller
{
    /**
     * 同步框架服务控制台的用户模型(Http)至框架服务控制台的用户模型(Redis)、栏目人员配置模型(MySQL)
     *
     * @throws ServerErrorHttpException
     * @throws HttpException 如果登录超时
     * @throws InvalidArgumentException if the $direction or $sortFlag parameters do not have
     */
    public function actionSync()
    {
        // 设置同步标识的缓存键
        $redisCache = Yii::$app->redisCache;
        $redisCacheIdentityKey = 'cmc_console_user_sync';

        // 从缓存中取回同步标识
        $redisCacheIdentityData = $redisCache[$redisCacheIdentityKey];

        if ($redisCacheIdentityData === false) {
            // HTTP 请求,获取开通有效服务的租户ID列表
            $httpCmcApiGroupIds = CmcApiGroupService::httpGetGroupIds();

            /* 判断 $httpCmcApiGroupIds 是否为空,如果为空,则成功退出 */
            if (empty($httpCmcApiGroupIds)) {
                // 延缓执行 60 * 60 秒
                // sleep(Yii::$app->params['cmcConsoleUser']['isEmptyYesSleepTime']);

                return ExitCode::OK;
            }

            // 设置租户ID列表的缓存键
            $redisCacheGroupIdsKey = 'cmc_api_group_ids';

            // 从缓存中取回租户ID列表
            $redisCacheGroupIdsData = $redisCache[$redisCacheGroupIdsKey];

            // 是否设置租户ID列表的缓存,默认:否
            $isSetRedisCacheGroupIds = false;

            if ($redisCacheGroupIdsData === false) {
                $cmcApiGroupIds = [];
                foreach ($httpCmcApiGroupIds as $httpCmcApiGroupId) {
                    $cmcApiGroupIds[] = [
                        'group_id' => $httpCmcApiGroupId,
                        'cmc_console_user_last_synced_at' => 0, //上次同步时间
                    ];
                }
                // 是否设置租户ID列表的缓存:是
                $isSetRedisCacheGroupIds = true;
            } else {
                // 获取 group_id 值列表
                $redisCacheGroupIds = ArrayHelper::getColumn($redisCacheGroupIdsData, 'group_id');
                $cmcApiGroupIds = $redisCacheGroupIdsData;
                foreach ($httpCmcApiGroupIds as $httpCmcApiGroupId) {
                    if (!in_array($httpCmcApiGroupId, $redisCacheGroupIds)) {
                        $cmcApiGroupIds[] = [
                            'group_id' => $httpCmcApiGroupId,
                            'cmc_console_user_last_synced_at' => 0, //上次同步时间
                        ];
                        // 是否设置租户ID列表的缓存:是
                        $isSetRedisCacheGroupIds = true;
                    }
                }
            }

            // 判断是否设置租户ID列表的缓存
            if ($isSetRedisCacheGroupIds) {
                // 将 $cmcApiGroupIds 存放到缓存供下次使用,将数据在缓存中永久保留
                $redisCache->set($redisCacheGroupIdsKey, $cmcApiGroupIds);
            }


            // 基于上次同步时间顺序排列,赋值给:$sortCmcApiGroupIds
            $sortCmcApiGroupIds = $cmcApiGroupIds;
            ArrayHelper::multisort($sortCmcApiGroupIds, 'cmc_console_user_last_synced_at', SORT_ASC);

            foreach ($sortCmcApiGroupIds as $sortCmcApiGroupId) {
                $isLockExist = RedisCmcConsoleUser::isLockExist($sortCmcApiGroupId['group_id']);
                // 返回 true,表示锁定存在,即已经被其他客户端锁定
                if ($isLockExist === true) {
                    continue;
                }

                // HTTP请求,获取租户ID下的用户列表
                $httpGetUserListData = [
                    'groupId' => $sortCmcApiGroupId['group_id'],
                    'loginId' => '',
                    'loginTid' => '',
                ];
                $getUserListData = CmcConsoleUserService::httpGetUserList($httpGetUserListData);

                // 框架服务控制台的用户模型(Http),重建数组索引(以 ID 索引结果集)
                $httpCmcConsoleUserItems = ArrayHelper::index($getUserListData['list'], 'id');

                // 销毁变量
                unset($getUserListData['list']);

                // 基于租户ID查询框架服务控制台的用户模型(Redis)(以 ID 索引结果集)
                $redisCmcConsoleUserItems = RedisCmcConsoleUser::find()->where(['group_id' => $sortCmcApiGroupId['group_id']])->indexBy('id')->asArray()->all();

                // 使用键名比较计算数组的差集,如果不为空,则删除出现在 Redis 中但是未出现在 Http 中的记录
                $redisArrayDiffItems = array_diff_key($redisCmcConsoleUserItems, $httpCmcConsoleUserItems);
                // 销毁变量
                unset($redisCmcConsoleUserItems);
                if (!empty($redisArrayDiffItems)) {
                    $redisArrayDiffIds = array_keys($redisArrayDiffItems);
                    // 销毁变量
                    unset($redisArrayDiffItems);
                    if (RedisCmcConsoleUser::deleteAllByIds($sortCmcApiGroupId['group_id'], $redisArrayDiffIds) === false) {
                        continue;
                    }
                }

                // 基于租户ID查询栏目人员配置模型(MySQL)(以 用户ID 索引结果集)
                $configColumnUserItems = ConfigColumnUser::find()->where(['group_id' => $sortCmcApiGroupId['group_id']])->isDeletedNo()->indexBy('user_id')->asArray()->all();

                // 使用键名比较计算数组的差集,如果不为空,则删除 (软删除) 出现在 栏目人员配置模型(MySQL) 中但是未出现在 框架服务控制台的用户模型(Http) 中的记录
                $diffItems = array_diff_key($configColumnUserItems, $httpCmcConsoleUserItems);

                // 销毁变量
                unset($configColumnUserItems);
                if (!empty($diffItems)) {
                    // 基于租户ID、用户ID查询栏目人员配置模型(MySQL)(待删除)
                    $toBeDeletedConfigColumnUserItems = ConfigColumnUser::find()->where([
                        'and',
                        ['group_id' => $sortCmcApiGroupId['group_id']],
                        ['in', 'user_id', $diffItems],
                    ])->isDeletedNo()->all();
                    foreach ($toBeDeletedConfigColumnUserItems as $toBeDeletedConfigColumnUserItem) {
                        /* @var $toBeDeletedConfigColumnUserItem ConfigColumnUser */
                        $toBeDeletedConfigColumnUserItem->softDelete();
                    }
                }

                // 遍历框架服务控制台的用户模型(Http),判断在 Redis 中是否存在,如果不存在,则插入,如果存在且更新时间不相等,则更新
                foreach ($httpCmcConsoleUserItems as $httpCmcConsoleUserItemValue) {
                    $redisCmcConsoleUserItem = RedisCmcConsoleUser::find()->where(['id' => $httpCmcConsoleUserItemValue['id']])->one();

                    if (!isset($redisCmcConsoleUserItem)) {

                        $redisCmcConsoleUser = new RedisCmcConsoleUser();
                        $attributes = $this->getAttributes($getUserListData['group_info']['group_id'],
                            $httpCmcConsoleUserItemValue);
                        $redisCmcConsoleUser->attributes = $attributes;
                        $redisCmcConsoleUser->insert();

                    } else {
                        if ($httpCmcConsoleUserItemValue['update_time'] != $redisCmcConsoleUserItem['update_time']) {

                            $attributes = $this->getAttributes($getUserListData['group_info']['group_id'],
                                $httpCmcConsoleUserItemValue);
                            $redisCmcConsoleUserItem->attributes = $attributes;
                            $redisCmcConsoleUserItem->save();

                        }
                    }

                }

                // 从缓存中取回租户ID列表
                $cmcApiGroupIds = $redisCache[$redisCacheGroupIdsKey];
                // 设置当前租户的上次同步时间
                foreach ($cmcApiGroupIds as $cmcApiGroupIdKey => $cmcApiGroupId) {
                    if ($cmcApiGroupId['group_id'] == $sortCmcApiGroupId['group_id']) {
                        $cmcApiGroupIds[$cmcApiGroupIdKey]['cmc_console_user_last_synced_at'] = time();
                        break;
                    }
                }

                // 将 $cmcApiGroupIds 存放到缓存供下次使用,将数据在缓存中永久保留
                $redisCache->set($redisCacheGroupIdsKey, $cmcApiGroupIds);

                // break 结束当前 foreach 结构的执行,即命令行的每一次运行,仅同步成功一个租户下的用户列表
                break;
            }

            // 延缓执行 60 秒
            // sleep(Yii::$app->params['cmcConsoleUser']['isEmptyNoSleepTime']);
            // 将同步标识存放到缓存供下次使用,将数据在缓存中保留 60 秒
            $redisCache->set($redisCacheIdentityKey, $redisCacheIdentityKey, Yii::$app->params['cmcConsoleUser']['isEmptyNoSleepTime']);

            // file_put_contents('E:/wwwroot/pcs-api/console/runtime/logs/cmc-console-user-sync-memory-get-usage-' . time() . '.txt', memory_get_usage() / 1024 / 1024 . 'MB');
            // file_put_contents('E:/wwwroot/pcs-api/console/runtime/logs/cmc-console-user-sync-memory-get-peak-usage-' . time() . '.txt', memory_get_peak_usage() / 1024 / 1024 . 'MB');

            return ExitCode::OK;
        } else {
            // 延缓执行 60 秒
            // sleep(Yii::$app->params['cmcConsoleUser']['isEmptyNoSleepTime']);
            return ExitCode::OK;
        }
    }

    /**
     * 获取属性列表
     * @param string $groupId 租户ID
     * @param array $httpCmcConsoleUser 框架服务控制台的用户模型(Http)
     *
     * @return array
     */
    private function getAttributes($groupId, $httpCmcConsoleUser) {
        return [
            'id' => $httpCmcConsoleUser['id'],
            'group_id' => $groupId,
            'login_name' => $httpCmcConsoleUser['login_name'],
            'user_token' => $httpCmcConsoleUser['user_token'],
            'user_nick' => $httpCmcConsoleUser['user_nick'],
            'user_pic' => $httpCmcConsoleUser['user_pic'],
            'user_mobile' => $httpCmcConsoleUser['user_mobile'] ? $httpCmcConsoleUser['user_mobile'] : '',
            'user_email' => $httpCmcConsoleUser['user_email'] ? $httpCmcConsoleUser['user_email'] : '',
            'user_sex' => $httpCmcConsoleUser['user_sex'],
            'user_type' => $httpCmcConsoleUser['user_type'],
            'user_birthday' => $httpCmcConsoleUser['user_birthday'],
            'user_chat_id' => $httpCmcConsoleUser['user_chat_id'] ? $httpCmcConsoleUser['user_chat_id'] : '',
            'is_open' => $httpCmcConsoleUser['is_open'],
            'add_time' => $httpCmcConsoleUser['add_time'],
            'update_time' => $httpCmcConsoleUser['update_time'],
        ];
    }
}

</pre>
2、break 结束当前 foreach 结构的执行,即命令行的每一次运行,仅同步成功一个租户下的用户列表。当租户数量过多的时候,假设 100 个租户,平均 1 个租户的同步时间为 10 秒钟 + 下一个租户的同步的间隔时间 60 秒(包含了 bash sleep 5 秒),那么可能某个租户下的用户同步,其最大间隔时间就有可能为 7000 秒钟了。因此,如果支持了集群的部署,假设为 10 个容器,那么某个租户下的用户同步,其最大间隔时间就有可能为 700 秒钟了,同步的即时性提升了 10 倍。/mcloud/yii-cmc-console-user-sync.ini


[program:yii-cmc-console-user-sync]
command = bash -c 'sleep 5 && exec php /mcloud/www/pcs-api/yii cmc-console-user/sync'
autorestart = true
startsecs = 5
stopwaitsecs = 10
stderr_logfile = /data/logs/yii-cmc-console-user-sync-stderr.log
stdout_logfile = /data/logs/yii-cmc-console-user-sync-stdout.log


3、如果要支持集群的部署,现阶段存在的问题:同一个租户下的用户同步,可能在某一时间段,多个容器皆在执行,导致了同步的冗余执行(未达到最大化利用集群部署,进而满足同步的即时性提升至 10 倍的理想值)。因此,应该保证同一个租户下的用户同步,在某一时间段,仅在 1 个容器中执行。 4、将同步标识存放到缓存供下次使用,将数据在缓存中保留 60 秒。之前实现的初衷是同步成功一个租户下的用户后,间隔 60 秒再同步下一个租户下的用户,以降低资源消耗。现在如果要支持集群,就需要取消。否则会导致某个容器同步成功一个租户下的用户后,在 60 秒的间隔时间段内,其他容器也无法同步其他租户下的用户。/console/controllers/CmcConsoleUserController.php
<pre class="wp-block-syntaxhighlighter-code">

<?php
/**
 * Created by PhpStorm.
 * User: Qiang Wang
 * Date: 2019/01/09
 * Time: 13:55
 */

namespace console\controllers;

use Yii;
use console\models\ConfigColumnUser;
use console\models\redis\cmc_console\User as RedisCmcConsoleUser;
use console\services\CmcApiGroupService;
use console\services\CmcConsoleUserService;
use yii\base\InvalidArgumentException;
use yii\console\Controller;
use yii\console\ExitCode;
use yii\helpers\ArrayHelper;
use yii\web\HttpException;
use yii\web\ServerErrorHttpException;

/**
 * 框架服务控制台的用户
 *
 * @author Qiang Wang <shuijingwanwq@163.com>
 * @since  1.0
 */
class CmcConsoleUserController extends Controller
{
    /**
     * 同步框架服务控制台的用户模型(Http)至框架服务控制台的用户模型(Redis)、栏目人员配置模型(MySQL)
     *
     * @throws ServerErrorHttpException
     * @throws HttpException 如果登录超时
     * @throws InvalidArgumentException if the $direction or $sortFlag parameters do not have
     */
    public function actionSync()
    {
        // 设置同步标识的缓存键
        $redisCache = Yii::$app->redisCache;

        // HTTP 请求,获取开通有效服务的租户ID列表
        $httpCmcApiGroupIds = CmcApiGroupService::httpGetGroupIds();

        /* 判断 $httpCmcApiGroupIds 是否为空,如果为空,则成功退出 */
        if (empty($httpCmcApiGroupIds)) {
            // 延缓执行 60 * 60 秒
            // sleep(Yii::$app->params['cmcConsoleUser']['isEmptyYesSleepTime']);

            return ExitCode::OK;
        }

        // 设置租户ID列表的缓存键
        $redisCacheGroupIdsKey = 'cmc_api_group_ids';

        // 从缓存中取回租户ID列表
        $redisCacheGroupIdsData = $redisCache[$redisCacheGroupIdsKey];

        // 是否设置租户ID列表的缓存,默认:否
        $isSetRedisCacheGroupIds = false;

        if ($redisCacheGroupIdsData === false) {
            $cmcApiGroupIds = [];
            foreach ($httpCmcApiGroupIds as $httpCmcApiGroupId) {
                $cmcApiGroupIds[] = [
                    'group_id' => $httpCmcApiGroupId,
                    'cmc_console_user_last_synced_at' => 0, //上次同步时间
                ];
            }
            // 是否设置租户ID列表的缓存:是
            $isSetRedisCacheGroupIds = true;
        } else {
            // 获取 group_id 值列表
            $redisCacheGroupIds = ArrayHelper::getColumn($redisCacheGroupIdsData, 'group_id');
            $cmcApiGroupIds = $redisCacheGroupIdsData;
            foreach ($httpCmcApiGroupIds as $httpCmcApiGroupId) {
                if (!in_array($httpCmcApiGroupId, $redisCacheGroupIds)) {
                    $cmcApiGroupIds[] = [
                        'group_id' => $httpCmcApiGroupId,
                        'cmc_console_user_last_synced_at' => 0, //上次同步时间
                    ];
                    // 是否设置租户ID列表的缓存:是
                    $isSetRedisCacheGroupIds = true;
                }
            }
        }

        // 判断是否设置租户ID列表的缓存
        if ($isSetRedisCacheGroupIds) {
            // 将 $cmcApiGroupIds 存放到缓存供下次使用,将数据在缓存中永久保留
            $redisCache->set($redisCacheGroupIdsKey, $cmcApiGroupIds);
        }


        // 基于上次同步时间顺序排列,赋值给:$sortCmcApiGroupIds
        $sortCmcApiGroupIds = $cmcApiGroupIds;
        ArrayHelper::multisort($sortCmcApiGroupIds, 'cmc_console_user_last_synced_at', SORT_ASC);

        foreach ($sortCmcApiGroupIds as $sortCmcApiGroupId) {
            $isLockExist = RedisCmcConsoleUser::isLockExist($sortCmcApiGroupId['group_id']);
            // 返回 true,表示锁定存在,即已经被其他客户端锁定
            if ($isLockExist === true) {
                continue;
            }

            // HTTP请求,获取租户ID下的用户列表
            $httpGetUserListData = [
                'groupId' => $sortCmcApiGroupId['group_id'],
                'loginId' => '',
                'loginTid' => '',
            ];
            $getUserListData = CmcConsoleUserService::httpGetUserList($httpGetUserListData);

            // 框架服务控制台的用户模型(Http),重建数组索引(以 ID 索引结果集)
            $httpCmcConsoleUserItems = ArrayHelper::index($getUserListData['list'], 'id');

            // 销毁变量
            unset($getUserListData['list']);

            // 基于租户ID查询框架服务控制台的用户模型(Redis)(以 ID 索引结果集)
            $redisCmcConsoleUserItems = RedisCmcConsoleUser::find()->where(['group_id' => $sortCmcApiGroupId['group_id']])->indexBy('id')->asArray()->all();

            // 使用键名比较计算数组的差集,如果不为空,则删除出现在 Redis 中但是未出现在 Http 中的记录
            $redisArrayDiffItems = array_diff_key($redisCmcConsoleUserItems, $httpCmcConsoleUserItems);
            // 销毁变量
            unset($redisCmcConsoleUserItems);
            if (!empty($redisArrayDiffItems)) {
                $redisArrayDiffIds = array_keys($redisArrayDiffItems);
                // 销毁变量
                unset($redisArrayDiffItems);
                if (RedisCmcConsoleUser::deleteAllByIds($sortCmcApiGroupId['group_id'], $redisArrayDiffIds) === false) {
                    continue;
                }
            }

            // 基于租户ID查询栏目人员配置模型(MySQL)(以 用户ID 索引结果集)
            $configColumnUserItems = ConfigColumnUser::find()->where(['group_id' => $sortCmcApiGroupId['group_id']])->isDeletedNo()->indexBy('user_id')->asArray()->all();

            // 使用键名比较计算数组的差集,如果不为空,则删除 (软删除) 出现在 栏目人员配置模型(MySQL) 中但是未出现在 框架服务控制台的用户模型(Http) 中的记录
            $diffItems = array_diff_key($configColumnUserItems, $httpCmcConsoleUserItems);

            // 销毁变量
            unset($configColumnUserItems);
            if (!empty($diffItems)) {
                // 基于租户ID、用户ID查询栏目人员配置模型(MySQL)(待删除)
                $toBeDeletedConfigColumnUserItems = ConfigColumnUser::find()->where([
                    'and',
                    ['group_id' => $sortCmcApiGroupId['group_id']],
                    ['in', 'user_id', $diffItems],
                ])->isDeletedNo()->all();
                foreach ($toBeDeletedConfigColumnUserItems as $toBeDeletedConfigColumnUserItem) {
                    /* @var $toBeDeletedConfigColumnUserItem ConfigColumnUser */
                    $toBeDeletedConfigColumnUserItem->softDelete();
                }
            }

            // 遍历框架服务控制台的用户模型(Http),判断在 Redis 中是否存在,如果不存在,则插入,如果存在且更新时间不相等,则更新
            foreach ($httpCmcConsoleUserItems as $httpCmcConsoleUserItemValue) {
                $redisCmcConsoleUserItem = RedisCmcConsoleUser::find()->where(['id' => $httpCmcConsoleUserItemValue['id']])->one();

                if (!isset($redisCmcConsoleUserItem)) {

                    $redisCmcConsoleUser = new RedisCmcConsoleUser();
                    $attributes = $this->getAttributes($getUserListData['group_info']['group_id'],
                        $httpCmcConsoleUserItemValue);
                    $redisCmcConsoleUser->attributes = $attributes;
                    $redisCmcConsoleUser->insert();

                } else {
                    if ($httpCmcConsoleUserItemValue['update_time'] != $redisCmcConsoleUserItem['update_time']) {

                        $attributes = $this->getAttributes($getUserListData['group_info']['group_id'],
                            $httpCmcConsoleUserItemValue);
                        $redisCmcConsoleUserItem->attributes = $attributes;
                        $redisCmcConsoleUserItem->save();

                    }
                }

            }

            // 从缓存中取回租户ID列表
            $cmcApiGroupIds = $redisCache[$redisCacheGroupIdsKey];
            // 设置当前租户的上次同步时间
            foreach ($cmcApiGroupIds as $cmcApiGroupIdKey => $cmcApiGroupId) {
                if ($cmcApiGroupId['group_id'] == $sortCmcApiGroupId['group_id']) {
                    $cmcApiGroupIds[$cmcApiGroupIdKey]['cmc_console_user_last_synced_at'] = time();
                    break;
                }
            }

            // 将 $cmcApiGroupIds 存放到缓存供下次使用,将数据在缓存中永久保留
            $redisCache->set($redisCacheGroupIdsKey, $cmcApiGroupIds);

            // break 结束当前 foreach 结构的执行,即命令行的每一次运行,仅同步成功一个租户下的用户列表
            break;
        }

        // 延缓执行 60 秒
        // sleep(Yii::$app->params['cmcConsoleUser']['isEmptyNoSleepTime']);

        // file_put_contents('E:/wwwroot/pcs-api/console/runtime/logs/cmc-console-user-sync-memory-get-usage-' . time() . '.txt', memory_get_usage() / 1024 / 1024 . 'MB');
        // file_put_contents('E:/wwwroot/pcs-api/console/runtime/logs/cmc-console-user-sync-memory-get-peak-usage-' . time() . '.txt', memory_get_peak_usage() / 1024 / 1024 . 'MB');

        return ExitCode::OK;
    }

}

</pre>
5、此时,当租户数量过多的时候,假设 100 个租户,平均 1 个租户的同步时间为 10 秒钟 + 下一个租户的同步的间隔时间 60 秒(包含了 bash sleep 60 秒),那么可能某个租户下的用户同步,其最大间隔时间就有可能为 7000 秒钟了。因此,如果支持了集群的部署,假设为 10 个容器,那么某个租户下的用户同步,其最大间隔时间就有可能为 700 秒钟了,同步的即时性提升了 10 倍。/mcloud/yii-cmc-console-user-sync.ini


[program:yii-cmc-console-user-sync]
command = bash -c 'sleep 60 && exec php /mcloud/www/pcs-api/yii cmc-console-user/sync'
autorestart = true
startsecs = 5
stopwaitsecs = 10
stderr_logfile = /data/logs/yii-cmc-console-user-sync-stderr.log
stdout_logfile = /data/logs/yii-cmc-console-user-sync-stdout.log


6、编辑 /common/logics/redis/Lock.php,Redis模型的锁定实现
<pre class="wp-block-syntaxhighlighter-code">

<?php

namespace common\logics\redis;

use Yii;

/**
 * This is the model class for table "{{%lock}}".
 *
 * @author Qiang Wang <shuijingwanwq@163.com>
 * @since 1.0
 */
class Lock extends \yii\redis\ActiveRecord
{

    /**
     * Redis模型的锁定实现
     * @param string $lockKeyName 锁定键名
     * 格式如下:
     *
     * 'game_category' //锁定键名,如比赛分类
     *
     * @return bool 成功返回真/失败返回假
     * 格式如下:
     *
     * true //状态,获取锁定成功,可继续执行
     * 
     * 或者
     * 
     * false //状态,获取锁定失败,不可继续执行
     *
     */
    public function lock($lockKeyName)
    {
        // 设置锁定的过期时间,获取相关锁定参数
        $time = time();
        $lockKey = Yii::$app->params['redisLock']['keyPrefix'] . $lockKeyName;
        $lockExpire = $time + Yii::$app->params['redisLock']['timeOut'];
        // 获取 Redis 连接,以执行相关命令
        $redis = Yii::$app->redis;
        // 获取锁定
        $executeCommandResult = $redis->setnx($lockKey, $lockExpire);
        // 返回0,表示已经被其他客户端锁定
        if ($executeCommandResult == 0) {
            // 防止死锁,获取当前锁的过期时间
            $lockCurrentExpire = $redis->get($lockKey);
            // 判断锁是否过期,如果已经过期
            if ($time > $lockCurrentExpire) {
                // 防止并发锁定,检查存储在 key 的旧值是否仍然是过期的时间戳,如果是,则获取锁定,否则返回假
                $executeCommandResult = $redis->getset($lockKey, $lockExpire);
                if ($lockCurrentExpire != $executeCommandResult) {
                    return false;
                }
            }

            // 返回0,表示已经被其他客户端锁定,且不存在死锁,返回假
            if ($executeCommandResult == 0) {
                return false;
            }

        }
        
        return true;
    }
    
    /**
     * 判断Redis模型的锁定是否存在
     * @param string $lockKeyName 锁定键名
     * 格式如下:
     *
     * 'game_category' //锁定键名,如比赛分类
     *
     * @return bool 锁定是否存在
     * 格式如下:
     *
     * true //状态:已存在
     * 
     * 或者
     * 
     * false //状态:不存在
     *
     */
    public function isLockExist($lockKeyName)
    {
        // 获取相关锁定参数
        $time = time();
        $lockKey = Yii::$app->params['redisLock']['keyPrefix'] . $lockKeyName;
        // 获取 Redis 连接,以执行相关命令
        $redis = Yii::$app->redis;
        // 获取锁定
        $executeCommandResult = $redis->get($lockKey);

        // 返回NULL,表示不存在锁定,否则表示存在
        if ($executeCommandResult === null) {
            return false;
        } else {
            // 如果存在锁定,判断锁是否过期,如果已经过期,则仍然认定为不存在锁定
            if ($time > $executeCommandResult) {
                // 如果已经过期,则释放锁定
                $redis->del($lockKey);
                return false;
            }
            
        }

        return true;
    }

    /**
     * Redis模型的释放锁定实现
     * @param string $lockKeyName 锁定键名
     * 格式如下:
     *
     * 'game_category' //锁定键名,如比赛分类
     *
     * @return integer 被删除的keys的数量
     * 格式如下:
     *
     * 1 //被删除的keys的数量
     * 
     * 或者
     * 
     * 0 //被删除的keys的数量
     *
     */
    public function unlock($lockKeyName)
    {
        // 获取相关锁定参数
        $lockKey = Yii::$app->params['redisLock']['keyPrefix'] . $lockKeyName;
        // 获取 Redis 连接,以执行相关命令
        $redis = Yii::$app->redis;
        // 释放锁定
        return $redis->del($lockKey);
    }
}


</pre>
7、编辑 /console/controllers/CmcConsoleUserController.php,Redis模型的锁定实现。在开始一个租户下的用户同步之前,判断Redis模型的锁定是否存在,如果存在,则跳出当前循环,继续下一个租户的同步。在开始一个租户下的用户同步之前,Redis模型的获取锁定实现,如果获取锁定失败,则跳出当前循环,继续下一个租户的同步。一个租户下的用户同步成功之后,释放锁定。结束循环。
<pre class="wp-block-syntaxhighlighter-code">

<?php
/**
 * Created by PhpStorm.
 * User: Qiang Wang
 * Date: 2019/01/09
 * Time: 13:55
 */

namespace console\controllers;

use Yii;
use console\models\ConfigColumnUser;
use console\models\redis\cmc_console\User as RedisCmcConsoleUser;
use console\models\redis\Lock as RedisLock;
use console\services\CmcApiGroupService;
use console\services\CmcConsoleUserService;
use yii\base\InvalidArgumentException;
use yii\console\Controller;
use yii\console\ExitCode;
use yii\helpers\ArrayHelper;
use yii\web\HttpException;
use yii\web\ServerErrorHttpException;

/**
 * 框架服务控制台的用户
 *
 * @author Qiang Wang <shuijingwanwq@163.com>
 * @since  1.0
 */
class CmcConsoleUserController extends Controller
{
    /**
     * 同步框架服务控制台的用户模型(Http)至框架服务控制台的用户模型(Redis)、栏目人员配置模型(MySQL)
     *
     * @throws ServerErrorHttpException
     * @throws HttpException 如果登录超时
     * @throws InvalidArgumentException if the $direction or $sortFlag parameters do not have
     */
    public function actionSync()
    {
        // 设置同步标识的缓存键
        $redisCache = Yii::$app->redisCache;

        // HTTP 请求,获取开通有效服务的租户ID列表
        $httpCmcApiGroupIds = CmcApiGroupService::httpGetGroupIds();

        /* 判断 $httpCmcApiGroupIds 是否为空,如果为空,则成功退出 */
        if (empty($httpCmcApiGroupIds)) {
            // 延缓执行 60 * 60 秒
            // sleep(Yii::$app->params['cmcConsoleUser']['isEmptyYesSleepTime']);

            return ExitCode::OK;
        }

        // 设置租户ID列表的缓存键
        $redisCacheGroupIdsKey = 'cmc_api_group_ids';

        // 从缓存中取回租户ID列表
        $redisCacheGroupIdsData = $redisCache[$redisCacheGroupIdsKey];

        // 是否设置租户ID列表的缓存,默认:否
        $isSetRedisCacheGroupIds = false;

        if ($redisCacheGroupIdsData === false) {
            $cmcApiGroupIds = [];
            foreach ($httpCmcApiGroupIds as $httpCmcApiGroupId) {
                $cmcApiGroupIds[] = [
                    'group_id' => $httpCmcApiGroupId,
                    'cmc_console_user_last_synced_at' => 0, //上次同步时间
                ];
            }
            // 是否设置租户ID列表的缓存:是
            $isSetRedisCacheGroupIds = true;
        } else {
            // 获取 group_id 值列表
            $redisCacheGroupIds = ArrayHelper::getColumn($redisCacheGroupIdsData, 'group_id');
            $cmcApiGroupIds = $redisCacheGroupIdsData;
            foreach ($httpCmcApiGroupIds as $httpCmcApiGroupId) {
                if (!in_array($httpCmcApiGroupId, $redisCacheGroupIds)) {
                    $cmcApiGroupIds[] = [
                        'group_id' => $httpCmcApiGroupId,
                        'cmc_console_user_last_synced_at' => 0, //上次同步时间
                    ];
                    // 是否设置租户ID列表的缓存:是
                    $isSetRedisCacheGroupIds = true;
                }
            }
        }

        // 判断是否设置租户ID列表的缓存
        if ($isSetRedisCacheGroupIds) {
            // 将 $cmcApiGroupIds 存放到缓存供下次使用,将数据在缓存中永久保留
            $redisCache->set($redisCacheGroupIdsKey, $cmcApiGroupIds);
        }


        // 基于上次同步时间顺序排列,赋值给:$sortCmcApiGroupIds
        $sortCmcApiGroupIds = $cmcApiGroupIds;
        ArrayHelper::multisort($sortCmcApiGroupIds, 'cmc_console_user_last_synced_at', SORT_ASC);

        foreach ($sortCmcApiGroupIds as $sortCmcApiGroupId) {
            $isLockExist = RedisCmcConsoleUser::isLockExist($sortCmcApiGroupId['group_id']);
            // 返回 true,表示锁定存在,即已经被其他客户端锁定
            if ($isLockExist === true) {
                continue;
            }

            /* 判断Redis模型的锁定是否存在 */
            $redisLockKeyName = 'cmc_console_user:sync:' . implode(':', ['group_id' => $sortCmcApiGroupId['group_id']]);
            $redisLock = new RedisLock();
            $redisLockResult = $redisLock->isLockExist($redisLockKeyName);
            // 返回 true,表示锁定存在,即已经被其他客户端锁定
            if ($redisLockResult === true) {
                continue;
            }

            /* Redis模型的锁定实现 */
            $redisLockResult = $redisLock->lock($redisLockKeyName);
            // 返回 false,表示已经被其他客户端锁定
            if ($redisLockResult === false) {
                continue;
            }

            // HTTP请求,获取租户ID下的用户列表
            $httpGetUserListData = [
                'groupId' => $sortCmcApiGroupId['group_id'],
                'loginId' => '',
                'loginTid' => '',
            ];
            $getUserListData = CmcConsoleUserService::httpGetUserList($httpGetUserListData);

            // 框架服务控制台的用户模型(Http),重建数组索引(以 ID 索引结果集)
            $httpCmcConsoleUserItems = ArrayHelper::index($getUserListData['list'], 'id');

            // 销毁变量
            unset($getUserListData['list']);

            // 基于租户ID查询框架服务控制台的用户模型(Redis)(以 ID 索引结果集)
            $redisCmcConsoleUserItems = RedisCmcConsoleUser::find()->where(['group_id' => $sortCmcApiGroupId['group_id']])->indexBy('id')->asArray()->all();

            // 使用键名比较计算数组的差集,如果不为空,则删除出现在 Redis 中但是未出现在 Http 中的记录
            $redisArrayDiffItems = array_diff_key($redisCmcConsoleUserItems, $httpCmcConsoleUserItems);
            // 销毁变量
            unset($redisCmcConsoleUserItems);
            if (!empty($redisArrayDiffItems)) {
                $redisArrayDiffIds = array_keys($redisArrayDiffItems);
                // 销毁变量
                unset($redisArrayDiffItems);
                if (RedisCmcConsoleUser::deleteAllByIds($sortCmcApiGroupId['group_id'], $redisArrayDiffIds) === false) {
                    continue;
                }
            }

            // 基于租户ID查询栏目人员配置模型(MySQL)(以 用户ID 索引结果集)
            $configColumnUserItems = ConfigColumnUser::find()->where(['group_id' => $sortCmcApiGroupId['group_id']])->isDeletedNo()->indexBy('user_id')->asArray()->all();

            // 使用键名比较计算数组的差集,如果不为空,则删除 (软删除) 出现在 栏目人员配置模型(MySQL) 中但是未出现在 框架服务控制台的用户模型(Http) 中的记录
            $diffItems = array_diff_key($configColumnUserItems, $httpCmcConsoleUserItems);

            // 销毁变量
            unset($configColumnUserItems);
            if (!empty($diffItems)) {
                // 基于租户ID、用户ID查询栏目人员配置模型(MySQL)(待删除)
                $toBeDeletedConfigColumnUserItems = ConfigColumnUser::find()->where([
                    'and',
                    ['group_id' => $sortCmcApiGroupId['group_id']],
                    ['in', 'user_id', $diffItems],
                ])->isDeletedNo()->all();
                foreach ($toBeDeletedConfigColumnUserItems as $toBeDeletedConfigColumnUserItem) {
                    /* @var $toBeDeletedConfigColumnUserItem ConfigColumnUser */
                    $toBeDeletedConfigColumnUserItem->softDelete();
                }
            }

            // 遍历框架服务控制台的用户模型(Http),判断在 Redis 中是否存在,如果不存在,则插入,如果存在且更新时间不相等,则更新
            foreach ($httpCmcConsoleUserItems as $httpCmcConsoleUserItemValue) {
                $redisCmcConsoleUserItem = RedisCmcConsoleUser::find()->where(['id' => $httpCmcConsoleUserItemValue['id']])->one();

                if (!isset($redisCmcConsoleUserItem)) {

                    $redisCmcConsoleUser = new RedisCmcConsoleUser();
                    $attributes = $this->getAttributes($getUserListData['group_info']['group_id'],
                        $httpCmcConsoleUserItemValue);
                    $redisCmcConsoleUser->attributes = $attributes;
                    $redisCmcConsoleUser->insert();

                } else {
                    if ($httpCmcConsoleUserItemValue['update_time'] != $redisCmcConsoleUserItem['update_time']) {

                        $attributes = $this->getAttributes($getUserListData['group_info']['group_id'],
                            $httpCmcConsoleUserItemValue);
                        $redisCmcConsoleUserItem->attributes = $attributes;
                        $redisCmcConsoleUserItem->save();

                    }
                }

            }

            // 从缓存中取回租户ID列表
            $cmcApiGroupIds = $redisCache[$redisCacheGroupIdsKey];
            // 设置当前租户的上次同步时间
            foreach ($cmcApiGroupIds as $cmcApiGroupIdKey => $cmcApiGroupId) {
                if ($cmcApiGroupId['group_id'] == $sortCmcApiGroupId['group_id']) {
                    $cmcApiGroupIds[$cmcApiGroupIdKey]['cmc_console_user_last_synced_at'] = time();
                    break;
                }
            }

            // 将 $cmcApiGroupIds 存放到缓存供下次使用,将数据在缓存中永久保留
            $redisCache->set($redisCacheGroupIdsKey, $cmcApiGroupIds);

            // 释放锁定
            $redisLock->unlock($redisLockKeyName);

            // break 结束当前 foreach 结构的执行,即命令行的每一次运行,仅同步成功一个租户下的用户列表
            break;
        }

        // 延缓执行 60 秒
        // sleep(Yii::$app->params['cmcConsoleUser']['isEmptyNoSleepTime']);

        // file_put_contents('E:/wwwroot/pcs-api/console/runtime/logs/cmc-console-user-sync-memory-get-usage-' . time() . '.txt', memory_get_usage() / 1024 / 1024 . 'MB');
        // file_put_contents('E:/wwwroot/pcs-api/console/runtime/logs/cmc-console-user-sync-memory-get-peak-usage-' . time() . '.txt', memory_get_peak_usage() / 1024 / 1024 . 'MB');

        return ExitCode::OK;
    }

}

</pre>
8、当一个租户下的用户同步时间长度小于等于 Redis锁定超时时间 的值 10秒时(sleep(8),实际长度超过了 8 秒),此时,此租户已经处于锁定状态,进而导致部署为集群时,可以保证同一个租户下的用户同步,在某一时间段,仅在 1 个容器中执行。在本地环境中,模拟了 3 个容器,3 个容器开始同步时间:1582784312、1582784315、1582784318,分别间隔 3 秒、3秒,皆小于 10 秒。第 1 个容器同步了租户:c10e87f39873512a16727e17f57456a5,第 2 个容器同步了租户:015ce30b116ce86058fa6ab4fea4ac63,第 3 个容器同步了租户:4fd58ceba1fbc537b5402302702131eb。3 个容器的并行执行,分别同步了 3 个租户,符合预期。文件生成顺序体现出了执行执行流程。如图1
当一个租户下的用户同步时间长度小于等于 Redis锁定超时时间 的值 10秒时(sleep(8),实际长度超过了 8 秒),此时,此租户已经处于锁定状态,进而导致部署为集群时,可以保证同一个租户下的用户同步,在某一时间段,仅在 1 个容器中执行。在本地环境中,模拟了 3 个容器,3 个容器开始同步时间:1582784312、1582784315、1582784318,分别间隔 3 秒、3秒,皆小于 10 秒。第 1 个容器同步了租户:c10e87f39873512a16727e17f57456a5,第 2 个容器同步了租户:015ce30b116ce86058fa6ab4fea4ac63,第 3 个容器同步了租户:4fd58ceba1fbc537b5402302702131eb。3 个容器的并行执行,分别同步了 3 个租户,符合预期。文件生成顺序体现出了执行执行流程。

图1



    'redisLock' => [
        'keyPrefix' => 'pa:lock:', //Redis锁定 key 前缀
        'timeOut' => 10, //Redis锁定超时时间,单位为秒
    ],




            file_put_contents('E:/wwwroot/pcs-api/console/runtime/logs/cmc-console-user-sync-' . $sortCmcApiGroupId['group_id'] . '-' . time() . '.txt', $sortCmcApiGroupId['group_id']);

            /* 判断Redis模型的锁定是否存在 */
            $redisLockKeyName = 'cmc_console_user:sync:' . implode(':', ['group_id' => $sortCmcApiGroupId['group_id']]);
            $redisLock = new RedisLock();
            $isLockExist = $redisLock->isLockExist($redisLockKeyName);
            // 返回 true,表示锁定存在,即已经被其他客户端锁定
            if ($isLockExist === true) {
                file_put_contents('E:/wwwroot/pcs-api/console/runtime/logs/cmc-console-user-sync-is-lock-exist-' . $sortCmcApiGroupId['group_id'] . '-' . time() . '.txt', $sortCmcApiGroupId['group_id']);
                continue;
            }

            /* Redis模型的锁定实现 */
            $lock = $redisLock->lock($redisLockKeyName);
            // 返回 false,表示已经被其他客户端锁定
            if ($lock === false) {
                file_put_contents('E:/wwwroot/pcs-api/console/runtime/logs/cmc-console-user-sync-lock-' . $sortCmcApiGroupId['group_id'] . '-' . time() . '.txt', $sortCmcApiGroupId['group_id']);
                continue;
            }

            // HTTP请求,获取租户ID下的用户列表
            $httpGetUserListData = [
                'groupId' => $sortCmcApiGroupId['group_id'],
                'loginId' => '',
                'loginTid' => '',
            ];
            $getUserListData = CmcConsoleUserService::httpGetUserList($httpGetUserListData);

            // 框架服务控制台的用户模型(Http),重建数组索引(以 ID 索引结果集)
            $httpCmcConsoleUserItems = ArrayHelper::index($getUserListData['list'], 'id');

            // 销毁变量
            unset($getUserListData['list']);

            // 基于租户ID查询框架服务控制台的用户模型(Redis)(以 ID 索引结果集)
            $redisCmcConsoleUserItems = RedisCmcConsoleUser::find()->where(['group_id' => $sortCmcApiGroupId['group_id']])->indexBy('id')->asArray()->all();

            // 使用键名比较计算数组的差集,如果不为空,则删除出现在 Redis 中但是未出现在 Http 中的记录
            $redisArrayDiffItems = array_diff_key($redisCmcConsoleUserItems, $httpCmcConsoleUserItems);
            // 销毁变量
            unset($redisCmcConsoleUserItems);
            if (!empty($redisArrayDiffItems)) {
                $redisArrayDiffIds = array_keys($redisArrayDiffItems);
                // 销毁变量
                unset($redisArrayDiffItems);
                if (RedisCmcConsoleUser::deleteAllByIds($sortCmcApiGroupId['group_id'], $redisArrayDiffIds) === false) {
                    continue;
                }
            }

            // 基于租户ID查询栏目人员配置模型(MySQL)(以 用户ID 索引结果集)
            $configColumnUserItems = ConfigColumnUser::find()->where(['group_id' => $sortCmcApiGroupId['group_id']])->isDeletedNo()->indexBy('user_id')->asArray()->all();

            // 使用键名比较计算数组的差集,如果不为空,则删除 (软删除) 出现在 栏目人员配置模型(MySQL) 中但是未出现在 框架服务控制台的用户模型(Http) 中的记录
            $diffItems = array_diff_key($configColumnUserItems, $httpCmcConsoleUserItems);

            // 销毁变量
            unset($configColumnUserItems);
            if (!empty($diffItems)) {
                // 基于租户ID、用户ID查询栏目人员配置模型(MySQL)(待删除)
                $toBeDeletedConfigColumnUserItems = ConfigColumnUser::find()->where([
                    'and',
                    ['group_id' => $sortCmcApiGroupId['group_id']],
                    ['in', 'user_id', $diffItems],
                ])->isDeletedNo()->all();
                foreach ($toBeDeletedConfigColumnUserItems as $toBeDeletedConfigColumnUserItem) {
                    /* @var $toBeDeletedConfigColumnUserItem ConfigColumnUser */
                    $toBeDeletedConfigColumnUserItem->softDelete();
                }
            }

            // 遍历框架服务控制台的用户模型(Http),判断在 Redis 中是否存在,如果不存在,则插入,如果存在且更新时间不相等,则更新
            foreach ($httpCmcConsoleUserItems as $httpCmcConsoleUserItemValue) {
                $redisCmcConsoleUserItem = RedisCmcConsoleUser::find()->where(['id' => $httpCmcConsoleUserItemValue['id']])->one();

                if (!isset($redisCmcConsoleUserItem)) {

                    $redisCmcConsoleUser = new RedisCmcConsoleUser();
                    $attributes = $this->getAttributes($getUserListData['group_info']['group_id'],
                        $httpCmcConsoleUserItemValue);
                    $redisCmcConsoleUser->attributes = $attributes;
                    $redisCmcConsoleUser->insert();

                } else {
                    if ($httpCmcConsoleUserItemValue['update_time'] != $redisCmcConsoleUserItem['update_time']) {

                        $attributes = $this->getAttributes($getUserListData['group_info']['group_id'],
                            $httpCmcConsoleUserItemValue);
                        $redisCmcConsoleUserItem->attributes = $attributes;
                        $redisCmcConsoleUserItem->save();

                    }
                }

            }

            // 从缓存中取回租户ID列表
            $cmcApiGroupIds = $redisCache[$redisCacheGroupIdsKey];
            // 设置当前租户的上次同步时间
            foreach ($cmcApiGroupIds as $cmcApiGroupIdKey => $cmcApiGroupId) {
                if ($cmcApiGroupId['group_id'] == $sortCmcApiGroupId['group_id']) {
                    $cmcApiGroupIds[$cmcApiGroupIdKey]['cmc_console_user_last_synced_at'] = time();
                    break;
                }
            }

            // 将 $cmcApiGroupIds 存放到缓存供下次使用,将数据在缓存中永久保留
            sleep(8);
            $redisCache->set($redisCacheGroupIdsKey, $cmcApiGroupIds);

            // 释放锁定
            $redisLock->unlock($redisLockKeyName);


9、打印出从缓存中取回租户ID列表,已经成功同步了 3 个租户:c10e87f39873512a16727e17f57456a5、015ce30b116ce86058fa6ab4fea4ac63、4fd58ceba1fbc537b5402302702131eb,但是,仅有租户 4fd58ceba1fbc537b5402302702131eb 的同步时间得到了更新。虽然在实际的生产环境中,不存在 sleep(8),此为在本地环境模拟并发请求,而添加的。但是,理论上来说,从缓存中取回租户ID列表,到 将 $cmcApiGroupIds 存放到缓存供下次使用,将数据在缓存中永久保留 的间隔时间段(假设租户数量为 10000 个,则遍历 10000 次,时间间隔为 30000 微秒,即 0.03 秒)内,如果存在 多个容器 在运行的话,便会出现相互覆盖的情况。暂时不做处理,即时出现了相互覆盖的情况,其后果是可以接受的。租户:c10e87f39873512a16727e17f57456a5、015ce30b116ce86058fa6ab4fea4ac63 会相继立即重复同步一次。如图2
打印出从缓存中取回租户ID列表,已经成功同步了 3 个租户:c10e87f39873512a16727e17f57456a5、015ce30b116ce86058fa6ab4fea4ac63、4fd58ceba1fbc537b5402302702131eb,但是,仅有租户 4fd58ceba1fbc537b5402302702131eb 的同步时间得到了更新。虽然在实际的生产环境中,不存在 sleep(8),此为在本地环境模拟并发请求,而添加的。但是,理论上来说,从缓存中取回租户ID列表,到 将 $cmcApiGroupIds 存放到缓存供下次使用,将数据在缓存中永久保留 的间隔时间段(假设租户数量为 10000 个,则遍历 10000 次,时间间隔为 30000 微秒,即 0.03 秒)内,如果存在 多个容器 在运行的话,便会出现相互覆盖的情况。暂时不做处理,即时出现了相互覆盖的情况,其后果是可以接受的。租户:c10e87f39873512a16727e17f57456a5、015ce30b116ce86058fa6ab4fea4ac63 会相继立即重复同步一次。

图2



Array
(
    [0] => Array
        (
            [group_id] => c10e87f39873512a16727e17f57456a5
            [cmc_console_user_last_synced_at] => 0
        )

    [1] => Array
        (
            [group_id] => 015ce30b116ce86058fa6ab4fea4ac63
            [cmc_console_user_last_synced_at] => 0
        )

    [2] => Array
        (
            [group_id] => 4fd58ceba1fbc537b5402302702131eb
            [cmc_console_user_last_synced_at] => 1582784318
        )

    [3] => Array
        (
            [group_id] => f53df1a8d46108afc8ae9eeb3f0e1f0e
            [cmc_console_user_last_synced_at] => 0
        )

)


10、当一个租户下的用户同步时间长度超过 Redis锁定超时时间 的值 10秒后(sleep(60),实际长度超过了 60 秒),此时,此租户已经被自动解除锁定,进而导致部署为集群时,无法保证同一个租户下的用户同步,在某一时间段,仅在 1 个容器中执行。在本地环境中,模拟了 3 个容器,3 个容器开始同步时间:1582773882、1582773895、1582773917,分别间隔 13 秒、22秒,皆大于 10 秒。第 3 个容器开始同步时,第 1 个容器仍然在同步中,并未结束(释放锁定)。因此,租户:c10e87f39873512a16727e17f57456a5 被 3 个容器同时同步。如图3
当一个租户下的用户同步时间长度超过 Redis锁定超时时间 的值 10秒后(sleep(60),实际长度超过了 60 秒),此时,此租户已经被自动解除锁定,进而导致部署为集群时,无法保证同一个租户下的用户同步,在某一时间段,仅在 1 个容器中执行。在本地环境中,模拟了 3 个容器,3 个容器开始同步时间:1582773882、1582773895、1582773917,分别间隔 13 秒、22秒,皆大于 10 秒。第 3 个容器开始同步时,第 1 个容器仍然在同步中,并未结束(释放锁定)。因此,租户:c10e87f39873512a16727e17f57456a5 被 3 个容器同时同步。

图3




            // 将 $cmcApiGroupIds 存放到缓存供下次使用,将数据在缓存中永久保留
            sleep(60);
            $redisCache->set($redisCacheGroupIdsKey, $cmcApiGroupIds);

            // 释放锁定
            $redisLock->unlock($redisLockKeyName);


11、编辑 /common/logics/redis/Lock.php。public function lock($lockKeyName),添加一个参数,支持自定义Redis锁定超时时间。以基于场景灵活设置。


    /**
     * Redis模型的锁定实现
     * @param string $lockKeyName 锁定键名
     * 格式如下:
     *
     * 'game_category' //锁定键名,如比赛分类
     *
     * @param int $timeOut Redis锁定超时时间,单位为秒
     * 格式如下:3
     *
     * @return bool 成功返回真/失败返回假
     * 格式如下:
     *
     * true //状态,获取锁定成功,可继续执行
     * 
     * 或者
     * 
     * false //状态,获取锁定失败,不可继续执行
     *
     */
    public function lock($lockKeyName, $timeOut = 3)
    {
        // 设置锁定的过期时间,获取相关锁定参数
        $time = time();
        $lockKey = Yii::$app->params['redisLock']['keyPrefix'] . $lockKeyName;
        $lockExpire = $time + $timeOut;
        // 获取 Redis 连接,以执行相关命令
        $redis = Yii::$app->redis;
        // 获取锁定
        $executeCommandResult = $redis->setnx($lockKey, $lockExpire);
        // 返回0,表示已经被其他客户端锁定
        if ($executeCommandResult == 0) {
            // 防止死锁,获取当前锁的过期时间
            $lockCurrentExpire = $redis->get($lockKey);
            // 判断锁是否过期,如果已经过期
            if ($time > $lockCurrentExpire) {
                // 防止并发锁定,检查存储在 key 的旧值是否仍然是过期的时间戳,如果是,则获取锁定,否则返回假
                $executeCommandResult = $redis->getset($lockKey, $lockExpire);
                if ($lockCurrentExpire != $executeCommandResult) {
                    return false;
                }
            }

            // 返回0,表示已经被其他客户端锁定,且不存在死锁,返回假
            if ($executeCommandResult == 0) {
                return false;
            }

        }
        
        return true;
    }


12、Redis模型的锁定实现,Redis锁定超时时间,单位为秒(自定义 600)。一个租户下的用户同步,耗费的最长时间只要不超过 10 分钟,当部署为集群时,就可以保证同一个租户下的用户同步,在某一时间段,仅在 1 个容器中执行。


            /* Redis模型的锁定实现 */
            $lock = $redisLock->lock($redisLockKeyName, 600);


13、在开发环境,部署了 3 个容器。以便于测试集群部署时,并发锁定的情况。在 bash sleep 60 秒 的情况下,很难出现并发锁定的情况。不过,当部署为集群时,已经可以保证同一个租户下的用户同步,在某一时间段,仅在 1 个容器中执行。当出现租户下的用户同步及时性不够理想的情况,可以通过添加容器的方案提升同步的及时性。在 3 个容器中,总计同步了 30 + 30 + 33 = 93 次。其中 租户 f53df1a8d46108afc8ae9eeb3f0e1f0e、c10e87f39873512a16727e17f57456a5、4fd58ceba1fbc537b5402302702131eb、015ce30b116ce86058fa6ab4fea4ac63 分别同步了:23、24、22、24 次。3 个容器的情况下,在 15:43 至 16:16 的时间段内(32 分钟左右),一个租户的同步次数平均为:23 次。实际测试结果,一个租户的同步时间间隔为:32 * 60 / 24 = 80 秒。理论上的计算公式,一个租户的同步时间间隔为:租户数量 / 容器数量 * 60,结果单位为秒。同步性能符合设计预期。如图4
在开发环境,部署了 3 个容器。以便于测试集群部署时,并发锁定的情况。在 bash sleep 60 秒 的情况下,很难出现并发锁定的情况。不过,当部署为集群时,已经可以保证同一个租户下的用户同步,在某一时间段,仅在 1 个容器中执行。当出现租户下的用户同步及时性不够理想的情况,可以通过添加容器的方案提升同步的及时性。在 3 个容器中,总计同步了 30 + 30 + 33 = 93 次。其中 租户 f53df1a8d46108afc8ae9eeb3f0e1f0e、c10e87f39873512a16727e17f57456a5、4fd58ceba1fbc537b5402302702131eb、015ce30b116ce86058fa6ab4fea4ac63 分别同步了:23、24、22、24 次。3 个容器的情况下,在 15:43 至 16:16 的时间段内(32 分钟左右),一个租户的同步次数平均为:23 次。实际测试结果,一个租户的同步时间间隔为:32 * 60 / 24 = 80 秒。理论上的计算公式,一个租户的同步时间间隔为:租户数量 / 容器数量 * 60,结果单位为秒。同步性能符合设计预期。

图4



[root@1d03b809a523 logs]# ls -ltr
total 120
-rw-r--r-- 1 root root 32 Feb 28 15:43 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1582875818.txt
-rw-r--r-- 1 root root 32 Feb 28 15:44 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1582875879.txt
-rw-r--r-- 1 root root 32 Feb 28 15:45 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1582875941.txt
-rw-r--r-- 1 root root 32 Feb 28 15:49 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1582876192.txt
-rw-r--r-- 1 root root 32 Feb 28 15:50 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1582876254.txt
-rw-r--r-- 1 root root 32 Feb 28 15:51 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1582876315.txt
-rw-r--r-- 1 root root 32 Feb 28 15:52 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1582876377.txt
-rw-r--r-- 1 root root 32 Feb 28 15:53 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1582876438.txt
-rw-r--r-- 1 root root 32 Feb 28 15:55 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1582876500.txt
-rw-r--r-- 1 root root 32 Feb 28 15:56 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1582876561.txt
-rw-r--r-- 1 root root 32 Feb 28 15:57 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1582876623.txt
-rw-r--r-- 1 root root 32 Feb 28 15:58 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1582876684.txt
-rw-r--r-- 1 root root 32 Feb 28 15:59 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1582876746.txt
-rw-r--r-- 1 root root 32 Feb 28 16:00 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1582876808.txt
-rw-r--r-- 1 root root 32 Feb 28 16:01 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1582876869.txt
-rw-r--r-- 1 root root 32 Feb 28 16:02 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1582876931.txt
-rw-r--r-- 1 root root 32 Feb 28 16:03 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1582876992.txt
-rw-r--r-- 1 root root 32 Feb 28 16:04 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1582877054.txt
-rw-r--r-- 1 root root 32 Feb 28 16:05 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1582877115.txt
-rw-r--r-- 1 root root 32 Feb 28 16:06 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1582877177.txt
-rw-r--r-- 1 root root 32 Feb 28 16:07 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1582877238.txt
-rw-r--r-- 1 root root 32 Feb 28 16:08 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1582877300.txt
-rw-r--r-- 1 root root 32 Feb 28 16:09 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1582877362.txt
-rw-r--r-- 1 root root 32 Feb 28 16:10 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1582877423.txt
-rw-r--r-- 1 root root 32 Feb 28 16:11 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1582877485.txt
-rw-r--r-- 1 root root 32 Feb 28 16:12 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1582877546.txt
-rw-r--r-- 1 root root 32 Feb 28 16:13 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1582877608.txt
-rw-r--r-- 1 root root 32 Feb 28 16:14 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1582877669.txt
-rw-r--r-- 1 root root 32 Feb 28 16:15 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1582877731.txt
-rw-r--r-- 1 root root 32 Feb 28 16:16 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1582877792.txt

[root@7e1ea0bc777c logs]# ls -ltr
total 120
-rw-r--r-- 1 root root 32 Feb 28 15:43 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1582875803.txt
-rw-r--r-- 1 root root 32 Feb 28 15:44 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1582875864.txt
-rw-r--r-- 1 root root 32 Feb 28 15:45 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1582875926.txt
-rw-r--r-- 1 root root 32 Feb 28 15:49 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1582876189.txt
-rw-r--r-- 1 root root 32 Feb 28 15:50 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1582876251.txt
-rw-r--r-- 1 root root 32 Feb 28 15:51 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1582876313.txt
-rw-r--r-- 1 root root 32 Feb 28 15:52 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1582876374.txt
-rw-r--r-- 1 root root 32 Feb 28 15:53 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1582876436.txt
-rw-r--r-- 1 root root 32 Feb 28 15:54 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1582876497.txt
-rw-r--r-- 1 root root 32 Feb 28 15:55 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1582876559.txt
-rw-r--r-- 1 root root 32 Feb 28 15:57 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1582876621.txt
-rw-r--r-- 1 root root 32 Feb 28 15:58 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1582876682.txt
-rw-r--r-- 1 root root 32 Feb 28 15:59 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1582876744.txt
-rw-r--r-- 1 root root 32 Feb 28 16:00 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1582876805.txt
-rw-r--r-- 1 root root 32 Feb 28 16:01 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1582876867.txt
-rw-r--r-- 1 root root 32 Feb 28 16:02 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1582876929.txt
-rw-r--r-- 1 root root 32 Feb 28 16:03 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1582876990.txt
-rw-r--r-- 1 root root 32 Feb 28 16:04 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1582877052.txt
-rw-r--r-- 1 root root 32 Feb 28 16:05 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1582877113.txt
-rw-r--r-- 1 root root 32 Feb 28 16:06 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1582877175.txt
-rw-r--r-- 1 root root 32 Feb 28 16:07 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1582877237.txt
-rw-r--r-- 1 root root 32 Feb 28 16:08 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1582877298.txt
-rw-r--r-- 1 root root 32 Feb 28 16:09 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1582877360.txt
-rw-r--r-- 1 root root 32 Feb 28 16:10 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1582877422.txt
-rw-r--r-- 1 root root 32 Feb 28 16:11 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1582877483.txt
-rw-r--r-- 1 root root 32 Feb 28 16:12 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1582877545.txt
-rw-r--r-- 1 root root 32 Feb 28 16:13 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1582877606.txt
-rw-r--r-- 1 root root 32 Feb 28 16:14 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1582877668.txt
-rw-r--r-- 1 root root 32 Feb 28 16:15 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1582877730.txt
-rw-r--r-- 1 root root 32 Feb 28 16:16 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1582877791.txt

[root@16fa59fcd4e0 logs]# ls -ltr
total 144
-rw-r--r-- 1 root root 8845 Feb 28 15:43 app.log
-rw-r--r-- 1 root root   32 Feb 28 15:44 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1582875846.txt
-rw-r--r-- 1 root root   32 Feb 28 15:45 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1582875908.txt
-rw-r--r-- 1 root root   32 Feb 28 15:46 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1582875969.txt
-rw-r--r-- 1 root root   32 Feb 28 15:47 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1582876031.txt
-rw-r--r-- 1 root root   32 Feb 28 15:48 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1582876093.txt
-rw-r--r-- 1 root root   32 Feb 28 15:49 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1582876155.txt
-rw-r--r-- 1 root root   32 Feb 28 15:50 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1582876218.txt
-rw-r--r-- 1 root root   32 Feb 28 15:51 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1582876279.txt
-rw-r--r-- 1 root root   32 Feb 28 15:52 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1582876341.txt
-rw-r--r-- 1 root root   32 Feb 28 15:53 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1582876403.txt
-rw-r--r-- 1 root root   32 Feb 28 15:54 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1582876465.txt
-rw-r--r-- 1 root root   32 Feb 28 15:55 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1582876526.txt
-rw-r--r-- 1 root root   32 Feb 28 15:56 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1582876588.txt
-rw-r--r-- 1 root root   32 Feb 28 15:57 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1582876650.txt
-rw-r--r-- 1 root root   32 Feb 28 15:58 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1582876712.txt
-rw-r--r-- 1 root root   32 Feb 28 15:59 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1582876773.txt
-rw-r--r-- 1 root root   32 Feb 28 16:00 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1582876835.txt
-rw-r--r-- 1 root root   32 Feb 28 16:01 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1582876897.txt
-rw-r--r-- 1 root root   32 Feb 28 16:02 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1582876959.txt
-rw-r--r-- 1 root root   32 Feb 28 16:03 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1582877020.txt
-rw-r--r-- 1 root root   32 Feb 28 16:04 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1582877082.txt
-rw-r--r-- 1 root root   32 Feb 28 16:05 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1582877144.txt
-rw-r--r-- 1 root root   32 Feb 28 16:06 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1582877206.txt
-rw-r--r-- 1 root root   32 Feb 28 16:07 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1582877268.txt
-rw-r--r-- 1 root root   32 Feb 28 16:08 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1582877330.txt
-rw-r--r-- 1 root root   32 Feb 28 16:09 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1582877392.txt
-rw-r--r-- 1 root root   32 Feb 28 16:10 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1582877454.txt
-rw-r--r-- 1 root root   32 Feb 28 16:11 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1582877515.txt
-rw-r--r-- 1 root root   32 Feb 28 16:12 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1582877577.txt
-rw-r--r-- 1 root root   32 Feb 28 16:13 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1582877639.txt
-rw-r--r-- 1 root root   32 Feb 28 16:15 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1582877701.txt
-rw-r--r-- 1 root root   32 Feb 28 16:16 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1582877763.txt
-rw-r--r-- 1 root root   32 Feb 28 16:17 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1582877825.txt


14、在 bash sleep 60 秒 的情况下,很难出现并发锁定的情况。或者增加更多的容器,或者提升执行命令行的频率。设置 bash sleep 10 秒。已经出现并发锁定(防止同一个租户下的用户同步同时在多个容器中执行)的情况。当部署为集群时,已经可以保证同一个租户下的用户同步,在某一时间段,仅在 1 个容器中执行。理论上的计算公式,一个租户的同步时间间隔为:4 / 3 * 10 = 13,结果单位为秒。符合设计预期。总结:部署的容器数量不要超过租户的数量,以防止并发锁定的情况过于频繁。如图5
在 bash sleep 60 秒 的情况下,很难出现并发锁定的情况。或者增加更多的容器,或者提升执行命令行的频率。设置 bash sleep 10 秒。已经出现并发锁定(防止同一个租户下的用户同步同时在多个容器中执行)的情况。当部署为集群时,已经可以保证同一个租户下的用户同步,在某一时间段,仅在 1 个容器中执行。理论上的计算公式,一个租户的同步时间间隔为:4 / 3 * 10 = 13,结果单位为秒。符合设计预期。总结:部署的容器数量不要超过租户的数量,以防止并发锁定的情况过于频繁。

图5



[root@0f5a081a481a logs]# ls -ltr
total 320
-rw-r--r-- 1 root root 8845 Mar  2 09:50 app.log
-rw-r--r-- 1 root root   32 Mar  2 09:50 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583113813.txt
-rw-r--r-- 1 root root   32 Mar  2 09:50 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583113825.txt
-rw-r--r-- 1 root root   32 Mar  2 09:50 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583113836.txt
-rw-r--r-- 1 root root   32 Mar  2 09:50 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583113848.txt
-rw-r--r-- 1 root root   32 Mar  2 09:51 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583113860.txt
-rw-r--r-- 1 root root   32 Mar  2 09:51 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583113871.txt
-rw-r--r-- 1 root root   32 Mar  2 09:51 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583113883.txt
-rw-r--r-- 1 root root   32 Mar  2 09:51 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583113894.txt
-rw-r--r-- 1 root root   32 Mar  2 09:51 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583113906.txt
-rw-r--r-- 1 root root   32 Mar  2 09:51 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583113917.txt
-rw-r--r-- 1 root root   32 Mar  2 09:52 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583113929.txt
-rw-r--r-- 1 root root   32 Mar  2 09:52 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583113940.txt
-rw-r--r-- 1 root root   32 Mar  2 09:52 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583113952.txt
-rw-r--r-- 1 root root   32 Mar  2 09:52 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583113964.txt
-rw-r--r-- 1 root root   32 Mar  2 09:52 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583113975.txt
-rw-r--r-- 1 root root   32 Mar  2 09:53 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583113987.txt
-rw-r--r-- 1 root root   32 Mar  2 09:53 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583113998.txt
-rw-r--r-- 1 root root   32 Mar  2 09:53 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114010.txt
-rw-r--r-- 1 root root   32 Mar  2 09:53 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114021.txt
-rw-r--r-- 1 root root   32 Mar  2 09:53 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114033.txt
-rw-r--r-- 1 root root   32 Mar  2 09:54 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114044.txt
-rw-r--r-- 1 root root   32 Mar  2 09:54 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114056.txt
-rw-r--r-- 1 root root   32 Mar  2 09:54 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114067.txt
-rw-r--r-- 1 root root   32 Mar  2 09:54 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114079.txt
-rw-r--r-- 1 root root   32 Mar  2 09:54 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114091.txt
-rw-r--r-- 1 root root   32 Mar  2 09:55 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114102.txt
-rw-r--r-- 1 root root   32 Mar  2 09:55 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114114.txt
-rw-r--r-- 1 root root   32 Mar  2 09:55 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114125.txt
-rw-r--r-- 1 root root   32 Mar  2 09:55 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114137.txt
-rw-r--r-- 1 root root   32 Mar  2 09:55 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114148.txt
-rw-r--r-- 1 root root   32 Mar  2 09:56 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114160.txt
-rw-r--r-- 1 root root   32 Mar  2 09:56 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114171.txt
-rw-r--r-- 1 root root   32 Mar  2 09:56 cmc-console-user-sync-is-lock-exist-c10e87f39873512a16727e17f57456a5-1583114171.txt
-rw-r--r-- 1 root root   32 Mar  2 09:56 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114171.txt
-rw-r--r-- 1 root root   32 Mar  2 09:56 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114183.txt
-rw-r--r-- 1 root root   32 Mar  2 09:56 cmc-console-user-sync-is-lock-exist-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114183.txt
-rw-r--r-- 1 root root   32 Mar  2 09:56 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114183.txt
-rw-r--r-- 1 root root   32 Mar  2 09:56 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114194.txt
-rw-r--r-- 1 root root   32 Mar  2 09:56 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114206.txt
-rw-r--r-- 1 root root   32 Mar  2 09:56 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114218.txt
-rw-r--r-- 1 root root   32 Mar  2 09:57 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114228.txt
-rw-r--r-- 1 root root   32 Mar  2 09:57 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114240.txt
-rw-r--r-- 1 root root   32 Mar  2 09:57 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114252.txt
-rw-r--r-- 1 root root   32 Mar  2 09:57 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114263.txt
-rw-r--r-- 1 root root   32 Mar  2 09:57 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114275.txt
-rw-r--r-- 1 root root   32 Mar  2 09:58 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114286.txt
-rw-r--r-- 1 root root   32 Mar  2 09:58 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114298.txt
-rw-r--r-- 1 root root   32 Mar  2 09:58 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114309.txt
-rw-r--r-- 1 root root   32 Mar  2 09:58 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114321.txt
-rw-r--r-- 1 root root   32 Mar  2 09:58 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114332.txt
-rw-r--r-- 1 root root   32 Mar  2 09:59 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114344.txt
-rw-r--r-- 1 root root   32 Mar  2 09:59 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114355.txt
-rw-r--r-- 1 root root   32 Mar  2 09:59 cmc-console-user-sync-is-lock-exist-4fd58ceba1fbc537b5402302702131eb-1583114355.txt
-rw-r--r-- 1 root root   32 Mar  2 09:59 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114355.txt
-rw-r--r-- 1 root root   32 Mar  2 09:59 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114367.txt
-rw-r--r-- 1 root root   32 Mar  2 09:59 cmc-console-user-sync-is-lock-exist-c10e87f39873512a16727e17f57456a5-1583114367.txt
-rw-r--r-- 1 root root   32 Mar  2 09:59 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114367.txt
-rw-r--r-- 1 root root   32 Mar  2 09:59 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114379.txt
-rw-r--r-- 1 root root   32 Mar  2 09:59 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114390.txt
-rw-r--r-- 1 root root   32 Mar  2 10:00 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114402.txt
-rw-r--r-- 1 root root   32 Mar  2 10:00 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114413.txt
-rw-r--r-- 1 root root   32 Mar  2 10:00 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114425.txt
-rw-r--r-- 1 root root   32 Mar  2 10:00 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114436.txt
-rw-r--r-- 1 root root   32 Mar  2 10:00 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114448.txt
-rw-r--r-- 1 root root   32 Mar  2 10:01 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114460.txt
-rw-r--r-- 1 root root   32 Mar  2 10:01 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114471.txt
-rw-r--r-- 1 root root   32 Mar  2 10:01 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114483.txt
-rw-r--r-- 1 root root   32 Mar  2 10:01 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114494.txt
-rw-r--r-- 1 root root   32 Mar  2 10:01 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114506.txt
-rw-r--r-- 1 root root   32 Mar  2 10:01 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114517.txt
-rw-r--r-- 1 root root   32 Mar  2 10:02 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114529.txt
-rw-r--r-- 1 root root   32 Mar  2 10:02 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114540.txt
-rw-r--r-- 1 root root   32 Mar  2 10:02 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114552.txt
-rw-r--r-- 1 root root   32 Mar  2 10:02 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114563.txt
-rw-r--r-- 1 root root   32 Mar  2 10:02 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114575.txt
-rw-r--r-- 1 root root   32 Mar  2 10:03 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114587.txt
-rw-r--r-- 1 root root   32 Mar  2 10:03 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114598.txt

[root@88f433b87315 logs]# ls -ltr
total 344
-rw-r--r-- 1 root root 9092 Mar  2 09:49 app.log
-rw-r--r-- 1 root root   32 Mar  2 09:49 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583113764.txt
-rw-r--r-- 1 root root   32 Mar  2 09:49 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583113776.txt
-rw-r--r-- 1 root root   32 Mar  2 09:49 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583113788.txt
-rw-r--r-- 1 root root   32 Mar  2 09:49 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583113799.txt
-rw-r--r-- 1 root root   32 Mar  2 09:50 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583113811.txt
-rw-r--r-- 1 root root   32 Mar  2 09:50 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583113823.txt
-rw-r--r-- 1 root root   32 Mar  2 09:50 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583113834.txt
-rw-r--r-- 1 root root   32 Mar  2 09:50 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583113846.txt
-rw-r--r-- 1 root root   32 Mar  2 09:50 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583113857.txt
-rw-r--r-- 1 root root   32 Mar  2 09:51 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583113869.txt
-rw-r--r-- 1 root root   32 Mar  2 09:51 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583113881.txt
-rw-r--r-- 1 root root   32 Mar  2 09:51 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583113892.txt
-rw-r--r-- 1 root root   32 Mar  2 09:51 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583113904.txt
-rw-r--r-- 1 root root   32 Mar  2 09:51 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583113915.txt
-rw-r--r-- 1 root root   32 Mar  2 09:52 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583113927.txt
-rw-r--r-- 1 root root   32 Mar  2 09:52 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583113939.txt
-rw-r--r-- 1 root root   32 Mar  2 09:52 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583113950.txt
-rw-r--r-- 1 root root   32 Mar  2 09:52 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583113962.txt
-rw-r--r-- 1 root root   32 Mar  2 09:52 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583113973.txt
-rw-r--r-- 1 root root   32 Mar  2 09:53 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583113985.txt
-rw-r--r-- 1 root root   32 Mar  2 09:53 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583113997.txt
-rw-r--r-- 1 root root   32 Mar  2 09:53 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114008.txt
-rw-r--r-- 1 root root   32 Mar  2 09:53 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114020.txt
-rw-r--r-- 1 root root   32 Mar  2 09:53 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114032.txt
-rw-r--r-- 1 root root   32 Mar  2 09:54 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114043.txt
-rw-r--r-- 1 root root   32 Mar  2 09:54 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114055.txt
-rw-r--r-- 1 root root   32 Mar  2 09:54 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114066.txt
-rw-r--r-- 1 root root   32 Mar  2 09:54 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114078.txt
-rw-r--r-- 1 root root   32 Mar  2 09:54 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114090.txt
-rw-r--r-- 1 root root   32 Mar  2 09:55 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114101.txt
-rw-r--r-- 1 root root   32 Mar  2 09:55 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114113.txt
-rw-r--r-- 1 root root   32 Mar  2 09:55 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114125.txt
-rw-r--r-- 1 root root   32 Mar  2 09:55 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114136.txt
-rw-r--r-- 1 root root   32 Mar  2 09:55 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114148.txt
-rw-r--r-- 1 root root   32 Mar  2 09:55 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114159.txt
-rw-r--r-- 1 root root   32 Mar  2 09:56 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114171.txt
-rw-r--r-- 1 root root   32 Mar  2 09:56 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114183.txt
-rw-r--r-- 1 root root   32 Mar  2 09:56 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114195.txt
-rw-r--r-- 1 root root   32 Mar  2 09:56 cmc-console-user-sync-is-lock-exist-4fd58ceba1fbc537b5402302702131eb-1583114195.txt
-rw-r--r-- 1 root root   32 Mar  2 09:56 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114195.txt
-rw-r--r-- 1 root root   32 Mar  2 09:56 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114206.txt
-rw-r--r-- 1 root root   32 Mar  2 09:56 cmc-console-user-sync-is-lock-exist-015ce30b116ce86058fa6ab4fea4ac63-1583114206.txt
-rw-r--r-- 1 root root   32 Mar  2 09:56 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114206.txt
-rw-r--r-- 1 root root   32 Mar  2 09:56 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114218.txt
-rw-r--r-- 1 root root   32 Mar  2 09:57 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114229.txt
-rw-r--r-- 1 root root   32 Mar  2 09:57 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114241.txt
-rw-r--r-- 1 root root   32 Mar  2 09:57 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114253.txt
-rw-r--r-- 1 root root   32 Mar  2 09:57 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114264.txt
-rw-r--r-- 1 root root   32 Mar  2 09:57 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114276.txt
-rw-r--r-- 1 root root   32 Mar  2 09:58 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114288.txt
-rw-r--r-- 1 root root   32 Mar  2 09:58 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114299.txt
-rw-r--r-- 1 root root   32 Mar  2 09:58 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114311.txt
-rw-r--r-- 1 root root   32 Mar  2 09:58 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114322.txt
-rw-r--r-- 1 root root   32 Mar  2 09:58 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114334.txt
-rw-r--r-- 1 root root   32 Mar  2 09:59 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114346.txt
-rw-r--r-- 1 root root   32 Mar  2 09:59 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114357.txt
-rw-r--r-- 1 root root   32 Mar  2 09:59 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114369.txt
-rw-r--r-- 1 root root   32 Mar  2 09:59 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114380.txt
-rw-r--r-- 1 root root   32 Mar  2 09:59 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114392.txt
-rw-r--r-- 1 root root   32 Mar  2 10:00 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114404.txt
-rw-r--r-- 1 root root   32 Mar  2 10:00 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114415.txt
-rw-r--r-- 1 root root   32 Mar  2 10:00 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114427.txt
-rw-r--r-- 1 root root   32 Mar  2 10:00 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114439.txt
-rw-r--r-- 1 root root   32 Mar  2 10:00 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114450.txt
-rw-r--r-- 1 root root   32 Mar  2 10:01 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114462.txt
-rw-r--r-- 1 root root   32 Mar  2 10:01 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114474.txt
-rw-r--r-- 1 root root   32 Mar  2 10:01 cmc-console-user-sync-is-lock-exist-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114474.txt
-rw-r--r-- 1 root root   32 Mar  2 10:01 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114474.txt
-rw-r--r-- 1 root root   32 Mar  2 10:01 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114485.txt
-rw-r--r-- 1 root root   32 Mar  2 10:01 cmc-console-user-sync-is-lock-exist-015ce30b116ce86058fa6ab4fea4ac63-1583114485.txt
-rw-r--r-- 1 root root   32 Mar  2 10:01 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114485.txt
-rw-r--r-- 1 root root   32 Mar  2 10:01 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114497.txt
-rw-r--r-- 1 root root   32 Mar  2 10:01 cmc-console-user-sync-is-lock-exist-4fd58ceba1fbc537b5402302702131eb-1583114497.txt
-rw-r--r-- 1 root root   32 Mar  2 10:01 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114497.txt
-rw-r--r-- 1 root root   32 Mar  2 10:01 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114509.txt
-rw-r--r-- 1 root root   32 Mar  2 10:02 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114520.txt
-rw-r--r-- 1 root root   32 Mar  2 10:02 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114532.txt
-rw-r--r-- 1 root root   32 Mar  2 10:02 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114543.txt
-rw-r--r-- 1 root root   32 Mar  2 10:02 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114555.txt
-rw-r--r-- 1 root root   32 Mar  2 10:02 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114567.txt
-rw-r--r-- 1 root root   32 Mar  2 10:02 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114578.txt
-rw-r--r-- 1 root root   32 Mar  2 10:03 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114590.txt
-rw-r--r-- 1 root root   32 Mar  2 10:03 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114601.txt

[root@c2e084f1424c logs]# ls -ltr
total 308
-rw-r--r-- 1 root root 8845 Mar  2 09:49 app.log
-rw-r--r-- 1 root root   32 Mar  2 09:49 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583113778.txt
-rw-r--r-- 1 root root   32 Mar  2 09:49 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583113790.txt
-rw-r--r-- 1 root root   32 Mar  2 09:50 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583113802.txt
-rw-r--r-- 1 root root   32 Mar  2 09:50 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583113814.txt
-rw-r--r-- 1 root root   32 Mar  2 09:50 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583113825.txt
-rw-r--r-- 1 root root   32 Mar  2 09:50 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583113837.txt
-rw-r--r-- 1 root root   32 Mar  2 09:50 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583113849.txt
-rw-r--r-- 1 root root   32 Mar  2 09:51 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583113861.txt
-rw-r--r-- 1 root root   32 Mar  2 09:51 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583113873.txt
-rw-r--r-- 1 root root   32 Mar  2 09:51 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583113884.txt
-rw-r--r-- 1 root root   32 Mar  2 09:51 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583113896.txt
-rw-r--r-- 1 root root   32 Mar  2 09:51 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583113908.txt
-rw-r--r-- 1 root root   32 Mar  2 09:52 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583113920.txt
-rw-r--r-- 1 root root   32 Mar  2 09:52 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583113932.txt
-rw-r--r-- 1 root root   32 Mar  2 09:52 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583113943.txt
-rw-r--r-- 1 root root   32 Mar  2 09:52 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583113955.txt
-rw-r--r-- 1 root root   32 Mar  2 09:52 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583113967.txt
-rw-r--r-- 1 root root   32 Mar  2 09:52 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583113979.txt
-rw-r--r-- 1 root root   32 Mar  2 09:53 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583113990.txt
-rw-r--r-- 1 root root   32 Mar  2 09:53 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114002.txt
-rw-r--r-- 1 root root   32 Mar  2 09:53 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114014.txt
-rw-r--r-- 1 root root   32 Mar  2 09:53 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114026.txt
-rw-r--r-- 1 root root   32 Mar  2 09:53 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114037.txt
-rw-r--r-- 1 root root   32 Mar  2 09:54 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114049.txt
-rw-r--r-- 1 root root   32 Mar  2 09:54 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114061.txt
-rw-r--r-- 1 root root   32 Mar  2 09:54 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114073.txt
-rw-r--r-- 1 root root   32 Mar  2 09:54 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114085.txt
-rw-r--r-- 1 root root   32 Mar  2 09:54 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114096.txt
-rw-r--r-- 1 root root   32 Mar  2 09:55 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114108.txt
-rw-r--r-- 1 root root   32 Mar  2 09:55 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114120.txt
-rw-r--r-- 1 root root   32 Mar  2 09:55 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114132.txt
-rw-r--r-- 1 root root   32 Mar  2 09:55 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114143.txt
-rw-r--r-- 1 root root   32 Mar  2 09:55 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114155.txt
-rw-r--r-- 1 root root   32 Mar  2 09:56 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114167.txt
-rw-r--r-- 1 root root   32 Mar  2 09:56 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114179.txt
-rw-r--r-- 1 root root   32 Mar  2 09:56 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114191.txt
-rw-r--r-- 1 root root   32 Mar  2 09:56 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114202.txt
-rw-r--r-- 1 root root   32 Mar  2 09:56 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114214.txt
-rw-r--r-- 1 root root   32 Mar  2 09:57 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114226.txt
-rw-r--r-- 1 root root   32 Mar  2 09:57 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114238.txt
-rw-r--r-- 1 root root   32 Mar  2 09:57 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114249.txt
-rw-r--r-- 1 root root   32 Mar  2 09:57 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114261.txt
-rw-r--r-- 1 root root   32 Mar  2 09:57 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114273.txt
-rw-r--r-- 1 root root   32 Mar  2 09:58 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114285.txt
-rw-r--r-- 1 root root   32 Mar  2 09:58 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114296.txt
-rw-r--r-- 1 root root   32 Mar  2 09:58 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114308.txt
-rw-r--r-- 1 root root   32 Mar  2 09:58 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114320.txt
-rw-r--r-- 1 root root   32 Mar  2 09:58 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114332.txt
-rw-r--r-- 1 root root   32 Mar  2 09:59 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114343.txt
-rw-r--r-- 1 root root   32 Mar  2 09:59 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114355.txt
-rw-r--r-- 1 root root   32 Mar  2 09:59 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114367.txt
-rw-r--r-- 1 root root   32 Mar  2 09:59 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114379.txt
-rw-r--r-- 1 root root   32 Mar  2 09:59 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114391.txt
-rw-r--r-- 1 root root   32 Mar  2 10:00 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114403.txt
-rw-r--r-- 1 root root   32 Mar  2 10:00 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114414.txt
-rw-r--r-- 1 root root   32 Mar  2 10:00 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114426.txt
-rw-r--r-- 1 root root   32 Mar  2 10:00 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114438.txt
-rw-r--r-- 1 root root   32 Mar  2 10:00 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114450.txt
-rw-r--r-- 1 root root   32 Mar  2 10:01 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114461.txt
-rw-r--r-- 1 root root   32 Mar  2 10:01 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114473.txt
-rw-r--r-- 1 root root   32 Mar  2 10:01 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114485.txt
-rw-r--r-- 1 root root   32 Mar  2 10:01 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114497.txt
-rw-r--r-- 1 root root   32 Mar  2 10:01 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114509.txt
-rw-r--r-- 1 root root   32 Mar  2 10:01 cmc-console-user-sync-is-lock-exist-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114509.txt
-rw-r--r-- 1 root root   32 Mar  2 10:01 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114509.txt
-rw-r--r-- 1 root root   32 Mar  2 10:02 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114520.txt
-rw-r--r-- 1 root root   32 Mar  2 10:02 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114532.txt
-rw-r--r-- 1 root root   32 Mar  2 10:02 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114544.txt
-rw-r--r-- 1 root root   32 Mar  2 10:02 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114556.txt
-rw-r--r-- 1 root root   32 Mar  2 10:02 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114568.txt
-rw-r--r-- 1 root root   32 Mar  2 10:03 cmc-console-user-sync-c10e87f39873512a16727e17f57456a5-1583114580.txt
-rw-r--r-- 1 root root   32 Mar  2 10:03 cmc-console-user-sync-f53df1a8d46108afc8ae9eeb3f0e1f0e-1583114592.txt
-rw-r--r-- 1 root root   32 Mar  2 10:03 cmc-console-user-sync-4fd58ceba1fbc537b5402302702131eb-1583114603.txt
-rw-r--r-- 1 root root   32 Mar  2 10:03 cmc-console-user-sync-015ce30b116ce86058fa6ab4fea4ac63-1583114615.txt


15、总结: (1) 理论上的计算公式,一个租户的同步时间间隔为:租户数量 / 容器数量 * 60,结果单位为秒。 (2) 部署的容器数量不要超过租户的数量,以防止并发锁定的情况过于频繁,且必要性不大(当容器数量等于租户数量时,同步时间间隔为:60 秒)。]]>
https://www.shuijingwanwq.com/2020/03/02/3964/feed/ 0
在 Yii 2.0 中,唯一性验证失败时,提示不够友好,自动调整优化的分析 https://www.shuijingwanwq.com/2020/02/20/3949/ https://www.shuijingwanwq.com/2020/02/20/3949/#respond Thu, 20 Feb 2020 05:36:14 +0000 https://www.shuijingwanwq.com/?p=3949 浏览量: 109 1、测试人员提交了一个 Bug,认为唯一性验证失败时,提示不够友好(中英文混杂,用户不易理解),提示信息如图1
测试人员提交了一个 Bug,认为唯一性验证失败时,提示不够友好(中英文混杂,用户不易理解)

图1

2、在本地环境的最新版本中,准备复现时,意外发现提示信息已经全部显示为中文,提示信息如图2
在本地环境的最新版本中,准备复现时,意外发现提示信息已经全部显示为中文

图2



{
    "code": 226004,
    "message": "数据验证失败:租户ID, 栏目名称, 是否被删除 与 删除时间 的值 \"\"015ce30b116ce86058fa6ab4fea4ac63\"-\"深圳市9\"-\"0\"-\"0\"\" 已经被占用了。"
}


3、查看相应程序文件,并未针对提示信息做相应调整,查看 Git 日志,提交:通过运行 composer update 来更新 Yii 2 至最新版本,已将 Yii Framework 从 2.0.15.1 版本升级到 2.0.31。初步怀疑是由于 Yii 框架版本的升级,进而调整了提示信息。如图3
查看相应程序文件,并未针对提示信息做相应调整,查看 Git 日志,提交:通过运行 composer update 来更新 Yii 2 至最新版本,已将 Yii Framework 从 2.0.15.1 版本升级到 2.0.31。初步怀疑是由于 Yii 框架版本的升级,进而调整了提示信息。

图3

4、部署标签:1.10.4-alpha.5,为升级前的版本,Bug 已复现,如图4
部署标签:1.10.4-alpha.5,为升级前的版本,Bug 已复现

图4



{
    "code": 226004,
    "message": "数据验证失败:The combination \"015ce30b116ce86058fa6ab4fea4ac63\"-\"深圳市1\"-\"0\"-\"0\" of 租户ID, 栏目名称, 是否被删除 and 删除时间 has already been taken."
}


5、部署标签:1.10.4-alpha.6,为升级后的版本,Bug 已修复,英文已经消失,提示信息更友好,如图5
部署标签:1.10.4-alpha.6,为升级后的版本,Bug 已修复,英文已经消失,提示信息更友好

图5



{
    "code": 226004,
    "message": "数据验证失败:租户ID, 栏目名称, 是否被删除 与 删除时间 的值 \"\"015ce30b116ce86058fa6ab4fea4ac63\"-\"深圳市1\"-\"0\"-\"0\"\" 已经被占用了。"
}


6、由此得出结论,唯一性验证失败时,提示更友好的缘故在于,已将 Yii Framework 从 2.0.15.1 版本升级到 2.0.31。究竟是期间的哪个版本导致的,查看 /vendor/yiisoft/yii2/messages/zh-CN/yii.php 的 Github 日志。参考网址:https://github.com/yiisoft/yii2/commit/b8a3fa4ff96cb80d77fcf8003163c9001770ae8b#diff-9083c63f8544587712f4083785a317cf ,在提交:b8a3fa 中,新增加了一行。提交于 2018年4月5日,如图6
由此得出结论,唯一性验证失败时,提示更友好的缘故在于,已将 Yii Framework 从 2.0.15.1 版本升级到 2.0.31。究竟是期间的哪个版本导致的,查看 /vendor/yiisoft/yii2/messages/zh-CN/yii.php 的 Github 日志。参考网址:https://github.com/yiisoft/yii2/commit/b8a3fa4ff96cb80d77fcf8003163c9001770ae8b#diff-9083c63f8544587712f4083785a317cf ,在提交:b8a3fa 中,新增加了一行。提交于 2018年4月5日

图6



    'The combination {values} of {attributes} has already been taken.' => '{attributes} 的值 "{values}" 已经被占用了。',


7、参考网址:https://github.com/yiisoft/yii2/tree/2.0.16/framework/messages/zh-CN ,提交:b8a3fa 存在于 Tag:2.0.16 中。因此,可以确定 Yii Framework 的 2.0.16 版本,已经优化了相应提示信息。如图7
参考网址:https://github.com/yiisoft/yii2/tree/2.0.16/framework/messages/zh-CN ,提交:b8a3fa 存在于 Tag:2.0.16 中。因此,可以确定 Yii Framework 的 2.0.16 版本,已经优化了相应提示信息。

图7

]]>
https://www.shuijingwanwq.com/2020/02/20/3949/feed/ 0