discuss_ja@glassfish.java.net

Re: glassfishのTimerServiceについて

From: Shinya Ogino <Shinya.Ogino_at_Sun.COM>
Date: Thu, 19 Nov 2009 09:42:47 +0900

石橋さん、よかったです!

荻布

石橋 和洋 wrote:
> 石橋です。お疲れ様です。
>
> 本日まで3日ほど、連続してTimerが動作しています。
> 直ったと言っていいのではないかと!
>
> 相談に乗っていただき、本当にありがとうございました。
>
>
> 石橋 和洋 さんは書きました:
>> 石橋です。お疲れ様です。
>>
>> 時間があいてしまい、申し訳ありません。
>> お教えいただいた方法などを使って色々試してみた結果、どうやら状況が改善しました。
>>
>> interval1時間で、今のところ停止していません。
>>
>> SessionBeanに直接Timerへの参照を持っていた事が間違っていたようなので、これを
>> 修正したところ、Timerが停止しなくなったようです。
>> (これが直接の原因である証拠はありませんが、他に直したところもないので・・・)
>>
>> 新しいコードです。
>>
>> public void startTimer(Date startdate, long interval ){
>> Collection<Timer> timers = timerService.getTimers();
>> for(Timer t : timers){
>> if("ActionTimer".equals(t.getInfo())) t.cancel();
>> }
>> if(interval!=0){
>> timerService.createTimer(startdate, interval, "ActionTimer");
>> System.out.println("**** TIMER STARTED AT " + new Date());
>> }
>> }
>> //getTimer()は廃止
>> public boolean actiontimerIsAlive(){
>> Collection<Timer> timers = timerService.getTimers();
>> for(Timer t :timers){
>> if("ActionTimer".equals(t.getInfo())) return true;
>> }
>> return false;
>> }
>> //handleTimeoutは同じ
>>
>>
>>
>> 石橋 和洋 さんは書きました:
>>> お疲れ様です。石橋です。
>>>
>>> いろいろそちらでも調査頂いている様で、本当にありがとうございます。
>>>
>>> 私も調査をしていますが、なかなか本筋にたどり着けずにいます。
>>> ためしにNetBeansのプロファイルなども使ってみましたが、よく分かりませんでした。
>>>
>>> 今、試しにSessionBeanの@PreDestroyでログ出力させて、タイマーが動かなくなる時間との
>>> 関連を見てみたのですが、確かにSessionBeanの破棄とTimerの停止はあまり
>>> 関係なさそうです。
>>>
>>> 今、glassfishの管理画面を見ていて気がついたのですが、
>>>
>>> Configuration>EJB Container>EJB Timer Service
>>> というタグがあり、少し弄って見ようと思います。
>>>
>>>
>>>
>>> Shinya Ogino さんは書きました:
>>>> お疲れさまです。
>>>>
>>>> 助けになっておらずすみません。
>>>> ご存じかとは思いますが、管理コンソールで、
>>>>
>>>> 設定 > EJB コンテナ
>>>>
>>>> からプールの設定を変更することができます。また、
>>>>
>>>> 設定 > 監視
>>>>
>>>> にて EJB コンテナの監視レベルを例えば HIGH と設定しておくと、
>>>>
>>>> アプリケーションサーバー > 監視 > アプリケーション
>>>>
>>>> からご自身のアプリケーションの EJB の生成/破棄などの統計を
>>>> 見ることができます。念のため試しましたが、セッションビーンの
>>>> 生成/破棄が繰り返されても Timer の通知は継続してました。
>>>>
>>>> 以上、調査の助けになれば。
>>>>
>>>> 荻布
>>>>
>>>> 石橋 和洋 wrote:
>>>>> 石橋です。お疲れ様です。
>>>>>
>>>>> テストプログラムを作成して動かしたところ、特にTimerが落ちる問題は発生しませんでした。
>>>>> Timer周りのコードは殆ど同じなんですが・・・
>>>>>
>>>>> よく考えると、落ちるとtimerがnullになってしまっているという事は、別人が勝手にnullに書き換える
>>>>> 事はありえないんで(privateメンバですし)、StatelessSessionBeanインスタンスが別のものになって
>>>>> しまっている可能性が高いように思います。
>>>>>
>>>>> 以下想像ですが、
>>>>> Timer用のSessionBeanだけだと何も起きない事から考えると、他にいろいろなBeanが存在する状況でのみ
>>>>> 発生するように思えます。
>>>>> メモリの利用のせいなのか、スレッドプールの利用のせいなのかわかりませんが、それらの理由で
>>>>> SessionBeanが一旦消え、別のSessionBeanに切り替わった段階でエラーになる・・・のではないでしょうか。
>>>>>
>>>>> 10分というのは、きっとSessinBeanが死ぬまでの期間なんでしょうか。
>>>>> 本来は、TimerはSessionBeanと関係なく生き続けるはず・・・ですよね。
>>>>>
>>>>>
>>>>> 石橋 和洋 さんは書きました:
>>>>>> こんばんわ。
>>>>>> 石橋です。
>>>>>>
>>>>>> コメントアウトされているほうでも、発生しています。
>>>>>>
>>>>>> 今テストプログラム作成中です。。。
>>>>>> 少々おまちください。
>>>>>>
>>>>>>
>>>>>> Shinya Ogino さんは書きました:
>>>>>>> どうもありがとうございます。
>>>>>>>
>>>>>>> コメントアウトされている方の handleTimeout でも現象は起きますか?
>>>>>>>
>>>>>>>> (再現するためのプログラムという事は、アプリの部分ではなく、再現するための
>>>>>>>> 最小セットを作らないといけないと言う事ですよね・・・そちらも少しおまちを)
>>>>>>> 仮に GlassFish のバグとして報告することになった場合にも
>>>>>>> あると良いのでできればよろしくお願いします。
>>>>>>>
>>>>>>> 荻布
>>>>>>>
>>>>>>> 石橋 和洋 wrote:
>>>>>>>> 荻布さま。こんばんわ。
>>>>>>>> 早速のご返事ありがとうございます。
>>>>>>>>
>>>>>>>> 再現されませんか・・・ということはコードの問題なんでしょうか。
>>>>>>>>
>>>>>>>> ログにはなにも出力されていないようです。
>>>>>>>> server.logですが、現象が何時起きるのか監視が難しいのですが取ってみます。
>>>>>>>>
>>>>>>>>
>>>>>>>> コードは以下のとおりです。不足ありましたらご指摘ください。
>>>>>>>> (極力元のまま貼り付けます)
>>>>>>>> (再現するためのプログラムという事は、アプリの部分ではなく、再現するための
>>>>>>>> 最小セットを作らないといけないと言う事ですよね・・・そちらも少しおまちを)
>>>>>>>>
>>>>>>>> -------------------------------
>>>>>>>> @Stateless
>>>>>>>> public class ActionFacadeBean implements ActionFacade{
>>>>>>>>
>>>>>>>> @Resource
>>>>>>>> private TimerService timerService;
>>>>>>>>
>>>>>>>> private Timer timer = null;
>>>>>>>>
>>>>>>>> public void startTimer(Date startdate, long interval ){
>>>>>>>> Collection<Timer> timers = timerService.getTimers();
>>>>>>>> for(Timer t : timers) t.cancel();
>>>>>>>> if(interval==0){
>>>>>>>> timer = null;
>>>>>>>> return;
>>>>>>>> }
>>>>>>>> timer = timerService.createTimer(startdate, interval, null);
>>>>>>>> System.out.println("**** TIMER STARTED AT " + new Date());
>>>>>>>>
>>>>>>>> }
>>>>>>>> public Timer getTimer(){
>>>>>>>> return timer;
>>>>>>>> }
>>>>>>>>
>>>>>>>> /**
>>>>>>>> * アクションタイマーが実行されたときに、実行するメソッド。
>>>>>>>> *
>>>>>>>> * @param timer
>>>>>>>> */
>>>>>>>> @Timeout
>>>>>>>>
>>>>>>>> public void handleTimeout(Timer timer){
>>>>>>>> try{
>>>>>>>> Collection<TimerAction> actions = em.createNamedQuery("findTimerAction").getResultList();
>>>>>>>> for(TimerAction a : actions){
>>>>>>>> System.out.println("************実行中のタイマーアクション:"+
>>>>>>>> a.getId());
>>>>>>>> Collection<Apply> applies =
>>>>>>>> applyfacade.findApplyByStatus(a.getStatus());
>>>>>>>> a.fireAll(applies);
>>>>>>>> }
>>>>>>>> }catch(Throwable e){
>>>>>>>> System.out.println("************アクションタイマーの実行中にエラーが
>>>>>>>> 発生しました。");
>>>>>>>> e.printStackTrace();
>>>>>>>> }
>>>>>>>> }
>>>>>>>> /*
>>>>>>>> public void handleTimeout(Timer time){
>>>>>>>> System.out.println("*************TIMER WORK AT "+new Date());
>>>>>>>> }*/
>>>>>>>> -----------------------------
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> Shinya Ogino さんは書きました:
>>>>>>>>> 石橋さん、こんにちは。
>>>>>>>>>
>>>>>>>>> 少し試してみたのですが、こちらで再現できていません。
>>>>>>>>> 下記、連絡頂くことはできますか?
>>>>>>>>> - エラーなどがログに出力されていたらその内容
>>>>>>>>> domains/ドメイン/logs/server.log
>>>>>>>>> - 再現するためのプログラム
>>>>>>>>>
>>>>>>>>> 荻布
>>>>>>>>>
>>>>>>>>> 石橋 和洋 wrote:
>>>>>>>>>> お世話になります。石橋といいます。
>>>>>>>>>>
>>>>>>>>>> 最近本MLに加入しました。既メンバーの皆様、よろしくお願いします。
>>>>>>>>>>
>>>>>>>>>> 早速ですが、glassfishについて質問があります。
>>>>>>>>>> ご存知の方がおられましたらお教えいただきたいと思います。
>>>>>>>>>>
>>>>>>>>>> 製品のバージョン:
>>>>>>>>>> glassfish v2.1
>>>>>>>>>>
>>>>>>>>>> 質問の内容:
>>>>>>>>>> glassfishのTimerServiceを利用しているのですが、Intervalをきっかり600秒以上に
>>>>>>>>>> すると、2時間ほどでTimerが落ちてしまいます。600秒だと落ちずにずっと
>>>>>>>>>> 動き続けています。
>>>>>>>>>> これは、glassfishの仕様なのでしょうか?
>>>>>>>>>> 制限を解除するような設定などはないのでしょうか?
>>>>>>>>>>
>>>>>>>>>> よろしくお願いします。