3

完全な IIS と複数のロール インスタンスを使用して、Windows azure エミュレーターでホステッド サービスを実行しようとしたことがありますか? 数日前、Web ロールの複数のインスタンスのうち、一度に 1 つのみが IIS で開始されることに気付きました。次のスクリーンショットは動作を示しており、スクリーンショットの前のメッセージ ボックスはこの動作の理由を示しています。IIS マネージャーで停止した Web サイトの 1 つを開始しようとすると、メッセージ ボックスが表示されます。

スクリーンショット: Web サイトが停止している IIS

サンプル クラウド アプリケーションには、MvcWebRole1 と WCFServiceWebRole1 の 2 つの Web ロールが含まれており、それぞれが 3 つのインスタンスを使用するように構成されています。私が最初に考えたのは、「確かに!実際の Azure の世界では、すべてのロール インスタンスが独自の仮想マシンであるため、ポートの競合は発生しません。エミュレーターでは機能しません!」というものでした。しかし、いくつかの調査と azure コンピューティング エミュレーターの多くの部分の分析の結果、コンピューティング エミュレーターがロール インスタンスごとに一意の IP を作成することがわかりました (私の例では 127.255.0.0 から 127.255.0.5 まで)。この MSDN ブログ記事 (http://blogs.msdn.com/b/avkashchauhan/archive/2011/09/16/whats-new-in-windows-azure-sdk-1-5-each-instance-in-any -role-gets-its-own-ip-address-to-match-compute-emulator-close-the-cloud-environment.aspx) は、Microsoft 従業員の Avkash Chauhan もこの動作について説明しています。なぜ計算エミュレーター (より正確には DevFC.exe) は、適切な役割の IP を各 Web サイトのバインディング情報に追加しないのですか?

私は手動で各 Web サイトに IP を追加しました。次のスクリーンショットは、変更されたバインディング情報が強調表示されていることを示しています。

スクリーンショット: Web サイトが開始された IIS

繰り返しますが、なぜエミュレーターは私のためにそれをしないのですか? 私は小さな静的ヘルパー メソッドを作成して、ロールの開始ごとにバインド拡張機能を実行しました。多分誰かがそれを使いたい:

public static class Emulator
{
    public static void RepairBinding(string siteNameFromServiceModel, string endpointName)
    {
        // Use a mutex to mutually exclude the manipulation of the iis configuration.
        // Otherwise server.CommitChanges() will throw an exeption!
        using (var mutex = new System.Threading.Mutex(false, "AzureTools.Emulator.RepairBinding"))
        {
            mutex.WaitOne();

            using (var server = new Microsoft.Web.Administration.ServerManager())
            {
                var siteName = string.Format("{0}_{1}", Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.CurrentRoleInstance.Id, siteNameFromServiceModel);
                var site = server.Sites[siteName];

                // Add the IP of the role to the binding information of the website
                foreach (Binding binding in site.Bindings)
                {
                    //"*:82:"
                    if (binding.BindingInformation[0] == '*')
                    {
                        var instanceEndpoint = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints[endpointName];
                        string bindingInformation = instanceEndpoint.IPEndpoint.Address.ToString() + binding.BindingInformation.Substring(1);
                        binding.BindingInformation = bindingInformation;
                        server.CommitChanges();
                    }
                    else
                    {
                        throw new InvalidOperationException();
                    }
                }
            }

            // Start all websites of the role if all bindings of all websites of the role are prepared.
            using (var server = new Microsoft.Web.Administration.ServerManager())
            {
                var sitesOfRole = server.Sites.Where(site => site.Name.Contains(RoleEnvironment.CurrentRoleInstance.Role.Name));
                if (sitesOfRole.All(site => site.Bindings.All(binding => binding.BindingInformation[0] != '*')))
                {
                    foreach (Site site in sitesOfRole)
                    {
                        if (site.State == ObjectState.Stopped)
                        {
                            site.Start();
                        }
                    }
                }
            }

            mutex.ReleaseMutex();
        }
    }
}

次のようにヘルパーメソッドを呼び出します

public class WebRole : RoleEntryPoint
{
    public override bool OnStart()
    {
        if (RoleEnvironment.IsEmulated)
        {
            AzureTools.Emulator.RepairBinding("Web", "ServiceEndpoint");
        }

        return base.OnStart();
    }
}
4

1 に答える 1

9

わかった!

最近、すべてフォーマットされ、クリーンな Windows 8、Visual Studio 2012、Azure SDK 1.8、および Azure Tools がインストールされた 3 つの異なるマシンでこの動作が発生しました。そのため、Azure SDK とツールを再インストールしても (Anton が示唆しているように)、何も変わらないはずです。しかし、私の3台のマシンの清潔さは重要なポイントです! アントン、VS2010 SP 1 以上がインストールされたマシンに Visual Studio 2010 がありますか? IISConfigurator.exeILSpy で解析したところ、Web サイトのバインディング情報の IP を'*'(ではなく127.255.0.*) に設定するコードが見つかりました。static プロパティに依存しますMicrosoft.WindowsAzure.Common.Workarounds.BindToAllIpsWorkaroundEnabled。Visual Studio 2010 の SP レベルが 1 より小さい場合、このメソッドは内部的に使用Microsoft.WindowsAzure.Common.Workarounds.TryGetVS2010SPVersionし、IP バインディングを に設定します。'*'TryGetVS2010SPVersion4つのレジストリキーをチェックし、理由はわかりませんが、キーの1つがレジストリに存在し、Visual Studio 2010 SPレベル0を返します(3台のマシンのいずれにもVS2010をインストールしたことはありません!!!)。HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\DevDiv\vs\Servicing\10.0\SP値を0 から 10に変更すると(0 より大きい値にする必要があります)、Azure Emulator127.255.0.*はロールの IP を IIS 内のすべての Web サイトのバインド情報に設定し始め、すべての Web サイトが正しく開始されます。

于 2012-12-19T17:39:03.673 に答える