I have serveral microservices communicating with each other.
For general configuration I use Spring Cloud Config which works well.
Some of the services need to access database resources of a legacy system. So they need to know where the database (databases in a multi-tenant environment) is located and which credentials to use.
Using Spring Cloud Config I see two possibilities:
application.properties: This would expose the db settings to all services. That´s no option.
my-crazy-service.properties: This would work fine but I would have to configure any service which needs db access. Doesn´t scale well.
So my idea is to implement another microservice which is responsible for any connection infomation. This service exposes a rest endpoint using spring-data-rest.
In case Service A wants to use the legacy db it can call the new service and ask for the required data.
Now I wonder when the best time is to request the connection info from the remote service.
On startup of each microservice? Where should such startup code be located?
In general where should initialization stuff be done?
Related
I am setting up the Spring-boot microservices with the cluster bi-direction Pivotal cloud cache.
I have set up the bi-directional cluster in Pivotal Cloud, I have a list of locators with ports.
I have already some online docs.
https://github.com/pivotal-cf/PCC-Sample-App-PizzaStore
But couldn't understand the on which configuration the spring boot app will know to connect.
I am looking for some tutorial or some reference where I can have spring boot app linked up with the PCC(gemfire)
The way you configure a app running in PCF (Pivotal Cloud Foundry) to talk to a PCC (Pivotal Cloud Cache) service instance is by binding the app to that service instance. You can bind it either by running the cf bind command or by adding the service name in the app`s manifest.yml, something like the below
path: build/libs/cloudcache-pizza-store-1.0.0-SNAPSHOT.jar
services:
- dev-service-instance
I hope you are using Spring Boot for Apache Geode & Pivotal GemFire (SBDG) in your app, if not I recommend you to use it as it makes connecting to PCC service instance extremely easy. SBDG has the logic to extract credentials, hostname:ports needed to connect to a service instance.
You as a app developer just need to
Create the service instance.
Bind your app to the service instance.
The boilerplate code for configuring credentials, hostnames, ips are handled by SBDG.
When you deploy an application in Cloud Foundry, (or Pivotal Cloud), you need to bind it to one or more services. Service details are then automatically exposed to the app via the VCAP_SERVICES environment variable. In the case of PCC this will include the name and port of the locator. By adding the spring-geode-starter (or spring-gemfire-starter) jar to the application it will automatically process the VCAP_SERVICES value and extract the necessary endpoint information in order to connect to the cluster.
Furthermore, if security is enabled on your PCC instance, you will also need to have created a service key. As with the locator details, the necessary credentials will be exposed via VCAP_SERVICES and the starter jar will automatically process and configure them.
I recently have learnt and practicing Microservice using Spring technology. I am currently writing a small program that has Eureka Server, Configuration Server, Gateway and Account service. I have all of my services register its instance to Eureka and have my Gateway gets its configuration from Configuration Server. After that, I got some question, should I my Account Service fetch its configuration directly from Configuration Server, or from Gateway because it can be done in both way. I think, if I decide to fetch it through Gateway, it might be better because Gateway is a load balancer, so in case if there are multiple Configuration Servers out there, I don't need to worry if any of them failed or down as Gateway can handle this for me. But, doing so, isn't I put too much weight on Gateway because it need to handle this and another requests. Furthermore, I am not sure and I can't find any information about if there is a way to load balancing Gateway or is it makes sense to do so?
Please advice and explain. Thank you.
Only user's requests from UI need to be passed via Gateway. Services should be able to fetch their configuration during startup disregarding whether gateway is online or doesn't exist at all.
Also I'd advise you to avoid registering config service in Discovery (Eureka). I suppose there is no need for your users to send requests to config service.
Along with spring cloud config and gateway documentation I'd recommend you to get familiar with these 2 books:
https://www.manning.com/books/enterprise-java-microservices
https://www.manning.com/books/spring-microservices-in-action
Was wondering the recommended way of starting a spring boot app if the Spring cloud config server is temporarily down or unavailable. What would be the approach? I know of the retry configurations, but I am wondering if there is a way to have a 'replica' config server and use that as a failover (or something along those lines).
Sure, why not?
After all, spring-cloud-config server exposes rest API and all the interaction with spring boot microservices is done over HTTP.
From this point of view, you can scale out the spring cloud config server by providing more than one instance of it all are up-and-running and mapping them to one virtual IP.
If you're running in some kind of orchestrated environment (like kubernetes) it is a very easy thing to do.
I am fairly new in microservices architecture. I've been trying to build a microservices stack using Spring Boot, Spring Cloud and Netflix OSS libraries.
I want to know what is the correct way and place to store session.
Here is an overview of the infrastructure that I created:
OAuth2 backed Authorization/Authentication Server
UI Service (Spring Boot, Front end service)
Backend Service-1
Backend Service-2
Redis Server to store session and other cachable data
Discovery Server (eureka)
Currently, I'm trying to store session in Redis by configuring UI service to perform it. It seems to be working fine, although I haven't had the chance to try it for multiple service instances. However, I'm already having serialization/deserialization issues while developing.
By the way, trying to store the session on front end app is the correct place to do or it should be done in Authorization/Authentication service as authentication is processed in that service?
Here is my Session config in UI service (front end service)
#Configuration
#EnableRedisHttpSession
public class SessionConfig extends
AbstractHttpSessionApplicationInitializer {
public SessionConfig() {
super(RedisConfig.class);
}
}
To sum up, I'm expecting to achieve and use best practices on this project. Your kind assistance would be appreciated.
The idea of a general server side user session and a microservices style architecture don't go together well. The reason being that you are likely to break the separation of concern that you use separate the domain boundaries of your services.
Remember, every service is supposed to service a specific domain problem autonomously - including all required data persistence. So for example if there is anything to remember for a users connected devices you would do that in the one service that is responsible for those device connections and nowhere else. The service would be responsible for processing those request and persisting any status that the devices require. Similarly when there is anything to remember about he users authorization you would do that in the authorization service.
And regarding the question to use Redis or not - In a microservices architecture the choice of storage system would be up to the service architect. Maybe one service stores its data in a relational database, maybe another uses a key-value-store and yet another may use an event queue system or a time series database.
So in summary you have to ask yourself what your session really is used for and make the corresponding services responsible to persist that information in a domain specific way. (If you give some more details in your question about this, I can give you my opinion).
I have spring web application (not spring boot) running in AWS. I am trying to create centralized configuration server. How to refresh the spring-cloud-client after the changing the properties? As per tutorial
Actuator endpoint by sending an empty HTTP POST to the client’s refresh endpoint, http://localhost:8080/refresh, and then confirm it worked by reviewing the http://localhost:8080/message endpoint.
But my aws Ec2 instances are behind the loadbalancer so i can't invoke the client url. I didn't understand the netflix Eureka and Ribbon much but it seems like adding another level of load balancer in the client side. I don't like this approach. Just to change a property i don't want to make the existing project unnecessarily complex. Is there any other way? or Am I misunderstood Eureka/Ribbon usage?
I have looked at the spring-cloud-config-client-without-spring-boot, spring-cloud-config-client-without-auto-configuration none of them have answer. First thread was answered in 2015. Wondering is there any update?
To get the configuration properties from a config server. You can do a http request. Example:
From the documentation we can see:
/{application}/{profile}[/{label}]
/{application}-{profile}.yml <- example
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
So if you would do a request to http://localhost:8080/applicationName-activeProfile.yml you would receive the properties in .yml format for the application with that name and active profile. Spring boot config clients would automatically provide these values but you will have to provide em manually.
You don't need Eureka/Ribbon for this to work, it's a separate component.
More info: http://cloud.spring.io/spring-cloud-static/spring-cloud.html#_spring_cloud_config
Maybe you could even use spring-cloud-config but I'm not sure what extra configuration is needed without spring-boot.
https://cloud.spring.io/spring-cloud-config/