您在哪里设置和访问服务结构的每个环境的运行时配置参数?

Posted

技术标签:

【中文标题】您在哪里设置和访问服务结构的每个环境的运行时配置参数?【英文标题】:Where do you set and access run-time configuration parameters per environment for service fabric? 【发布时间】:2016-02-28 22:24:08 【问题描述】:

对于本地和云两种环境,我将如何为 Sql 数据库、存储帐户等资源设置自定义设置或参数...理想情况下,它是在代码中调用的一个参数名称,即指向一个 DbContext对于特定数据库,本地或云环境的配置不同。谢谢你。

【问题讨论】:

虽然我希望他们包含实际使用配置的应用程序代码,但微软确实在以下文章中向您展示了如何设置它:docs.microsoft.com/en-us/azure/service-fabric/… 【参考方案1】:

为了获得在本地和云中运行 Service Fabric 的每个环境变量,您必须执行以下操作:

    将您的自定义配置部分和参数添加到 Service/Actor 项目的 Settings.xml 文件(位于项目根目录的 \PackageRoot\Config\Settings.xml)。将参数留空,因为我们将在每个环境的其他地方设置这些参数。这是一个示例。
<?xml version="1.0" encoding="utf-8" ?>
<Settings xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<!-- Add your custom configuration sections and parameters here -->
    <Section Name="UserDatabase">
        <Parameter Name="UserDatabaseConnectionString" Value="" />
    </Section>
</Settings>
    在 Service Fabric 项目的 ApplicationManifest.xml 文件中,每个包含的项目都有 &lt;ServiceManifestImport&gt; 元素。在其下方将是一个&lt;ConfigOverrides&gt; 元素,我们将在其中声明我们的配置的哪些值将被我们的 Service Fabric 项目中 ApplicationParameters 下的本地和云 xml 文件中的每个环境设置的值取代。在同一个 ApplicationManifest.xml 文件中,您需要添加将出现在本地和云 xml 文件中的参数,否则它们将在构建时被覆盖。

继续上面的示例,这就是它的设置方式。

<Parameters>
    <Parameter Name="ServiceName_InstanceCount" DefaultValue="-1" />
    <Parameter Name="UserDatabaseConnectionString" DefaultValue="" />
</Parameters>
<ConfigOverrides>
    <ConfigOverride Name="Config">
        <Settings>
            <Section Name="UserDatabase">
                <Parameter Name="UserDatabaseConnectionString" Value="[UserDatabaseConnectionString]" />
            </Section>
        </Settings>
    </ConfigOverride>
</ConfigOverrides>
    在 Service Fabric 项目的 ApplicationParameters 下的 local.xml 和 cloud.xml 文件中,您将像这样指定特定于环境的变量。
<?xml version="1.0" encoding="utf-8"?>
<Application xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="fabric:/AppFabricName.ServiceFabric" xmlns="http://schemas.microsoft.com/2011/01/fabric">
    <Parameters>
        <Parameter Name="ServiceName_InstanceCount" Value="1" />
        <Parameter Name="UserDatabaseConnectionString" Value="Server=(localdb)\MsSqlLocalDb;Database=Users;User=ReadOnlyUser;Password=XXXXX;" />
    </Parameters>
</Application>
    最后,在您的 Service/Actor 中,您可以像这样访问这些每个环境的配置变量。
var configurationPackage = Context.CodePackageActivationContext.GetConfigurationPackageObject("Config");

var connectionStringParameter = configurationPackage.Settings.Sections["UserDatabase"].Parameters["UserDatabaseConnectionString"];

【讨论】:

我可以说“糟糕!”。对于一个简单的基于环境的设置来说,这是无可救药的复杂化。这对于 SF 团队的一些开发工作来说已经成熟了。 不确定我缺少什么,但我的上下文没有 CodePackageActivationContext。我在我的无状态服务中看到它通过构造函数传递给 OwinCommunicationListener。但我不确定在 Actor 中的哪里可以找到它? 过早地询问。这里的cmets:azure.microsoft.com/en-us/documentation/articles/…指向使用这个:CodePackageActivationContext activationContext = FabricRuntime.GetActivationContext(); 这比实际的文档要好得多,谢谢!也同意这是非常令人费解的......修复这个SF团队! 我遇到了一个问题,这些设置没有被覆盖。您必须在ServiceManifestImportApplicationManifest 的子级)上方定义参数,但 ConfigOverrides 必须进入其中(ServiceManifestImport 的子级)。【参考方案2】:

您可以像使用任何其他应用程序一样使用 环境变量,这也适用于服务结构中的 guest 可执行文件,这与 settings.xml 不同,因为这需要内置服务结构运行时。

在您的应用程序中,您可以像访问任何其他 .net 应用程序一样通过 Environment 类上的 GetEnvironmentVariable 方法访问环境变量:

var baseUri = Environment.GetEnvironmentVariable("SuperWebServiceBaseUri");

然后我们需要设置一些默认的环境变量值,这是在服务的ServiceManifest.xml 清单文件中完成的。

<?xml version="1.0" encoding="utf-8" ?>
<ServiceManifest Name="MyServicePkg" Version="1.0.0" xmlns="http://schemas.microsoft.com/2011/01/fabric" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <!-- snip -->
    <CodePackage Name="Code" Version="1.0.0">
        <!-- snip -->
        <EnvironmentVariables>
            <EnvironmentVariable Name="SuperWebServiceBaseUri" Value="http://localhost:12345"/>
        </EnvironmentVariables>
    </CodePackage>
    <!-- snip -->
</ServiceManifest>

然后可以使用以下代码在 ApplicationManifest.xml 文件中覆盖这些环境变量:

<?xml version="1.0" encoding="utf-8"?>
<ApplicationManifest xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ApplicationTypeName="ChileTargetType" ApplicationTypeVersion="1.0.0" xmlns="http://schemas.microsoft.com/2011/01/fabric">
    <Parameters>
        <!-- snip -->
    </Parameters>
    <ServiceManifestImport>
        <ServiceManifestRef ServiceManifestName="MyServicePkg" ServiceManifestVersion="1.0.0" />
        <EnvironmentOverrides CodePackageRef="Code">
            <EnvironmentVariable Name="SuperWebServiceBaseUri" Value="https://the-real-live-super-base-uri.com/"/>
        </EnvironmentOverrides>
    </ServiceManifestImport>
    <!-- snip -->
</ApplicationManifest>

然后可以像使用 local.xmlcloud.xml 的任何其他应用程序清单设置一样对其进行参数化。

<?xml version="1.0" encoding="utf-8"?>
<Application xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="fabric:/AppFabricName.ServiceFabric" xmlns="http://schemas.microsoft.com/2011/01/fabric">
    <Parameters>
        <Parameter Name="MyService_SuperWebServiceBaseUri" Value="https://another-base-uri.com/" />
    </Parameters>
</Application>

然后我们必须更新ApplicationManifest.xml 以支持这些参数;

<?xml version="1.0" encoding="utf-8"?>
<ApplicationManifest xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ApplicationTypeName="ChileTargetType" ApplicationTypeVersion="1.0.0" xmlns="http://schemas.microsoft.com/2011/01/fabric">
    <Parameters>
        <Parameter Name="MyService_SuperWebServiceBaseUri" DefaultValue="https://the-real-live-super-base-uri.com/" />
    </Parameters>
    <ServiceManifestImport>
        <ServiceManifestRef ServiceManifestName="MyServicePkg" ServiceManifestVersion="1.0.0" />
        <EnvironmentOverrides CodePackageRef="Code">
            <EnvironmentVariable Name="SuperWebServiceBaseUri" Value="[MyService_SuperWebServiceBaseUri]"/>
        </EnvironmentOverrides>
    </ServiceManifestImport>
    <!-- snip -->
</ApplicationManifest>

【讨论】:

更简洁的环境变量设置方法 这个链接也帮助了我:binaryradix.com/2016/10/…【参考方案3】:

上面的答案很好地解释了它是如何完成的。我想加个边标,为什么是'convoluted':

必须采用这种方式,因为服务旨在实现自包含。默认情况下,它们应该在它们链接到的任何应用程序中运行。独立于应用程序的清单。所以服务只能依赖参数,这些参数至少是在自己的配置中预定义的。

这些预设可以被应用程序覆盖。这是唯一通用的方法。

【讨论】:

以上是关于您在哪里设置和访问服务结构的每个环境的运行时配置参数?的主要内容,如果未能解决你的问题,请参考以下文章

[K8s]Kubernetes-容器

Chrome SameSite=无;安全 Cookie 设置 - 您在第一方和第三方环境中访问的 Cookie

OSGI的系统服务

部署气流代码库

Eclipse 中的 Willdfly 8.1 运行时在哪里? [复制]

docker容器技术