spring boot actuator refreshscope - java

I have an application which is running on multiple AWS hosts behind a load balancer. All of these instances load the configuration from a spring config server. I can use spring boot admin server to identify the the URL's so that I can execute the POST at hostname:port/actuator/refresh command for individual host using POSTMAN. As the number of hosts increase, it becomes difficult to run a command for each one of the hosts. Is there a way I can do the same with a single command?

We use something similar for our application
i.e Spring applications fetching properties from config server and a spring boot admin server to which all these application registers.
We have exposed an post api in bootadmin which calls refresh endpoint on all instances of specified app.
Since bootadmin has all information about registered apps, we are using it to 'publish' message to all 'subscribed' apps.

Related

Eureka instance appname not working with Spring Cloud Gateway

It seems like gateway can't resolve application registered in eureka server using eureka.instance.appname. In our case we have applications deployed in two different environment (uat and qa) but both will register on one clustered eureka server. We differentiate the applications from two environments using eureka.instance.appname. One is registered as service_app_uat and another one as service_app_qa however the spring.application.name is service.app. Eureka is able to register the app from two different environment just fine but Spring Cloud Gateway can't resolve these two registered instances from eureka. However if we removed the eureka.instance.appname both app from two environments registered as service_app with two instances which we don't want.
Is there any other way to register application in Eureka with custom service name?
Can't you just utilize Spring Profiles and provide different naming via spring.application.name?

How do http requests work in deployed Spring Boot app?

Can someone explain how hosting works ? in my spring boot app there'ss embedded tomcat server. as I understand the spring app runs with tomcat, tomcat takes some port, 8080 for example, and listens to requests coming to that port (when deployed locally at least) localhost:8080. I can make requests from my front end app, which runs on localhost:3000 and tomcat will take the requests, find controllers mapped to the urls that front request is directed to "/user" or "/myposts" or whatever, that controller runs code, talks to db inserts data into response and tomcat sends it back to front end.
If I deploy my app to some hosting service, like Google cloud, does the spring app still run with tomcat ? in that case which port will tomcat run on, where would my front end send requests to ? to the subdomain that google cloud has set up for my project ? Where would i need to configure SSL/https ? Would my front end send secure requests to google subdomain over https endpoints and it would relay those requests to deployed spring app through http(unsecured, inside hosting server) ? Or how ?
One of the most straightforward way to do this is to spin up an instance, ssh into the that instance and run your spring boot app the same way you would run it on your machine. Everything works the same as it would on that cloud instance. Your spring boot app still runs within tomcat and it still listens to port 8080. The only difference is now the hostname is no longer localhost and it will be the DNS name of that instance. You can find the DNS name on the console.
You need to get a SSL certificate if you wanna enable https "natively" in your spring boot app. Alternatively, you can set up a load balancer or an API gateway in front of your cloud instance to do the SSL termination for you. In this case, your frontend will send request to the load balancer or API gateway instead of your spring boot app. They accept https requests and transform them to http request and send it to your spring boot app.

Is there any use of registering my config server in Eureka?

I'm specifying the config server URI spring.cloud.config.uri in the bootstrap.properties file of all my config server clients.
So is there any use of adding an #EnableDiscoveryClient annotation to it, and registering the configuration service in Eureka?
There are various use cases why registering your config server on Eureka could be useful:
Discovery-first bootstrapping
When using the Spring cloud config service, you have two choices when bootstrapping your application, as mentioned by the documentation:
Using a config-first setup (default)
Using a discovery-first setup
When you use a discovery-first setup, all applications can retrieve their configuration by looking up the URL of the configuration service on Eureka:
spring.cloud.config.discovery.enabled=true
spring.cloud.config.uri=http://config-service
In this case, the application will look for a service named config-service on Eureka, and will use the given hostname and port to connect.
Discoverability
Some tools, like Zuul, Spring boot admin, ... will automatically discover all applications and use them, for example:
Spring boot admin can be setup to automatically discover all applications to manage them.
Zuul will automatically forward all routes matching /{application-name}/** to the given application.
#EnableDiscoveryClient activates the Netflix Eureka DiscoveryClient implementation and tells it to register itself with a service registry.
So, without this annotation, your application will not able to register itself to any Registry. And hence will not be discovered from any service as well.
Edit: Registering your application to DiscoveryServer provides many benefits, some of them are below :
Application independence: When you register your application to DiscoveryServer it decouples it from another application. Doing so you don't need to hardcode the name and URL of your application in using application.
Load Balancing: Register your application to DiscoveryServer provides an effective and efficient way to provide load balancing.
Multiple instances of same application: In order to provide load balancing you can add multiple instances of a single application.
Resilience: When an instance is not working then Server can use the circuit breaker to handle requests effectively and helps in making system responsive and resilient.

spring boot application in cluster

I am developing a spring boot application.
Since spring boot created a .jar file for an application.
I want to cluster this particular application on different server. Lets say I build a jar file and ran a project then it should run in cluster mode from number of defined servers and should be able to serve end user needs.
My jar will reside on only one server but it will be clustered across number of servers. When end user calls a web service from my spring boot app he never know from where it is getting called.
The reason behind clustering is suppose any of the server goes down in future, end user will still be able to access web services from another server. But I don't know how to make it clustered.
Can any one please give me insight on this ?
If you want to have it clustered, you just run your Spring Boot application on multiple servers (of course, the JAR must be present on those servers, otherwise you can't run it). You would then place a loadbalancer in front of the application servers to distribute the load.
If all services you are going to expose are stateless so you only need to use load balancer in front of your nodes for ex. apache or nginx, if your services are stateful "store any state [session, store data in db]" so you have to use distributed cache or in memory data grid:
for session you can use spring-session project which could used rails to store sessions.
for store data in DB you need to cluster DB it self and can use distributed cache above your DB layer like Hazelcast.
Look into spring cloud, they have used some netflix open software along with amazons to create 12 factor apps for micro services.
Ideally you would need a load balancer, service registry that can help you achieve multiple instances of spring boot. I believe you have to add a dependency called eureka.
Check the below link
Spring cloud
You can deploy it in cloud foundry and use autoscale function to increase your application instances.

Name based virtual hosting with Spring Boot

I am looking for the best method to host multiple websites developed using Spring Boot.
I have a public IP and it points to EC2 machine.
Already I am running one web application on it, developed using Spring Boot.
Now, I am looking for a way to create my second Spring Boot application(running on a different port).
My configuration should result like this(Single public IP),
www.app1.com(x.x.x.x) => Spring Boot App1
www.app2.com(x.x.x.x) => Spring Boot App2
I found many articles on internet dealing with conf/server.xml file, http://tomcat.apache.org/tomcat-7.0-doc/config/host.html
Can someone help me to achieve the same
The best way is probably to use a reverse proxy front end. E.g. install nginx on your EC2 box, or (probably better if you are serious about it) use an ELB, and Route 53 to register your DNS record.

Categories