Similar to Cloud Foundry’s blue-green deployments, you can perform rolling upgrades on the applications orchestrated by Spring Cloud Data Flow.
Let’s start with the following simple stream definition.
dataflow:>stream create --name foo --definition "time | log" --deploy
List Apps.
→ cf apps Getting apps in org test-org / space development as test@pivotal.io... OK name requested state instances memory disk urls foo-log started 1/1 1G 1G foo-log.cfapps.io foo-time started 1/1 1G 1G foo-time.cfapps.io
Let’s assume you’ve to make an enhancement to update the "logger" to append extra text in every log statement.
Log Sink
application starter with "Rabbit binder starter" from start-scs.cfapps.io/LogSinkConfiguration.class
loggingHandler.setLoggerName("TEST [" + this.properties.getName() + "]");
@SpringBootApplication @Import(LogSinkConfiguration.class) public class DemoApplication { @Autowired private LogSinkProperties properties; public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } @Bean @ServiceActivator(inputChannel = Sink.INPUT) public LoggingHandler logSinkHandler() { LoggingHandler loggingHandler = new LoggingHandler(this.properties.getLevel().name()); loggingHandler.setExpression(this.properties.getExpression()); loggingHandler.setLoggerName("TEST [" + this.properties.getName() + "]"); return loggingHandler; } }
Let’s deploy the locally built application to Cloud Foundry
→ cf push foo-log-v2 -p demo-0.0.1-SNAPSHOT.jar -n foo-log-v2 --no-start
List Apps.
→ cf apps Getting apps in org test-org / space development as test@pivotal.io... OK name requested state instances memory disk urls foo-log started 1/1 1G 1G foo-log.cfapps.io foo-time started 1/1 1G 1G foo-time.cfapps.io foo-log-v2 stopped 1/1 1G 1G foo-log-v2.cfapps.io
The stream applications do not communicate via (Go)Router, so they aren’t generating HTTP traffic. Instead, they
communicate via the underlying messaging middleware such as Kafka or RabbitMQ. In order to rolling upgrade to route the
payload from old to the new version of the application, you’d have to replicate the SPRING_APPLICATION_JSON
environment
variable from the old application that includes spring.cloud.stream.bindings.input.destination
and spring.cloud.stream.bindings.input.group
credentials.
Note | |
---|---|
You can find the |
cf set-env foo-log-v2 SPRING_APPLICATION_JSON '{"spring.cloud.stream.bindings.input.destination":"foo.time","spring.cloud.stream.bindings.input.group":"foo"}'
Let’s start foo-log-v2
application.
cf start foo-log-v2
As soon as the application bootstraps, you’d now notice the payload being load balanced between two log application instances running on Cloud Foundry. Since they both share the same "destination" and "consumer group", they are now acting as competing consumers.
Old App Logs:
2016-08-08T17:11:08.94-0700 [APP/0] OUT 2016-08-09 00:11:08.942 INFO 19 --- [ foo.time.foo-1] log.sink : 08/09/16 00:11:08 2016-08-08T17:11:10.95-0700 [APP/0] OUT 2016-08-09 00:11:10.954 INFO 19 --- [ foo.time.foo-1] log.sink : 08/09/16 00:11:10 2016-08-08T17:11:12.94-0700 [APP/0] OUT 2016-08-09 00:11:12.944 INFO 19 --- [ foo.time.foo-1] log.sink : 08/09/16 00:11:12
New App Logs:
2016-08-08T17:11:07.94-0700 [APP/0] OUT 2016-08-09 00:11:07.945 INFO 26 --- [ foo.time.foo-1] TEST [log.sink : 08/09/16 00:11:07] 2016-08-08T17:11:09.92-0700 [APP/0] OUT 2016-08-09 00:11:09.925 INFO 26 --- [ foo.time.foo-1] TEST [log.sink : 08/09/16 00:11:09] 2016-08-08T17:11:11.94-0700 [APP/0] OUT 2016-08-09 00:11:11.941 INFO 26 --- [ foo.time.foo-1] TEST [log.sink : 08/09/16 00:11:11]
Deleting the old version foo-log
from the CF CLI would make all the payload consumed by the foo-log-v2
application. Now,
you’ve successfully upgraded an application in the streaming pipeline without bringing it down in entirety to do
an adjustment in it.
List Apps.
→ cf apps Getting apps in org test-org / space development as test@pivotal.io... OK name requested state instances memory disk urls foo-time started 1/1 1G 1G foo-time.cfapps.io foo-log-v2 started 1/1 1G 1G foo-log-v2.cfapps.io
Note | |
---|---|
A comprehensive canary analysis along with rolling upgrades will be supported via Spinnaker in future releases. |