Having covered infrastructure services Spring Cloud Config server here with Refreshable Configuration here and Registration and Discovery here with Multi-versioned service support here, in this post I’ll cover the Spring Cloud Netflix Zuul server, another infrastructure service used in a microservice architecture.
Zuul is an edge server that seats between the outside world and the downstream services and can handle cross-cutting concerns like security, geolocation, rate limiting, metering, routing, request / response normalization (encoding, headers, urls). Developed and used by Netflix to handle tens of billions of requests daily, it has also been integrated for Spring Boot / Spring Cloud applications by Pivotal.
A core component of the Zuul server is the Zuul filters, which Zuul provides four types of:
|pre filters||Executed before the request is routed.|
|routing filters||Handles the actual routing of the request.|
|post filters||Executed after the request has been routed.|
|error filters||Executed if an error happens while handling the request.|
This post shows how to configure a Spring Cloud Netflix Zuul server to route requests to a demo downstream service using the provided
routing filter RibbonRoutingFilter and how to dynamically refresh the Zuul routes using Spring Cloud Eureka and Spring Cloud Config servers.
A few days ago I was working on a new Spring Boot web application where some dependencies version and common Maven plugins configuration were inherited from a parent pom. Everything was just fine, APIs would work as intended, Unit and Integration Tests were passing except when generating the Cobertura code coverage report. It didn’t matter how minimalist this Spring Boot app could get, code coverage was just failing attempt after attempt.
This posts describes troubleshooting a Spring Boot application and Cobertura dependencies to fix multiple SLF4J bindings - found in the classpath - Failed to load ApplicationContext.
Often times I have seen API implementations not taking advantage of client side caching. Consider this example, a REST service needs to get data from a handful of other services and for every request, even though the upstream response might have not changed for the same input, it’s being calculated repeatedly and sent back to the client.
Depending on how expensive this calculation might be, wouldn’t be a better approach if the HTTP request includes data about what it previously has stored from a prior server response in an attempt for the server to find out if this calculation would be needed at all? This will improve the application performance while saving on server resources.
And what about if this expensive calculation is not needed, wouldn’t be a good practice for the server to let the client know that nothing has changed on the server side for that request? This will also save on bandwidth, assuming the client service is able to reconstruct the response payload.
This post focuses on the client side of this improvement, configuring Spring’s RestTemplate to use HttpClient and Ehcache to cache upstream HTTP responses using ETags.
Consider this scenario, the development team has increased over the last few years, software releases and deployment takes more time, that quick fix or feature couldn’t be delivered this Sprint because the deliverable now includes many changes that haven’t been signed off by QA and it might take another month to do so.
This seems like a good opportunity to break up the big Java monolithic application into multiple services or for that legacy set of applications in which business logic is duplicated to be refactored or rewritten, each by a small team benefiting from more frequent releases, easier to understand a small piece of functionality, having a low impact on other services, promoting ownership and accountability, etc..
Assuming for instance, it has been decided to implement the APIs using Spring Boot, Apache CXF and Swagger along with logging, metrics, security, etc. and maybe packaging the service in a Docker image, how do you setup this up for a dozen or more services? Do you create a baseline project to be copied and pasted for each service? Do you create a custom Maven archetype? What are other options?
This post covers how to create a custom Spring Boot starter for Apache CXF 3.1.x and Swagger 2 as the starting point to create services with a common set of dependencies and functionality also providing Spring beans auto-configuration to reduce explicit beans definition.
A while back I published a blog post about Microservices using Spring Boot, Jersey, Swagger and Docker that takes advantage of the Spring ecosystem and a JAX-RS implementation in Jersey 2. In another post, Services Registration and Discovery using Eureka, Ribbon and Feign I also mentioned that Jersey 2-based endpoints attempting to register with Spring Cloud Netflix Eureka registry failed due to the fact that Eureka and Ribbon clients bring in Jersey 1 dependencies and thus conflicting with Jersey 2’s.
Instead some endpoints were implemented using Jersey 1 successfully registering with Eureka but the downside was it required configuring Jersey 1 in a multi-module Maven setup because there is no Spring Boot starter for Jersey 1 and a limitation to scan nested jars.
In this follow-up post I plan to demonstrate how to integrate Apache CXF 3.1.x JAX-RS-based endpoints implementation with Spring Boot and documenting them using Swagger. The services following this setup should be able to register with Spring Cloud Netflix Eureka since no Jersey dependency would be transitively included.
As services evolve over time, changes are made to the domain that very-likely require API versioning to prevent breaking backwards compatibility.
Unless you work in a very controlled environment, for instance, where it’s known that client applications are also distributed with the API services and there is no possibility of an old client using newer API services deployment, I’m a firm believer you should never break backwards compatibility.
I’ll say it again because this is very important, you should never break backwards compatibility, if you do, customers and partners get very angry and fixing it afterwards normally requires more effort than versioning from the beginning.
The question now is, how does versioning work in a microservice architecture where services are registered with and discovered using a Discovery infrastructure microservice such as Netflix Eureka?
In this post I’ll explain how to register and discover multiple version of a service using Spring Cloud Netflix Eureka and Ribbon.
This post is a continuation of Centralized and versioned configuration using Spring Cloud Config Server and Git where I covered the Spring Cloud Config server to prevent hard-coding properties that most-likely would be different for each deployment environment.
At the end of said post I outlined how updating a Git-backed property and sending a POST request to the client application’s
/refresh actuator endpoint caused the configuration property to be reloaded and the dependent Spring beans to be refreshed picking up the new value.
But what if it’s not just one or two microservices but maybe dozens or even hundreds that would need to reload those properties changes? Hitting
/refresh for each one doesn’t seem like an elegant solution. What if the numbers of instances keep growing?
In this post I’ll extend the Spring Cloud Config Server and the client service implemented in part 1 with Spring Cloud Bus and RabbitMQ support and a Bitbucket webhook to automatically notify subscribed client services of changes in the Git-backed configuration files.
Multitenancy is an approach in which an instance of an application is used by different customers and thus dropping software development and deployment costs when compared to a single-tenant solution where multiple parts would need to be touched in order to provision new clients or update existing tenants.
There are multiple well known strategies to implement this architecture, ranging from highly isolated (like single-tenant) to everything shared.
In this post I’ll review configuring and implementing a multitenancy solution with multiple databases and one API service using Spring Boot, JPA, Hibernate and Postgres.
Spring’s RestTemplate is one of the options to make client HTTP requests to endpoints, it facilitates communication with the HTTP servers, handles the connections and transforms the XML, JSON, … request / response payloads to / from POJOs via HttpMessageConverter.
By default RestTemplate doesn’t use a connection pool to send requests to a server, it uses a SimpleClientHttpRequestFactory that wraps a standard JDK’s HttpURLConnection taking care of opening and closing the connection.
But what if an application needs to send a large number of requests to a server? Wouldn’t it be a waste of efforts to open and close a connection for each request sent to the same host? Wouldn’t it make sense to use a connection pool the same way a JDBC connection pool is used to interact with a DB or a thread pool is used to execute tasks concurrently?
In this post I’ll cover configuring RestTemplate to use a connection pool using a pooled-implementation of the ClientHttpRequestFactory interface, run a load test using JMeter, troubleshoot requests timeout and reconfigure the connection pool.
Today I landed in a stackoverflow question about how to access the JavaMelody UI using a port other than the one used by the APIs. I went ahead I answered the question with some initial code I had for another blog post I’m working on but then decided to make it its own post.
While this could certainly be accomplished adding a couple of Spring Boot configuration properties: management.context-path and management.port to
application.yml for instance, and reuse the same path used for actuator endpoints (
/admin/health, …), there might be some cases where having the servlet container listening on a port other that the two mentioned earlier might make sense, maybe for monitoring, traffic analysis, firewall rules, etc..
In this post I’ll add support for configuring embedded Tomcat to listen on multiple ports and configure JavaMelody to exclusively use one of those ports to display its reports using Spring Boot.