4. 服务实例
您可以在 App Broker 配置属性中配置服务的详细信息,包括要部署的应用程序、应用程序部署详细信息和要创建的后备服务。这些属性通常位于spring.cloud.appbroker.services
.
4.1. 配置 App Deployment
后备应用程序的部署详细信息可以在 Service Broker 的应用程序配置中静态配置,也可以使用服务实例参数和自定义实施动态配置。
4.1.1. 静态自定义
您可以使用spring.cloud.appbroker
.
Properties 配置
您可以在 configuration 中指定应用程序部署属性。这些属性可以具有默认值和特定于服务的值。
对于 Cloud Foundry,您可以在spring.cloud.appbroker.deployer.cloudfoundry.*
如下:
spring:
cloud:
appbroker:
deployer:
cloudfoundry:
properties:
memory: 1G
health-check: http
health-check-http-endpoint: /health
health-check-timeout: 180
api-polling-timeout: 300
下表列出了可为所有部署或部署设置的属性:
财产 | 描述 | 违约 |
---|---|---|
|
轮询的异步 CF API 调用的超时时间(以秒为单位)。 |
300 |
|
用于部署应用程序的 buildpack。 |
|
|
用于部署应用程序的 buildpack 列表。 |
|
|
映射应用程序路由时使用的域。 |
|
|
映射应用程序路由时要使用的域列表。 |
|
|
要对已部署的应用程序执行的运行状况检查的类型(如果未按应用程序覆盖)。 |
港口 |
|
http 运行状况检查将使用的路径。 |
/健康 |
|
运行状况检查的超时值(以秒为单位)。 |
120 |
|
用于部署应用程序的 javaOpts。 |
|
|
用于部署应用程序的内存。 |
|
|
如果应用程序不需要路由 |
假 |
|
用于部署应用程序的 route-path。 |
|
|
用于部署应用程序的路由。 |
|
|
用于部署应用程序的堆栈。 |
您可以在服务配置的spring.cloud.appbroker.services.*
如下:
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
下表列出了可以为所有或特定应用程序部署设置的属性:
财产 | 描述 | 违约 |
---|---|---|
|
||
|
||
|
||
|
||
|
||
|
为已部署的应用程序映射路由时要使用的域。 |
|
|
要将已部署的应用程序绑定到的路由。 |
|
|
要对已部署的应用程序执行的运行状况检查的类型。 |
|
|
HTTP 运行状况检查使用的路径。 |
|
|
运行状况检查使用的超时值(以秒为单位)。 |
|
|
用于阻止 API 调用的超时值,以秒为单位。 |
|
|
用于轮询异步 API 端点(例如,CF create/update/delete 服务实例)的超时值,以秒为单位。 |
|
|
||
|
||
|
||
|
是否在取消部署应用程序时删除路由。 |
|
|
||
|
决定将环境变量写入 SPRING_APPLICATION_JSON 或将其写入原始环境变量 |
|
环境配置
您可以提供要在已部署应用程序上设置的环境变量。环境变量是使用environment
对于已部署的应用程序,如下所示:
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:
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 应用程序配置来提供自定义实现的名称。
支持应用程序目标
您可以使用target
规范,如以下示例所示:
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
.
这SpacePerServiceInstance
目标
如果您使用SpacePerServiceInstance
target,则 App Broker 会将后备应用程序部署到使用平台在服务实例创建时提供的服务实例 GUID 命名的唯一目标位置。对于 Cloud Foundry,此目标位置是spring.cloud.appbroker.deployer.cloudfoundry.default-org
,并使用服务实例 GUID 作为空间名称创建新空间。
这ServiceInstanceGuidSuffix
目标
如果您使用ServiceInstanceGuidSuffix
target,则 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]
是name
在spring.cloud.appbroker.services.apps
和[SI-GUID]
是服务实例 GUID。应用程序还使用包含服务实例 GUID 作为后缀的主机名,如[APP-NAME]-[SI-GUID]
.
创建自定义目标
如果要创建自定义目标,App Broker 提供了一种灵活的方法来添加新目标,方法是创建新的Bean
它从TargetFactory
并实现create
方法,如下所示:
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:
cloud:
appbroker:
services:
- service-name: example
plan-name: standard
target:
name: CustomSpaceTarget
服务实例参数
当用户在创建或更新服务实例时提供参数时,App Broker 可以使用参数转换器将这些参数转换为后备应用程序部署的详细信息。您可以使用parameters-transformers
如下:
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 对象。参数转换器可以接受一个或多个参数来配置其行为,并且可以修改后备应用程序部署的任何方面(属性、环境变量、服务等)。
这EnvironmentMapping
参数 Transformer
这EnvironmentMapping
parameters transformer 根据创建或更新服务实例时提供的参数填充后备应用程序上的环境变量。它支持单个参数include
,它指定映射到环境变量的参数的名称。
这PropertyMapping
参数 Transformer
这PropertyMapping
parameters transformer 根据创建或更新服务实例时提供的参数设置后备应用程序的部署属性。它支持单个参数include
,它指定应识别的部署属性的名称。
4.2. 创建 Service 实例
Spring Cloud App Broker 提供了AppDeploymentCreateServiceInstanceWorkflow
工作流,用于处理部署已配置的后备应用程序和服务,如前面部分所示。Service Broker 应用程序可以实现CreateServiceInstanceWorkflow
接口以进一步修改 deployment。多个工作流可以使用@Order
以便按特定顺序处理工作流。或者,Service Broker 应用程序也可以实现ServiceInstanceService
接口。请参阅 Spring Cloud Open Service Broker 文档中的服务实例。
4.3. 更新 Service 实例
Spring Cloud App Broker 提供了AppDeploymentUpdateServiceInstanceWorkflow
工作流,用于处理更新已配置的后备应用程序和服务,如前面几节所示。如果更新了后备服务列表,则默认行为是创建并绑定新的后备服务实例,并取消绑定并删除配置中不再列出的现有后备服务实例。
Service Broker 应用程序可以实现UpdateServiceInstanceWorkflow
接口以进一步修改 deployment。多个工作流可以使用@Order
以便按特定顺序处理工作流。或者,Service Broker 应用程序也可以实现ServiceInstanceService
接口。请参阅 Spring Cloud Open Service Broker 文档中的服务实例。
在更新应用程序时修改某些属性 (如磁盘和内存) 可能会导致停机。 |
4.4. 删除 Service 实例
Spring Cloud App Broker 提供了AppDeploymentDeleteServiceInstanceWorkflow
工作流,用于处理删除已配置的后备应用程序和服务,如前面部分所示。Service Broker 应用程序可以实现DeleteServiceInstanceWorkflow
接口以进一步修改 deployment。多个工作流可以使用@Order
以便按特定顺序处理工作流。或者,Service Broker 应用程序也可以实现ServiceInstanceService
接口。请参阅 Spring Cloud Open Service Broker 文档中的服务实例。
4.5. 持久化服务实例状态
Spring Cloud App Broker 提供了ServiceInstanceStateRepository
用于持久化服务实例状态的接口。默认实现为InMemoryServiceInstanceStateRepository
,它使用内存中的Map
保存状态,并提供简单的入门体验。要使用合适的数据库来持久化状态,您可以实现ServiceInstanceStateRepository
在您的应用程序中。
这InMemoryServiceInstanceStateRepository 仅用于演示和测试目的。它不适合生产应用! |
4.5.1. 示例实现
以下示例显示了服务实例状态存储库实现:
package com.example.appbroker;
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
实现:
package com.example.appbroker;
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
型:
package com.example.appbroker;
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;
}
}