【问题标题】:Replace WCF service library without restarting the service在不重新启动服务的情况下替换 WCF 服务库
【发布时间】:2011-06-24 14:02:02
【问题描述】:

我有一个托管在 Windows 服务中的 WCF 服务,并且我有 2 个程序集,即主机 (.exe) 和服务库 (.dll)。当服务库更新时,我们必须停止服务才能更换库。我想要 IIS 类似的功能,比如在不重新启动服务的情况下替换库。 有可能吗?如何实现?

【问题讨论】:

    标签: c# .net wcf iis windows-services


    【解决方案1】:

    IIS 使用称为卷影副本的东西来实现此目的。您可以为您的服务主机实现类似的东西。基本上,这个想法是在启动服务之前,将 .DLL 复制到其他位置并让主机从该副本加载您的服务类。然后主机设置一个文件系统监视器来监听对原始文件的更改。如果检测到一个,它会停止服务,复制新文件,然后重新启动。

    编辑

    (1) 要使用特定类型库中的类启动 ServiceHost,您必须使用反射。类似于以下内容:

    Assembly myAssembly = Assembly.LoadFile(path);
    
    Type serviceType = myAssembly.GetType(className);
    
    ServiceHost serviceHost = new ServiceHost(serviceType);
    

    从文档中不清楚 LoadFile 如何解决依赖关系。您可能需要挂钩 Assembly.ModuleResolve 事件才能完成这项工作。

    (2) 文件系统监视器肯定会产生一些开销,但根据我的经验,这是最小的。无论如何,这确实是您唯一的选择,除非您想使用更新 DLL 的安装程序。

    (3) 我不知道您的文件为什么被锁定。您必须自己解决问题。

    【讨论】:

    • 感谢彼得的分析员。只是想明白你的意思是主机重启,你的意思是无论如何都必须重启windows服务?
    • 没有。 Windows 服务应用程序永远不会重新启动。 “重新启动”意味着关闭托管服务的 ServiceHost 对象,复制新的 DLL,然后创建并启动新的 ServiceHost 对象。
    • 拥有很多这样的服务不是问题。我的意思是拥有大量文件观察器不会影响系统性能吗?以及如何告诉 ServiceHost 从确切的目录加载程序集。
    • @Peter 这不起作用,因为它不允许我复制已锁定的库。
    • 非常感谢彼得。我想出了如何使用程序集的临时副本来实现。你对我帮助很大。我发现 FCL 已经提供了用于卷影复制的 API,因此尝试检查它。谢谢!
    【解决方案2】:

    彼得有一个建议。根据大小以及您是否可以保证,另一种方法是将您的基础架构移动到至少 2 个集群服务器。这允许您一次更新一个,而其他(S)继续接受请求。只要您的版本正确(合同更改 == 新方法),这种方法就可以很好地工作,因为无论您的新位如何,旧客户端都会继续获得相同的数据。

    【讨论】:

    • 是的,集群服务器可能是一个实用的解决方案,但我对更换库感兴趣,而无需重新启动服务,无论是否出现中断。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-29
    • 2011-04-21
    • 1970-01-01
    • 1970-01-01
    • 2012-10-03
    • 1970-01-01
    相关资源
    最近更新 更多