Xegara
Xegara

Reputation: 131

How to cache Consul service lookup in a separate Spring Boot application?

Running our spring boot application takes 2-3 minutes to boot. Bulk of the time was spent on connecting to different servers via Spring Cloud Consul Discovery Client.

I'm looking for a way to cache service discovery in a separate application like in the following diagram:

+----------------------+     +----------------------+                   
|                      |     |                      |                   
|     Target Server    |     |    Consul Server     |                   
|                      |     |                      |                   
+-----------^----------+     +-----------^----------+                   
            |(3)                         |(2)                           
            |                            |                              
+----------------------+     +----------------------+                   
|                      |(1)  |                      |                   
|     Application      |---> | Consul Client Cache  |                   
|                      |     |                      |                   
+----------------------+     +----------------------+     
  1. Application queries consul client cache instead consul server directly to retrieve the network address of the target server.
  2. Consul Client Cache is a standalone application where it loads and caches the IP addresses of the services registered in consul server.
  3. Application connects to target server.

At the top of my mind, I believe this is possible by:

  1. Writing a spring boot application of consul client cache wherein it caches the services registered in consul server and serves them to the application upon request.
  2. Intercept the HTTP requests of application and re-route to consul client cache server.

But this seems a generic problem so I'm hoping there is already a ready-made solution out there.

Anyone has ideas?

Upvotes: 1

Views: 570

Answers (2)

aatwork
aatwork

Reputation: 2270

I don't have all the info. But service discovery with consul should anyways be fast.

Application is making call to consul server to get network addresses of the target. I believe the lookup would be super fast as the values would be cached in consul (stored in RAM). Did you check that? Otherwise it defeats the purpose of having consul. So writing a separate consul-cache won't improve anything.

I think the network address lookup from consul is not an issue. Issue should be with the multiple network connections that you are making to multiple targets when service starts up. Did you benchmark the network latency & response time of the HTTP calls that you are making? That should be where things can improve, especially if some of your targets reside outside VPC & connection goes over public internet.

Your current improvement plan won't most likely work if the above hold true.

Some improvement approaches:

  1. If you don't need to connect all the target servers at the startup, don't do it. Wait till you need it. And if any class instantiation depends on it, lazy load it.

2.1 Let's say you need to make all the HTTP calls at the startup. Why do you need that? I don't know the exact reason. But most likely, you get some settings/configurations dynamically that you need to initialize objects of this application.

Then you need to think, how frequently these values get changed? If they don't change frequently, you can cache them for some duration. So once you fetch it, you can cache it in existing consul or you can use redis (or any other caching server you use). So next time your service starts up, it can directly read them from the cache server (preferably in multi-get so that only one network connection is made).

Basically, you need to avoid that many HTTP connections while application starts up. You should cache the data. You don't need new application to do that. That would be an overkill.

Upvotes: 0

Borislav Stoilov
Borislav Stoilov

Reputation: 3687

Spring actuator from here provides a refresh endpoint that can dynamically reload application properties in runtime.

You can define a "ManagedResource" that has a scope refresh bean.

@Component
@ConfigurationProperties(prefix = "prefix")
@RefreshScope
class DynamicConfiguration { .. }

You don't need to intercept anything, just make the application talk only to the Consul server. Then the consul server can decide whether a certain property should be fetched from the cache or not. I Used Netflix's Eureka in the past to manage the application properties of multiple spring boot apps, but it seems HashiCorp's Consul server is a fully functional replacement of Eureka.

Upvotes: 0

Related Questions