yii2 and load balancing

Bin*_*hen 4 javascript css apache load-balancing yii2

I'm working on a PHP Yii2 application. I have a strange problem with yii2 ,here is my problem.

As we known, there is a web\assets folder in Yii2 project and it will load it's own asset bundle,but when configuring load balance , I found that chrome's developer tools console throw some errors below:

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)
Run Code Online (Sandbox Code Playgroud)

It can't find js,css file when using the load balance ip to visit,but once I use the ip of the server where there exactly is a Yii2 application running,the web page will load js,css file successfully:

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

There are two servers exactly running Yii2 and they both have their own web\assets folder and have different caches:

web\assets folders in two Yii2 servers

I found that once I stop one of the Yii2 Server,the load balance server will work successfully.Therefore,I guess maybe the problem result from Yii2's web\assets folder.From the two pictures above we can find that Yii2 use md5 to rename the folders in it,so maybe it was because the two Yii2 servers' web\assets folders have different named child-folders that makes the problem happened?

However,I've try to solve the problem with below codes:

<?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;
Run Code Online (Sandbox Code Playgroud)

and

public function beforeAction($action){

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

    return parent::beforeAction($action);
}
Run Code Online (Sandbox Code Playgroud)

I try to use assetManager or

$config['components']['assetManager']['forceCopy'] = true;
Run Code Online (Sandbox Code Playgroud)

in config\web.php or function beforeAction in my own controller to forbid assets folder,but it doesn't work.Is there any way to solve the problem?

Ngô*_*hao 5

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

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

例如:

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

其他一些方式:

  1. 使用 hashCallback 属性:http : //www.yiiframework.com/doc-2.0/yii-web-assetmanager.html# $hashCallback-detail
  2. 将负载均衡配置更改为基于会话的路由 例如:NGINX 会话持久性
  3. 对资产使用 CDN