3

RoleEnvironment.Stopping/RoleEntryPoint.OnStop() は、ロール インスタンスの数を減らすと、瀕死のインスタンスに対して呼び出されません。これら、インスタンスの再起動時またはデプロイの停止時に呼び出されます。私は何を間違っていますか、またはこの場合、クリーンアップする必要はないのでしょうか?

私は単純なワーカー ロールを持っています (VS2012 更新 1、1 つのワーカー ロールを持つ既定のクラウド プロジェクト、smarx のテーブル ストレージ トレース リスナーが追加されました)。ここにすべてのコード。他の依存関係はありません:

using System;
using System.Collections.Generic;
using System.Data.Services.Client;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Threading;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.Diagnostics;
using Microsoft.WindowsAzure.ServiceRuntime;
using Microsoft.WindowsAzure.StorageClient;

namespace WorkerRole1
{
    public class WorkerRole : RoleEntryPoint
    {
        bool shouldRun = true;
        EventWaitHandle runFinished = new EventWaitHandle(true, EventResetMode.ManualReset);

        public override bool OnStart()
        {
            ServicePointManager.DefaultConnectionLimit = 12;
            RoleEnvironment.Stopping += (object sender, RoleEnvironmentStoppingEventArgs e) => {
                Trace.WriteLine("WorkerRole1 Stopping called", "Information");
                shouldRun = false;
            };
            return base.OnStart();
        }

        public override void Run()
        {
            runFinished.Reset();
            try {
                Trace.WriteLine("WorkerRole1 entry point called", "Information");
                while (shouldRun) {
                    Thread.Sleep(10000);
                    Trace.WriteLine("Working", "Information");
                }
                Trace.WriteLine("Finished", "Information");
            } finally {
                runFinished.Set();
            }
        }

        public override void OnStop()
        {
            Trace.WriteLine("OnStop: Waiting for Run() to finish", "Information");
            runFinished.WaitOne();
            Trace.WriteLine("OnStop: Run() finished", "Information");
            base.OnStop();
        }
    }

    public class LogMessage : TableServiceEntity
    {
        public DateTime Time { get; set; }
        public string Message { get; set; }
        public string InstanceId { get; set; }
        public string Category { get; set; }

        public LogMessage() { }
        public LogMessage(string message, string category)
        {
            Message = message;
            Category = category;
            Time = DateTime.UtcNow;
            InstanceId = RoleEnvironment.CurrentRoleInstance.Id;
            PartitionKey = RoleEnvironment.DeploymentId;
            RowKey = (DateTime.MaxValue.Ticks - Time.Ticks).ToString("d19");
        }
    }

    public class TableTraceListener : TraceListener
    {
        private TableServiceContext _context = null;
        private TableServiceContext context
        {
            get
            {
                if (_context == null) {
                    var tables = CloudStorageAccount
                        .Parse(RoleEnvironment.GetConfigurationSettingValue(
                            Attributes["connectionStringName"] ?? "DataConnectionString"))
                        .CreateCloudTableClient();
                    tables.CreateTableIfNotExist("log");
                    _context = tables.GetDataServiceContext();
                    _context.MergeOption = MergeOption.NoTracking;
                }
                return _context;
            }
        }

        protected override string[] GetSupportedAttributes() { return new[] { "connectionStringName" }; }

        public override void Write(string message, string category)
        {
            context.AddObject("log", new LogMessage(message, category));
            context.SaveChangesWithRetries();
        }

        public override void WriteLine(string message, string category) { Write(message + "\n", category); }
        public override void Write(string message) { Write(message, null); }
        public override void WriteLine(string message) { Write(message + "\n"); }
    }
}
4

1 に答える 1

2

私の実験では、ロールのスケールダウン操作中に (ロールが完全に削除される前に)、ファブリック コントローラーが DB サーバーの動的ホワイトリストからロール IP を削除するようです。

これが問題の原因でもある場合、可能性のある回避策は、IP 範囲 0.0.0.0-255.255.255.255 を DB サーバーのホワイトリストに手動で追加することです (ただし、セキュリティがいくらか犠牲になります)。または、OnStop 中に DB ではなくキューにデータ/メッセージを書き込むようにアプリケーションを再構築することもできます (worker ロールが後で DB にコピーするため)。

于 2013-07-16T14:51:23.690 に答える