2011年10月21日金曜日

DB接続プールから無効なコネクションを検知するように

久しぶりの更新です。
過去似たような問題が、ある案件に対応したようだが、
最近友人から、解決方法が聞かれたきっかけで
一応spring+mysqlを利用した場合の設定方法をブログにもメモしておきます。

以下spring設定ファイルの抜粋です
<beans>
...

  <!-- Local Apache Commons DBCP DataSource that refers to a combined database -->
  <!-- (see dataAccessContext-jta.xml for an alternative) -->
  <!-- The placeholders are resolved from jdbc.properties through -->
  <!-- the PropertyPlaceholderConfigurer in applicationContext.xml -->
  <bean id="dataSource"
    class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close">
    <property name="driverClassName"
      value="${jdbc.driverClassName}" />
    <property name="url" value="${jdbc.url}" />
    <property name="username" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />
    <!-- 最大接続数 -->
    <property name="maxActive" value="300" />
    <!-- <property name="maxActive" value="30" /> -->
    <!-- 未使用の接続を保持する最大数 -->
    <property name="maxIdle" value="10" />
    <!-- 未使用の接続を保持する最小数 -->
    <property name="minIdle" value="5" />
    <!-- maxActiveを超える接続要求に対するウェイトタイム ミリ秒(-1でタイム アウトなし) -->
    <!-- <property name="maxWait" value="1000" /> -->
    <property name="maxWait" value="10000" />
    <!-- The initial number of connections that are created when the pool -->
    <property name="initialSize" value="5" />

    <!-- クローズ漏れとなったコネクションを回収する。-->
    <property name="removeAbandoned" value="true" />
    <property name="removeAbandonedTimeout" value="60" />
    <property name="logAbandoned" value="true" />

    <!--
      MySQL側から強制切断されるコネクションがなくなるため、
      dbcpは常に接続されたコネクションを返してくるよう
      30分毎に監視をし、1時間使用されていないコネクションがあればプールから削除する
    -->
    <property name="timeBetweenEvictionRunsMillis" value="1800000" />
    <property name="minEvictableIdleTimeMillis" value="1800000" />


    <!-- プールから接続を取得する前に接続の有効性を確認 -->
    <property name="validationQuery" value="SELECT 1" />
    <property name="testOnBorrow" value="true" />
    <property name="testOnReturn" value="true" />
    <property name="testWhileIdle" value="true" />
    <property name="numTestsPerEvictionRun" value="5" />
  </bean>

...
</beans>

詳細設定はデータソースのクラス(本例はorg.apache.commons.dbcp.BasicDataSource)やDB(本例はMYSQL)により異なる可能性がありますが、APIを参考した上各自設定してください。

2011年2月14日月曜日

特定客先がサイトを閲覧すると白い画面のままになる問題について

クエリパラメータが付加されるGoogle、Yahooで検索。
検索結果をクリック。
ブラウザが白い画面になり、そのまま結果が返らない。

前提条件
・特定のお客様でのみ発生
・IE6でのみ発生
・全てのサイトが検索後に同じ症状になるわけではない

【発生原因について】
HTTP1.1 でクライアントがアクセスした場合、NetCacheがICAP連携している事により、
その返信には「Transfer- Encoding chunked」が使用されます。
(HTTP1.0のcontent lengthと比較して、データの終了を「0」として告げるもの)
NetCacheは全てのデータをクライアントへ返信していますが、
ブラウザ側がその受信内容(chunked data)を正しく処理できず、
この返信されたjavascript群が正しくIEにて処理されずに停止しているようです。

----------

調べたところ、あるjsonファイルのレスポンスが下記のようになっている

--------------------------------------------------------------------------------------
POST yyy.json
http://www.myserver.com/xxx/yyy.json

200 OK

myserver.com

52.7 KB

640ms

パラメータヘッダPOSTPUTレスポンスキャッシュHTMLJSON
レスポンスヘッダソース表示
Date Mon, 27 Dec 2010 10:51:56 GMT
Etag W/"269287-1293447004000"
Last-Modified Mon, 27 Dec 2010 10:50:04 GMT
Vary Accept-Encoding,User-Agent
Content-Encoding gzip
Keep-Alive timeout=10, max=289
Connection Keep-Alive
Transfer-Encoding chunked
Content-Type application/json
--------------------------------------------------------------------------------------

開発機で再現できないのは未だに謎です。。。
参考に、もしかしたら
http://ameblo.jp/phpwalker/entry-10444869607.html

apacheの設定にある

# deflate setting
# Insert filter
SetOutputFilter DEFLATE
# Netscape 4.x has some problems...
BrowserMatch ^Mozilla/4 gzip-only-text/html
# Netscape 4.06-4.08 have some more problems
BrowserMatch ^Mozilla/4\.0[678] no-gzip
# MSIE masquerades as Netscape, but it is fine
BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
# Don't compress images
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|zip|swf)$ no-gzip dont-vary
# Make sure proxies don't deliver the wrong content
Header append Vary User-Agent env=!dont-vary


SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|zip|swf)$ no-gzip dont-vary

SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|zip|swf|json)$ no-gzip dont-vary
と変更したら、レスポンスは下記のように変わりました。

Date Fri, 28 Jan 2011 08:43:58 GMT
Etag W/"228501-1296204003000"
Last-Modified Fri, 28 Jan 2011 08:40:03 GMT
Content-Length 228501
Keep-Alive timeout=5, max=74
Connection Keep-Alive
Content-Type application/json

うまく治りましたね、
これで、WWWへ公開してYahoooやGoogleから開いた場合に確認したいです。

2010年7月16日金曜日

MySQLのJDBCドライバーのバグでサービスダウン?

あるWEBシステム(apache+tomcat+struts2+Sping+iBatis+MySQL)
をリリースして、しばらく経ったら、頻繁にサービスダウンになって大ビンチ!

いろいろメモリーリーク調査や、設定のチューニングを行ったところ
大した効果が見えなかった。

偶然に、以下のURLが見つかりました
http://bugs.mysql.com/bug.php?id=25514

どうやら、MySQLのJDBCドライバーのバグのようで
バージョン5.0.3をやめ、5.1.xに切り替わったら
解決しました。

iBatisのバージョンにもよるかもしれませんが
JDBCドライバーのバージョンアップする際に、
iBatisの以下のような記述がNGこともわかったので
一応メモします

limit #row_count#
limit #offset#, #row_count#
limit #row_count# offset #offset#

上記の記述に使用する"#"がNGで、SQLのコンパイルエラーになってしまいます。
下記のように

limit $row_count$
limit $offset$, $row_count$
limit $row_count$ offset $offset$

"#" を "$" に変更したら、SQLのエラーがなくなりました。

世の中、このようなMySQLのJDBCドライバーの障害で
ひどい目にあった人は他にもあったのでしょうか。。。

2010年7月1日木曜日

ブログ名が指摘された。。。

「ブログ」だよ!「ブログ(blog)」!!
「プログ(plog)」ってなんだよ~

と指摘されました。。。

いやいや、それば「プロ(pro)」のブログだから
略称で「prog」ということです!

と言い訳をしました ^^;

2010年6月18日金曜日

ブラウザチェック用ツール

先月、作業用パソコンが変わりまして、OSがwindows7になりました
IEブラウザチェック用に、いままで Multiple IE を利用していたが、そいつXPしか動かない。

自分のwindows7がhome premiumなので、
XPモードを利用するにはXPのライセンスが必要、
いろいろ面倒くさくて、別のチェック用ツールを探しました。

そして「IETester」と出会いました
http://www.my-debugbar.com/wiki/IETester/HomePage
使ってみたら、問題なさそうで、よかった~

また、
http://spoon.net/browsers/
も使ってみました。
IE6の場合、たまに画面を開いた瞬間に落ちるケースもありますが、
それ以外はFFなど多数対応できるので
バックアップとして利用するつもりです。
プラグインのインストールが必要で、
http://www.hislab.net/blog/tools/spoon-browser-sandbox.html
には利用方法の説明があります。

URLリライトはjsessionidの対応を忘れないように

J2EEの仕様により、JSPの画面に貼り付くリンクが
生成方法により画面に表示されたら、
そのリンクのURLの末尾に";jsessionid=XXXXX"のようなものがつけられてしまうことがあります。
通常その情報がcookieにより送信するけれども、
ブラウザが閉じたまま、いきなりURLを開いた場合には
cookie対応されているかどうかの判断ができないようで、
そのような情報がURLに付加されます。

URLリライトを書く済に、
その内容の有無に関わらず正しくリライトできるように心がけないと、
画面の遷移がうまくできなくなったり、
予想外な画面に遷移してしまいます。

imageボタンのform二重送信に要注意

WEBアプリの画面デザインにはimageボタン(<input type="image" ...>)がよく利用されます。
仕様によって、onclick属性にjsの関数を記述して
その関数からform.submit()を呼び出して送信することもよくありますが、
imageボタン自身がformの送信も起こせますので、
ブラウザによってformの二重送信になってしまいます。
Firefoxでは特に問題ないですけど、
IEの場合には、容赦なく二重に送信してしまう。
解決方法としては

<a ... onclick="..." ><img src="..."></a>

のようにすることもいけますが、

<input type="image" ... onclick="xxx();return false;">

のようにimageボタンのonclickの最後に「return false;」
を付加する方法は一番シンプルを思います。