Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么在Azure中进行扩展时不调用Stopping/OnStop?_Azure - Fatal编程技术网

为什么在Azure中进行扩展时不调用Stopping/OnStop?

为什么在Azure中进行扩展时不调用Stopping/OnStop?,azure,Azure,当我减少角色实例计数时,不会为即将死亡的实例调用roleenEnvironment.Stopping/RoleEntryPoint.OnStop()。在实例重新启动或部署停止时调用它们。我做错了什么,或者在这种情况下我不需要清理 我有一个简单的工作者角色(VS2012更新1,添加了一个工作者角色的默认云项目)。所有代码都在这里;没有其他依赖项: using System; using System.Collections.Generic; using System.Data.Services.C

当我减少角色实例计数时,不会为即将死亡的实例调用roleenEnvironment.Stopping/RoleEntryPoint.OnStop()。在实例重新启动或部署停止时调用它们。我做错了什么,或者在这种情况下我不需要清理

我有一个简单的工作者角色(VS2012更新1,添加了一个工作者角色的默认云项目)。所有代码都在这里;没有其他依赖项:

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"); }
    }
}

根据我的实验,在角色缩小操作期间(在角色完全删除之前),结构控制器似乎从DB服务器的动态白名单中删除了角色IP


如果这也是问题的原因,那么可能的解决方法是手动将IP范围0.0.0.0-255.255.255.255添加到DB服务器的白名单中(以牺牲某些安全性为代价)。或者,您可以重新设计应用程序,在OnStop期间将数据/消息写入队列,而不是DB(以便工作角色稍后复制到DB)。

好的,应该调用它们。有没有可能它们被调用了,出了问题,而你却看不到任何输出?@sharptooth,我不知道怎么做,但我怎么能检查?(所有代码都显示在我的问题中,程序不知道用于停止它的机制。在缩放期间,我可以看到来自主循环的日志消息,然后它们停止出现。在其他情况下,我看到各种启动/停止日志消息,主循环关闭。)可能有两个原因。首先,由于Azure SDK版本中存在某些错误,可能确实没有调用事件和方法(请注意,您没有指定版本号)。其次,Azure Diagnostics可能没有足够的时间传输日志,并且VM在传输日志之前被终止。无论如何,缩小比例时应调用停止/
在顶部
。@sharptooth,我使用的是SDK v1.8,但v1.7用于存储。我将日志记录放在表存储中(请参阅代码),因此Azure Diagnostics不涉及其中。Microsoft仍在调查中。我已经提交了一个不同的示例,它使用SQLAzure进行日志记录。