4. 服务实例

您可以在 App Broker 配置属性中配置服务的详细信息,包括要部署的应用程序、应用程序部署详细信息和要创建的后备服务。这些属性通常位于 .spring.cloud.appbroker.servicesspring-doc.cn

4.1. 配置 App Deployment

后备应用程序的部署详细信息可以在 Service Broker 的应用程序配置中静态配置,也可以使用服务实例参数和自定义实施动态配置。spring-doc.cn

4.1.1. 静态自定义

您可以使用 下的属性在 Service Broker 的应用程序配置中静态配置后备应用程序部署详细信息。spring.cloud.appbrokerspring-doc.cn

Properties 配置

您可以在 configuration 中指定应用程序部署属性。这些属性可以具有默认值和特定于服务的值。spring-doc.cn

对于 Cloud Foundry,您可以为 下的所有服务设置默认值,如下所示:spring.cloud.appbroker.deployer.cloudfoundry.*spring-doc.cn

spring:
  cloud:
    appbroker:
      deployer:
        cloudfoundry:
          properties:
            memory: 1G
            health-check: http
            health-check-http-endpoint: /health
            health-check-timeout: 180
            api-polling-timeout: 300

下表列出了可为所有部署或部署设置的属性:spring-doc.cn

财产 描述 违约

api-polling-timeoutspring-doc.cn

轮询的异步 CF API 调用的超时时间(以秒为单位)。spring-doc.cn

300spring-doc.cn

buildpackspring-doc.cn

用于部署应用程序的 buildpack。spring-doc.cn

buildpacksspring-doc.cn

用于部署应用程序的 buildpack 列表。spring-doc.cn

domainspring-doc.cn

映射应用程序路由时使用的域。spring-doc.cn

domainsspring-doc.cn

映射应用程序路由时要使用的域列表。spring-doc.cn

health-checkspring-doc.cn

要对已部署的应用程序执行的运行状况检查的类型(如果未按应用程序覆盖)。spring-doc.cn

港口spring-doc.cn

health-check-http-endpointspring-doc.cn

http 运行状况检查将使用的路径。spring-doc.cn

/健康spring-doc.cn

health-check-timeoutspring-doc.cn

运行状况检查的超时值(以秒为单位)。spring-doc.cn

120spring-doc.cn

javaOptsspring-doc.cn

用于部署应用程序的 javaOpts。spring-doc.cn

memoryspring-doc.cn

用于部署应用程序的内存。spring-doc.cn

no-routespring-doc.cn

如果应用程序不需要路由spring-doc.cn

spring-doc.cn

route-pathspring-doc.cn

用于部署应用程序的 route-path。spring-doc.cn

routesspring-doc.cn

用于部署应用程序的路由。spring-doc.cn

stackspring-doc.cn

用于部署应用程序的堆栈。spring-doc.cn

您可以在 服务配置中的 下为特定服务设置覆盖值,如下所示:spring.cloud.appbroker.services.*spring-doc.cn

spring:
  cloud:
    appbroker:
      services:
        - service-name: example
          plan-name: standard
          apps:
            - name: example-service-app1
              path: classpath:app1.jar
              properties:
                memory: 2G
                count: 2
                no-route: true

下表列出了可以为所有或特定应用程序部署设置的属性:spring-doc.cn

财产 描述 违约

countspring-doc.cn

memoryspring-doc.cn

diskspring-doc.cn

hostspring-doc.cn

targetspring-doc.cn

domainspring-doc.cn

为已部署的应用程序映射路由时要使用的域。 和 与 互斥。domainhostroutesspring-doc.cn

routesspring-doc.cn

要将已部署的应用程序绑定到的路由。spring-doc.cn

health-checkspring-doc.cn

要对已部署的应用程序执行的运行状况检查的类型。spring-doc.cn

PORTspring-doc.cn

health-check-http-endpointspring-doc.cn

HTTP 运行状况检查使用的路径。spring-doc.cn

/healthspring-doc.cn

health-check-timeoutspring-doc.cn

运行状况检查使用的超时值(以秒为单位)。spring-doc.cn

120spring-doc.cn

api-timeoutspring-doc.cn

用于阻止 API 调用的超时值,以秒为单位。spring-doc.cn

360spring-doc.cn

api-polling-timeoutspring-doc.cn

用于轮询异步 API 端点(例如,CF create/update/delete 服务实例)的超时值,以秒为单位。spring-doc.cn

300spring-doc.cn

status-timeoutspring-doc.cn

staging-timeoutspring-doc.cn

startup-timeoutspring-doc.cn

delete-routesspring-doc.cn

是否在取消部署应用程序时删除路由。spring-doc.cn

truespring-doc.cn

java-optsspring-doc.cn

use-spring-application-jsonspring-doc.cn

决定将环境变量写入 SPRING_APPLICATION_JSON 或将其写入原始环境变量spring-doc.cn

truespring-doc.cn

环境配置

您可以提供要在已部署应用程序上设置的环境变量。环境变量是使用已部署应用程序 下的属性设置的,如下所示:environmentspring-doc.cn

spring:
  cloud:
    appbroker:
      services:
        - service-name: example
          plan-name: standard
          apps:
            - name: example-service-app1
              path: classpath:app1.jar
              environment:
                logging.level.spring.security: DEBUG
                spring.profiles.active: cloud
服务配置

您可以配置应绑定到已部署应用程序的服务。使用已部署应用程序 下的属性配置服务,如下所示:servicesspring-doc.cn

spring:
  cloud:
    appbroker:
      services:
        - service-name: example
          plan-name: standard
          apps:
            - name: example-service-app1
              path: classpath:app1.jar
              services:
              - service-instance-name: example-db
          services:
          - service-instance-name: example-db
            name: mysql
            plan: small
            parameters:
            param-key: param-value

4.1.2. 动态自定义

要使用仅在执行 Service Broker 操作时可用或必须为每个服务实例生成的信息来自定义后备应用程序部署,您可以使用 Service Broker 应用程序配置来提供自定义实现的名称。spring-doc.cn

支持应用程序目标

您可以使用规范配置后备应用程序(在 Cloud Foundry、组织和空间中)的目标位置,如以下示例所示:targetspring-doc.cn

spring:
  cloud:
    appbroker:
      services:
        - service-name: example
          plan-name: standard
          target:
          *  name: SpacePerServiceInstance*
        apps:
          apps:
            - name: example-service-app1
              path: classpath:app1.jar

默认情况下(如果未提供规范),所有后备应用程序都将部署到 中指定的默认目标。对于 Cloud Foundry,这是名为 的组织,以及名为 的空间。targetspring.cloud.appbroker.deployerspring.cloud.appbroker.deployer.cloudfoundry.default-orgspring.cloud.appbroker.deployer.cloudfoundry.default-spacespring-doc.cn

SpacePerServiceInstance 目标

如果您使用目标,App Broker 会将后备应用程序部署到使用平台在服务实例创建时提供的服务实例 GUID 命名的唯一目标位置。对于 Cloud Foundry,此目标位置是名为 的组织,并且使用服务实例 GUID 作为空间名称来创建新空间。SpacePerServiceInstancespring.cloud.appbroker.deployer.cloudfoundry.default-orgspring-doc.cn

ServiceInstanceGuidSuffix 目标

如果您使用目标,则 App Broker 会使用唯一名称和主机名来部署后备应用程序,该名称和主机名包含平台在创建服务实例时提供的服务实例 GUID。对于 Cloud Foundry,目标位置是名为 的组织,由 命名的空间,以及 名为 的应用程序名称,其中 是 下列出的应用程序,是服务实例 GUID。应用程序还使用包含服务实例 GUID 作为后缀的主机名,如 .ServiceInstanceGuidSuffixspring.cloud.appbroker.deployer.cloudfoundry.default-orgspring.cloud.appbroker.deployer.cloudfoundry.default-space[APP-NAME]-[SI-GUID][APP-NAME]namespring.cloud.appbroker.services.apps[SI-GUID][APP-NAME]-[SI-GUID]spring-doc.cn

创建自定义目标

如果要创建自定义目标,App Broker 提供了一种灵活的方法来添加新目标,方法是创建扩展自该方法的新目标并实施该方法,如下所示:BeanTargetFactorycreatespring-doc.cn

public class CustomSpaceTarget extends TargetFactory<CustomSpaceTarget.Config> {

	public CustomSpaceTarget() {
		super(Config.class);
	}

	@Override
	public Target create(Config config) {
		return this::apply;
	}

	private ArtifactDetails apply(Map<String, String> properties, String name, String serviceInstanceId) {
		String space = "my-custom-space";
		properties.put(DeploymentProperties.TARGET_PROPERTY_KEY, space);

		return ArtifactDetails.builder()
			.name(name)
			.properties(properties)
			.build();
	}

	public static class Config {
	}

}

配置完成后,我们可以在服务中指定新的自定义 Target,如下所示:spring-doc.cn

spring:
  cloud:
    appbroker:
      services:
        - service-name: example
          plan-name: standard
          target:
            name: CustomSpaceTarget
服务实例参数

当用户在创建或更新服务实例时提供参数时,App Broker 可以使用参数转换器将这些参数转换为后备应用程序部署的详细信息。您可以使用 下的 属性来配置参数 transformers,如下所示:parameters-transformersspring-doc.cn

spring:
  cloud:
    appbroker:
      services:
        - service-name: example
          plan-name: standard
          apps:
            - name: example-service-app1
              path: classpath:app1.jar
              parameters-transformers:
                - name: EnvironmentMapping
                  args:
                    - include: parameter1,parameter2
                - name: PropertyMapping
                  args:
                    - include: count,memory

named 引用已贡献给 Spring 应用程序上下文的 Java 对象。参数转换器可以接受一个或多个参数来配置其行为,并且可以修改后备应用程序部署的任何方面(属性、环境变量、服务等)。parameters-transformersspring-doc.cn

EnvironmentMapping 参数转换器

parameters transformer 根据创建或更新服务实例时提供的参数填充后备应用程序上的环境变量。它支持单个参数 ,该参数指定映射到环境变量的参数的名称。EnvironmentMappingincludespring-doc.cn

PropertyMapping 参数转换器

parameters transformer 根据创建或更新服务实例时提供的参数设置后备应用程序的部署属性。它支持单个参数 ,该参数指定应识别的部署属性的名称。PropertyMappingincludespring-doc.cn

4.2. 创建 Service 实例

Spring Cloud App Broker 提供了 AppDeploymentCreateServiceInstanceWorkflow 工作流,该工作流处理部署配置的后备应用程序和服务,如前面部分所示。Service Broker 应用程序可以实现 CreateServiceInstanceWorkflow 接口以进一步修改部署。可以注释多个工作流,以便按特定顺序处理工作流。或者,Service Broker 应用程序可以实现 Spring Cloud Open Service Broker 提供的接口。请参阅 Spring Cloud Open Service Broker 文档中的服务实例@OrderServiceInstanceServicespring-doc.cn

4.3. 更新 Service 实例

Spring Cloud App Broker 提供了AppDeploymentUpdateServiceInstanceWorkflow工作流,该工作流处理更新的配置后备应用程序和服务,如前面部分所示。如果更新了后备服务列表,则默认行为是创建并绑定新的后备服务实例,并取消绑定并删除配置中不再列出的现有后备服务实例。spring-doc.cn

Service Broker 应用程序可以实现 UpdateServiceInstanceWorkflow 接口以进一步修改部署。可以注释多个工作流,以便按特定顺序处理工作流。或者,Service Broker 应用程序可以实现 Spring Cloud Open Service Broker 提供的接口。请参阅 Spring Cloud Open Service Broker 文档中的服务实例@OrderServiceInstanceServicespring-doc.cn

在更新应用程序时修改某些属性 (如磁盘和内存) 可能会导致停机。

4.4. 删除 Service 实例

Spring Cloud App Broker 提供了 AppDeploymentDeleteServiceInstanceWorkflow 工作流,该工作流处理删除已配置的后备应用程序和服务,如前面部分所示。Service Broker 应用程序可以实现 DeleteServiceInstanceWorkflow 接口以进一步修改部署。可以注释多个工作流,以便按特定顺序处理工作流。或者,Service Broker 应用程序可以实现 Spring Cloud Open Service Broker 提供的接口。请参阅 Spring Cloud Open Service Broker 文档中的服务实例@OrderServiceInstanceServicespring-doc.cn

4.5. 持久化服务实例状态

Spring Cloud App Broker 提供了ServiceInstanceStateRepository接口,用于持久化服务实例状态。默认实现是 InMemoryServiceInstanceStateRepository,它使用内存中来保存状态,并提供简单的入门体验。要使用适当的数据库来持久保存状态,您可以在应用程序中实现。MapServiceInstanceStateRepositoryspring-doc.cn

仅用于演示和测试目的。它不适合生产应用!InMemoryServiceInstanceStateRepository

4.5.1. 示例实现

以下示例显示了服务实例状态存储库实现:spring-doc.cn

package com.example.appbroker;

import reactor.core.publisher.Mono;

import org.springframework.cloud.appbroker.state.ServiceInstanceState;
import org.springframework.cloud.appbroker.state.ServiceInstanceStateRepository;
import org.springframework.cloud.servicebroker.model.instance.OperationState;

class ExampleServiceInstanceStateRepository implements ServiceInstanceStateRepository {

	private final ServiceInstanceStateCrudRepository serviceInstanceStateCrudRepository;

	ExampleServiceInstanceStateRepository(ServiceInstanceStateCrudRepository serviceInstanceStateCrudRepository) {
		this.serviceInstanceStateCrudRepository = serviceInstanceStateCrudRepository;
	}

	@Override
	public Mono<ServiceInstanceState> saveState(String serviceInstanceId, OperationState state, String description) {
		return serviceInstanceStateCrudRepository.findByServiceInstanceId(serviceInstanceId)
				.switchIfEmpty(Mono.just(new ServiceInstance()))
				.flatMap(serviceInstance -> {
					serviceInstance.setServiceInstanceId(serviceInstanceId);
					serviceInstance.setOperationState(state);
					serviceInstance.setDescription(description);
					return Mono.just(serviceInstance);
				})
				.flatMap(serviceInstanceStateCrudRepository::save)
				.map(ExampleServiceInstanceStateRepository::toServiceInstanceState);
	}

	@Override
	public Mono<ServiceInstanceState> getState(String serviceInstanceId) {
		return serviceInstanceStateCrudRepository.findByServiceInstanceId(serviceInstanceId)
				.switchIfEmpty(Mono.error(new IllegalArgumentException("Unknown service instance ID " + serviceInstanceId)))
				.map(ExampleServiceInstanceStateRepository::toServiceInstanceState);
	}

	@Override
	public Mono<ServiceInstanceState> removeState(String serviceInstanceId) {
		return getState(serviceInstanceId)
				.doOnNext(serviceInstanceState -> serviceInstanceStateCrudRepository.deleteByServiceInstanceId(serviceInstanceId));
	}

	private static ServiceInstanceState toServiceInstanceState(ServiceInstance serviceInstance) {
		return new ServiceInstanceState(serviceInstance.getOperationState(), serviceInstance.getDescription(), null);
	}

}

保留服务实例状态的一种选择是使用 Spring Data 。以下示例显示了一个实现:CrudRepositoryReactiveCrudRepositoryspring-doc.cn

package com.example.appbroker;

import reactor.core.publisher.Mono;

import org.springframework.data.r2dbc.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.data.repository.reactive.ReactiveCrudRepository;

interface ServiceInstanceStateCrudRepository extends ReactiveCrudRepository<ServiceInstance, Long> {

	@Query("select * from service_instance where service_instance_id = :service_instance_id")
	Mono<ServiceInstance> findByServiceInstanceId(@Param("service_instance_id") String serviceInstanceId);

	@Query("delete from service_instance where service_instance_id = :service_instance_id")
	Mono<Void> deleteByServiceInstanceId(@Param("service_instance_id") String serviceInstanceId);

}

模型对象对于使用 .以下示例显示了一个模型:CrudRepositoryServiceInstancespring-doc.cn

package com.example.appbroker;

import org.springframework.cloud.servicebroker.model.instance.OperationState;
import org.springframework.data.annotation.Id;

class ServiceInstance {

	@Id
	private Long id;

	private String serviceInstanceId;

	private String description;

	private OperationState operationState;

	public ServiceInstance() {

	}

	public ServiceInstance(String serviceInstanceId, String description, OperationState operationState) {
		this.serviceInstanceId = serviceInstanceId;
		this.description = description;
		this.operationState = operationState;
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getServiceInstanceId() {
		return serviceInstanceId;
	}

	public void setServiceInstanceId(String serviceInstanceId) {
		this.serviceInstanceId = serviceInstanceId;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public OperationState getOperationState() {
		return operationState;
	}

	public void setOperationState(OperationState operationState) {
		this.operationState = operationState;
	}

}