简体   繁体   English

Azure云服务角色实例 - 自动缩放 - 更改事件未触发

[英]Azure Cloud Service role instances - auto-scaling - Changing event not firing

I got a Cloud Service deployment with 4 worker roles, one of which got auto-scaling enabled. 我获得了一个包含4个辅助角色的Cloud Service部署,其中一个角色启用了自动扩展。 As soon as auto-scaling occurs, all instances of all roles are recycling. 一旦发生自动缩放,所有角色的所有实例都将进行回收。

Ideally, I'd like to stop the roles from recycling or at least terminate the work of all other roles in a controlled way. 理想情况下,我想停止回收角色,或者至少以受控方式终止所有其他角色的工作。

I found out, that you can react to the RoleEnvironment.Changing event and cancel it to request a graceful shutdown (ie make OnStop being called). 我发现,您可以对RoleEnvironment.Changing事件做出反应并取消它以请求正常关闭(即调用OnStop)。 However, by adding tracing output to the Changing event handler, I noticed that the Changing event was obviously not even fired, so the cancellation was not being registered either. 但是,通过向Changing事件处理程序添加跟踪输出,我注意到Changing事件显然甚至没有被触发,因此取消也没有被注册。

private void RoleEnvironmentChanging(object sender, RoleEnvironmentChangingEventArgs e)
{
    // This tracing output does not show up in the logs table.
    Trace.TraceInformation("RoleEnvironmentChanging event fired.");
    if ((e.Changes.Any(change => change is RoleEnvironmentConfigurationSettingChange)))
    {
        // This one neither.
        Trace.TraceInformation("One of the changes is a RoleEnvironmentConfigurationSettingChange. Cancelling..");

        e.Cancel = true;
    }
    if ((e.Changes.Any(change => change is RoleEnvironmentTopologyChange)))
    {
        // This one neither.
        Trace.TraceInformation("One of the changes is a RoleEnvironmentTopologyChange. Cancelling.");

        e.Cancel = true;
    }
}

public override bool OnStart()
{
    // Hook up to the changing event to prevent roles from unnecessarily restarting.
    RoleEnvironment.Changing += RoleEnvironmentChanging;

    // Set the maximum number of concurrent connections
    ServicePointManager.DefaultConnectionLimit = 12;

    bool result = base.OnStart();

    return result;
}

Also adding an internal endpoint to each role did not bring the change. 此外,为每个角色添加内部端点并未带来更改。 Here the configuration from the .csdef: 这里是.csdef的配置:

<WorkerRole name="MyRole" vmsize="Medium">
[...ConfigurationSettings...]
<Endpoints>
  <InternalEndpoint name="Endpoint1" protocol="http" />
</Endpoints>
</WorkerRole>

Also changing the protocol to "any" wasn't successful. 将协议更改为“任何”也不成功。

How can I stop my role instances from recycling after a scaling operation? 如何在缩放操作后停止回收角色实例?

EDIT: 编辑:
» Included code snippets »包含的代码段
» Fixed typos »修正了拼写错误

Did you try one of the following? 你尝试过以下其中一种吗?

  • Check whether the event is being fired in the instances of role which is auto-scaling (to make sure its not a problem with the internal endpoint) 检查是否在自动扩展的角色实例中触发了事件(以确保它不是内部端点的问题)
  • Do a complete re-deployment (instead of update). 完成重新部署(而不是更新)。
  • Add a short Thread.Sleep() after the Tracing output in the event handler (sometimes the role is being shut down before the trace output can be registered) 在事件处理程序中的跟踪输出之后添加一个简短的Thread.Sleep()(有时在可以注册跟踪输出之前关闭角色)
  • Do a change in one of the configs via the management portal (and check whether event is being triggered) 通过管理门户对其中一个配置进行更改(并检查事件是否被触发)
  • Check whether the other events (for instance RoleEnvironment.Changed) are being fired 检查是否正在触发其他事件(例如RoleEnvironment.Changed)

Wow, over 2 years w/oa real answer here. 哇,超过2年没有真正的答案在这里。 Too bad. 太糟糕了。 My experience with the topic is: set e.Cancel to false if your instance is able to work after and while scaling without needed to be reconfigured. 我对该主题的体验是:如果您的实例能够在之后和缩放时工作而无需重新配置,则将e.Cancel设置为false。

if (e.Changes.Any(change => change is RoleEnvironmentConfigurationSettingChange)){
Trace.WriteLine("with recycle");
e.Cancel = true;
}
else {
Trace.WriteLine("without recycle");
e.Cancel = false;
}

Maybe you want to set Trace.AutoFlush = true at OnStart. 也许你想在OnStart上设置Trace.AutoFlush = true。

Role Environment Methods and Events There are five main places where you can write code to respond to environment changes. 角色环境方法和事件您可以在五个主要位置编写代码以响应环境更改。 Two of these, OnStart and OnStop, are methods on the RoleEntryPoint class which you can override in your main role class (which is called WebRole or WorkerRole by default). 其中两个,OnStart和OnStop,是RoleEntryPoint类的方法,您可以在主角色类中覆盖它们(默认情况下称为WebRole或WorkerRole)。 The other three are events on the RoleEnvironment class which you can subscribe to: Changing, Changed and Stopping. 其他三个是RoleEnvironment类上的事件,您可以订阅它们:更改,更改和停止。

The purpose of these methods is pretty clear from their names: 这些方法的目的非常清楚:

OnStart gets called when the instance is first started.
Changing gets called when something about the role environment is about to change.
Changed gets called when something about the role environment has just been changed.

Stopping gets called when the instance is about to be stopped. 当实例即将停止时,将调用Stopping。 OnStop gets called when the instance is being stopped. 在实例停止时调用OnStop。 In all cases, there's nothing your code can do to prevent the corresponding action from occurring, but you can respond to it in any way you wish. 在所有情况下,您的代码都无法阻止相应的操作发生,但您可以以任何方式对其进行响应。 In the case of the Changing event, you can also choose whether the instance should be recycled to deal with the configuration change by setting e.Cancel = true. 对于Changing事件,您还可以通过设置e.Cancel = true来选择是否应该回收实例以处理配置更改。

Why aren't Changing and Changed firing in my application? 为什么不在我的应用程序中更改和更改触发? When I first started exploring this topic, I observed the following unusual behaviour in both the Windows Azure Compute Emulator (previously known as the Development Fabric) and in the cloud: 当我第一次开始探索这个主题时,我在Windows Azure计算模拟器(以前称为开发结构)和云中观察到以下异常行为:

The Changing and Changed events did not fire on any instance when I made configuration changes. 当我进行配置更改时,更改和更改事件未在任何实例上触发。 RoleEnvironment.CurrentRoleInstance.Role.Instances.Count always returned 1, even when there were many instances in the role. 即使角色中有多个实例,RoleEnvironment.CurrentRoleInstance.Role.Instances.Count也始终返回1。 It turns out that this is the expected behaviour when a role has in no internal endpoints defined, as documented in this MSDN article. 事实证明,这是在角色没有定义内部端点时的预期行为,如本MSDN文章中所述。 So the solution is simply to define an internal endpoint in your ServiceDefinition.csdef file like this: 所以解决方案就是在ServiceDefinition.csdef文件中定义一个内部端点,如下所示:

<Endpoints>
  <InternalEndpoint name=”InternalEndpoint1″ protocol=”http” />
</Endpoints>

Which Events Fire Where and When? 哪些事件在何时何地发生? Even though the names of the events seem pretty self-explanatory, the exact behaviour when scaling deployments up and down is not necessarily what you might expect. 即使事件的名称看起来非常明显,但在上下调整部署时的确切行为并不一定是您所期望的。 The following diagram shows which events fire in an example scenario containing a single role. 下图显示了包含单个角色的示例方案中触发的事件。 2 instances are deployed initially, the deployment is then scaled to 4 instances, then back down to 3, and finally the deployment is stopped. 最初部署了2个实例,然后将部署扩展到4个实例,然后再降低到3个实例,最后部署停止。

taken from http://azure.microsoft.com/blog/2011/01/04/responding-to-role-topology-changes/ 取自http://azure.microsoft.com/blog/2011/01/04/responding-to-role-topology-changes/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM