We are in the process of standing up a new microservices architecture with Zuul at the front-end and a bunch of tomcat enabled microservices at the backend. Each service as it starts up, will register itself with Eureka and any client that wants to call those service will do so through Zuul. We've got this all wired in and everything is working fine.
However, I have a couple questions as to how we can make this architecture much more dynamic.
One thing that we assumed was there out of the box with Ribbon/Eureka, but have yet to find a solution for is that as we add more services to the backend, that somehow (via Archiaus and update to Zuul's eureka-client.properties file) Zuul's Ribbon client would update itself with the new service details (e.g. vipaddress, load balancing algorithm, etc). So far, the only thing that works is to update the properties file and restart Zuul (ughhh).
For example, let's say today we have 2 microservices at the backend, therefore, Zuul's eureka/ribbon client configuration would include the below:
ribbon.client.niws.clientlist=service1|service2
zuul.ribbon.namespace=zuul.client
service1.zuul.client.DeploymentContextBasedVipAddresses=myService1
service1.zuul.client.NIWSServerListClassName=com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList
service2.zuul.client.DeploymentContextBasedVipAddresses=myService2
service2.zuul.client.NIWSServerListClassName=com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList
Now tomorrow, let's assume we need to add service3. What we have observed is that if we add those details to the same configuration (see below), they only become available to Zuul after a restart. Is there some other configuration parameter we are missing that would allow us to dynamically introduce the new service details or do we have to roll our own Eureka/Ribbon client to do this?
ribbon.client.niws.clientlist=service1|service2|service3
zuul.ribbon.namespace=zuul.client
service1.zuul.client.DeploymentContextBasedVipAddresses=myService1
service1.zuul.client.NIWSServerListClassName=com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList
service2.zuul.client.DeploymentContextBasedVipAddresses=myService2
service2.zuul.client.NIWSServerListClassName=com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList
service3.zuul.client.DeploymentContextBasedVipAddresses=myService3
service3.zuul.client.NIWSServerListClassName=com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList
My other question is related and that is do we really need to add a client configuration (in eureka-client.properties) for every service that Zuul could possibly route to? At some point, we may have 100's of services running and trying to maintain all the related client configurations in Zuul seems a bit clumsy. Is there a way to globally configure Zuul to load all services into its client list from Eureka (or based on some service metadata in Eureka) and dynamically update this list as new services register themselves with Eureka?
Thanks!
The issue is with namespaces.If we use the default namespace it should be able to pick up the new properties addedd by default.
Related
I just created simple Zuul Proxy at the front end for our microservices environment but now I wanted to log all the entries into the log file which went through the proxy.
Do any properly which I need to enable to do this.
I assume an implementation of zuul as a regular spring boot driven microservice with a bunch of netflix's beans running under the hood.
In this case it can run on tomcat (probably for other services the idea is the same, but the technical implementation might be different).
So for tomcat:
As a first resort you can take advantage of tomcat feature of "access logs" that logs all the requests anyway. It also allows some level of customizations (what to log). The technical difficulty is that tomcat access log is not by default managed by logback, so you'll have to use some kind of adapter.
Here you can find ideas of how to resolve this technically and integrate access log with logback.
An another approach would be creating a Filter that will extract required pieces and log the request / response / whatever you want to log
Here is an example of creating a custom filter like this.
Of course I you also need to log something from response you should configure the filter type (see the java code example in the link)
One tip / caution: think about performance implications, so that this feature won't slow down the processing if the server is under high load of requests.
I am using Zuul as an api-gateway in a spring-cloud micro-service app, so that every access to api-gateway/some-service/a_route is redirected to /a_route in a generic way (the discovery is backed by consul).
I am trying to use Jaeger to instrument this system. And at this point I am using opentracing-spring-web-autoconfigure, because I cannot upgrade my spring boot/cloud version easily (I am using1.4.5.RELEASE Camden.SR7). So I just added the dependency, created the Jaeger tracer and redirect it to the docker all in one collector.
I have begin by instrumenting the gateway and It somewhat works => It generate span on the gateway, but all the route are marked :
apigateway-service: GET
and there is no information concerning the forwarded route at this level, the full route itself is store in a tag : http.url
"http://localhost:8080/collection-service/collections/projects/"
To be useful I would prefer to have span named :
apigateway-service: GET collection-service/collections/projects/
Can this be configured somewhere ?
No, it cannot, but it wouldn't hurt to open an issue there with this suggestion.
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
I setup an Eureka cluster composed of 3 replicas.
I got the nice dashboard which is automatically populated with the instances currently registered with Eureka and the DS Replicas.
However the DS Replicas links seems to point to the value I set as eureka.client.serviceUrl.defaultZone. In my case this value is something similar to http://node-01:8761/eureka/ which in reality returns a 404. Is there a way I could configure the dashboard to strip out the /eureka/ part so when I follow the links I end up in the other dashboards or am I misunderstanding the use of those links?
There is no easy way to alter the link as you ask.
However, the UI part of the Eureka server is a standard Spring MVC #Controller. An instance of it is created by org.springframework.cloud.netflix.eureka.server.EurekaServerConfiguration. Have a look at the current implementation... it shouldn't be too hard to provide your own customized version instead.
My organization is using Websphere Application Server with RAD. My unit is developing Web Services that take data from a consumer, and often pass the data through other Web Services.
Currently, we have two ways of defining time-out's for data to be returned from called services:
Using the Spring framework
Websphere profile configuration
If we need to update the values using Spring we need to re-deploy our service. If we define them as JVM properties we need to do a JVM configuration change and 'restart/recycle/stop and start' the application.
My co-worker had it suggested to him that there may be some better solutions to this problem. I'm wondering if this is true, and if so what they are?
edit:
One option we might be considering is "Application Policy Sets". We'd like to know if this is a good alternative method:
can we define Spring to leverage policy sets
can we define multiple policy sets for an application when timeout values for different services called by our service are different?
Does this console change take affect at run-time, or do we need to recycle?
I suggest you use JAX-WS policy sets and bindings on WAS level, because it allows you to:
define policy set for each web service separately
in policy set define web service parameters, from HTTP transport parameters to WS-Security policies such as UsernameToken, digital signature and encryption
web services remain unchanged, the code remains the same
there is only one place where you change it: in WAS console, application is not changed
The only drawback here is that web services should be generated from RAD (you can use top-down or bottom-up approach).
Please see more details in this excellent 3-part DeveloperWorks tutorial