• HeartCorelogo
  • ハートコア株式会社
  • 販売パートナー
  • EN

パフォーマンス

チューニング

ページ閲覧時の高速化

HeartCoreはWEBアプリケーションのため、タイマーカウント機能を持っていません。しかし、公開時間の制御や、その他の処理のために時間を判断する機能が必要です。そのために、ページがアクセスされる度に、現在の時間をデータベースに書き込み、該当時間が来ればコンテンツを公開処理する方式をとっています。
ページの閲覧に関しては、ユーザ側のページ、管理者側のページを問わず処理をいたします。つまり、ページが閲覧される度に毎回データベースに書き込み処理を行う仕様になっています。これによってスケジューラーを動作させ公開処理を行っていますが、この書き込みがパフォーマンスを悪化させる原因となる可能性があります。一般的なデータベースの場合、参照処理より、書き込み処理に時間がかかる仕様です。

HeartCoreではパフォーマンス向上のため、ページの閲覧時のデータベース書き込みを停止させる事が可能です。

  • 「/config.static.jsp」ファイル内の「myconfig.setTemp("scheduled_next", "");」をアンコメントします。
  • // Configuration - Features - Publishing
    //myconfig.setTemp("scheduled_next", ""); // !!!!! disables scheduled publishing/expiration functionality

    // Configuration - Features - Publishing
    myconfig.setTemp("scheduled_next", ""); // !!!!! disables scheduled publishing/expiration functionality

    これで、データベースへの書き込みが実施されなくなります。
    ※ただし、その場合スケジューラーが機能しなくなるため公開処理が実行されません。よって、代わりにクーロンを設定します。

  • 「"wget"」を使って、「/webadmin/publishscheduled.jsp」に1分毎(もしくは5分毎)にアクセスをさせます。
  • wget http://localhost//webadmin/publishscheduled.jsp

    Windowsの場合は、バッチ処理を行ってください。これで、スケジューラーを利用できるようになります。

データベース接続設定

HeartCoreでデータベースに接続する方法は複数有ります。ご利用の言語、OSによって多少異なりますが、「直接接続」、「{ODBC}{JDBC}での接続」、「データソースでの接続」の3種類があります。
パフォーマンスは、以下の順に高速となります。

  • 「データソースでの接続」
  • 「{ODBC}{JDBC}での接続」
  • 「直接接続」

つまり、何も問題が無ければ、「データソースでの接続」をご利用ください。
「データソースでの接続」の場合は、データベースとのコネクションプールの利用や、その他の制御も可能です。詳細は「Apache-Tomcatの連携」に記載してあります。「データソースでの接続」と「直接接続」の単純比較の場合、パフォーマンスは数倍違ってきます。

コンテンツ保存時の高速化

HeartCoreの管理画面でコンテンツを保存しようとした際に、遅いと感じるケースが出てきます。これは、コンテンツを保存する際に、リンクチェックを行う機能が働いているためです。
リンクは内部リンク、外部リンクを問わず、リンク切れを確認しています。もし、外部リンクが存在していれば問題はございませんが、404エラーでリンク切れになっていた場合、404のエラーが返ってくるまで保存を行わずに待ちます。インターネットの通信環境にもよりますが、かなり待たされるケースが出てきます。

これを防ぐために「/config.static.jsp」ファイルを編集し、下記3項目のいずれかをアンコメントします。

///myconfig.setTemp("checklinks_domains", "yourwebsite\\.com");

⇒リンクチェックさせたい特定のドメインのみ記述する方法

///myconfig.setTemp("checklinks_domains", "
(yourwebsite\\.com|otherwebsite\\.com|thirdwebsite\\.com)");

⇒リンクチェックさせたい複数のドメインを記述する方法

///myconfig.setTemp("checklinks_domains", "-");

⇒リンクチェックを行わない方法

リンクチェックを行わない設定にすれば、保存時のパフォーマンスを大幅に上げることが可能です。

コネクションプール設定

データベースコネクションプールの設定(あくまで参考値です。実際のサーバー構成に合わせてください。データベースはMySQLを利用するサンプルです。)
下記手順に従い、「server.xml」および「web.xml」の設定、またHeartCore管理画面の変更を行います。

Tomcatのconfファイルにある「server.xml」の下部、の前に、以下を追記します。

<Context path="" docBase="ROOT" debug="0" reloadable="true" crossContext="true"
 allowLinking="true">
<Resource name="jdbc/heartcore" auth="Container" type="javax.sql.DataSource" maxActive="100" 
maxIdle="512" maxWait="10000" username="username" password="password" 
driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://127.0.0.1:3306/DBname?useUnicode=true& 
characterEncoding=UTF-8" removeAbandoned="true" removeAbandonedTimeout="300" 
logAbandoned="true" validationQuery="select 1" testOnBorrow="true" testOnReturn="true" 
testWhileIdle="true" timeBetweenEvictionRunsMillis="10000" minEvictableIdleTimeMillis="60000"/>
</Context>

※「Resource name="jdbc/heartcore"」とありますが、⁄ の後ろは好きな名前にしてください。また、Usernameとpasswordはデータベース接続に必要な物を入れてください。

指定内容の詳細
パラメータ 説明
Context path=""
docBase="ROOT" ドキュメントルートがROOTフォルダー
debug="0" debug="0"はデバッグのための出力情報レベル
reloadable="true" trueで再ロードが可能になり変更が直ちに動作に反映される。
crossContext="true" trueにするとServletContext.getContext() メソッドを使って他のコンテキストにアクセスできる。
allowLinking="true" trueにするとシンボリックリンクを有効にすることが可能。
Resource name="jdbc/heartcore" Javaデータソース名
auth="Container" リソースマネージャに接続する主体を指定。
type="javax.sql.DataSource" JNDIリソースのクラス型、インタフェース型を指定する。
maxActive="100" データベース接続の最大接続数を指定。0の場合は無制限になる。
maxIdle="512" アイドル状態になっている最大接続数を指定。0の場合は無制限になる。
maxWait="10000" 接続しているコネクションが再度利用されるまでの待ち時間を指定。指定した時間を過ぎると例外が発生する。-1の場合は無制限になる。
username="meniu" DBへの接続ユーザ名
password="menip" DBへの接続パスワード名
driverClassName="com.mysql.jdbc.Driver" JDBCドライバのJavaクラスを指定。
removeAbandoned="true" removeAbandonedを有効にするとクローズ漏れ(見捨てられた:abandoned)となったコネクションを回収する。
removeAbandonedTimeout="300" 利用不可能とみなすまでの時間を秒単位で指定する。
logAbandoned="true" 接続のcloseに失敗した場所をログに出力する。
vatddationQuery="select1" データベースによっては、接続を長時間維持していると、自動的に接続を切断する場合がある。コネクションプーリングでは、このようにして無効となった接続をアプリケーションに引き渡すのを防ぐために、あらかじめ検証クエリで接続が維持されているかを確認する。
testOnBorrow="true" プールから取得する前に、接続の有効性を確認する。ここで有効性が確認できない場合、SQLException がthrow される。
testOnReturn="true" 使用済接続をプールに返却する前に、接続の有効性を確認する。有効性が確認できない場合、接続はプールに保管されず破棄される。
testWhileIdle="true" 監視処理時、アイドル接続の有効性を確認する。有効性が確認できない場合、その接続はプールから削除される。
timeBetweenEvictionRunsMiltds="10000" これは接続監視スレッドで一定時間毎にプール内のアイドル接続をチェックする。
minEvictableIdleTimeMiltds="60000" 監視処理時、アイドル接続の生存期間をチェックする。アイドル接続が一定の期間使われなかった場合、その接続をプールから削除する。
【注意点】
DBCPのようにコネクションプールを実装するライブラリは、実際のConnection オブジェクトをラップしたクラスを用意します。そのラップしたクラスのオブジェクトのclose()メソッドを呼ぶとコネクションは実際にはクローズされず、プールに返却されます。 そして、クローズ漏れが発生すると、プールに戻らないコネクションが生まれてしまいます。 プールのコネクション数が上限に達し、不足した場合、後続のコネクション取得処理はプールから取り出すところで待ちとなります。そのため、無応答になってしまいます。 クローズ漏れを起こしたコネクションはどうなるのかですが、実コネクションに関しては、GCされたタイミングでfinalizeメソッドにより物理的なコネクションをクローズするように実装されています。しかし、DBCPのラッパーオブジェクトはfinalizeを実装しておらず、GCによってプールに戻ってくることもありません。
【解決方法】
BCPには、クローズ漏れ(見捨てられた:abandoned)となったコネクションを回収する仕組みが存在します。removeAbandonedを有効にすると、コネクションをプールから取り出す際に、“trace”リストにコネクションへの参照が格納されます。コネクションには、そのときの呼び出しのstackTrace情報が保存されます。 プールから取り出されたコネクションの数がプールの最大値(maxActive)に近づくと、コネクションの取得を要求したスレッドは、“trace”リストを基に、取り出しから一定時間たったコネクションを追跡、closeを呼ぶことでプールにコネクションを返却します。
次に、「ROOT/WEB-INF/web.xml」へ以下を追記してください。
<resource-ref>
        <description>MySQL Datasource</description>
        <res-ref-name>jdbc/heartcore</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
</resource-ref>

これでデータベースのコネクションプールを利用することが可能になります。

最後に、HeartCore設定画面の変更を行います。

「設定」>「システム」>「データベース」>「データベース接続」を選択し、「MySQL Database Server(Javaデータソースを使用して接続します)」を選択してください。

データベース接続オプション

そして、データベース接続のユーザ名・パスワード・データソースを、「server.xml」で設定した名前に変更して保存してください。

データベース接続

Apache-Tomcatの連携

Apache-Tomcatの連携部分の設定です(あくまで参考値です。実際のサーバー構成に合わせてください)
「Server.xml」を変更する事で、Apache-Tomcatの連携に関するパフォーマンスを上げることが可能です。

参考例は下記の通りです。何も設定がない場合には、必ず設定をしてください。ポート8009の部分を編集します。

<Connector port="8009" maxHttpHeaderSize="8192" maxThreads="600" minSpareThreads="25
" maxSpareThreads="100" enableLookups="false" redirectPort="8443" acceptCount="100
" connectionTimeout="20000" disableUploadTimeout="true" protocol="AJP/1.3" />

これで、パフォーマンスが向上します。

MySQLのチューニング

元々オープンソースであったMySQLですが、Oracle社が買収した後に、商用のデータベースとしてのEnterpriseと、オープンソースのCommunityの2つのバージョンが発生しました。基本的には同じ物ですが、Oracle社は差別化を行うために商用のEnterpriseにのみ、パフォーマンスを上げる高速化モジュール(スレッドプーリング)をリリースしています。
HeartCoreで利用される場合も、Communityと比べて2割から3割のパフォーマンスの差が出てきます。また、サポートも有るため、有償のMySQL Enterpriseの利用を推奨します。

データベースはInnoDBで構築してください。
高速化のために、「my.cnf」ファイル中の[mysqld]の項目に、スレッドプーリングの設定を行ってください。

plugin-load=thread_pool=thread_pool.so

上記を追記し、MySQLサーバーを再起動することで、スレッドプーリングの利用が可能になります。高負荷時に非常に力を発揮する設定です。