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

时间:2015-08-04 12:01:37

标签: azure azure-web-sites azure-web-roles azure-webjobs

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

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

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

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.

所以当然我采取了快速解决方案并且去了'属性>复制local'并将其设置为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(显然)。 这给了我一些选择;

  1. 找到一个解决方案,这样我就可以将azure网站连接到仍然在cloudservice中运行的workerrole。如果这有效,我可以删除webrole,我可以将多个实例连接到一个workerrole。
  2. 找到一个解决方案,将workrole转换成azure网站支持的东西(不知道这可能是什么)。
  3. 忘掉整个想法,坚持使用web-workerrole进行cloudservice设置。
  4. 来自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的云服务中。由于开发过程,我们正在运行单独的测试,接受和生产环境。由于这是一个沉重的过程,我们在天蓝色的机器上运行相当昂贵的机器,但这通常只需要工人。 webpart很轻巧。因此,主要是尝试降低成本的想法。因此,我们的想法是将webrole转换为azure网站(这部分工作只需要进行一些小修改即可从web.config而不是cloudconfiguration中读取信息)。但是工人目前还没有工作,因为我们还没有改变任何东西。我的一位同事基本上说“为configpart编写一个包装器,将azurewebsite发布到一个或多个testenvironments并将它们指向同一个workerrole”。但我怀疑这是否有可能..

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

3 个答案:

答案 0 :(得分:4)

  

找到解决方案,以便将azure网站连接到workerrole   仍然在cloudservice中运行。如果这工作,我可以放弃   webrole,我可以将多个实例连接到一个workerrole。

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

  

找到将workerrole转换为某种东西的解决方案(不知道是什么   这可能是由天蓝色网站支持的。

请查看Azure Webjobs。在Web Apps世界中,它们与Worker Roles相对应。

<强>更新

根据评论,我认为您应该能够将代码移植到Web作业中。有两种方法可以做到:

  1. 如果您创建了Continuous Web Job,那么您必须在代码本身中放置这10秒的睡眠逻辑。工作将持续运行,但每10秒钟才会唤醒。与您当前的工作者角色实施类似。
  2. 通过将您的Web作业设置为Scheduled Web Job,您可以从代码中取出这10秒睡眠逻辑,并计划每隔10秒运行一次。我建议你沿着这条路走下去,因为你已经从你的应用程序中解耦了你的调度逻辑(10秒睡眠)。所以明天如果你要增加睡眠时间,你只需更改门户中的时间表而无需重新部署代码。

答案 1 :(得分:3)

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

关于这个问题:

  

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

     

无法加载文件或程序集“Microsoft.WindowsAzure.ServiceRuntime,Version = 2.5.0.0,Culture = neutral,PublicKeyToken = 31bf3856ad364e35”或其中一个依赖项。系统找不到指定的文件。

     

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

     

无法加载文件或程序集'msshrtmi,Version = 2.5.0.0,Culture = neutral,PublicKeyToken = 31bf3856ad364e35'或其依赖项之一。系统找不到指定的文件。

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

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

var value = RoleEnvironment.GetConfigurationSettingValue(settingName);

您可以将其更改为:

var value = CloudConfigurationManager.GetSetting(settingName);

因为此方法从适当的配置存储(from MSDN)读取配置设置值。

答案 2 :(得分:0)

这里的最佳解决方案是将工作者角色转换为WebJob,如上所述@Graurav。

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