How to make sure there will be a fixed DB server across multiple deployments in Cloud Foundry? - microservices

I am a newbie with CF microservices and I am trying to deploy a service multiple times. As far as I understood, each time I deploy into a space the application is getting a different database server and schema. Is there a way to tell the Cloud Foundry to use only a fixed DB server all the times across multiple deployments in one environment?

The keyword for your case is 'Service Instance'
You can create a service instance of database server within the environment specific for your application and bind it via application manifest.
e.g.
cf create-service rabbitmq small-plan myapplication-rabbitmq-instance
As long as you have a binding to myapplication-rabbitmq-instance in your application manifest it would be preserved/be the same between application deployments within this space.
e.g. in your application manifest:
---
...
services:
- myapplication-rabbitmq-instance
More on https://docs.cloudfoundry.org/devguide/services/

Related

How PCF works internally when deploying Spring boot project

Will PCF run the Tomcat embedded in Spring boot jar or it runs its own tomcat. In PCF we never mention the port number. In the classic approach, we start 3 Tomcat instances in different port number and have apache server before that. Does PCF work the same way.
This is a pretty broad question, so I'm going to answer with a pretty broad response but link you to where you can find more details, if you are inclined to dig in more.
How PCF works internally when deploying Spring boot project
Will PCF run the Tomcat embedded in Spring boot jar or it runs its own tomcat.
When you run cf push -p my/cool/file.jar (or even file.war), the cf cli extracts everything from that archive and pushes it up to CF. CF stores your app files & then your app is staged.
During staging, the Java build pack runs. It looks at all the files that were pushed & tries to determine what to do with them. It knows how to handle several different types of apps [1], including both standard WAR files & Spring Boot apps. The build pack will check your app to see if its one of the supported types in order [2] and will select the first match.
After selecting the type of app, it runs through and installs what is necessary to run your app. For a Spring Boot app, that's basically just the JVM. For a WAR file, it installs Tomcat & a JVM. In addition, it writes out the configuration & start up commands necessary for CF to launch your app.
At this point staging is complete and you have what is called a "droplet". If you have any additional questions on the staging workflow, read here for more details [3].
At this point, the app would be started. The platform takes the droplet that was created and executes the command specified by the build pack to start the app [4]. If all goes well, your app will then be up and running on CF.
In PCF we never mention the port number.
Correct. The platform will tell you the port on which your application should listen. For Java apps, you don't have to do anything. The Java buildpack will handle configuring Spring Boot or Tomcat to start and listen on the correct port.
For Spring Boot apps, you can look at the start up command to see how it's doing this. For Tomcat, it happens in the server.xml that's generated by the Java buildpack [5].
In the classic approach, we start 3 Tomcat instances in different port number and have apache server before that. Does PCF work the same way.
Yes and no. Each application you run can have multiple instances. If you scaled your app to have three instances, that would be roughly like having 3 Tomcat instances in your classic approach.
The main difference is that there would be no Apache Web Server in front. On Cloud Foundry, this is not necessary because it has it's own load balancer called Gorouter [6] which handles proxying traffic to your app and load balancing across available app instances.
This is a classic mistake that people new to CF make. They try to replicate classic architectures and shoehorn a reverse proxy into their app when it's not necessary. This is one of the benefits of CF. It handles routing traffic to your app in a scalable way, freeing you up to focus more on your app.
[1] See "Standard Containers -> https://github.com/cloudfoundry/java-buildpack#additional-documentation
[2] https://github.com/cloudfoundry/java-buildpack/blob/master/config/components.yml#L18
[3] https://docs.cloudfoundry.org/concepts/how-applications-are-staged.html
[4] https://docs.cloudfoundry.org/concepts/overview.html#apps-anywhere
[5] https://github.com/cloudfoundry/java-buildpack/blob/master/resources/tomcat/conf/server.xml#L21
[6] https://docs.cloudfoundry.org/concepts/architecture/#routing
No. The simple answer is each instance of ur application jar is running in its own container within PCF. So there is no clash of using the same port numbers.

Spring Cloud Dataflow deployment on premises Cloud Foundry

I'm deploying Spring Cloud Dataflow 1.4.0.RELEASE on my org's Cloud Foundry. I took the CF deployable server and used a manifest to deploy it. We use it mostly for tasks developed using Spring Cloud Task. In the documentation (that uses PCF) suggests this configuration:
SPRING_CLOUD_DEPLOYER_CLOUDFOUNDRY_TASK_SERVICES my_mysql
Where my_mysql is the DB to keep track of task related information. Documentation suggests using this as CF's cups but that won't work since my org uses Vault to store keys and secrets so DB connections are not allowed in such way.
Since I did not provided any value for SPRING_CLOUD_DEPLOYER_CLOUDFOUNDRY_TASK_SERVICES in my manifest when I start SPDF it throws an error indicating that bean "taskService" could not be created.
Haven't found a workaround for this. Is this the only way to specify DB connection for tasks in version 1.4?
You can also pass a deployment property when launching the task:
task launch --name mytask --properties "deployer.mytask.cloudfoundry.services=-Duser.timezone=my_mysql"
This way, you don't have to use the server level environment property SPRING_CLOUD_DEPLOYER_CLOUDFOUNDRY_TASK_SERVICES

Understanding Microservice Architecture

Since I am trying hard to understand the microservice architecture pattern for some work, I came across the following question:
It's always said that a microservice usually has its own database. But does this mean that it always has to be on the same server or container (for example having one docker container that runs a MongoDB and my JAR)? Or can this also mean that on one server my JAR is running while my MongoDB is located somewhere else (so two containers for example)?
If the first one is correct (JAR and database within one container), how can I prevent that after some changes regarding my application and after a new deployment of my JAR my data of the MongoDB is resetted (since a whole new container is now running)?
Thanks a lot already :-)
Alternative opinion:
In 99% of real life cases you musnt have a single container that runs
database and the application, those should be separated, since one
(db) is keeping state, while the other (app) should be stateless.
You don't need a separate database for microservice, very often a separate schema is more than enough (e.g. you dont want to deploy a separate Exadata for each microservice :)). What is important is that only this microservice can read and write and make modifications to given tables others can operate on those tabls only through interfaces exposed by the microservice.
First of all each Microservice should have its own database.
Secondly it's not necessary and also not recommended to have the Microservice and its database on the same container.
Generally a single Microservice will have multiple deployments for scaling and they all connect to a single Database instance which should be a diff. container and if using things like NoSql DB's its a database cluster.
Yes, Each Microservice should have its own database and if any other Microservice needs data owned by another microservice, then they do it using an API exposed by Microservices. No, it's not at all necessary to have the Microservice and its database to be hosted on the same server. For Example - A Microservice can be hosted on-premise and its database can live in the cloud like AWS DynamoDB or RDS.

How to run Spring Cloud Config server in Fault Tolerance mode?

In my project we have a requirement to run two instances of spring cloud config server so if one instance goes down, other will take care the config server responsibilities.
Currently, you would need to put config server behind a load balancer. It is stateless, so that wouldn't hurt. There is an open issue to configure multiple config server url's in the client, so it could do failover there.
If you are running multiple instances of the config server, you can have them all register themselves in Eureka, and maybe do a lookup to the config server with it's application name via Eureka in all the other microservices. This way, Zuul (and Ribbon) will take care of the load balancing.
Edit:
I guess spencergibb is right. It's best to use a load balancer, for eg: ELB, if you're going to deploy on AWS.
Consider multiple spring-cloud-config-uris for high availability

IBM Worklight - Can Worklight be deployed to an existing WAS server?

Can a Worklight Server be deployed to a WebSphere application server which also runs other non-Worklight .ear applications? Or does Worklight need its own separate instance of WAS?
Just like you can deploy multiple instances of Worklight (v6 and above) projects - multiple .war files to the same WAS application server, there should not be issues to deploy it to an application server running other services.
That said, possible issues to consider:
When deploying a Worklight project, you will want to enable "application security"
(in the WAS admin console, Security > Global Security). If there are some other web
applications for which application security is undesired, you need a different WAS server
instance.
Setting up, enabling and migrating security
The list of users that can use the web applications are configured through LDAP or
"federated repositories", or similar. If, for Worklight, you need to use a completely
different set of user logins than for the other web applications, then you need to use
multiple "security domains".
Configuring multiple security domains
The machine hosting the application server will probably need memory upgrades...
Deploying the Enterprise Archive (EAR) Using the WebSphere Admin Console
Probably also need to make clear seperation where required:
IBM WebSphere Developer Technical Journal: Co-hosting multiple versions of J2EE applications
Worklight is itself an application running inside a web container, whether that be Tomcat, WAS Liberty, or full WAS. It's essentially a layer running underneath the container to handle requests for Worklight applications, fielding their context root requests. If you create the WAR file for your Worklight app and extract out the deployment descriptor you'll find all the necessary filters and listeners that most other apps would have.
Things like adapters and wlapps are "installed" to this underlying layer, and are merely extracted and stored as whatever was packaged with them, such as the JS and CSS you used to make you app. In fact, with a standard Liberty install you can typically find your adapters in plain sight at (for the WL5.0.6 instance I have handy, it's different for WL6):
/opt/IBM/Worklight/server/wlp/usr/servers/worklightServer/worklight.home/worklight/data/export/adapters
So, in addition to what Idan has said, I also present you with the following docs (assuming WL6)
Overview of the Worklight Server installation process
Given my own experience, you should be perfectly able to install other EAR and WAR files to your existing WAS instance, just make sure your context roots are unique, as always ;)
I also second the memory considerations.

Resources