首页 文章

将azure web应用程序转换为azure网站

提问于
浏览
1

在我们公司内部,我们有一个相当大的服务应用程序作为azure cloudservice运行 . 该服务包含webrole和workerrole . webrole包含一个MVC应用程序,而workerrole正在后台运行 . workerrole用于处理几个大型进程和一堆24/7的小进程,每5分钟检查一次 .

我为这个应用程序创建了一个azure网站,并编写了一个小包装器类,用于检查是否需要从web.config文件或 Cloud 配置文件(.cscfg文件)中获取配置值 . 我添加了适当的转换来转换一些额外的设置并将应用程序发布到azure网站 .

到目前为止一切都很好,但我已经预料到的确实已经发生了...... Worker 不再工作并且正在抛出错误 . 我见过的第一个错误是;

Could not load file or assembly 'Microsoft.WindowsAzure.ServiceRuntime, Version=2.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.

所以当然我采取了快速解决方案并且去了'属性>复制本地'并将其设置为true . 将此发布到azure网站后,我收到以下错误;

Could not load file or assembly 'msshrtmi, Version=2.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.

我可以找出这个错误来自哪里,但感觉这是另外一堆错误中的第二个 . 在几个网站上我读过,azure网站不支持workerroles(显然) . 这给了我一些选择;

  • 找到解决方案,这样我就可以将azure网站连接到仍然在cloudservice中运行的workerrole . 如果这有效,我可以删除webrole,我可以将多个实例连接到一个workerrole .

  • 找到一个解决方案,将workrole转换成azure网站支持的东西(不知道这可能是什么) .

  • 忘掉整个想法,坚持使用web和workerrole进行cloudservice设置 .

Fragment from workerrole.cs

Facade进行数据库调用以检查任何新添加的进程 .

public override void Run()
    {

        // Only process if the web.config says we're allowed to do so.
        while (true)
        {
            var process = Convert.ToBoolean(WebConfigurationManager.GetSetting("Process"));
            try
            {
                if (process )
                {
                    var username = WebConfigurationManager.GetSetting("UsernameWorkerRole");
                    if (string.IsNullOrEmpty(username))
                    {
                        var version = Assembly.Load("Ecare.Productie.WorkerRole").GetName().Version;
                        var versionString = String.Format("{0}.{1}.{2}.{3}", version.Major, version.Minor, version.Build.ToString("000"), version.Revision.ToString("00000"));

                        username = ApplicatieConstanten.WorkerRoleName + " " + versionString;
                    }

                    IServiceFacade serviceFacade = new ServiceFacade(username);
                    serviceFacade.Start();
                }
            }
            catch (Exception ex)
            {
                AuditingLoggingHelper.GetLoggerInstance(ApplicatieConstanten.WorkerRoleName).Error("Exception while starting service", ex);
            }
            Thread.Sleep(10000);
        }

        // ReSharper disable once FunctionNeverReturns
    }

我们这样做的主要原因是因为我们的VS解决方案具有MVC应用程序(Web角色)和workerrole . 我们目前正在将此发布到azure的 Cloud 服务中 . 由于开发过程,我们正在运行单独的测试,接受和 生产环境 环境 . 由于这是一个沉重的过程,我们在天蓝色的机器上运行相当昂贵的机器,但这通常只需要 Worker . webpart很轻巧 . 因此,主要是尝试降低成本的想法 . 因此,我们的想法是将webrole转换为azure网站(这部分工作只需要进行一些小修改即可从web.config而不是cloudconfiguration中读取信息) . 但是 Worker 目前还没有工作,因为我们还没有改变任何东西 . 我的一位同事基本上说“为configpart编写一个包装器,将azurewebsite发布到一个或多个testenvironments并将它们指向同一个workerrole” . 但我怀疑这是否有可能..

有没有其他人遇到过这种情况并为此找到了解决方案?非常感谢任何寻求解决方案的帮助!

3 回答

  • 4

    找到一个解决方案,这样我就可以将azure网站连接到仍然在cloudservice中运行的workerrole . 如果这有效,我可以删除webrole,我可以将多个实例连接到一个workerrole .

    我猜你正在使用某种队列机制(Azure存储队列或服务总线队列)来促进Web和工作者角色之间的通信 . 如果是这种情况,那么你可以继续使用相同的 . 您的网站将推送队列中的消息,您的工作人员角色将轮询此队列并获取消息并对其进行处理 .

    找到一个解决方案,将workrole转换成azure网站支持的东西(不知道这可能是什么) .

    请看一下Azure Webjobs . 在Web Apps世界中,它们与Worker Roles相对应 .

    UPDATE

    基于这些评论,我认为您应该能够将代码移植到Web作业中 . 有两种方法可以做到:

    • 如果您创建 Continuous Web Job ,那么您必须在代码本身中放置这10秒的睡眠逻辑 . 这项工作将持续运行,但每10秒钟才会被唤醒 . 与您当前的Worker Role实现类似 .

    • 您可以通过将Web作业设置为 Scheduled Web Job 来从代码中取出这10秒睡眠逻辑,您可以计划每隔10秒运行一次 . 因为你已经解决了你的调度逻辑(10秒睡眠),我建议你沿着这条路走下去从你的申请 . 所以明天如果你要增加睡眠时间,你只需更改门户中的时间表而无需重新部署代码 .

  • 3

    正如Gaurav指出的那样,App Service空间中的工作者角色相当于Azure WebJobs .

    关于这个问题:

    到目前为止,一切都运作良好,但我已经预料到的确实已经发生了...... Worker 不再工作,并且正在抛出错误 . 我见过的第一个错误是;无法加载文件或程序集'Microsoft.WindowsAzure.ServiceRuntime,Version = 2.5.0.0,Culture = neutral,PublicKeyToken = 31bf3856ad364e35'或其依赖项之一 . 该系统找不到指定的文件 . 所以当然我采取了快速解决方案并且去了'属性>复制本地'并将其设置为true . 将此发布到azure网站后,我收到以下错误;无法加载文件或程序集'msshrtmi,Version = 2.5.0.0,Culture = neutral,PublicKeyToken = 31bf3856ad364e35'或其依赖项之一 . 该系统找不到指定的文件 .

    Microsoft.WindowsAzure.ServiceRuntime 特定于 Cloud 服务,不适用于Web应用程序(这就是您在Web应用程序中出现 msshrtmi 错误的原因) . 如果您仍在运行辅助角色,则该文件位于实例GAC中,并且也应位于本地计算机中 . 也就是说, Microsoft.WindowsAzure.ServiceRuntime 可以在worker角色项目中引用,但不能在Web应用程序项目中引用 .

    我猜你正在使用ServiceRuntime来获取一些配置设置值:

    var value = RoleEnvironment.GetConfigurationSettingValue(settingName);
    

    您可以将其更改为:

    var value = CloudConfigurationManager.GetSetting(settingName);
    

    因为此方法从相应的配置存储(from MSDN)中读取配置设置值 .

  • 0

    这里的 best 解决方案是将Worker Role转换为WebJob,如上面提到的@Graurav .

    如果要将Web App连接到Worker Role,则可以使用Azure Queue或其他中间存储,其中操作可以从WebApp中删除并由Worker Role获取 .

相关问题