考虑到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使用模式有什么看法?
因此,您将程序集分组到目录中,每个目录获取一个服务实例,并且在每个服务实例中动态加载程序集并在一个actor中执行它?凉!服务实例是一个不错的选择,因为您可以根据需要动态创建和删除实例,因此您可以完全控制规模。我还看到了服务实例管理单个程序集执行的模式,这对于长时间运行的操作很有用。在你的情况下,演员对单个程序集工作良好,因为创建actor实例比服务实例快得多。 –
你在哪里存储组件? –
这是用于内部部署的,所以我一直计划使用文件共享。我也尝试过使用'Assembly.UnsafeLoadFrom'通过HTTP为动态程序集提供服务,到目前为止它的工作正常,只要Web服务器为程序集二进制文件返回适当的头文件('Cache-Control:max-age = 0,private '为我工作)。 –