我们有一个IIS WCF服务,它以另一个用户的身份启动另一个进程(app.exe).我完全控制了两个应用程序(现在这是一个开发环境).IIS应用程序池以我的身份运行,域用户(DOMAIN \nirvin),也是该框的本地管理员.第二个进程应该作为本地用户运行(svc-low).我正在System.Diagnostics.Process.Start(ProcessStartInfo)
用来启动这个过程.该过程成功启动 - 我知道因为没有抛出异常,我得到了一个进程ID.但是进程立即死亡,我在事件日志中看到如下错误:
错误应用程序名称:app.exe,版本:1.0.3.0,时间戳:0x514cd763
错误模块名称:KERNELBASE.dll,版本:6.2.9200.16451,时间戳:0x50988aa6
异常代码:0xc06d007e
故障偏移:0x000000000003811c
错误进程id:0x10a4
错误应用程序启动时间:0x01ce274b3c83d62d
错误的应用程序路径:C:\ Program Files\company\app\app.exe
错误模块路径:C:\ Windows\system32\KERNELBASE.dll
报告编号:7a45cd1c-933e-11e2-93f8-005056b316dd
错误包全名:
错误包相关的应用程序ID:
我已经在app.exe(现在)中进行了非常彻底的日志记录,因此我认为它不会在.NET代码中引发错误(不再).
这是真正令人讨厌的部分:我认为我只是启动了错误的进程,所以我Process.Start()
在一个愚蠢的WinForms应用程序中复制了我的调用并在机器上像我一样运行它,希望能够修改,直到我得到正确的参数.因此,当然这是第一次和每次都有效:我能够始终如一地启动第二个流程并使其按预期运行.它只从IIS启动不起作用.
我已经尝试过"以批处理作业登录"的svc-low权限,并且我已尝试授予自己"替换进程级别令牌"(在本地安全策略中)的权限,但似乎都没有任何区别.
救命!
起初app.exe是一个控制台应用程序.尝试启动是让conhost.exe在事件日志中生成错误,因此我将app.exe切换为Windows应用程序.这让conhost脱离了这个等式,但是留给我这里描述的情况.(通过这个问题引导了这条道路.)
ProcessStartInfo
我使用的对象如下所示:
new ProcessStartInfo
{
FileName = fileName,
Arguments = allArguments,
Domain = domainName,
UserName = userName,
Password = securePassword,
WindowStyle = ProcessWindowStyle.Hidden,
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardOutput = false
//LoadUserProfile = true //I've done it with and without this set …
Run Code Online (Sandbox Code Playgroud) 我们继承了一个设计不太好的WCF服务,我们希望改进它.它的一个问题是它有超过一百种方法(在两个不同的接口上),其中大多数我们怀疑没有使用.我们决定对每种方法进行一些记录,以跟踪它们何时以及如何被调用.为了使跟踪代码重构友好且防止错误,我们实现了它:
public void LogUsage()
{
try
{
MethodBase callingMethod = new StackTrace().GetFrame(1).GetMethod();
string interfaceName = callingMethod.DeclaringType.GetInterfaces()[0].Name;
_loggingDao.LogUsage(interfaceName, callingMethod.Name, GetClientAddress(), GetCallingUrl());
}
catch (Exception exception)
{
_legacyLogger.Error("Error in usage tracking", exception);
}
}
Run Code Online (Sandbox Code Playgroud)
LogUsage()
然后在我们想要跟踪的每个方法的开头调用.
该服务的流量非常高,每天有500,000多个电话.99.95%的时间,这段代码执行得很漂亮.但另外0.05%的时间,GetInterfaces()
返回一个空(但不是null
)数组.
为什么GetInterfaces()
偶尔会返回不一致的结果?
这似乎是微不足道的 - 0.05%的错误率是我们通常只能梦想的.但重点是识别所有服务接触点,如果此错误总是来自一个(或几个)方法调用,那么我们的跟踪是不完整的.我试图通过调用服务上的每个方法在我的开发环境中重现此错误,但无济于事.
我正在使用具有枚举的外部库.这个枚举中有一些成员,当你调用ToString()
它们时,返回枚举的另一个成员的名字.
Console.WriteLine("TOKEN_RIGHT = {0}", Tokens.TOKEN_RIGHT.ToString()); //prints TOKEN_OUTER
Console.WriteLine("TOKEN_FROM = {0}", Tokens.TOKEN_FROM.ToString()); //prints TOKEN_FROM
Console.WriteLine("TOKEN_OUTER = {0}", Tokens.TOKEN_OUTER.ToString()); //prints TOKEN_FULL
Run Code Online (Sandbox Code Playgroud)
我知道当两个枚举成员具有相同的数值时,你可以得到这样的行为,但我知道,从反编译和检查运行时的值,枚举中的每个成员都有一个唯一的值.
这是enum定义的片段(由dotPeek生成):
public enum Tokens
{
TOKEN_OR = 134,
TOKEN_AND = 135,
TOKEN_NOT = 136,
TOKEN_DOUBLECOLON = 137,
TOKEN_ELSE = 138,
TOKEN_WITH = 139,
TOKEN_WITH_CHECK = 140,
TOKEN_GRANT = 141,
TOKEN_CREATE = 142,
TOKEN_DENY = 143,
TOKEN_DROP = 144,
TOKEN_ADD = 145,
TOKEN_SET = 146,
TOKEN_REVOKE = 147,
TOKEN_CROSS = 148,
TOKEN_FULL = 149,
TOKEN_INNER = 150, …
Run Code Online (Sandbox Code Playgroud) 我们有一个 Amazon S3 存储桶,其中包含大约一百万个 JSON 文件,每个文件的压缩大小约为 500KB。这些文件由 AWS Kinesis Firehose 放置在那里,并且每 5 分钟写入一个新文件。这些文件都描述了类似的事件,因此逻辑上都是相同的,并且都是有效的 JSON,但具有不同的结构/层次结构。它们的格式和行结尾也不一致:有些对象在一行上,有些在多行上,有时一个对象的结尾与另一个对象的开头在同一行(即,}{
)。
我们需要解析/查询/粉碎这些对象,然后将结果导入到我们的本地数据仓库 SQL Server 数据库中。
Amazon Athena 无法处理不一致的间距/结构。我想过创建一个 Lambda 函数来清理间距,但这仍然留下了不同结构的问题。由于文件是由 Kinesis 放置的,这迫使您将文件放入按年、月、日和小时嵌套的文件夹中,因此我们每年必须创建数千个分区。Athena 中分区数量的限制尚不清楚,但研究表明,如果我们每小时创建一个分区,我们很快就会耗尽这一限制。
我考虑过首先将数据输入 Redshift,然后将其拉下来。Amazon Redshift 外部表可以处理间距问题,但无法处理几乎所有这些文件都具有的嵌套 JSON。COPY
命令可以处理嵌套的 JSON,但要求我们事先知道 JSON 结构,并且不允许我们访问完整导入所需的文件名(这是我们获取日期的唯一方法)。总的来说,Redshift 与 Athena 存在同样的问题:不一致的结构导致难以定义模式。
我研究过使用 AWS Glue 等工具,但它们只是移动数据,无法将数据移动到我们的本地服务器中,因此我们必须找到某种中介,这会增加成本、延迟和维护开销。
我尝试过去掉中间人并使用 ZappySys 的 S3 JSON SSIS 任务直接拉取文件并将它们聚合在 SSIS 包中,但它无法处理间距问题或不一致的结构。
我不是第一个面对这个问题的人,但我只是一直在原地踏步。