javascript - yii2 和负载均衡

标签 javascript css apache yii2 load-balancing

我正在开发一个 PHP Yii2 应用程序。我对 yii2 有一个奇怪的问题,这是我的问题。

众所周知,Yii2 元素中有一个 web\assets 文件夹,它会加载自己的 Assets 包,但是在配置负载平衡时,我发现 chrome 的开发者工具控制台抛出一些错误如下:

http://firekylin.eastasia.cloudapp.azure.com/assets/fde0fce1/css/bootstrap.css Failed to load resource: the server responded with a status of 404 (Not Found)
http://firekylin.eastasia.cloudapp.azure.com/assets/ebd0699a/css/AdminLTE.min.css Failed to load resource: the server responded with a status of 404 (Not Found)
http://firekylin.eastasia.cloudapp.azure.com/assets/5e97633a/jquery.js Failed to load resource: the server responded with a status of 404 (Not Found)
yii.js:464 Uncaught ReferenceError: jQuery is not defined(…)
http://firekylin.eastasia.cloudapp.azure.com/assets/14e563af/yii.validation.js Failed to load resource: the server responded with a status of 404 (Not Found)
http://firekylin.eastasia.cloudapp.azure.com/assets/fde0fce1/js/bootstrap.js Failed to load resource: the server responded with a status of 404 (Not Found)
yii.activeForm.js:14 Uncaught TypeError: Cannot read property 'fn' of undefined(…)
http://firekylin.eastasia.cloudapp.azure.com/assets/fde0fce1/js/bootstrap.js Failed to load resource: the server responded with a status of 404 (Not Found)
app.min.js:13 Uncaught Error: AdminLTE requires jQuery(…)
index.php:555 Uncaught ReferenceError: jQuery is not defined(…)
http://firekylin.eastasia.cloudapp.azure.com/assets/88d3a068/css/font-awesome.min.css Failed to load resource: the server responded with a status of 404 (Not Found)
http://firekylin.eastasia.cloudapp.azure.com/assets/ebd0699a/css/skins/_all-skins.min.css Failed to load resource: the server responded with a status of 404 (Not Found)

使用负载均衡ip访问是找不到js,css文件的,但是当我使用正好有Yii2应用运行的服务器ip时,网页会成功加载js,css文件:

left one is using load balance server to visit and right one is using Yii2 server to visit

有两台服务器完全运行 Yii2,它们都有自己的 web\assets 文件夹和不同的缓存:

web\assets folders in two Yii2 servers

我发现一旦我停止其中一个Yii2 Server,负载均衡服务器就会正常工作。因此,我猜测问题可能出在Yii2的web\assets文件夹。从上面两张图我们可以发现Yii2使用的是md5重命名其中的文件夹,所以可能是因为两个 Yii2 服务器的 web\assets 文件夹具有不同的命名子文件夹导致问题发生?

不过,我尝试用下面的代码解决这个问题:

<?php

$params = require(__DIR__ . '/params.php');

$config = [
'id' => 'basic',
'defaultRoute'=>'firekylin',
'basePath' => dirname(__DIR__),
'bootstrap' => ['log'],
'components' => [

    'view' => [
        'theme' => [
            'pathMap' => [
                '@app/views' => '@app/views/dmstr/yii2-adminlte-asset/example-views/yiisoft/yii2-app'
            ],
        ],
    ],

    'assetManager' => [
        'class' => 'yii\web\AssetManager',
        'forceCopy' => true,
    ],


    'request' => [
        // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
        'cookieValidationKey' => '2MhlyGaaGs_uqt_apwy1jLahR_wZ8dBv',

        'parsers' => [
            'application/json' => 'yii\web\JsonParser',
            'text/json' => 'yii\web\JsonParser',
        ]
    ],
    'cache' => [
        'class' => 'yii\caching\FileCache',
    ],
    'user' => [
        'identityClass' => 'app\models\OriginUser',
        'enableAutoLogin' => true,
    ],
    'errorHandler' => [
        'errorAction' => 'site/error',
    ],
    'mailer' => [
        'class' => 'yii\swiftmailer\Mailer',
        // send all mails to a file by default. You have to set
        // 'useFileTransport' to false and configure a transport
        // for the mailer to send real emails.
        'useFileTransport' => true,
    ],
    'log' => [
        'traceLevel' => YII_DEBUG ? 3 : 0,
        'targets' => [
            [
                'class' => 'yii\log\FileTarget',
                'levels' => ['error', 'warning'],
            ],
        ],
    ],
    'db' => require(__DIR__ . '/db.php'),
    /*
    'urlManager' => [
        'enablePrettyUrl' => true,
        'showScriptName' => false,
        'rules' => [
        ],
    ],
    */
],
'params' => $params,
];

if (YII_ENV_DEV) {
$config['bootstrap'][] = 'debug';
$config['modules']['debug'] = [
    'class' => 'yii\debug\Module',
];

$config['bootstrap'][] = 'gii';
$config['modules']['gii'] = [
    'class' => 'yii\gii\Module',
];
$config['components']['assetManager']['forceCopy'] = true;
}

return $config;

public function beforeAction($action){

        Yii::$app->assetManager->forceCopy = YII_DEBUG;

    return parent::beforeAction($action);
}

我尝试使用 assetManager 或

$config['components']['assetManager']['forceCopy'] = true;

在我自己的controller中的config\web.php或者function beforeAction中禁止assets文件夹,但是没有用,请问有什么办法可以解决这个问题吗?

最佳答案

确保两台服务器上的文件路径和 yii2 核心版本相同。

扩展assetManager 类和自定义hash() 函数。 每次更改 Assets 时请记住清除 Assets 文件夹。

例如:

Class MyAssetManager extend yii\web\AssetManager{
    protected function hash($path)
    {
        $path = is_file($path) ? dirname($path) : $path;
        return sprintf('%x', crc32($path . Yii::getVersion()));
    }
}

其他方式:

  1. 使用 hashCallback 属性:http://www.yiiframework.com/doc-2.0/yii-web-assetmanager.html# $hashCallback-详细信息
  2. 将负载平衡配置更改为基于 session 的路由 例如:NGINX session 持久性
  3. 对 Assets 使用 CDN

关于javascript - yii2 和负载均衡,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40553273/

相关文章:

php - 按带宽限制成员资格

php - 使用 lamp-server^ 包安装 LAMP 与单独安装 Apache、PHP、MySQL 的优缺点

javascript - 使用 Angular Directive(指令)添加 CSS 元素

html - 如何将 .png 图像文件中的前景色从蓝色转换为黑色?

CSS 舍入在 Safari 中有效,但在 Chrome 中无效

缺少 CSS Lbrace

php - .htaccess URL 重写错误 - 在此服务器上找不到请求的 URL

javascript - 变量提升的意义是什么?

javascript - jquery中的for循环错误

javascript - 如何在 jQuery UI 选项卡中重新加载 AJAX 内容