2012年5月30日水曜日

ASP.NET IIS で cron 的なジョブ処理を実行する

IISではcronのような機能はない。なので、代わりの方法についてご紹介します。

<検討案>
以下の手法が考えられる。今回推奨するのは、③。
1.普通にコンソールアプリケーションを作成し、タスクスケジューラーで実行
一番無難だが、Webサイト内の(App_Codeの)Entityやクラスなどは使えない。
プリコンパイルして参照を通すか、Webアプリケーションにしてしまうなどの対応があるが、特に前者の場合同期を取るのが面倒。

2.キャッシュの有効期限とコールバック関数を使用する
こちらで紹介されている手法。よく考えたな・・・と感嘆せずにはいられない。

ASP.NETでWindowsサービスのような機能を実装する方法

ただ、記事に書いてる通りちょっと危なっかしい。キャッシュクリアによるJOBの中断と、マルチスレッドによる複数回実行の危険性を考慮しておく必要がある。

3.Webサービスを作成して、VBScript/JScript Windows Power Shell からキックする
今回推奨案。直接サイト内に作成できるためApp_Codeのクラスが使用できるのと、起動自体はVBScript/JScriptから行うため、JOB実行はタスクスケジューラーで監視できる。

※Windows Power Shellを使用するとMSSOAP無しに実行できることが判明したので、推奨方法をこちらに切替(2012/6/21)


<推奨案:Webサービスを作成して、WindowsPowerShellからキックする方法>

以下のようなコードでサイトのWebサービスをキックできるので、これをタスクスケジューラーから実行すればよい。

<JOB用Windows Power Shellコードサンプル>
$web = New-WebServiceProxy -uri http://xxxx/yyyyy/サービス名.asmx?wsdl
$exe =  $web.サービスメソッド("引数",・・・)

参考 Windows PowerShell を使用して株価をすばやく確認する方法はありますか


<JOB用VBSコードサンプル(一応掲載)>
'Soap Toolkit 3.0を使用する場合"MSSOAP.SoapClient30"にする
Set SC = CreateObject("MSSOAP.SoapClient")

SC.ClientProperty("ServerHTTPRequest") = True
SC.MSSoapInit("http://xxxx/yyyyy/サービス名.asmx?wsdl")

'EndPointURLを指定しないとタイムアウトのエラーになることがある
SC.ConnectorProperty("EndPointURL") = "http://xxxx/yyyyy/サービス名.asmx"

SC.サービスメソッド(引数・・・)

Set SC = Nothing


※1 イントラネットから外部にアクセスする場合などで、プロキシを超える必要があるときはこれではNGになるので注意(色々なサイトで言われているConnectorPropertyによるプロキシ設定は、サービスにアクセスする前のプロキシに対して無力)。MSSOAP.HttpConnectorを使用してガチで書く必要がある。以下サイトをご参照ください。

Microsoft SOAP Toolkitを使ってJScriptでSOAP - 低レベルAPI (1) SoapConnector, SoapReader

上記サイトの補足となるが、呼び出すメソッドに引数を渡す場合は以下のようにしてやる。
soapSerializer.startElement("引数名",サービス名称空間,"","SOAPSDK1")
   soapSerializer.writeString("値")
  soapSerializer.endElement()

※2 MSSOAP.SoapClientはWindows7には入っていない?と思われる(Windows7 64bitでコードが動かないことを確認)。そのため、以下サイトからSOAP ToolKitをダウンロードする必要がある(コードを"MSSOAP.SoapClient30"にするのを忘れずに)。

Soap Toolkit 3.0

なお、64bitの場合vbsを作成するとデフォルト64bitで動作するため、32bitのdllであるこのツールを読み込むことができなくてエラーになる。
これを回避するには、32bit用のwscript/cscriptで実行をしてやる必要がある。場所は以下。

  C:\Windows\SysWOW64\wscript.exe / cscript.exe

ファイルのプロパティにあるプログラムの指定で32bitのほうを設定してやればよい。。。のだが、wscriptの方は何度指定してやっても64bitのほうになってしまうので(プログラム名が同名のため?)、32bit cscriptの方を指定してやるとうまくいく(実行できることに差はない)。

※3 windows7にこのtoolkitが入っていないのは、「これからは.NET Frameworkの方を使用してくれ」というお達しが出ているためである。そのため本ツールキットも開発が中止されているが、どうやらVB6が死に絶えるまでは大丈夫な模様。

開発ツール ライフサイクル Q&A

.NET FrameworkでのSOAPClientは事前にWeb参照を登録することが前提の開発のようで、VBScriptなどのスクリプト系言語にはかなりなじまずちょっと・・・という感じである(VBScriptから.NET Frameworkを使うこと自体は可能)

Hey.Scripting Guys

コンストラクタに引数あるときどうするの?という気もするが、渡せるのだろうか。


なお、本方式はWebサービスにアクセスする形態なので、当然サイトが生きていないとNGである点、またコネクションタイムアウトの時間を調整する必要がある点は要注意。
しかし、App_Codeとの連携と開発にVisual Studioが使えるメリットは大きいはず。



0 件のコメント:

コメントを投稿