セッションのデッドロックによる管理画面のフリーズについて

プログラム(機能)関連の開発の話題
jeyson
メンバー
メンバー
記事: 24
登録日時: 2010年7月20日(火) 11:31

セッションのデッドロックによる管理画面のフリーズについて

投稿記事by jeyson » 2020年3月04日(水) 18:13

MODXを使用する際に「読み込み中」のまま、画面が固まってしまい、次の操作に移るどころか、ログインし直そうとしても、全てが固まってしまい、何もできない状態になることが発生することがあります。
これはネットワークが重い環境や、アクセス負荷の高いサイトで頻発するようです。
1分ぐらい待つと解消されるのですが、はっきり言って待つ時間は最低の時間です。

この現象について原因が判明したので共有させていただきます。

原因はPHPセッションのデッドロックでした。
https://unsolublesugar.com/20121103/113321/

MODXの管理画面では複数のAPIが同時に走っているため、どこかで処理が滞ると発生します。
どこかで処理が握られてしまい、次の処理が走らない状態になります。

対処コードとしては
MODXのセッションをDBセッションにする形以外には思いつかなかったので下記のように対処しました。

1.
添付のファイル「session_db.php」を
/manager/includes/
に配置します。

2.
下記のSQLを発行します。

コード: 全て選択

DROP TABLE IF EXISTS `modx_tbl_session`;
CREATE TABLE IF NOT EXISTS `modx_tbl_session` (
  `session_id` varchar(50) NOT NULL,
  `session_data` text DEFAULT NULL,
  `create_date` int(10) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE `modx_tbl_session`
  ADD PRIMARY KEY (`session_id`);


3.
/manager/includes/config.session.php
というファイルを作成し
下記のようなコードを入れます。

コード: 全て選択

<?php
$database_server             = 'localhost';
$database_user               = 'xxxx';
$database_password           = 'xxxxx';
$dbase                       = 'xxxxxxx';

※xxxxの部分は各自適切なものを

4.
/manager/includes/initialize.functions.inc
に下記のようなものを加えます。

コード: 全て選択

<?php
include_once('session_db.php');  ← これを加える
// start cms session
function startCMSSession() {
    global $site_sessionname;
    $_ = crc32(__FILE__);
    $_ = sprintf('%u', $_);
    $_ = base_convert($_,10,36);
    $site_sessionname = 'evo' . $_;

    if (MODX_DB_SESSION_OK) {  ← これを加える
        $mysql_sesshandler = new MySessionHandler();  ← これを加える
        session_set_save_handler($mysql_sesshandler, true);  ← これを加える
    }  ← これを加える

    session_name($site_sessionname);
    session_set_cookie_params(0,MODX_BASE_URL);
    session_start();
   


正直に言って、きれいな対処ではないです。
ですが
initialize.functions.inc

/manager/includes/config.inc.php
で読み込みされる
/manager/includes/initialize.inc.php
の中でさらに読み込みされるファイルです。

そして、startCMSSessionファンクションは
DBモジュールが読み込みされる前にコールされています。

さらに
/manager/session_keepalive.php

ダイレクトに
/manager/includes/document.parser.class.inc.php
を読み込みしてからスタートするという素直な読み込み順序ではないのです。

きれいじゃないけど、
ひとまずはこれで現在は対処してうまく動いているようです。
添付ファイル
session_db.zip
(1.22 KiB) ダウンロード数: 30 回