常见问题解答
Data Flow
流应用程序和 Spring Cloud Data Flow (SCDF) 之间是什么关系?
流应用程序是独立的,它们通过消息代理(例如 RabbitMQ 或 Apache Kafka)与其他应用程序通信。它们独立运行,应用程序和 SCDF 之间不存在运行时依赖关系。但是,根据用户操作,SCDF 会与平台运行时交互,以更新当前运行的应用程序、查询当前状态或停止应用程序。
任务和批处理应用程序与 Spring Cloud Data Flow (SCDF) 之间是什么关系?
虽然批处理和任务应用程序是独立的 Spring Boot 应用程序,但要记录批处理和任务应用程序的执行状态,您*必须*将 SCDF 和批处理应用程序连接到同一个数据库。然后,由 SCDF 部署的各个批处理应用程序会尝试将其执行状态更新到共享数据库。SCDF 继而使用该数据库在 SCDF 的仪表板中显示执行历史记录以及有关批处理应用程序的其他详细信息。您还可以构建批处理和任务应用程序,使其仅连接到 SCDF 数据库以记录执行状态,但在另一个数据库中执行工作。
组合任务运行器 和 SCDF 之间是什么关系?
组合任务 将任务集合的运行委托给一个名为组合任务运行器 (CTR) 的单独应用程序。CTR 协调在组合任务图中定义的任务的启动。要使用组合任务,您必须将 SCDF、CTR 和批处理应用程序连接到共享数据库。只有这样,您才能从 SCDF 的仪表板跟踪所有应用程序的执行历史记录。
SCDF 是否使用消息代理?
否。Data Flow 和 Skipper 服务器不与消息代理交互。由 Data Flow 部署的流应用程序连接到消息代理以发布和使用消息。
Skipper 在 Spring Cloud Data Flow (SCDF) 中的作用是什么?
SCDF 将流应用程序的生命周期管理委托给 Skipper 并依赖于 Skipper。借助 Skipper,流数据管道中包含的应用程序会被版本化,并且可以更新到新版本(滚动更新)并回滚到先前版本。
有哪些工具可以与 Spring Cloud Data Flow (SCDF) 交互?
为什么 Spring Cloud Data Flow (SCDF) 不在 Spring Initializr 中?
Initializr 的目标是为创建 Spring Boot 应用程序提供入门体验。Initializr 的目标不是创建生产就绪的服务器应用程序。我们过去尝试过这样做,但由于我们需要对依赖库进行细粒度控制,因此我们未能成功。因此,我们直接提供二进制文件。我们希望用户按原样使用二进制文件,或者通过从源代码本地构建 SCDF 来扩展它们。
Spring Cloud Data Flow (SCDF) 可以与 Oracle 数据库一起使用吗?
是的。您可以在此处阅读有关支持的数据库的更多信息。
我应该在何时何地使用任务属性而不是参数?
如果每个任务执行的配置在所有任务启动中都保持不变,则您可以在创建任务定义时设置属性。以下示例展示了如何执行此操作
task create myTaskDefinition --definition "timestamp --format='yyyy'"
如果每个任务执行的配置对于每个任务启动都会发生变化,则您可以在任务启动时使用参数,如下例所示
task launch myTaskDefinition "--server.port=8080"
当您使用 Spring Cloud Data Flow 来协调使用 Spring Batch 的任务应用程序的启动时,您应该使用参数来设置批处理作业所需的作业参数。
请记住:如果您的参数是非标识参数,请在参数后缀--
。
如何将命令行参数传递给组合任务图的子任务?您可以使用组合任务运行程序的composedTaskArguments
属性来实现。
在以下示例中,--timestamp.format=YYYYMMDD
命令行参数应用于组合任务图中的所有子任务。
task launch myComposedTask --arguments "--composedTaskArguments=--timestamp.format=YYYYMMDD"
如何配置远程 Maven 存储库?
您可以在启动 Data Flow 服务器时,通过命令行属性设置 Maven 属性(例如本地 Maven 存储库位置、远程 Maven 存储库、身份验证凭据和代理服务器属性)。或者,您可以通过为 Data Flow 服务器设置SPRING_APPLICATION_JSON
环境属性来设置属性。
如果从 Maven 存储库解析应用程序,则需要显式配置远程 Maven 存储库,但local
Data Flow 服务器除外。其他 Data Flow 服务器实现(使用 Maven 资源进行应用程序工件解析)没有远程存储库的默认值。local
服务器具有https://repo.spring.io/libs-snapshot
作为默认远程存储库。
要将属性作为命令行选项传递,请使用类似于以下内容的命令运行服务器
java -jar <dataflow-server>.jar --maven.localRepository=mylocal
--maven.remote-repositories.repo1.url=https://repo1
--maven.remote-repositories.repo1.auth.username=repo1user
--maven.remote-repositories.repo1.auth.password=repo1pass
--maven.remote-repositories.repo2.url=https://repo2 --maven.proxy.host=proxyhost
--maven.proxy.port=9018 --maven.proxy.auth.username=proxyuser
--maven.proxy.auth.password=proxypass
您还可以设置SPRING_APPLICATION_JSON
环境属性
export SPRING_APPLICATION_JSON='{ "maven": { "local-repository": "local","remote-repositories": { "repo1": { "url": "https://repo1", "auth": { "username": "repo1user", "password": "repo1pass" } },
"repo2": { "url": "https://repo2" } }, "proxy": { "host": "proxyhost", "port": 9018, "auth": { "username": "proxyuser", "password": "proxypass" } } } }'
以下是格式良好的 JSON 中的相同内容
export SPRING_APPLICATION_JSON='{
"maven": {
"local-repository": "local",
"remote-repositories": {
"repo1": {
"url": "https://repo1",
"auth": {
"username": "repo1user",
"password": "repo1pass"
}
},
"repo2": {
"url": "https://repo2"
}
},
"proxy": {
"host": "proxyhost",
"port": 9018,
"auth": {
"username": "proxyuser",
"password": "proxypass"
}
}
}
}'
根据 Spring Cloud Data Flow 服务器实现,您可能必须使用特定于平台的环境设置功能来传递环境属性。例如,在 Cloud Foundry 中,您将它们作为cf set-env <your app> SPRING_APPLICATION_JSON '{...
传递。
如何为平台部署启用 DEBUG 日志?
Spring Cloud Data Flow 建立在Spring Cloud Deployer SPI 之上,特定于平台的 dataflow 服务器使用相应的SPI 实现。具体来说,如果我们要解决特定于部署的问题,例如网络错误,那么在底层部署程序及其使用的库中启用 DEBUG 日志将非常有用。
要为 local-deployer 启用 DEBUG 日志,请按如下方式启动服务器
java -jar <dataflow-server>.jar --logging.level.org.springframework.cloud.deployer.spi.local=DEBUG
(其中 org.springframework.cloud.deployer.spi.local
是与 local-deployer 相关的所有内容的全局包。)
要为 cloudfoundry-deployer 启用 DEBUG 日志,请设置 logging.level.cloudfoundry-client
环境变量,并在重新启动 Data Flow 服务器后,您可以看到更多有关请求和响应的日志,并查看故障的详细堆栈跟踪。Cloud Foundry 部署器使用 cf-java-client,因此您还必须为此库启用 DEBUG 日志
cf set-env dataflow-server JAVA_OPTS '-Dlogging.level.cloudfoundry-client=DEBUG'
cf restage dataflow-server
(其中 cloudfoundry-client
是与 cf-java-client
相关的所有内容的全局包。)
要查看 cf-java-client
使用的 Reactor 日志,请运行以下命令
cf set-env dataflow-server JAVA_OPTS '-Dlogging.level.cloudfoundry-client=DEBUG -Dlogging.level.reactor.ipc.netty=DEBUG'
cf restage dataflow-server
(其中 reactor.ipc.netty
是与 reactor-netty
相关的所有内容的全局包。)
与上述 local-deployer
和 cloudfoundry-deployer
选项类似,Kubernetes 也提供了等效的设置。有关要为日志记录配置的包的更多详细信息,请参阅相应的链接:https://github.com/spring-cloud?utf8=%E2%9C%93&q=spring-cloud-deployer[SPI 实现]。
如何为应用程序部署启用 DEBUG 日志?
Spring Cloud Data Flow 中的流式应用程序是 Spring Cloud Stream 应用程序,而 Spring Cloud Stream 应用程序又基于 Spring Boot。您可以使用不同的日志记录配置独立设置它们。
例如,如果您必须对在源、处理器和接收器通道之间传递的 header
和 payload
详细信息进行故障排除,则应使用以下选项部署流
dataflow:>stream create foo --definition "http --logging.level.org.springframework.integration=DEBUG | transform --logging.level.org.springframework.integration=DEBUG | log --logging.level.org.springframework.integration=DEBUG" --deploy
(其中 org.springframework.integration
是与 Spring Integration 相关的所有内容的全局包,Spring Integration 负责消息通道)
您还可以在部署流时通过设置 deployment
属性来指定这些属性,如下所示
dataflow:>stream deploy foo --properties "app.*.logging.level.org.springframework.integration=DEBUG"
如何远程调试已部署的应用程序?
Data Flow 本地服务器允许您调试已部署的应用程序。为此,请通过部署属性启用 JVM 的远程调试功能,如下所示
stream deploy --name mystream --properties "deployer.fooApp.local.debugPort=9999"
前面的示例在调试模式下启动 fooApp
应用程序,允许在端口 9999 上附加远程调试器。默认情况下,应用程序以“挂起”模式启动,并等待远程调试会话附加(启动)。否则,您可以提供一个值为 n
的附加 debugSuspend
属性。
此外,当应用程序存在多个实例时,每个实例的调试端口是 debugPort
+ instanceId
的值。
与其他属性不同,您不得对应用程序名称使用通配符,因为每个应用程序都必须使用唯一的调试端口。
是否可以将本地部署聚合到单个日志中?
鉴于每个应用程序都是一个维护自己日志集的独立进程,因此访问单个日志可能会有些不便,尤其是在开发的早期阶段,此时访问日志的频率更高。由于依赖本地 SCDF 服务器(将每个应用程序部署为本地 JVM 进程)也是一种常见模式,因此您可以将已部署应用程序的 stdout 和 stdin 重定向到父进程。因此,对于本地 SCDF 服务器,应用程序日志将出现在正在运行的本地 SCDF 服务器的日志中。
通常,当您部署流时,您会在服务器日志中看到类似于以下内容的内容
017-06-28 09:50:16.372 INFO 41161 --- [nio-9393-exec-7] o.s.c.d.spi.local.LocalAppDeployer : Deploying app with deploymentId mystream.myapp instance 0.
Logs will be in /var/folders/l2/63gcnd9d7g5dxxpjbgr0trpw0000gn/T/spring-cloud-dataflow-5939494818997196225/mystream-1498661416369/mystream.myapp
但是,通过将 local.inheritLogging=true
设置为部署属性,您可以看到以下内容
017-06-28 09:50:16.372 INFO 41161 --- [nio-9393-exec-7] o.s.c.d.spi.local.LocalAppDeployer : Deploying app with deploymentId mystream.myapp instance 0.
Logs will be inherited.
之后,应用程序日志会与服务器日志一起显示,如下例所示
stream deploy --name mystream --properties "deployer.*.local.inheritLogging=true"
前面的流定义为流中的每个应用程序启用日志重定向。以下流定义仅为名为 my app
的应用程序启用日志重定向
stream deploy --name mystream --properties "deployer.myapp.local.inheritLogging=true"
同样,您也可以使用相同的选项来重定向和聚合已启动的任务应用程序的所有日志。该属性对于任务也是一样的。
注意:日志重定向仅受 local-deployer 支持。
如何为给定的流应用程序获取可预测的路由、URL 或 IP 地址?
要为给定应用程序获取静态且可预测的 IP 地址,您可以定义一个类型为 LoadBalancer
的显式服务,并使用 Kubernetes 中的标签选择器功能通过分配的静态 IP 地址路由流量。
以下示例显示了 LoadBalancer
部署
kind: Service
apiVersion: v1
metadata:
name: foo-lb
namespace: kafkazone
spec:
ports:
- port: 80
name: http
targetPort: 8080
selector:
FOOZ: BAR-APP
type: LoadBalancer
此部署将生成一个静态 IP 地址。例如,假设 foo-lb
的 IP 地址为:"10.20.30.40"。
现在,当您部署流时,您可以将标签选择器附加到所需的应用程序(例如,deployer.<yourapp>.kubernetes.deploymentLabels=FOOZ: BAR-APP
),以便 10.20.30.40
的所有传入流量都由 yourapp
自动接收。
在此设置中,当应用程序升级或在 SCDF 中重新部署或更新流时,静态 IP 地址保持不变,并且上游或下游流量可以依赖于此地址。
流式传输
我可以连接到现有的 RabbitMQ 队列吗?
请按照参考指南中的步骤连接到现有的 RabbitMQ 队列。
Apache Kafka 与 Spring Cloud Stream 的兼容性如何?
请参阅 Wiki 中的兼容性矩阵。
我可以管理绑定生命周期吗?
默认情况下,绑定在应用程序初始化时自动启动。绑定实现了 Spring SmartLifecycle
接口。SmartLifecycle
允许分阶段启动 bean。生产者绑定在早期阶段启动(Integer.MIN_VALUE + 1000
)。消费者绑定在后期阶段启动(Integer.MAX_VALUE - 1000
)。这在频谱中留出了空间,以便您可以在生产者绑定之前、消费者绑定之后或两者之间的任何位置启动实现 SmartLifecycle
的用户 bean。
您可以通过将消费者或生产者的 autoStartup
属性设置为 false
来禁用自动启动。
您可以使用 Boot 执行器来可视化和控制绑定生命周期。请参阅绑定可视化和控制。
您还可以使用绑定名称以编程方式调用执行器端点,如下所示
@Autowired
private BindingsEndpoint endpoint;
...
bindings.changeState("myFunction-in-0", State.STARTED);
这将启动先前已停止(或 autoStartup=false
)的名为 myFunction-in-0
的绑定。要停止正在运行的绑定,请使用 State.STOPPED
。某些绑定(例如 Kafka)还支持消费者绑定的 State.PAUSED
和 State.RESUMED
。
由于 BindingsEndpoint
是执行器基础架构的一部分,因此您必须按照绑定可视化和控制中的说明启用执行器支持。
批处理
什么是组合任务运行器 (CTR)?
Spring Cloud Data Flow (SCDF) 中的组合任务功能将组合任务的运行委托给一个名为组合任务运行器 (CTR) 的独立应用程序。 CTR 协调任务的启动(这些任务在组合任务图中定义)。 组合任务运行器 (CTR) 解析图 DSL,并针对图中的每个节点,针对指定的 Spring Cloud Data Flow 实例运行 RESTful 调用以启动关联的任务定义。 对于运行的每个任务定义,组合任务运行器都会轮询数据库以验证任务是否完成。 任务完成后,组合任务运行器将根据 DSL 指定的任务运行顺序,继续执行图中的下一个任务或失败。
如何从头开始重新启动 Spring Batch 作业,而不是从失败的地方重新启动?
简而言之,您需要为新的任务启动创建一个新的作业实例。 您可以通过更改现有的标识作业参数或在下一次任务启动时添加新的标识作业参数来实现。 以下示例显示了典型的任务启动
task launch myBatchApp --arguments="team=yankees"
假设前面的任务启动失败,我们可以再次启动任务,如果我们更改 team
参数的值,则会创建一个新的作业实例,如下例所示
task launch myBatchApp --arguments="team=cubs"
但是,首选方法是编写您的任务或批处理应用程序,使其能够处理使用新的作业实例重新启动。 一种方法是为您的批处理作业设置 JobParamsIncrementer
,如Spring Batch 参考指南中所述。
为什么我的任务执行没有显示结束时间?
这可能发生的原因有三个
- 您的应用程序实际上仍在运行。 您可以通过该任务执行的任务执行详细信息页面查看任务的日志,以检查状态。
- 您的应用程序使用 SIG-KILL 终止。 在这种情况下,Spring Cloud Task 没有收到应用程序正在终止的信号。 相反,任务的进程被杀死了。
- 您正在运行一个上下文保持打开状态的 Spring Cloud Task 应用程序(例如:如果您正在使用
TaskExecutor
)。 在这些情况下,您可以在启动任务时将spring.cloud.task.closecontext_enabled
属性设置为true
。 这样做会在任务完成后关闭应用程序的上下文,从而允许应用程序终止并记录结束时间。
我想从 Spring Batch Admin 迁移到 Spring Cloud Data Flow。我可以使用 Spring Batch 作业已在使用的现有数据库吗?
不可以。Spring Cloud Data Flow 会创建自己的 schema,其中包含 Spring Batch 表。为了让 Spring Cloud Data Flow 在仪表板或 shell 中显示 Spring Batch 作业执行的状态,您的 Spring Batch 应用程序需要使用与 Spring Cloud Data Flow 相同的“数据源”配置。