4. 服务实例

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

4.1. 配置 App Deployment

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

4.1.1. 静态自定义

您可以使用spring.cloud.appbroker.spring-doc.cadn.net.cn

Properties 配置

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

对于 Cloud Foundry,您可以在spring.cloud.appbroker.deployer.cloudfoundry.*如下:spring-doc.cadn.net.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.cadn.net.cn

财产 描述 违约

api-polling-timeoutspring-doc.cadn.net.cn

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

300spring-doc.cadn.net.cn

buildpackspring-doc.cadn.net.cn

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

buildpacksspring-doc.cadn.net.cn

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

domainspring-doc.cadn.net.cn

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

domainsspring-doc.cadn.net.cn

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

health-checkspring-doc.cadn.net.cn

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

港口spring-doc.cadn.net.cn

health-check-http-endpointspring-doc.cadn.net.cn

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

/健康spring-doc.cadn.net.cn

health-check-timeoutspring-doc.cadn.net.cn

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

120spring-doc.cadn.net.cn

javaOptsspring-doc.cadn.net.cn

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

memoryspring-doc.cadn.net.cn

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

no-routespring-doc.cadn.net.cn

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

spring-doc.cadn.net.cn

route-pathspring-doc.cadn.net.cn

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

routesspring-doc.cadn.net.cn

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

stackspring-doc.cadn.net.cn

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

您可以在服务配置的spring.cloud.appbroker.services.*如下:spring-doc.cadn.net.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.cadn.net.cn

财产 描述 违约

countspring-doc.cadn.net.cn

memoryspring-doc.cadn.net.cn

diskspring-doc.cadn.net.cn

hostspring-doc.cadn.net.cn

targetspring-doc.cadn.net.cn

domainspring-doc.cadn.net.cn

为已部署的应用程序映射路由时要使用的域。domainhost与 互斥routes.spring-doc.cadn.net.cn

routesspring-doc.cadn.net.cn

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

health-checkspring-doc.cadn.net.cn

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

PORTspring-doc.cadn.net.cn

health-check-http-endpointspring-doc.cadn.net.cn

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

/healthspring-doc.cadn.net.cn

health-check-timeoutspring-doc.cadn.net.cn

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

120spring-doc.cadn.net.cn

api-timeoutspring-doc.cadn.net.cn

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

360spring-doc.cadn.net.cn

api-polling-timeoutspring-doc.cadn.net.cn

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

300spring-doc.cadn.net.cn

status-timeoutspring-doc.cadn.net.cn

staging-timeoutspring-doc.cadn.net.cn

startup-timeoutspring-doc.cadn.net.cn

delete-routesspring-doc.cadn.net.cn

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

truespring-doc.cadn.net.cn

java-optsspring-doc.cadn.net.cn

use-spring-application-jsonspring-doc.cadn.net.cn

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

truespring-doc.cadn.net.cn

环境配置

您可以提供要在已部署应用程序上设置的环境变量。环境变量是使用environment对于已部署的应用程序,如下所示:spring-doc.cadn.net.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
服务配置

您可以配置应绑定到已部署应用程序的服务。服务是使用services对于已部署的应用程序,如下所示:spring-doc.cadn.net.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.cadn.net.cn

支持应用程序目标

您可以使用target规范,如以下示例所示:spring-doc.cadn.net.cn

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

默认情况下(如果您没有提供target规范),则所有后备应用程序都将部署到spring.cloud.appbroker.deployer.对于 Cloud Foundry,这是由spring.cloud.appbroker.deployer.cloudfoundry.default-org以及由spring.cloud.appbroker.deployer.cloudfoundry.default-space.spring-doc.cadn.net.cn

SpacePerServiceInstance目标

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

ServiceInstanceGuidSuffix目标

如果您使用ServiceInstanceGuidSuffixtarget,则 App Broker 使用唯一名称和主机名来部署后备应用程序,该名称和主机名包含平台在服务实例创建时提供的服务实例 GUID。对于 Cloud Foundry,目标位置是spring.cloud.appbroker.deployer.cloudfoundry.default-org,则由spring.cloud.appbroker.deployer.cloudfoundry.default-space,应用程序名称为[APP-NAME]-[SI-GUID]哪里[APP-NAME]namespring.cloud.appbroker.services.apps[SI-GUID]是服务实例 GUID。应用程序还使用包含服务实例 GUID 作为后缀的主机名,如[APP-NAME]-[SI-GUID].spring-doc.cadn.net.cn

创建自定义目标

如果要创建自定义目标,App Broker 提供了一种灵活的方法来添加新目标,方法是创建新的Bean它从TargetFactory并实现create方法,如下所示:spring-doc.cadn.net.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.cadn.net.cn

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

当用户在创建或更新服务实例时提供参数时,App Broker 可以使用参数转换器将这些参数转换为后备应用程序部署的详细信息。您可以使用parameters-transformers如下:spring-doc.cadn.net.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

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

EnvironmentMapping参数 Transformer

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

PropertyMapping参数 Transformer

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

4.2. 创建 Service 实例

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

4.3. 更新 Service 实例

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

Service Broker 应用程序可以实现UpdateServiceInstanceWorkflow接口以进一步修改 deployment。多个工作流可以使用@Order以便按特定顺序处理工作流。或者,Service Broker 应用程序也可以实现ServiceInstanceService接口。请参阅 Spring Cloud Open Service Broker 文档中的服务实例spring-doc.cadn.net.cn

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

4.4. 删除 Service 实例

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

4.5. 持久化服务实例状态

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

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

4.5.1. 示例实现

以下示例显示了服务实例状态存储库实现:spring-doc.cadn.net.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 DataCrudRepository.以下示例显示了ReactiveCrudRepository实现:spring-doc.cadn.net.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);

}

模型对象对于使用CrudRepository.以下示例显示了ServiceInstance型:spring-doc.cadn.net.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;
	}

}