博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
三步快速解决dll冲突问题
阅读量:6840 次
发布时间:2019-06-26

本文共 2636 字,大约阅读时间需要 8 分钟。

最近在推广应用我们的分布式服务网关(Web Api):业务组大部分对外的业务逻辑以HSF服务或者自定义扩展插件的方式,注册并发布到分布式服务网关中,统一对外提供WebApi服务。临时介绍下我们的分布式服务网关:

1. 一键注册、发布WebApi服务,

2. 统一管理发布WebApi服务,实现WebApi的服务化治理

3. 集成安全认证、加解密、监控、日志等Aspect

4. 流量安全控制:流控

5. 横向伸缩、弹性扩展,支持大规模并发 

6. 简化WebApi开发,提升开发效率,减少重复开发工作

在实际的开发应用中,业务逻辑dll要注册、发布到分布式服务网关中,例如参数类型、自定义扩展插件等。

每次业务的变更,都需要重新发布服务,例如实体类的注解(属性标签)发生变化,重新发布服务,分布式服务网关侦测到变化,重新加载。

同时,各个业务模块之间存在SPI层接口、实体类的依赖,例如:A中依赖B.Spi.dll, B发布了最新的B.Spi.dll, A未发布,这样会产生一个问题:

一个AppDomain中只能加载一个B.Spi.dll,如果先访问A服务,那么旧版本的B.Spi.dll就会先加载到AppDomain,此时,访问B服务时,就会出现dll冲突问题:

例如:

{"ErrorInfo":"数据序列化错误:程序集“***.Module.CarMdelAnalyse.SPI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null”中的类型“***.Module.CarMdelAnalyse.SPI.CarModelAnalyseResult”未标记为可序列化。r\rn   在 System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType type)\r\n   在 System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type type, StreamingContext context)\r\n   在 System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo()\r\n   在 System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector,  StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter, SerializationBinder binder)\r\n   在 System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Write(WriteObjectInfo objectInfo,  NameInfo memberNameInfo, NameInfo typeNameInfo)\r\n   在 System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph,  Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck)\r\n   在 System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers,  Boolean fCheck)\r\n   在 System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph)\r\n

类似的错误还有:

 未能加载文件或程序集“***.dll”或它的某一个依赖项

运行时如何快速定位到dll 冲突的根本原因,找到到底加载的dll是在GAC中、还是Bin中、还是指定目录中的dll?

有经验的老司机,分享给大家一个三步法,屡试不爽!!!

1. 找到程序主进程,右键:Create Dump File,如果IIS站点:指定应用程序池下的w3wp进程,如果自己的服务进程,直接找进程即可

2. 安装指定版本的Windbg(X86\X64), Ctrl+D 加载第一步抓的Dump文件,.loadby sos clr  -> !dumpdomain

3. 找到相关的dll文件路径,ILSpy,反编译定位问题,解决。

show:

1. 抓dump:通过上面的错误堆栈,我们定位到w3wp.exe,  右键创建转储文件

2. 安装Windbg, 请根据程序的32/64版本下载安装不同的Windbg,我们用的64位,因此用的Windbg是X64版本的。打开windbg,Ctrl+D, 加载刚才抓的dump文件

依次输入命令:.loadby sos clr  -> !dumpdomain

得到domain信息输出:

以ServiceStack.Redis.dll这个dll为例,可以找到在哪个路径下加载的dll:类似的找业务相关的dll即可:

3. 找到AppDomain加载的dll,拷贝,ILSpy:

windbg的确在内存镜像分析时是一个利器,赞一个!

 

周国庆

2017/4/23

posted on
2017-05-12 10:37 阅读(
...) 评论(
...)

转载于:https://www.cnblogs.com/yezuhui/p/6844394.html

你可能感兴趣的文章
项目启动时注意事项
查看>>
第37篇 Asp.Net源码解析(二)--详解HttpApplication
查看>>
Java的继承
查看>>
Tomcat7 配置 ssl
查看>>
HLG 1349 Graph [floyed]
查看>>
Java Array 常见报错
查看>>
条件注释判断浏览器版本<!--[if lt IE 9]>
查看>>
Switching JRE Version
查看>>
caffe之mac下环境搭建
查看>>
Redis系列-远程连接redis并给redis加锁
查看>>
记一次网易前端实习面试
查看>>
vue
查看>>
Windows 下端口被占用
查看>>
20130605
查看>>
JavaScript引擎研究与C、C++与互调用(转)
查看>>
Java中switch对整型/字符型/字符串型具体实现细节
查看>>
js制作倒计时效果
查看>>
HDU6315 Naive Operations(多校第二场1007)(线段树)
查看>>
Ubuntu架设FTP
查看>>
探索.NET中事件机制(续)——虚事件和事件重写问题,微软的Bug?!
查看>>