2011年12月27日火曜日

新しい.NET PaaS

Iron Foundryっていうのがあるらしいですね。Tier 3っていうIaaSの会社が、Cloud Foundry(vmware発のオープンソースPaaSフレームワーク)を利用して、.NET PaaSを自社クラウド上のサービスとして提供。

Tier 3 Contributes .NET Framework Support for Cloud Foundry™ Platform as a Service to the Open Source Community « Tier 3 Company Blog

InfoQ: Tier 3がCloud Foundryで.NET Frameworkをサポート

この記事を見るまで、Cloud Foundryを全然しらなかったっす。面白いですね。IaaSのレイヤに依存しないPaaSフレームワーク。

なるほどー。面白そうついでにどんなものなのか、ちょびっとだけ触ってみました。触っただけなので中身はないです。具体的に知りたい(Cloud Foundryそのもの)場合は、ソースを見るといいかもね!

IronFoundry's Profile – GitHub

いろいろ試してたんですけどね、勝手が分からないっていうのもあるかもしれないけど、とにかく情報がNai!どーなんよ!

まずはIronFoundryのサイトからCloud Foundry ExplorerとVS2010用のVisual Studio Extensionをダウンロードしてインストール。

Sign upしてもSign inページもなくて「どーこー」。まぁね、サイトにサインインする場所なんか無いわけです。すべてツール経由。

手順はコミュニティサイトに書かれてるのでその通りにどーぞ。

Using the Cloud Foundry Explorer for Windows : Iron Foundry

ちなみに単体起動したCloud Foundry ExplorerとVS起動したものとで、プロファイルが共有されてないっぽい。ので、試すときはVSからの起動だけにしてしまいましょう。入力が2度手間。

んで、何より初期選択肢にIronFoundryのURLが登録されてない!(api.gofoundry.net)ので、そこから自分で登録。凄いね!さすが出たばっかり。その辺はご愛嬌。

試しに起動したサイトは↓こちら。

たけはらの国

分かりやすくServerVariables全部書き出しときました。

どういう設定になってるかというと↓こんなです。

if 

クリックして拡大してね。

右下がインスタンス。メモリ512MBのインスタンス4つ起動しました。なんでかというと、アカウントに2048MBシバリがあるから。それ以上のメモリを必要とするインスタンスは起動できなかったです。LOCAL_ADDRの値がInstanceのHostアドレスと同じものが繰り返し表示されることが確認できるのできちんと4つのインスタンスに振り分けられてるのがわかります。

if2

メモリは↑この中から選択して起動できました。インスタンスの合計が2048MBを超えなければいいので、インスタンス毎にメモリ容量が違っても起動できます。なるほどね。これって、どういうことですかね。AppDomainのメモリ上限指定なんでしょうか。超えるとリサイクルされるアレ。それともWeb.configに指定してるのかな?と思って、ちゃんとWeb.configがどういうふうになってしまうのか(変更されるはず)を見るためのページも用意。

if3

どこまで隠したほうがいいのかよく分からないから、一応それっぽいところはモザイク。各自で確認してみてね!

DBがSQLServer認証だから、ConnectionStringにuidとpwdが埋まったものが自動追加されてて、AppSettingsにイロイロ追加されます。AppSettingsの値を見て挙動を制御するといいようですが。なるほど。でも項目の意味がわかりません!

えと、パッと見、Web.configにはメモリ制限らしきものは無いですね。VM自体に割り当てるメモリ量なのかなー。それにしては起動がめちゃめちゃ早いのが気になる。その辺Cloud Foundryに詳しい人なら知ってるのかな。まぁ、いいや。

VCAP_SERVICES/VMC_SERVICESそれぞれの値の中にplan:freeっていうのが見えます。無料お試しアカウント!

最初のスクリーンショットの真ん中したが各種サービスの登録で、選択できるのはMSSQLとMongoDB。

if4

でも、MongoDBはエラーになって作れませんでした。んじゃ、MSSQLは?と思ってどんどこ作って行ったら10個までは何も言われずに作成できちゃいましたよ。どこまで作れるんだろ。怖くなって10個でやめちゃった。実際には、ServicesのアイテムをドラッグしてApplication Servicesにドロップして初めて利用可能になるみたい。なので、そういうふうにしたら、Web.configに"Default"って言う名前で接続文字列が追加されました。ココはまだちょっと不具合があるみたい。なんかちゃんと生成した文字列が追加されてる気がしない。DBの容量がいくらに制限されてるのかの情報も見つけられない...。すげーぜ!

ソースを確認してみると、ちゃんとサービスのクレデンシャルからInitial Catalogを指定するようになってたり、すでに"Default"って言う名前のものがあったら、そこに追加する(SqlConnectionStringBuilderを使ってる)ようになってるんだけど、そういう動きをしてくれない。

しょうがないので、接続文字列は自分で追加しておきました。追加される接続文字列を参考にDefaultConnectionっていう名前でね。なんか、VSからのデプロイ時に確定させたらPaaSのメリットが~、とは思うけど、いつかきっとちゃんと動くようになるはずだから、今はこれでもいいかな。ちなみにVSの発行機能とは別の機能(Cloud Foundryの機能)でデプロイされるから、Web.configの構成変更が全然動いてくれない。これもまた残念。ソースがあるんだからカスタムしちゃえばいいかもしれないけどね。試したいだけだからスルー。

で、結局Initial Catalogが分からないので、SQL実行ページを用意して、SQLServerに問い合わせ(Universal ProviderがInitial Catalog必須。デフォルトデータベースに指定があってもダメなんす)。

if5

なるほどね。そんな文字列なのか。ん?これってVCAP_SERVICESのcredentialsのnameの値。なるほど。ソースは正しくかかれてるんだね。ちゃんと生成してくれればいいのに。

後は、MachinKeyをちゃんとWeb.configに書きたして、晴れてログインまで動くようになりました。Sessionは...。まぁ、いいや。

Web.configの表示とSQL実行のコード

[Authorize(Users = "許可したいアカウント")]
public class SecretController : Controller
{
  public ActionResult Config()
  {
    var config = XDocument.Load(Server.MapPath("~/web.config"));

    return View(config);
  }

  public ActionResult Database()
  {
    var connectionString = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;
    ViewBag.ConnectionString = connectionString;

    return View();
  }

  [HttpPost]
  public ActionResult Database(string sql)
  {
    if (string.IsNullOrWhiteSpace(sql))
      return View();

    var response = new StringBuilder();
    var connectionString = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;
    ViewBag.ConnectionString = connectionString;

    using (var connection = new SqlConnection(connectionString))
    using (var command = new SqlCommand(sql, connection))
    {
      connection.Open();

      var reader = command.ExecuteReader();
      var table = new DataTable("result");
      table.Load(reader);

      var writer = new StringWriter(response);
      table.WriteXml(writer);
    }
    ViewBag.Database = response.ToString();
    return View();
  }
}

雑...。どんまい。

ConfigのView

@model System.Xml.Linq.XDocument

@{
    ViewBag.Title = "Config";
}

<h2>Config</h2>
<pre>
@Model.ToString()
</pre>

DatabaseのView

@{
    ViewBag.Title = "Database";
}

<h2>Database</h2>
ConnectionString: @ViewBag.ConnectionString
<h3>SQL</h3>
@using (Html.BeginForm())
{
    @Html.TextArea("sql",new{cols=80,rows=10})
    <button type="submit">実行</button>
}
<h3>Result</h3>
<pre>
@ViewBag.Database
</pre>

Iron Foundry自体ソースが公開されてるから、Tier 3じゃなくても自分で環境作って(SQLServer最新にしてMongoDBも最新にして、とか待たなくても自分で用意すれば解決するし)、実行環境にすることもできるので、コレはコレで面白い選択肢。知っといて損はなさそーですね。今後にも期待できそうだし!

追記

追跡調査の結果、メモリ制限はリサイクルのプライベートメモリ制限でした!

dotnetConf2015 Japan

https://github.com/takepara/MvcVpl ↑こちらにいろいろ置いときました。 参加してくださった方々の温かい対応に感謝感謝です。