What is the recommended configuration when running both Config Server with Eureka Server? Should Config Server be a client of Eureka? Or should Eureka be dependent on Config Server properties for its configuration? Or is both OK?
The default way to use Eureka and Config Server is to use Config First bootstrap. Essentially, you make eureka server a client of the config server but you don't make the config server a client of eureka.
As said by David Syer on these (and this) issues, the founder of spring cloud, you have to use the config server with a front end load balancer, so a single URL is already highly available.
I'm also a newbie in Spring Cloud but I agree with him since Eureka is a Service Discovery, IMHO it should function on it's problem domain only. It would make a complicated logic for Eureka servers who are asking the Config servers for it's configuration. I can't imagine how the Eureka Server would know which config server to get if the Config Server is also the Server of Eureka to get its list of defaultZone.
It would be much more simpler for me to separate the Config Server's HA.
Based on #Mideel's answer
Eureka and Config Client configuration (needs to be Bootstrap):
# bootstrap.yml
cloud:
config:
discovery:
enabled: true # This is required
service-id: configserver # Config Server's eureka registry name
enabled: true # This is default true already
Config Server configuration:
spring:
application:
name: configserver # Needs to match client configuration
Register the Config Server with the annotation #EnableEurekaClient (it should be Auto Configured to register with Eureka already though)
The Spring Cloud Config service provides configuration info for various other microservices, of which the Eureka service is one.
Each app/microservice is pointed to its configuration (from the Config service) via bootstrap.properties/.yml, which is loaded in the parent context for that application, before the app "recognizes" that it is a discovery/Eureka client per its annotated main class. This bit of documentation provides a bit more detail on that process.
Cheers,
Mark
EDIT1: I think this is a wrong answer, see the replies
If you use Spring Boot:
I'm using Spring Microservices in Action as my guide book and based on the source code example there, we make the configuration server as the Eureka Client with the #EnableEurekaClient annotation and in the config server application.yml, we need to add this property:
spring:
cloud:
config:
discovery:
enabled: true
And in the other Eureka client that uses this config server, you need to add this property to the application.yml :
spring:
cloud:
config:
enabled: true
That's it, just set up the config server normally, I think behind the scene the config libraries from spring cloud will take care of the rest using Eureka.
Related
I'm trying trying to write some basic microservices examples. Firstly, I'm using a ConfigServer application using Spring, with this resources/application.yaml file:
server:
port: 8081
spring:
cloud:
config:
server:
git:
default-label: main
uri: https://github.com/mguzm4n/microservices-data
search-paths: config-data
application:
name: config-server
You can see the repo: https://github.com/mguzm4n/microservices-data
For Eureka, in resources/bootstrap.yaml:
spring:
application:
name: eureka-server
cloud:
config:
enabled: true
uri: http://localhost:8081
I build first ConfigServer App and then Eureka service, so it can load its config on Git, but I can't manage it to work. Eureka ends up running on localhost:8080 instead of port 8761 as shown in https://github.com/mguzm4n/microservices-data/blob/main/config-data/eureka-server.yaml.
Could anyone help me?
I'm new using this concepts like a config server and eureka for registering other services, so I'm sorry if it's something simple.
Looks like your eureka-server is not picking up the bootstrapping config.
First cause might be that this config file should be named bootstrap.yml, not bootstrap.yaml.
Also, since Spring Boot 2.4 bootstrapping via bootstrap.yml is disabled by default and the usual application.yml should be used instead or it can be enabled back by adding the org.springframework.cloud:spring-cloud-starter-bootstrap dependency to your project.
I have a Spring Cloud Config server for configuration, a Eureka server for service discovery, and two app servers (App A and App B).
I'm trying to share a logging configuration (log4j2) between App A and App B by utilizing Spring Cloud Config for serving the configuration file. I can make the config file available from the server (http://localhost:1234/log4j2/default/config/log4j2.properties).
If I hardcode that value in my application configs (also served by my config server) then my applications can read the log4j config and everything works. However, I don't want to put the absolute URL of the config server in my application configuration file, as the config server information should be provided by the Eureka discovery server.
Sort of a chicken/egg problem. Does anybody have a method for resolving this?
I want to know if there is a way to filter the registration in eureka according to the URL.
For exemple Prohibit localhost instances.
and thank you.
I do believe you can use the preferredNetworks property on Eureka Client, here's a YAML configuration sample:
spring:
cloud:
inetutils:
preferredNetworks:
- 192.168
- 10.0
Instead of configuring it on application.yml add this configuration to the bootstrap.yml file.
You can read more on the official documentation.
Context
I'm developing a proof of concept with Spring Zuul and Eureka. I want Zuul to work as an API Gateway and I want it to discover my microservices registered in Eureka. I want my microservices to be versioned. Zuul, Eureka and each microservice run on their own (I have a separate project for all of them).
I'm using Spring Boot 1.5.3 and Spring Cloud Dalston. But I can upgrade, if necessary.
Now, let's say that I have one microservice configured in the following way in the application.yml:
spring:
application:
name: microservice-v1
server:
port: 11001
eureka:
client:
serviceUrl:
defaultZone: http://localhost:11000/eureka/
This microservice has a GET /microservice REST endpoint configured which I can access from the address http://localhost:11001/microservice. It runs well and it registers itself with Eureka.
This ZuulReverseProxy.java is the main class of my Zuul project:
#SpringBootApplication
#EnableDiscoveryClient
#EnableZuulProxy
public class ZuulReverseProxy {
public static void main(String[] args) {
SpringApplication.run(ZuulReverseProxy.class, args);
}
}
Based on the Spring Cloud Docs, I have this configuration class:
#Configuration
public class ZuulConfiguration {
#Bean
public PatternServiceRouteMapper serviceRouteMapper() {
return new PatternServiceRouteMapper(
"(?<name>^.+)-(?<version>v.+$)",
"${version}/${name}");
}
}
And this is the application.yml of my Zuul project:
spring:
application:
name: zuul
server:
port: 8888
zuul:
prefix: /api
strip-prefix: true
eureka:
client:
serviceUrl:
defaultZone: http://localhost:11000/eureka/
Zuul looks into Eureka, gets the list of registered microservices and creates a mapping for each one according to the PatternServiceRouteMapper above. I'm not ignoring any services for now.
All of the above, allows Zuul to redirect http://localhost:8888/api/v1/microservice/microservice to http://localhost:11001/microservice, for example. In a more general way, it redirects anything with the path /api/v1/microservice/<some-path> to http://localhost:11001/<some-path>
Question
How can I avoid writing microservice twice in the URL, but still be able to request the mapping /microservice in the controller of my microservice?
A solution to this problem could be requesting the mapping / instead of /microservice. But I don't want to do that. The reason is that I'm using Swagger and its Codegen to generate interfaces and if I request the mappings without writing a collection name, I feel that my specification is not as good.
I thought of writing a route Zuul filter, but I couldn't find a good example. Also, I think that if I could alter the code that handles the moment when Zuul tries to map the Eureka services to a path, that could be a solution.
When not in conjunction with Eureka, Zuul allows to specify an input path and a forward URL with address, port and something else. The same should be possible when specifying a Service Id. Maybe I can modify some code in a way that the routing is still dynamic but that I can add that something else.
Would modifying the classes SimpleRouteLocator or ZuulHandlerMapping help? or is another class in charge of that dynamic routing? Also what would be the best way of implementing something like this?
Edit
I realized that when you configure Zuul like this for example:
zuul:
add-proxy-headers: true
sensitive-headers: Cookie,Set-Cookie
routes:
uaa:
path: /uaa/**
service-id: oauth-v1
strip-prefix: false
sensitive-headers:
It does what I want it to do. That strip-prefix is different from the global one.
When I configured my Zuul that way, in the log I see:
... o.s.c.n.zuul.filters.SimpleRouteLocator : Matching pattern:/uaa/**
... : route matched=ZuulProperties.ZuulRoute(id=uaa, path=/uaa/**, serviceId=oauth-v1, url=null, stripPrefix=false, retryable=null, sensitiveHeaders=[], customSensitiveHeaders=true)
When Zuul loads the services registered in Eureka, in the log I see
.... o.s.c.n.zuul.filters.SimpleRouteLocator : route matched=ZuulProperties.ZuulRoute(id=v1/microservice, path=/v1/microservice/**, serviceId=microservice-v1, url=null, stripPrefix=true, retryable=null, sensitiveHeaders=[], customSensitiveHeaders=false)
The only significant difference is that the latter says stripPrefix=true and to solve my problem, it should be false.
I think that it should be possible to change that default behaviour somehow...
When a client application is registered into Spring Eureka server the client id appears at dashboard, but the link url only contains the hostname and port without the context-path of client.
If I create the Spring Boot client application without setting a context-path, I mean default root context, Eureka server can access all actuators available in there.
Is there any way to inform Eureka server about it? I tried to set health and info properties, but it did not work.
If your Eureka client is setup via Spring's #EnableEurekaClient, then the client will default the health check and status check to /health and /info respectively. (These paths may be the default values beyond the Spring #EnableEurekaClient setup, but I am unfamiliar with those at this point in time).
You can override these defaults by setting the following properties:
eureka.instance.statusPageUrlPath
eureka.instance.healthCheckUrlPath
The Spring Cloud Documentation contains this information, plus much more.
application.yml
server:
servlet:
context-path: /your-path