Spring Cloud Config Client Actuator Refresh - spring

I have a Client which listens to config server. Config Server is pointing to github. Things work fine with localhost. However when i deploy the application to Kubernetes the Client endpoint to refresh the properties doesn't work properly.
Endpoint (Post) : http://config-client.sbx.com/actuator/refresh
This returns an empty response on Postman "[]" and Response code is 200 OK. I am able to see that the Config server is up and running on K8s.
Any suggestion on what could be wrong?
P.S. I have enabled DEBUG logs but do not see much information there.

Can you verify if the application link has got the hostname and the application name when doing the refresh. Because while doing a refresh in the localhost, it will just be springboot application locally, so there wont be any need for an additional path of application-name. Wherehas when you deploy to a server normally we have to give the path name of the application in addition to the hostname. In tomcat, the URL I use is as below,
http://<hostname>/**<application-name>**/actuator/refresh/
Normally when you hit this URL via postman, it will give you a 200 response with an empty body of []. And then, you should be able to see the below lines in the log files of the client application. [ Also I had the attribute #RefreshScope attribute at the main method of the application just below the #SpringBootApplication attribute to refresh the attributes of the application.]
INFO o.s.c.c.c.ConfigServicePropertySourceLocator.getRemoteEnvironment:249 - Fetching config from server at : http://<hostname>/<Config-server-application-name>/
INFO o.s.c.c.c.ConfigServicePropertySourceLocator.log:168 - Located environment: name=config-client, profiles=[development], label=null, version=ab36989c85922f1c9cf7803fac4, state=null
INFO o.s.c.b.c.PropertySourceBootstrapConfiguration.initialize:112 - Located property source: [BootstrapPropertySource {name='bootstrapProperties-configClient'}, BootstrapPropertySource {name='bootstrapProperties-https://<gitlaburl>/<companyname>/config-server.git/config-client-development.yml'}]
INFO o.s.boot.SpringApplication.logStartupProfileInfo:655 - The following profiles are active: development
INFO o.s.boot.SpringApplication.logStarted:61 - Started application in 1.557 seconds (JVM running for 70689.032)
For Kubernetes,
Try using
kubectl apply
(instead of kubectl create configmap.)
To deploy the config map, just run the following command on Kubernetes:
kubectl apply -f config-map.yml
Make sure the name of the config map matches the name of the spring boot application .Also see the below link ,
https://github.com/spring-cloud/spring-cloud-kubernetes/issues/255
Also there is a spring cloud kuberenetes which you can explore as below,
https://cloud.spring.io/spring-cloud-static/spring-cloud-kubernetes/2.0.0.M1/reference/html/#why-do-you-need-spring-cloud-kubernetes

Related

enable ssl logs in spring boot application from applicaiton.properties

I wanted to print the SSL handshake debug log, this can be achieved easily by using jvm argument -Djavax.net.debug=ssl:handshake:verbose.
My scenario, need to enable the ssl debug logs on a third-party springboot application image. Is it possible to use the jvm arguments in application.properties to print the SSL debug level log?
I don't have the option to update the Dockerfile to use java -Djavax.net.debug=ssl:handshake:verbose applicaiton.jar .....
I'm not sure you can do exactly that with application.properties but you should be able to get close by adding this:
logging.level.javax.net=TRACE
Have a look at this to see how to set logging levels in application.properties

Google Cloud Trace doesn't correlate logs from Spring Boot applications using Sleuth

I've recently upgraded my applications to Spring Boot 2.4.2, Cloud 2020.0.0, changing Spring Cloud GCP dependencies following the migration guide: https://googlecloudplatform.github.io/spring-cloud-gcp/2.0.0/reference/html/index.html#migration-guide-from-spring-cloud-gcp-1-x-to-2-x
Regarding the applications everything seems to be working fine. I can see calls between the microservices propagating the trace-id headers:
gateway:
2021-01-24 20:18:36.471 DEBUG [gateway,0bc6b9664e6604e2,eb9f834718fe33c9] 1 ---
service1:
2021-01-24 20:18:36.700 DEBUG [service1,0bc6b9664e6604e2,570653ac93add270,true]
In the Google Cloud Trace console I can see that the trace id (0bc6b9664e6604e2) was captured (prefixed with 16 extra 0's) and that it shows both microservices (the first post corresponds to gateway and the third call correspons to service1:
However notice the message "No logs found for this trace".
Also the Trace Logs View link complaints about it:
If I open the link it just looks by timestamp, not using the correlation trace id.
The funny thing is if I look for a log statement directly in the GCP Logging view, the trace id is there:
I can then run a GCP Logging query to find all the logs correctly:
Apparently everything seems to be OK. Could you tell why GCP Trace isn't able to correlate with GCP Logging?
For the logs to appear correlated with tracing you need to add the stackdriver log dependency (I think it only works if your log implementation is logback).
Check https://cloud.spring.io/spring-cloud-gcp/reference/html/#integration-with-logging

Spring boot microservices doesn't work with Intelij IDEA

I am creating a spring boot microservice project with intelij IDEA.
Currently I have developed three seperate spring boot rest services as customer service, vehicle service and spring cloud config server. Spring cloud config server is pointing to a github repository.
The issue is sometimes above projects take more than 10 minutes to run and sometimes does't run and give an error message as "failed to check application readystate intellij attached provider for the vm is not found". I have no idea why this happens ?
There are two possible causes:
1. IntelliJ IDEA and the Spring application are running in different JVMs.
There is a bug for IntelliJ IDEA regarding that:
https://youtrack.jetbrains.com/issue/IDEA-210665
Here is short summary:
IntelliJ IDEA uses local JMX connector for retrieving Spring Boot actuator endpoint's data by default. However, it could be impossible to get local JMX connector address via attach api if Spring Boot application and IntelliJ IDEA are run by different JVMs. In this case, add the following lines to VM options of your Spring Boot run configuration:
-Dcom.sun.management.jmxremote.port={some_port}
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
As mentioned in the official Oracle documentation, this configuration is insecure. Any remote user who knows (or guesses) your port number and host name will be able to monitor and control your Java applications and platform.
2. Prolonged time to retrieve local hostname
You can check that time using inetTester. Normally it should take only several milliseconds to complete. If it takes a long time then you can add the hostname returned by inetTester to /etc/hosts file like this:
127.0.0.1 localhost winsky
::1 localhost winsky

Spring Cloud Bus not working /bus/refresh call goes to controller and searching mapping in controller and failing

I have configured my application with config server and github supported external config files. It works fine when I am having single instance of my application in cloud foundry.
But for multiple instance it is said to implement spring cloud bus to apply external config changes to all the instances. For this I have bind my config server with rabbit MQ instance available on Pivotal Cloud foundry. have added spring.cloud.starter.bus.amqp jar in my build.gradle file.
Problem: But when I am hitting POST request to client app at:
http://server:port/bus/refresh the call goes to controller rather than refreshing all the instances and failing as no mapping for same.
Please let me know if I am missing any configuration to make spring-cloud-bus work.
Thanks in advance!
application.properties(Client application):
spring.profiles=cloud
spring.rabbitmq.host= 10.17.128.102
spring.rabbitmq.port= 5672
spring.rabbitmq.virtual-host= *****
spring.rabbitmq.username= ******
spring.rabbitmq.password= *****
rabbit.exchangeName= demoPartyServiceexc
rabbit.routingKey= demoPartyService
rabbit.queueName= demoPartyServicequeue
logging.level.ROOT= ERROR
bootstrap.properties(Client application):
spring.application.name=demo-api
spring.cloud.bus.enabled=true
spring.cloud.config.bus.enabled=true
spring.cloud.bus.amqp.enabled=true
spring.cloud.bus.refresh.enabled=true
spring.cloud.bus.env.enabled=true
spring.cloud.config.uri=https://config-a5e99419-8179-47f7-8c23-62ed5b38db0b.cf.com
spring.cloud.config.server.bootstrap=true
spring.cloud.config.server.git.uri= My Github repository URI
spring.cloud.config.server.git.username= ********
spring.cloud.config.server.git.password= ********
application.properties file in GIT repo:
logging.level.ROOT=WARN
What are server.servlet-path and management.context-path in client app set to?
I think you might need to send the request to http://host/<management.context-path>/bus/refresh.
Or better yet, to http://config-server-host/monitor so that it publishes a message to a topic in RabbitMQ and all client apps get notified.
Configuration snippets, source code and more details could be found at my blog post: Refreshable Configuration using Spring Cloud Config Server, Spring Cloud Bus, RabbitMQ and Git

Eureka First Discovery & Config Client Retry with Docker Compose

We've three Spring Boot applications:
Eureka Service
Config Server
Simple Web Service making use of Eureka and Config Server
I've set up the services so that we use a Eureka First Discovery, i.e. the simple web application finds out about the config server from the eureka service.
When started separately (either locally or by starting them as individual docker images) everything is ok, i.e. start config server after discovery service is running, and the Simple web service is started once the config server is running.
When docker-compose is used to start the services, they obviously start at the same time and essentially race to get up and running. This isn't an issue as we've added failFast: true and retry values to the simple web service and also have the docker container restarting so that the simple web service will eventually restart at a time when the discovery service and config server are both running but this doesn't feel optimal.
The unexpected behaviour we noticed was the following:
The simple web service reattempts a number of times to connect to the discovery service. This is sensible and expected
At the same time the simple web service attempts to contact the config server. Because it cannot contact the discovery service, it retries to connect to a config server on localhost, e.g. logs show retries going to http://localhost:8888. This wasn't expected.
The simple web service will eventually successfully connect to the discovery service but the logs show it stills tries to establish communication to the config server by going to http://localhost:8888. Again, this wasn't ideal.
Three questions/observations:
Is it a sensible strategy for the config client to fall back to trying localhost:8888 when it has been configured to use discovery to find the config server?
When the eureka connections is established, should the retry mechanism not now switch to trying the config server endpoint as indicated by Eureka? Essentially putting in higher/longer retry intervals and periods for the config server connection is pointless in this case as it's never going to connect to it if it's looking at localhost so we're better just failing fast.
Are there any properties that can override this behaviour?
I've created a sample github repo that demonstrates this behaviour:
https://github.com/KramKroc/eurekafirstdiscovery/tree/master

Resources