ラベル tomcat の投稿を表示しています。 すべての投稿を表示
ラベル tomcat の投稿を表示しています。 すべての投稿を表示

2014年9月4日木曜日

tomcatのログローテート

logrotateコマンドを使用する方法


Amazon Linux、CentOS では、yum でインストール出来る。
Redhat系だったら導入は簡単ということ。他のディストリビューションは手元に無いので確認していない。

以下に設定ファイルを作成する。

/etc/logrotate.d

ファイルの名前で、logrorateを使っているアプリケーションがわかる。

ここでは、「/etc/logrotate.d/tomcat」とする。root で作業。

# vi /etc/logrotate.d/tomcat

# logrotate file for Tomcat
/opt/tomcat/logs/catalina.out {
  missingok
  copytruncate
  daily
  dateext
  rotate 60
}


オプションの整理



  • missingok:ログファイルが無くてもエラーを出さない
  • copytruncate:
  • daily:日でローテート
  • dateext:ファイル名末尾に日付をつける
  • rotate:残す世代数
  • compress:最新世代以外は圧縮
  • size:最大サイズを指定。最大になるとローテート


/etcc/cron.daily 配下のファイル logrotate がある。つまり、logrotateはcronによって毎日走る。

実行スクリプトがどこにあるかというと、logrotate.d にすべてのスクリプトが含まれる。

include /etc/logrotate.d



logrotateの強制実行


# logrotate -f /etc/logrotate.d/tomcat


cron.dailyの強制実行


# anacon -f

上記で、少なくとも logrotate と cron による実行確認可能。

サーバに設定して、動作確認すればOK。


accesslogの設定



catalina.outだけでなく、accessログも logrotate でローテートする場合は、tomcatが自動でローテートしないように以下の設定を行う。

        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="access_log." suffix=".txt" ←★ファイル名は access_log.txt に固定される
               rotatable="false" ←★ 自動ローテートをOFF
               pattern='%h %l %u %t "%r" %s %b %D "%{Referer}i" "%{User-Agent}i"' />

その後、tomcatのローテート設定にファイルを追加する。

# logrotate file for Tomcat
/opt/tomcat/logs/catalina.out
/opt/tomcat/logs/access_log.txt
{
  missingok
  copytruncate
  daily
  dateext
  rotate 60
}

2014年8月15日金曜日

tomcatアプリケーションの負荷テスト

tomcatアプリケーションを負荷テストするにあたって必要なことをまとめる。

負荷テストクライアント


負荷テストツールには、JMeter を使う。
メーカーにいた8年くらい前からずっとスタンダードなツール。

pluginは入れておいたほうが良い。

http://jmeter-plugins.org/downloads/all/


リスナーとしては、以下を表示しておくと良い。

  • jp@gc – Response Times Over Time
  • jp@gc – Transactions per Second
  • jp@gc – Active Threads Over Time
  • jp@gc – Composite Graph (上記の選択表示)


スループットを制御するには jp@gc - Throughput Shaping Timer を使う。

RPS(Requests Per Second) とその継続秒数を指定して、スケジューリングすることが可能だ。


JMeterでハマった点は、PUT Method で Body パラメータをPOSTと同様には送信出来ないことだ。
Body Dataに直接 {key}={value}&... と記述すると送信出来た。変な仕様。


監視ツール

VisualVM と JConsole を使う。

VisualVM
http://visualvm.java.net/ja/gettingstarted.html
http://itpro.nikkeibp.co.jp/article/COLUMN/20090902/336270/?ST=develop&P=1

JConsole
JDKに標準で付属する監視ツール。


負荷テスト中監視したいのは、リクエストに成功しているかどうか、とメモリ領域に異常が無いかどうかである。

リクエストに成功しているかは、以下で確認出来る。


  • JMeter:レスポンスを確認
  • VisualVM :ヒープサイズに異常が無いか
  • VisualVM:待機スレッドが不必要に増加していないか


メモリ領域は、OutOfMemoryの原因が潜んでいないかどうかを確認する。


  • PermSize
  • CodeCache

CodeCacheについて


Hotspot VM は 動的コンパイラ(Just in Time) の1つであり、よく使われるプログラム(Hotspot)の
メモリ上のバイトコードをメモリ上のネイティブコードに変換するキャッシュの仕組みである。

よく使われる部分について、ネイティブと同程度の性能を得られる。


PermSizeが不足したOutOfMemoryError


perm領域を食いつぶしていた話



運用しておいた方が良いパラメータ

以下のブログにまとめられている。


こちらも参考になる。
http://kohago.blogspot.jp/2013/09/jvm-memory-system-jconsole.html


負荷テストの時だけ有効にしておきたい設定


2014年8月14日木曜日

JavaServletサーバ設定

JavaのServletサーバを構築することがあったので、ついでに設定についてまとめておきます。

サーバの構成はレガシーです。


  • tomcat:Webアプリケーションサーバ
  • Jersey:JAX-RSの実装
  • Doma:ORM、DAO
  • DBCP:DB接続プール
  • MySQL:RDB


裏側、DBとアプリケーションの接続からまとめます。

DBCPを使ってDB接続プールを保持する場合の設定です。

ここでは、WEBアプリケーション直下にMETA-INFディレクトリを作成し、context.xmlを格納する方法を使い、以下のように記述します。


設定値は以下の意味を持ちます。
  • factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory" #dbcpのコネクションプーリングを使用する
  • initialSize="5" #プールの初期状態に確保するコネクション数
  • minIdle="1" #未使用の接続を保持する最小数
  • maxIdle="10" #未使用の接続を保持する最大数
  • maxActive="50" #最大接続数
  • maxWait="5000" #接続が取得出来るまでwaitする秒数
  • validationQuery="SELECT 1" #コネクションの有効性検証用クエリ
  • validationQueryTimeout="5" #検証クエリが失敗した場合に、再接続するまでの秒数
  • testOnBorrow="true" #trueの場合、プールからコネクションを取得する際に検証を行う
  • testWhileIdle="true" #trueに設定すると、監視スレッドがアイドル状態のコネクションの生存確認を行う際に、有効性確認も行う。検証に失敗した場合、プールから削除する。
  • timeBetweenEvictionRunsMillis="1800000" #指定した間隔で監視スレッドを起動する。監視スレッドはコネクションの生存確認を行う。デフォルトは 30 分以上アイドル状態のコネクションをプールから削除する。(設定値は30分)
  • numTestsPerEvictionRun="5" #プール無いで生存を確認するアイドル接続数
  • minEvictableIdleTimeMillis="86400000" #アイドル接続するミリ秒数 (設定値は24時間)
  • removeAbandoned="true" #クローズ漏れコネクションの自動切断
  • removeAbandonedTimeout="600" #クローズ漏れとみなすまでの秒数 (設定値は10分)


これら以外に設定することを悩んだパラメータがあります。


  • preparedStatementのキャッシュ(非採用)
poolPreparedStatements="false"がデフォルトです。設定しませんでした。理由は、統計情報によりキャッシュクエリを保持するため、有効になるかどうかは博打を打つようなもので、緊急の手段として用いるものです。

これで、DBCPによるコネクションプーリングが出来ました。最大接続数はアプリケーションの特性に合わせて決定すべきです。


続けて、表側のtomcatの設定をします。

その前に、JVMのメモリ領域について整理しましょう。

JVMのメモリ領域の種類

○ヒープ
New領域:インスタンス化されたオブジェクトの情報
Old領域:寿命の長いオブジェクトの情報

○非ヒープ
Permanent領域:JVMにロードされたクラスやメソッドの情報(基本GC対象外だが、ユーザ定義のクラスローダーが存在する場合は、ロード情報はGCされる。)

□New領域
Eden領域:オブジェクトがインスタンス化されてはじめて配置される領域
From領域:Scavenge GC時のオブジェクト退避領域1
To領域:Scavenge GC時のオブジェクト退避領域2

FromとToを合わせてSurvivor領域と呼ぶことがあります。

□GC
Scavenge GC:New領域のみを対象とするGC。比較的短時間。
 トリガーはEden領域が一杯になった時。
 Scavenge GCが実行されたら、不要なオブジェクトは破棄、必要なオブジェクトはTo領域へ。
 既にToに入っているオブジェクトはFrom領域へ、FromからはToへ移動する。
 To、From間の移動がMaxTenuringThreashold(default 32)を超えると、Old領域へ移動。

Full GC:Old領域及びPermanent領域を対象とするGC。処理時間は長い。
 トリガーはOldまたはPermanent領域が不足した時。実施中はシステムがほぼ停止状態になる。

OldとPermanetが肥大化しないように注意する。
  • オブジェクトをあまり使いまわさないことや、新しいオブジェクトを大量に使用するな、Newを大きくして、Oldに移動しにくくなるようにする。
  • Permanent領域については、staticメソッドを多用しないこと。

サーバーモード

○起動サーバモード
起動時に -server オプションを指定する。:サーバモードを有効化する。
 サーバーモード:プログラム実行速度が最大化するように調整される。
 クライアントモード:起動時間を退縮し、メモリサイズを縮小するように調整される。

○Permanent領域
-XX:MaxPermSize:Permanent領域の最大値。
-XX:PermSize:Permanent領域の初期値、MaxPermSizeと同じ値を設定。

Permanentサイズの設定は、OutOfMemoryエラー対策になる。デフォルトは64MBと小さいので、
必ず設定すること。

○New、Old領域
-XX:NewRatio:New領域とOld領域の比を設定する、サーバVMの場合、デフォルトが 2 である。つまり、New:Old = 1:2 となる。

-XX:SurvivorRatio:EdenとSurvivorの比。デフォルトはEden:8、From:1、To:1 である。


初期設定は以下。負荷試験によって変更すると良い。

-Xms2048m -Xmx2048m -XX:NewRatio=2 -XX:SurvivorRatio=8 -XX:PermSize=512m -XX:MaxPermSize=512m -server

2014年7月3日木曜日

Jersey で Restful API をつくる

Jersey で Restful な API を作成する。

前提知識として、JAX-RS をさらっと認識しておくと良い。
何故 REST なのか、REST の何がうれしいかを見ておく。

JAX-RS 1 について : http://www.coppermine.jp/docs/programming/2012/12/jaxrs1.html

JAX-RS 2 について : http://www.coppermine.jp/docs/programming/2012/12/jaxrs2.html


JAX-RS 2 を見るにあたっては、CDI も見ておくと良い。

CDI :: https://blogs.oracle.com/nishigaya/entry/javaee6_understanding_cdi_part_1


1 と 2 どちらを用いるかは、作成するアプリケーションの API の複雑性・多様性によって決めると良い。

テキストのみを扱うシンプルな API に JAX-RS 2 の仕様を実装するのもどうかと思う。

Jersey1


ここでは、JAX-RS 1 の実装である、Jersey 1系 を使って、Servlet 環境を作成する。

Jersey 1系の最新 1.18 を以下からダウンロードできる。

https://jersey.java.net/download.html


ダウンロードしたファイルを解凍して、以下を Tomcat プロジェクトのライブラリとして登録する。


  • asm-3.1.jar
  • jersey-client-1.18.jar
  • jersey-core-1.18.jar
  • jersey-json-1.18.jar
  • jersey-server-1.18.jar
  • jersey-servlet-1.19.jar
  • jsr311-api-1.1.1.jar

次に、web.xml を準備する。WEB-INF/web.xml を以下の様に作成する。




servlet タグには、servlet-name と対応する servlet-class を記載する。
これは、jerseyのクラスを設定する。init-paramには、jerseyを使うパッケージを設定する。

ここでは「jp.masazdream.scryi.server.api」である。
load-on-startup で、アプリケーションがコンテナにロードされるときに、初期化するよう設定する。

servlet-mapping では、servlet-name が一致した servlet にアクセスする url-patternを設定する。

ここでは、<アプリケーションコンテキスト名>/api/~ でアクセスする。

~ は、Jerseyによってアノテーションで記述する。

次に、jp.masazdream.scryi.server.api パッケージにクラスを記述する。



アノテーション「@Path」に続けて書いたのが、~部分である。
また、Doma を使った DAO 部分の記述をテストとして記述しているが、適当な文字列を返すほうがはじめの一歩の検証に良いだろう。


アプリケーションコンテキスト名は、Eclipse で作成したプロジェクトの場合、通常プロジェクト名がデフォルトで設定されるが、以下の手順で変更が可能である。

[プロジェクトプロパティ]-[Tomcat]-[全般タブ]-コンテキスト名

である。例えば、「test」と設定したとする。


Tomcatプロジェクト全般の設定については、以下が参考になる。

http://seesaawiki.jp/salyu/d/Eclipse%A4%CB%A4%AA%A4%B1%A4%EBTomcat%A4%CE%C0%DF%C4%EA

以上で、以下のURLからAPIをたたくことが可能である。

http://localhost:8080/test/api/communication



2013年5月30日木曜日

Tomcat Servletを簡単に使う

windowsでやったけど、Linuxでも同じだと思う。

■tomcatのcore版

http://tomcat.apache.org/download-70.cgi


適当なディレクトリに変更した後、

単体で動作するためには、
インストールディレクトリを環境変数CATALINA_HOMEとして登録。
binをPATHに追加。
JAVA_HOMEに使用するJDKを指定する。

その後、コマンドラインからstartup.batをたたくと、起動する。

以下のような標準出力があり、tomcat用のウィンドウが起動します。
ウィンドウにServer startup in ~msと出たらOKです。

Using CATALINA_BASE:   "C:\apache-tomcat\apache-tomcat-7.0.40"
Using CATALINA_HOME:   "C:\apache-tomcat\apache-tomcat-7.0.40"
Using CATALINA_TMPDIR: "C:\apache-tomcat\apache-tomcat-7.0.40\temp"
Using JRE_HOME:        "C:\Java\jdk1.7.0_07"
Using CLASSPATH:       "C:\apache-tomcat\apache-tomcat-7.0.40\bin\bootstrap.jar;
C:\apache-tomcat\apache-tomcat-7.0.40\bin\tomcat-juli.jar"

起動の確認は、localhost:8080にhttpアクセスします。


■Eclipseに統合
tomcat plugin
http://www.eclipsetotale.com/tomcatPlugin/tomcatPluginV33.zip

展開して、ディレクトリごとeclipseのpluginディレクトリ直下にコピー。

eclipseを起動(再起動)するとtomcatアイコンが追加されているはず。

起動したら設定のtomcatからパスを設定。

また、conf/tomcat-users.xmlに以下を追加して、guiでtomcatマネージャを
使用できる用に設定。

  <role rolename="manager-gui"/>
  <user username="admin" password="admin" roles="manager-gui"/>


■tomcatプロジェクト
tomcatプロジェクトを作成する。
tomcat用のディレクトリ構成は以下。

・WEB-INF/src・・ソースコードはここに置く。

・WEB-INF・・・・jar(ライブラリ)など外部からアクセスしないものを置く。

・work, bin, src・・とりあえずまだ使わない。

web.xmlはServletAPI3.0から必須では無いのでとりあえずは作らない。


WEB-INF/srcにパッケージを作成、Javaクラスも作成したら、まずはテスト。

ほとんどアノテーションで記述出来る。

@WebServlet(urlPatterns={"/AAA"})

これでwarパッケージ配下のurlを決定出来る。getもpostも簡単にサーバ側
APIの処理が実装出来る。楽しい。
目的はREST APIを簡単に実装することなので、次回はRESTを。