2016-04-25 38 views
1

我正在考虑一个设计,其中“DynamicActors”能够从动态创建的AppDomain中的给定文件共享中加载和执行任意代码。像这样的伪独立AppDomain中的服务结构参与者

class DynamicActor: Actor, IDynamicActor 

    Task ExecuteAsync(string assemblyName, string typeName)  
    AppDomain appDomain = AppDomain.CreateDomain(...) 
    appDomain.SetData("AssemblyName", assemblyName) 
    appDomain.SetData("TypeName", typeName) 
    appDomain.DoCallBack(<load the type and execute a predefined/interface method>) 

的理由东西是能够经常更新的动态加载的代码,而无需升级DynamicActors服务。

这是一个好主意吗?

孤立AppDomain中的动态加载的代码是否可以使用SF运行时,例如创建一个代理并调用其方法?

感谢,

帕罗奥

回答

1

考虑到Vaclav的回答后,我决定转到下面介绍的“所有服务结构”路线。在此之前,让我告诉你一点有关的应用场景:

  • 将有数百实现无人值守的ETL型“任务”组件
  • 这些任务将定期执行,持续时间范围为几秒,最长一分钟。
  • 任务组件必须单独进行版本控制(包括它们的依赖关系),并且它们将经常进行版本控制。
  • 任务程序集不得在SF程序集上有依赖关系。

目标确实是使用Service Fabric群集来执行通过文件共享可访问的任何代码。

我已经在GitHub上提供了一个样本概念验证解决方案 - https://github.com/PaloMraz/ServiceFabricDynamicTaskExecution

注意:在下面的论述中,术语“任务”是指任何公共类的公共默认构造函数暴露的公共方法具有以下签名:

Task<string> ExecuteAsync(string parameters) 

样品溶液由以下几部分组成:

TaskExecutorActors含有TaskExecutorActor演员单ExecuteTaskAsync方法服务:

Task<string> ExecuteTaskAsync(string taskAssemblyPath, string taskClassName, string taskParameters); 

该实现使用Activator。CreateInstanceFrom API实例化指定程序集中的类,然后使用指定的参数调用ExecuteAsync方法。

TaskExecutorGateway是一种无状态服务,它公开Web API HTTP端点以便从群集外部调用。

TaskExecutorClientLib是包含与方法TaskExecutorClient类容易调用TaskExecutorGateway HTTP端点类库:

Task<string> ExecuteTaskAsync(string taskAssemblyPath, string taskClassName, string taskParameters) 

内TaskExecutorGateway此方法的实现使用目录名传入的taskAssemblyPath创建TaskExecutorActors服务的唯一实例以从目录中的程序集加载和执行任务。

一旦由TaskExecutorActors服务进程加载,任务程序集就被锁定并且不能被替换。为了更换组件,该TaskExecutorClient暴露了另一种方法:

Task<string> UnloadTaskAssembliesAsync(string assembliesFolderPath) 

实施(内TaskExecutorGateway)简单地删除按需创建“目录装订” TaskExecutorActors服务拆除其进程并释放了加载的程序集。

该解决方案包含两个示例任务程序集和一个代码超出整个基础结构的代码控制台项目TaskExecutorTestConsole

请注意:本TaskExecutorGateway暴露通过端口80的Web API,所以一定要确保,如果你在你的本地开发集群已经监听端口的其他应用程序来改变这个在ServiceManifest.xml和TaskExecutorTestConsole示例代码80.

你对这种SF使用模式有什么看法?

+0

因此,您将程序集分组到目录中,每个目录获取一个服务实例,并且在每个服务实例中动态加载程序集并在一个actor中执行它?凉!服务实例是一个不错的选择,因为您可以根据需要动态创建和删除实例,因此您可以完全控制规模。我还看到了服务实例管理单个程序集执行的模式,这对于长时间运行的操作很有用。在你的情况下,演员对单个程序集工作良好,因为创建actor实例比服务实例快得多。 –

+0

你在哪里存储组件? –

+0

这是用于内部部署的,所以我一直计划使用文件共享。我也尝试过使用'Assembly.UnsafeLoadFrom'通过HTTP为动态程序集提供服务,到目前为止它的工作正常,只要Web服务器为程序集二进制文件返回适当的头文件('Cache-Control:max-age = 0,private '为我工作)。 –

1

听起来并不像一个好主意,如果你只是想一个方法来升级你的演员服务代码。应用程序升级是服务结构中的核心方案,而服务结构很好。如果您使用动态装配加载来设计自己的设计,那么您必须考虑版本控制,运行状况监控,安全滚动升级,回滚等等,这些Service Fabric都已经完成了。

如果您正在寻找一个用户可以运行插件的“插件”模型,我可能会建议您查看专为此目的而设计的Managed Extensibility Framework