Smile Engineering blog ( スマイルエンジニアリング・ブログ )

ジェイエスピーからTipsや技術特集、プロジェクト物語を発信します

Windows Azure Platform 事始め 第1回

2011-12-28 14:34:57 | Windows Azure
この記事は、Azureプログラミングの初心者用注意点について掲載します。
Windows Azure Platform(ウィンドウズ・アジュール・プラットフォーム)とは、マイクロソフトのクラウドプラットフォーム(PaaS)です。
そして、そのプラットフォーム上で動作するアプリケーションのプログラミングをAzureプログラミングと呼びます。

いきなり、Azureプログラミングの内容に入る前に、クラウドコンピューティングやWindows Azure Platformについて解説します。
記事は、複数回に分けて掲載する予定です。

■1 クラウドコンピューティングについて

(1)クラウドコンピューティングとは
 クラウドコンピューティングのクラウドとは、『雲』のことであり、ネットワーク(インターネット)を意味しています。
従来より「コンピュータシステムのイメージ図」ではネットワークを雲の図で表す場合が多かったため、それが由来と言われています。



 クラウドコンピューティングでは、ユーザ(企業、個人など)は、コンピュータ処理をネットワーク経由で、サービスとして利用します。
従来のコンピュータ利用形態としては、ユーザーがコンピュータのハードウェア、ソフトウェア、データなどを、自前で準備して保有・管理していました。それに対し、クラウドコンピューティングでは、ユーザーはインターネットの向こう側からサービスを受け、サービス利用料金を支払う形になります。具体的なサービスとしては、Webブラウザを利用して、ニュースを読んだり、オンラインショッピングをしたり、ブログやSNSなどで情報交換を行ったりするなどがあります。

 Webブラウザを使って利用できるこれらのWebサービスは、インターネットの向こう側に存在する無数のサーバーコンピュータによって運用されています。
無数のサーバーコンピュータは、ネットワーク接続されて大規模クラスタシステムを構成しています。そして、クラウドのためのソフトウェアを搭載することによって、1つの巨大なサーバーコンピュータが稼動しているように見せかけ、世界中の利用者からの膨大な量のリクエストを処理しています。

(2)クラウドコンピューティングの特徴
 主なクラウドコンピューティングの環境では、次のような特徴を備えています。

1.仮想化
 コンピューティングリソースを必要な分だけ利用することができる。

2.スケールアウト(接続されたサーバの台数を増やして処理能力を向上させること)
 需要の増減によって、コンピューティングリソースを追加・削除が可能なため、事前に行うべきコンピューティングリソースの需要予測が不必要である。

3.従量課金
 コンピューティングリソースを利用した分だけ料金を支払う。

 以上のような特徴から、最大のメリットとして挙げられるのは、コストに対する柔軟性です。
通常、新しいサービスを構築する場合、需要予測は大変難しいものになります。しかし、クラウドコンピューティングであれば、取りあえずサービスを構築して、コンピューティングリソースに関しては、需要を見ながら増減することが可能になります。
 現在クラウドコンピューティングが注目を集めている最大の理由は、コンピューティングリソースへの投資効率を向上させることができる点にあります。

(3)クラウドコンピューティングのテクノロジ
 クラウドコンピューティングのテクノロジは、コモディティ(メーカーごとの差・違いが不明瞭化したり、なくなること)ハードウェアを大量に利用することによって、膨大なコンピューティングパワーを低コストで調達する考えを実現したものです。
GoogleやAmazonなどの大規模Webサービスを提供している企業は、自社のサーバーに集まる膨大な数のリクエストを処理するため、このような膨大なコンピューティングパワーを持つ、情報インフラストラクチャが必要になります。しかし、コンピュータベンダーが提供する機能的にもコスト的にも高性能・高額なサーバーシステムを使用したのでは、設備コストの負担が重過ぎて事業が成立しません。
そこで、
 ハードウェア:パーツで購入し自社で組み立てる。
 ソフトウェア:オープンソースソフトウェアをベースにシステムを構築し、不足する機能は自社で開発する。
といった自給自足的な開発アプローチをとってきたようです。
 このような経緯により開発されたクラウドコンピューティングのテクノロジは、大規模自立分散システムの技術を基盤としており、技術的には、グリッドコンピューティングやユーティリティコンピューティングに類似しているようです。

1.レイヤーモデル
 クラウドコンピューティングのシステムアーキテクチャは事例ごとに異なっています。
現状では既存の事例をサービス種別で分類したXXX-as-a-Service(XaaS)式のレイヤーモデルで説明されることが多いようです。



◆SaaS(Software-as-a-Service:サービスとしてのソフトウエア)
 SaaSは、一般的なWebアプリケーションを提供する形態です。
従来のソフトウェア販売で中心となっていたのは、ソフトウェアをパッケージ製品としてユーザーにライセンス販売する形態であり、ユーザーは自分の持つコンピュータでそのソフトウェアを稼働させ、利用する形態でありました。
一方、SaaSでは、ソフトウェアを提供者側のコンピュータで稼働させ、ユーザーはそのソフトウェア機能をインターネットなどのネットワーク経由でサービスとして利用し、サービス料を支払う形態です。

●ユーザー側のメリット
・使用した期間・量だけのサービス料で済む。
・ユーザー側のコンピュータ導入・構築・管理などが不要(または最小限)になる、このため短期間での利用開始や、ユーザー数や処理量の急な増減にも対応しやすい。
・常に最新のソフトウェア機能を使用できる。

●提供者側のメリット
・新規ユーザーの獲得が容易である。
・ソフトウェアのみの販売よりも売上の向上・平準化になる。
・コンピュータ運用はスケールメリットと自社要員が生かせる。
・各ユーザー固有の導入や保守のサポートが軽減できる。

●デメリット
・プロバイダ側や通信回線、ネットワークの障害時には使用できない。
・セキュリティ上の懸念。
・ユーザー固有の仕様変更や運用変更は困難。
・長期利用の場合に割高となる可能性。
・クラウドが示す「インターネットの向こう側」がどこなのかが不明確なため、海外のデータセンターで運用されていた場合、データの損失などの問題が発生したときに、国内法が適用されないリスクもある。

◆PaaS(Platform-as-a-Service:サービスとしてのプラットフォーム)
 PaaSは、ソフトウェアを構築および稼動させるための土台となるコンピュータプラットフォームとそれを支援するサブシステムを、インターネット経由のサービスとして提供する形態です。
コンピューティングプラットフォームの導入や維持・管理に関わる煩雑でコストのかかる作業をサービスとして提供します。PaaSでのユーザは、開発者が対象になります。ユーザは、プラットフォーム上で構築したサービスを自分の顧客に提供することができます。
実際には、提供者側のデータセンターから提供される仮想化された開発・実行環境を利用し、ブラウザベースの管理ツールとともにインターネット経由でユーザは利用することになります。

 PaaSは、SaaSの発展形ともいわれており、業務ソフトなどをインターネット上のサービスとして利用できるようにするSaaSの考え方をさらに深化させたものです。 
実際、PaaS事業者はSaaS事業も同時に提供していることが多く、独自の業務アプリケーションをPaaS上に構築し、一般的なソフトはSaaSを利用する、といったように組み合わせて利用する場合が多いようです。

●メリット
・サービスを構築する場合、コンピュータのハードウェアやソフトウェアを購入し、システムを構築して管理・運用する必要がない。
・契約したその瞬間からアプリケーション構築に着手することができる。

●デメリット
・既存のソフトウェアを実行するためにはそれなりの移植作業が必要になる。

◆IaaS(Infrastructure-as-a-Service:サービスとしてのインフラストラクチャ
 コンピュータシステムを構築および稼動させるための基盤(仮想マシンやネットワークなどのインフラ)そのものを、インターネット経由のサービスとして提供する形態です。コンピュータハードウェアを提供しているイメージになります。
IaaSでのユーザは、開発者が対象になります。ユーザーはサーバやソフトウェアやデータセンターのスペースなどを自分で購入する代わりに、完全にアウトソースされたサービスとして購入することになります。そのサービスは利用レベルに応じた従量制で課金されます。

●メリット
・既存のソフトウェアをOSごとそのまま搭載することができるので、手が出しやすい。

●デメリット
・システムのスケールアップ(ダウン)やフェイルオーバーへの対応は、すべてプログラマ自身で実現しなければならない。

◆レイヤーモデルのまとめ
 各々のレイヤーモデルは、Webアプリケーションの構築を支援する独立した選択肢となります。
クラウドの利用者が独自のWebアプリケーションを構築する場合に、
・SaaSを使えばWebアプリケーションの機能の一部を流用することができる。
・PaaSを利用すればWebアプリケーションの実行環境とその開発環境一式を手にすることができる。
・IaaSを利用すれば従量課金でサーバーを調達することができる。

2.具体的な事例
 
◆Salesforce CRM(SaaS)
 Force.comのシステムは、コンピュータベンダーから調達したハードウェアとソフトウェアを利用して構築されており、リレーショナルデータベースのテクニックを駆使して実現しており、Applicationレイヤーにおいて仮想化を行っています。

◆Google App Engine(PaaS)
 Webアプリケーションの仮想エンジン、つまり抽象度が高いアプリケーションフレームワークのレベルでの仮想化を実現しています。プログラミング環境には、Python と Javaなどに対応しています。
利用者は原則的にWebアプリケーションとしての振る舞いを記述するだけで、システムのスケールアップ(ダウン)やフェイルオーバーへの対応はすべてシステムに委ねることができます。

◆Windows Azure(PaaS)
 ソフトウェアは特定の言語に依存しないCLRと呼ばれる仮想マシンで実行されるので、App Engineとは異なりプログラミングの自由度があります。しかし、EC2のように利用者自身がOSなどを直接操作できるわけではありません。
また、システムのスケジューリングやアベイラビリティ制御を自動化するための機能も提供されますが、App Engineのようにすべてをシステムに委ねてしまえるわけでもありません。

◆Amazon EC2(IaaS)
 抽象度の低い物理ハードウェアをシミュレートする仮想化方法を採用しています。利用者には普通のPCと同様に見えるので、基本的には手馴れた操作で扱えます。
また任意のOSを選択できるので、サービスを開発するプログラマの自由度は従来のプログラミングと同様に非常に大きくなります。

(4)プライベートクラウド
 プライベートクラウドとは、企業が自社内でクラウドコンピューティングのシステムを構築し、企業内の部門やグループ会社などに対してクラウドサービスを提供する形態のことです。



 本来クラウドコンピューティングは、パブリックなサービスにすることによって大量の利用者を収容し、「コンピューティングリソースの投資効率の改善」を提供しています。
しかし、「クラウドの技術は使いたいが、クラウドサービスを利用することができない」といったニーズもあります。
そのニーズとは、
・企業内の基幹システムのような事業戦略上、運用を他社に委ねることのできない情報システムである。
・事業者として遵守せざる得ない法令に対してクラウドサービス事業者からの保証を得られないケース。

 こういった、コストよりも優先しなければならないさまざまなニーズに対応するために、利用者自身でクラウド的なデータセンターを運用することを前提に、「購入可能なクラウド技術のパッケージ」としての製品が登場してきました。
これがいわゆるプライベートクラウドと呼ばれるシステムです。

●メリット
・運用管理の効率化が図れる。
・信頼できるセキュリティメカニズムを堅持できる。

●デメリット
・パブリッククラウドのような大きなスケールメリットはあまり期待できない。
・システム構築のイニシャルコストやランニングコストは従来どおり自社内の課題として残る。


今回は、『クラウドコンピューティングについて』を掲載しました。次回は、マイクロソフトが提供するPaaSである『Windows Azure Platformについて』を掲載いたします。

参考文献
Windows Azure入門

-------------------------
株式会社ジェイエスピー
システム部
鈴木真一郎
------------------------- 

monipet
  動物病院の犬猫の見守りをサポート
  病院を離れる夜間でも安心

ASSE/CORPA
  センサー、IoT、ビッグデータを活用して新たな価値を創造
  「できたらいいな」を「できる」に

OSGi対応 ECHONET Lite ミドルウェア
  短納期HEMS開発をサポート!

GuruPlug
  カードサイズ スマートサーバ

株式会社ジェイエスピー
  横浜に拠点を置くソフトウェア開発・システム開発・
  製品開発(monipet)、それに農業も手がけるIT企業

OSGiの最新仕様を追っかけろ【第2回】

2011-12-22 10:04:54 | OSGi

●はじめに第1回で仕様を確認したBundle Hook Serviceについて今回は実際にコードを書いて動作確認する。当初はEventHookサービスとFindHookサービスを載せる予定であったが、長いので2回に分けることにした。今回はEventHookサービスをとりあげる。FindHookサービスについては第3回にてとりあげる予定である。コードについては多少の手抜きがあるかもしれないがご容赦いただきたい。また、今回の動作確認ではフレームワークとしてFelix Framework 4.0.1を使用する。環境構築の手順は弊社HPを参照されたい。●EventHookサービスを試みろ今回はEventHookサービスの動作を確認する。EventHookサービスはBundleListenerへコールバックするBundleEventをフィルタリングする際に使用するサービスである。フレームワークがBundleListenerへのコールバック前にEventHook#event(BundleEvent, Collection)がコールされ、EventHook実装クラスによってフィルタリングされる。これにより、管理者が利用者に見せたくない管理用バンドル等のBundleEventを通知しないようにする、といったことが実現できる。今回、確認する内容は以下の通り。1.EventHookサービスなしでBundleEventが発生した場合の挙動2.EventHookサービスありでBundleEventが発生した場合の挙動3.event()の第2引数に指定されたCollectionにaddした場合の挙動4.event()にてフィルタリング処理の前に例外をスローした場合の挙動5.event()にてフィルタリング処理の後に例外をスローした場合の挙動これらの確認では以下のバンドルを作成する。・リスナバンドル1,2:BundleListenerを実装したバンドル・ターゲットバンドル:BundleEventの発生源となるバンドル・EventHook実装バンドル:EventHookを実装したバンドル<1.EventHookサービスなしでBundleEventが発生した場合の挙動>最初に、EventHookサービスがサービス登録されていない状態でBundleEventを発生させ、BundleListenerがコールバックされることを確認する。リスナバンドルとしてBundleListenerを実装したバンドルを作成する。---リスナバンドル1(Bundle-SymbolicName: listener.bundle1)---public class Activator implements BundleActivator, BundleListener {    public void start(BundleContext context) throws Exception {        context.addBundleListener(this);    }        public void stop(BundleContext context) throws Exception {        context.removeBundleListener(this);    }    public void bundleChanged(BundleEvent event) {        System.out.println("Listener 1 bundleChanged( event=" + event + " )");    }}----------------------これを複製し、bundleChangedメソッドの実装を以下のように変えて2つ目のリスナバンドルを用意する。---リスナバンドル2(Bundle-SymbolicName: listener.bundle2)---    public void bundleChanged(BundleEvent event) {        System.out.println("Listener 2 bundleChanged( event=" + event + " )");    }----------------------bundleChanged()がコールバックされた際に出力されるメッセージからどちらのバンドルがコールバックされたかがわかる。次にBundleEventを発生させる為にコントロールするターゲットバンドルを用意する。これはインストール出来ればなんでもよい。作成するもよし。既存のバンドルを利用するもよし。今回は空実装のバンドルを作成した。---ターゲットバンドル---public class Activator implements BundleActivator, BundleListener {    public void start(BundleContext context) throws Exception {    }        public void stop(BundleContext context) throws Exception {    }}------------------------これでバンドルの準備が完了した。リスナバンドル1,リスナバンドル2をインストール,スタートした後にターゲットバンドルをインストールする。(リスナバンドル1,2や後に作成するEventHook実装バンドルのコントロールによってもBundleEventは通知されるが、解り易くする為にターゲットバンドルのコントロールによって通知されるBundleEventのみ注目する。以降も同様。)---以下、出力内容---g! lbSTART LEVEL 1   ID|State      |Level|Name    0|Active     |    0|System Bundle (4.0.1)    1|Active     |    1|Apache Felix Bundle Repository (1.6.6)    2|Active     |    1|Apache Felix Gogo Command (0.12.0)    3|Active     |    1|Apache Felix Gogo Runtime (0.10.0)    4|Active     |    1|Apache Felix Gogo Shell (0.10.0)    5|Active     |    1|ListenerBundle1 (1.0.0)    6|Active     |    1|ListenerBundle2 (1.0.0)g!g! install http://localhost:8080/bundlehook/plugins/target.bundle_1.0.0.jarBundle ID: 7g! Listener 1 bundleChanged( event=org.osgi.framework.BundleEvent[source=target.bundle [7]] )Listener 2 bundleChanged( event=org.osgi.framework.BundleEvent[source=target.bundle [7]] )g!--------------------"Listener 1 bundleChanged"と"Listener 2 bundleChanged"が出力されており、双方のBundleListenerがコールバックされていることがわかる。<2.EventHookサービスありでBundleEventが発生した場合の挙動>次にEventHookサービスがサービス登録された状態でBundleEventを発生させ、BundleListenerのコールバックがフィルタリングされることを確認する。EventHookサービスを登録するバンドルを作成する。---EventHook実装バンドル---public class Activator implements BundleActivator {    public void start(BundleContext bundleContext) throws Exception {        EventHook service = new MyEventHook();        bundleContext.registerService(EventHook.class.getName(), service, null);    }    public void stop(BundleContext bundleContext) throws Exception {    }}class MyEventHook implements EventHook {    public void event(BundleEvent event, Collection contexts) {        System.out.println("MyEventHook#event() called.");        for (Iterator iterator = contexts.iterator();                 iterator.hasNext();) {            BundleContext bundleContext = iterator.next();            String symbolicName = bundleContext.getBundle().getSymbolicName();            if ("listener.bundle1".equals(symbolicName)) {                iterator.remove();                break;            }        }    }}---------------------------MyEventHook#event()の実装にて、Collectionの要素のBundleContextが、Bundle-SymbolicNameが"listener.bundle1"のBundleつまりリスナバンドル1のものである場合、イテレータから削除している。これによりリスナバンドル1はコールバックされないはずである。では準備ができたので、EventHook実装バンドルをインストール、スタートする。バンドルが起動した時点でEventHookサービスは登録されている。EventHook#event()がコールバックされると、BundleListenerのフィルタリング処理が行われリスナバンドル2のBundleListenerにのみ通知されるはずである。ターゲットバンドルをスタートしてみると、g! start 7MyEventHook#event() called.MyEventHook#event() called.g! Listener 2 bundleChanged( event=org.osgi.framework.BundleEvent[source=target.bundle [7]] )と出力され、もくろみ通りリスナバンドル2のBundleListenerにのみ通知された。<3.event()の第2引数に指定されたCollectionにaddしたした場合の挙動>次に、仕様書で"shrinkable collection"と記述されている、追加してはいけないCollectionのadd()をコールしてみる。仕様書ではUnsupportedOperationExceptionがスローされると記述されていた。EventHook実装バンドルを次のように改造する。---EventHook実装バンドル---    public void event(BundleEvent event, Collection contexts) {        System.out.println("MyEventHook#event() called.");        try {            contexts.add(event.getBundle().getBundleContext());        } catch (Exception e) {            e.printStackTrace();        }    }---------------------------コールバックされた際のcontextsにBundleEventが内包するBundleのBundleContextをaddしている。EventHook実装バンドルをアップデートし、ターゲットバンドルをストップする。---以下、出力内容---MyEventHook#event() called.java.lang.UnsupportedOperationException        at org.apache.felix.framework.util.ShrinkableCollection.add(ShrinkableCollection.java:38)        at event.hook.bundle.MyEventHook.event(Activator.java:60)…--------------------UnsupportedOperationExceptionがスローされていることが確認できた。<4.event()にてフィルタリング処理の前に例外をスローした場合の挙動>さて、3では例外をcatchしているが、catchしなかった場合どうなるのか。また、フィルタリング処理をする前,した後でコールバックされるBundleListenerに影響があるのかが気になった。まずは、フィルタリング処理前に例外をスローした場合の挙動を確認する。EventHook実装バンドル実装を次のように変える。---EventHook実装バンドル---    public void event(BundleEvent event, Collection contexts) {        System.out.println("MyEventHook#event() called.");        throw new NullPointerException();    }---------------------------実装のミスでNullPointerExceptionがスローされる。ありがちだ。EventHook実装バンドルをアップデートし、ターゲットバンドルをスタートする。---以下、出力内容---MyEventHook#event() called.MyEventHook#event() called.g! Listener 2 bundleChanged( event=org.osgi.framework.BundleEvent[source=target.bundle [7]] )Listener 1 bundleChanged( event=org.osgi.framework.BundleEvent[source=target.bundle [7]] )--------------------少なくともFelixの実装ではevent()から例外がスローされても他の処理に影響はださないようだ。安心。Equinox3.7.1でも試してみたが、結果は同じであった。こちらも安心。<5.event()にてフィルタリング処理の後に例外をスローした場合の挙動>最後に、フィルタリング処理後に例外をスローした場合の挙動を確認する。EventHook実装バンドル実装を次のように変える。---EventHook実装バンドル---    public void event(BundleEvent event, Collection contexts) {        System.out.println("MyEventHook#event() called.");        for (Iterator iterator = contexts.iterator();                 iterator.hasNext();) {            BundleContext bundleContext = iterator.next();            String symbolicName = bundleContext.getBundle().getSymbolicName();            if ("listener.bundle1".equals(symbolicName)) {                iterator.remove();                break;            }        }                throw new NullPointerException();    }---------------------------EventHook実装バンドルをアップデートし、ターゲットバンドルをストップする。---以下、出力内容---MyEventHook#event() called.MyEventHook#event() called.g! Listener 2 bundleChanged( event=org.osgi.framework.BundleEvent[source=target.bundle [7]] )--------------------フィルタリングされるようだ。●まとめ今回はド正常系1つといくつかの異常系の動作確認を行った。動作確認に使用したバンドルのEclipseプロジェクトはこちらからダウンロードできるので参考にしていただきたい。●次回の予定FindHookサービスの動作確認を試みる。株式会社ジェイエスピーシステム部齊藤 貴生



monipet
  動物病院の犬猫の見守りをサポート
  病院を離れる夜間でも安心

ASSE/CORPA
  センサー、IoT、ビッグデータを活用して新たな価値を創造
  「できたらいいな」を「できる」に

OSGi対応 ECHONET Lite ミドルウェア
  短納期HEMS開発をサポート!

GuruPlug
  カードサイズ スマートサーバ

株式会社ジェイエスピー
  横浜に拠点を置くソフトウェア開発・システム開発・
  製品開発(monipet)、それに農業も手がけるIT企業