【问题标题】:Does OnStart() have a maximum time limit?OnStart() 是否有最大时间限制?
【发布时间】:2011-07-26 17:26:59
【问题描述】:

我正在使用 AzureRubyRails sln,它是一个扩展 RoleEntryPoint 类的 WorkerRole。 我注意到我的应用程序到达特定点(就在复制之前),然后 Azure 决定重新启动角色,而无需在表日志中进行任何推理。是否有可能我在 OnStart 中超出了我的时间限制?

public override bool OnStart()
{
    try
    {
        LogInfo("Worker Role OnStart Entered");

        RoleEnvironment.Changing += RoleEnvironmentChanging;

        DiagnosticMonitorConfiguration dmc = DiagnosticMonitor.GetDefaultInitialConfiguration();

        dmc.Logs.ScheduledTransferPeriod = TimeSpan.FromMinutes(1);
        dmc.Logs.ScheduledTransferLogLevelFilter = LogLevel.Verbose;

        DiagnosticMonitor.Start("DiagnosticsConnectionString", dmc);

        this.roleId = RoleEnvironment.CurrentRoleInstance.Id;
        string outputContainer = RoleEnvironment.GetConfigurationSettingValue("OutputContainer");
        CloudStorageAccount storageAccount = CloudStorageAccount.Parse(RoleEnvironment.GetConfigurationSettingValue("StorageAccount"));
        CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
        this.container = blobClient.GetContainerReference(outputContainer);
        this.container.CreateIfNotExist();

        BlobContainerPermissions permissions = this.container.GetPermissions();
        permissions.PublicAccess = BlobContainerPublicAccessType.Container;
        this.container.SetPermissions(permissions);

        //Get the local Storage resources 
        LocalResource disk = RoleEnvironment.GetLocalResource("App");

        //Copy files across (log files and database are writeable)

        DirectoryInfo localStorageRoot = new DirectoryInfo(disk.RootPath);

        //Get the root of this role

        this.roleRoot = System.Environment.GetEnvironmentVariable("RoleRoot");
        this.roleRoot += "\\approot";

        try
        {
            LogInfo("Starting Git extract");
            var proc = new Process
            {
                StartInfo = new ProcessStartInfo(string.Format("{0}\\Ruby\\7za.exe", this.roleRoot), "x -oGit -y Git.7z")
                {
                    UseShellExecute = false,
                    WorkingDirectory = string.Format("{0}\\Ruby", this.roleRoot)
                },
                EnableRaisingEvents = true
            };
            proc.Start();

            proc.WaitForExit();
        }
        catch (Exception fErr)
        {
            LogError(fErr.Message);
        }

        try
        {
            LogInfo("Starting Git clone");
            var proc = new Process
            {
                StartInfo = new ProcessStartInfo(string.Format("{0}\\Ruby\\git\\bin\\git.exe", this.roleRoot), string.Format("clone git://github.com/callumj/InPerthAzure.git web_app", this.roleRoot))
                {
                    UseShellExecute = false,
                    WorkingDirectory = string.Format("{0}\\Ruby", this.roleRoot)
                },
                EnableRaisingEvents = true
            };
            proc.Start();

            proc.WaitForExit();
        }
        catch (Exception fErr)
        {
            LogError(fErr.Message);
        }

        string rubyFolderName = RoleEnvironment.GetConfigurationSettingValue("RubyFolder");
        this.rubyLocation = string.Format("{0}\\{1}", localStorageRoot.FullName, rubyFolderName);

        string rubySrc = string.Format("{0}\\{1}", this.roleRoot, rubyFolderName);

        try
        {
            LogInfo("Starting Ruby extraction");
            var proc = new Process
            {
                StartInfo = new ProcessStartInfo(Path.Combine(rubySrc, @"Ruby"))
                {
                    UseShellExecute = false,
                    WorkingDirectory = rubySrc
                },
                EnableRaisingEvents = true
            };
            proc.Start();

            proc.WaitForExit();
        }
        catch (Exception fErr)
        {
            LogError(fErr.Message);
        }

        LogInfo("Beginning copy");
        CopyFolder(string.Format("{0}\\{1}", this.roleRoot, rubyFolderName), this.rubyLocation);

        string appFolderName = RoleEnvironment.GetConfigurationSettingValue("AppFolder");
        this.appLocation = string.Format("{0}\\{1}", localStorageRoot.FullName, appFolderName);
        //CopyFolder(string.Format("{0}\\{1}", this.roleRoot, appFolderName), this.appLocation);

        string memcacheFolderName = RoleEnvironment.GetConfigurationSettingValue("MemcacheFolder");
        this.memcacheLocation = string.Format("{0}\\{1}", localStorageRoot.FullName, memcacheFolderName);

        //Get the local endpoint 
        LogInfo("Acquiring endpoint");
        this.endPoint = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["Server"].IPEndpoint;

        // Start the server

        LogInfo("Beginning bootup");

        BootApp();

        LogInfo("Worker Role OnStart Exited");
    }
    catch (Exception err)
    {
        LogError(err.Message);
    }
    return base.OnStart();
}

我发现它在我的本地开发人员计算模拟器上运行良好(但我认为这并不意味着什么)。

【问题讨论】:

    标签: .net azure


    【解决方案1】:

    我怀疑您的代码在角色中崩溃了,因为缺少一些依赖项。为了解决这个问题,我会尝试将您的代码拆分为一个带有大量 try/catch 的控制台应用程序。然后,我将使用 RDP 登录机器并尝试运行控制台应用程序。这将为您提供堆栈跟踪,并让您找出失败的地方。只需确保从与 RoleEntryPoint 相同的目录中启动它,以便它具有相同的相对路径。

    但一般来说,您会遇到的 OnStart() 中没有超时。您的角色看起来永远很忙,可能会被报告为“无响应”,但它仍会运行 OnStart。

    我的一般经验法则是,您的 OnStart 和 Startup 任务应该在 20 分钟内完成,否则您做的太多了。

    最后 - 因为你正在使用 Git 和诸如此类的东西 - 看看 Steve 的 smarxrole(bing it),因为它有所有启动的东西工作并且是这类事情的一个很好的起点。

    【讨论】:

    • 感谢 dunnry,我最终通过使用 GitSharp 执行简单的克隆来剥离在 OnStart 中执行的操作。我之前看过 Smarx 的解决方案,但它并不真正符合我的需求。
    猜你喜欢
    • 2014-11-18
    • 2011-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-20
    相关资源
    最近更新 更多