ZipEngine 角色在“正在重启”和“忙碌”状态之间停滞

本文提供有关以下问题的故障排除信息:ZipEngine 角色在 “正在重启 ”和“ 忙碌 ”状态之间停滞,并引发异常,指出:无法加载文件或程序集“WorkerAssembly - 尝试加载格式不正确的程序”。

原始产品版本:API 管理服务
原始 KB 编号: 4464909

注意

请参阅 Azure 云服务故障排除系列文章,这是实验室的第一个方案。 请确保已按照针对压缩器应用程序的实验室设置说明重新创建问题。

症状

压缩器应用程序的 ZipEngine 角色实例在“重启”和“忙碌”状态之间不断循环,在“Azure 门户”边栏选项卡中引发以下未处理的异常:

Unhandled Exception: Could not load file or assembly 'WorkerAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. An attempt was made to load a program with an incorrect format. at ZipEngine.WorkerRole.OnStart() at Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.InitializeRoleInternal(RoleType roleTypeEnum) at Microsoft.WindowsAzure.ServiceRuntime.Implementation.Loader.RoleRuntimeBridge. <InitializeRole> b__0() at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart()'[2018-08-12T11:28:39Z] Last exit time: [2018/08/12, 11:28:39.434].

排查步骤问题

如果角色未启动,或者正在初始化、忙碌和停止状态之间回收,则每次角色重启时,代码可能会在某个生命周期事件中引发未经处理的异常。 因此,如果你仔细查看上面的调用堆栈,你会注意到,从辅助角色 的 OnStart () 方法中,存在未经处理的异常。 开始排查此类方案的最佳位置是检查 Microsoft Azure 事件日志,其中包含 Microsoft Azure 运行时的关键诊断输出,包括角色启动/停止、启动任务、OnStart 启动和停止、OnRun 启动、崩溃、回收等信息。

System.BadImageFormatException

Process ID: 5132
Process Name: WaWorkerHost
Thread ID: 4
AppDomain Unhandled Exception for role ZipEngine_IN_0
Exception: Could not load file or assembly 'WorkerAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. An attempt was made to load a program with an incorrect format.
at ZipEngine.WorkerRole.OnStart()
at Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.InitializeRoleInternal(RoleType roleTypeEnum)
at Microsoft.WindowsAzure.ServiceRuntime.Implementation.Loader.RoleRuntimeBridge.
<InitializeRole>
b__0()
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()

现在,你可以更详细地了解 Microsoft Azure 事件日志 中的异常,该异常指出,由于 System.BadImageFormatException,承载辅助角色的进程无法加载程序集“WorkerAssembly”。 通常,当进程无法加载程序集时,捕获 Fusion 日志始终是一种很好的做法。 在路径 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Fusion 下进行以下注册表项更改,以启用融合日志记录。 向 每个人授予 对融合日志路径文件夹 C:\FusionLogs的完全控制权限。

屏幕截图显示了 Fusion 下的注册表项。

检查“WorkerAssembly”的融合日志后,可能会获取详细信息,以便进一步进行故障排除。

*** Assembly Binder Log Entry  (8/12/2018 @ 12:51:00 PM) ***
The operation failed.
Bind result: hr = 0x8007000b. An attempt was made to load a program with an incorrect format.
Assembly manager loaded from:  D:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
Running under executable  E:\base\x64\WaWorkerHost.exe
--- A detailed error log follows. 
=== Pre-bind state information ===
LOG: DisplayName = WorkerAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
(Fully-specified)
LOG: Appbase = file:///E:/approot
LOG: Initial PrivatePath = E:\approot
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = RoleManager
Calling assembly : ZipEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: E:\approot\ZipEngine.dll.config
LOG: Using host configuration file: 
LOG: Using machine configuration file from D:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: Attempting download of new URL file:///E:/approot/WorkerAssembly.DLL.
LOG: Assembly download was successful. Attempting setup of file: E:\approot\WorkerAssembly.dll
LOG: Entering run-from-source setup phase.
LOG: Assembly Name is: WorkerAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
ERR: Invalid assembly platform or ContentType in file (hr = 0x8007000b).
ERR: Run-from-source setup phase failed with hr = 0x8007000b.
ERR: Failed to complete setup of assembly (hr = 0x8007000b). Probing terminated.

上述融合日志中突出显示的错误消息指出程序集的位数存在错误。 如果查看此 BadImageFormatException 文章,则此错误的最可能原因与以下相关:

“DLL 或可执行文件作为 64 位程序集加载,但它包含 32 位功能或资源。 例如,它依赖于 COM 互操作或调用 32 位动态链接库中的方法。 若要解决此异常,请将项目的 平台目标 属性设置为 x86 (,而不是 x64 或 AnyCPU) 和重新编译。”

为了找出程序集的位数,可以运行所选的任何 .NET 反编译程序。 在使用 ILSpy 反编译“WorkerAssembly”后,你可能会发现以下程序集。

这是 x86) (32 位程序集。

// C:\WorkerAssembly.dll
// WorkerAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// Global type:
<Module>
// Architecture: x86
// Runtime: .NET 4.0

Azure 是一个 64 位环境。 因此,为 32 位目标编译的 .NET 程序集在 Azure 上不起作用。 若要解决此异常,请将“WorkerAssembly”项目的 平台目标 属性设置为 x64 (,而不是 x86 或 AnyCPU) 和重新编译。

如果查看 ZipEngine 角色的WorkerRole.cs代码,你会注意到以下两行代码实际上正在加载程序集“WorkerAssembly”并执行某些功能。 由于它是 32 位程序集, 因此WaWorkerHost.exe 无法加载该程序集。

WorkerAssembly.WorkerAssembly workerAssembly = new WorkerAssembly.WorkerAssembly();
workerAssembly.DoWork();

联系我们寻求帮助

如果你有任何疑问或需要帮助,请创建支持请求联系 Azure 社区支持。 还可以向 Azure 反馈社区提交产品反馈。