How to run a spring application on cloud foundry a

2019-06-22 13:27发布

问题:

I would like to run a spring application on cloudfoundry as a one-off task using the java buildpack.

Please note that my app is not a web application but a spring batch application that also uses spring cloud task.

Here is my manifest:

---
buildpack: https://github.com/cloudfoundry/java-buildpack.git
memory: 1024M
env:
  APPLICATION_URL: http://bignibou-server.cfapps.io/
  APPLICATION_MAIL_NO_REPLY_ADDRESS: balteo@bignibou-server.cfapps.io
  SPRING_PROFILES_ACTIVE: cloud

applications:
- name: bignibou-server
  path: bignibou-server/build/libs/bignibou-server.jar
  env:
    APPLICATION_GOOGLE_API_KEY: ******************
- name: bignibou-batch
  path: bignibou-batch/build/libs/bignibou-batch.jar
  no-hostname: true
  no-route: true
  command: null
  health-check-type: none
  env:
    JAVA_OPTS: -Dspring.batch.job.names=messagesDigestMailingJob

Whenever I push the app, it is detected as a worker app:

App bignibou-batch is a worker, skipping route creation

which is what I want.

But then it tries to start the batch as a web application (still whilst deploying the app)... See:

2017-03-24T22:33:50.828+01:00 [CELL/0] [OUT] Destroying container
2017-03-24T22:33:50.854+01:00 [API/3] [OUT] Process has crashed with type: "web"
2017-03-24T22:33:50.873+01:00 [API/3] [OUT] App instance exited with guid befc8bf2-d338-45e1-90b9-430ff3b09a3f payload: {"instance"=>"", "index"=>0, "reason"=>"CRASHED", "exit_description"=>"2 error(s) occurred:\n\n* Codependent step exited\n* cancelled", "crash_count"=>1, "crash_timestamp"=>1490391230813627797, "version"=>"8f92e459-a6c7-4558-bc0b-09ac398eb069"}
2017-03-24T22:33:51.473+01:00 [CELL/0] [OUT] Successfully destroyed container
2017-03-24T22:33:51.634+01:00 [CELL/0] [OUT] Creating container
2017-03-24T22:33:52.478+01:00 [CELL/0] [OUT] Successfully created container
2017-03-24T22:33:56.824+01:00 [APP/PROC/WEB/0] [OUT] JVM Memory Configuration: -XX:MaxMetaspaceSize=164239K -XX:ReservedCodeCacheSize=240M -XX:CompressedClassSpaceSize=25984K -Xmx295151K -XX:MaxDirectMemorySize=10M
2017-03-24T22:33:56.827+01:00 [APP/PROC/WEB/0] [ERR] JVM Memory Configuration: -XX:ReservedCodeCacheSize=240M -XX:CompressedClassSpaceSize=25984K -Xmx295151K -XX:MaxDirectMemorySize=10M -XX:MaxMetaspaceSize=164239K
2017-03-24T22:33:59.073+01:00 [APP/PROC/WEB/0] [OUT] . ____ _ __ _ _
2017-03-24T22:33:59.073+01:00 [APP/PROC/WEB/0] [OUT] /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
2017-03-24T22:33:59.073+01:00 [APP/PROC/WEB/0] [OUT] \\/ ___)| |_)| | | | | || (_| | ) ) ) )
2017-03-24T22:33:59.073+01:00 [APP/PROC/WEB/0] [OUT] ' |____| .__|_| |_|_| |_\__, | / / / /
2017-03-24T22:33:59.073+01:00 [APP/PROC/WEB/0] [OUT] =========|_|==============|___/=/_/_/_/
2017-03-24T22:33:59.073+01:00 [APP/PROC/WEB/0] [OUT] ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
2017-03-24T22:33:59.075+01:00 [APP/PROC/WEB/0] [OUT] :: Spring Boot :: (v1.5.2.RELEASE)
2017-03-24T22:33:59.266+01:00 [APP/PROC/WEB/0] [OUT] 2017-03-24 21:33:59.256 INFO 16 --- [ main] pertySourceApplicationContextInitializer : Adding 'cloud' PropertySource to ApplicationContext
2017-03-24T22:33:59.381+01:00 [APP/PROC/WEB/0] [OUT] 2017-03-24 21:33:59.359 WARN 16 --- [ main] o.c.r.o.s.cloud.AbstractCloudConnector : No suitable service info creator found for service elasticsearch Did you forget to add a ServiceInfoCreator?
2017-03-24T22:33:59.389+01:00 [APP/PROC/WEB/0] [OUT] 2017-03-24 21:33:59.388 INFO 16 --- [ main] nfigurationApplicationContextInitializer : Adding cloud service auto-reconfiguration to ApplicationContext
2017-03-24T22:33:59.465+01:00 [APP/PROC/WEB/0] [OUT] 2017-03-24 21:33:59.451 INFO 16 --- [ main] com.bignibou.batch.Batch : Starting Batch on a1e87528-637d-4dae-62ab-0538e48fb49b with PID 16 (/home/vcap/app/BOOT-INF/classes started by vcap in /home/vcap/app)

which is not what I want...

So my questions are:

  • How can I configure my manifest in order for the batch app to be pushed properly without starting automatically - I just want the binaries pushed to cf so that I can run tasks later on...
  • How can I start my spring batch as a cf task on cloudfoundry?

回答1:

How can I configure my manifest in order for the batch app to be pushed properly without starting automatically - I just want the binaries pushed to cf so that I can run tasks later on... How can I start my spring batch as a cf task on cloudfoundry?

In order to run a task, you need an app to be deployed and to be completely staged (so there's a droplet). You can then cf run-task <app> <task-cmd>.

A couple ideas:

First option, you could use a manifest.yml like this:

---
applications:
- name: spring-music
  memory: 32M
  path: build/libs/spring-music.war
  health-check-type: none
  no-route: true
  command: while [ 1 == 1 ]; do sleep 9999; done
  buildpack: java_buildpack

This will setup an app with a very small memory limit and a command that essentially does nothing forever (the forever part is key so that the app will completely stage and start). We also set the health check to none and no route, so that no route is bound and no TCP health check is done. You can optionally set your build pack.

Then run cf push. The app should stage and start OK. After that you can cf run-task as many times as you want. You can optionally stop the app.

Second option, just push your app without making any special manifest.yml configurations. The app should stage properly, fail to start running then after it's failed you can cf stop the app. From there, you should be able to cf run-task as many times as you want.

You might also be able to use the v3 API directly, which would give you some additional flexibility, but all the interaction is manual via cf curl at this point.

If you want to see a concrete example of how to use cf run-task, see Selwyn's answer.



回答2:

push your app like so to pcf

cf push --health-check-type none -p myapp-0.0.1-SNAPSHOT.jar myapp

use the special task launcher to start your app as a task. You can also append arguments after the ".JarLauncher arg1" that will show up as string[] args to your main method or CommandLineRunner

Runs the task using the Task runner. This support for tasks is built into the platform.

cf run-task myapp ".java-buildpack/open_jdk_jre/bin/java org.springframework.boot.loader.JarLauncher arg1" --name my-task

Note link below also shows you have to schedule it

Source: https://github.com/joshlong/cf-task-demo