How to configure DC automatically when use Spring Cloud Consul? - spring-cloud-consul

When use Spring Cloud and Consul to do the service discovery, if a service wants to access another service which is located in different DCs, the DC name must be specified in the configuration like following:
spring.cloud.consul.discovery.datacenters.STORES=dc-west
In which STORES is a service name and dc-west is a DC name.
I think the ideal situation is that the DC info of any service can be acquired automatically, not be configured via any configuration file or configuration service.
So my question is that will this DC auto-discovery mechanism be provided in the future? Or can be achieved in an another way currently?

Related

Register a service with multiple instance in Consul

I have a couple of microservices that I want to register in Consul, so that they can find each other and communicate.
Everything runs on docker compose.
I am wondering how that would work if one of the two services has multiple replicas. How does Consul (or docker compose) deal with that? Is there some sort of internal load balancing or what?
Consul supports registering multiple instances/replicas of a service. When a consumer queries the Consul catalog, Consul will return information for each of the registered service instances.
If the consumer/client is querying Consul via DNS, the client's DNS resolver will ultimately be responsible for choosing the endpoint to connect to from the list of IP's in the DNS response.
If the client is querying Consul via the HTTP API (e.g., /v1/agent/health/service/:service), the client must implement its own logic to select an upstream instance from the list of instances returned in the API response.
See the query services section of the Register a Service with Consul Service Discovery tutorial for more info.

Can Spring Cloud Loadbalancer be used together with Netflix Eureka instead of Netflix Ribbon?

From the announcement of the Spring Cloud Greenwich release, see https://spring.io/blog/2019/01/23/spring-cloud-greenwich-release-is-now-available, I noticed that is recommended to replace Netflix Ribbon with Spring Cloud Loadbalancer.
Does that mean that Spring Cloud Loadbalancer can be use by a client to connect to services registered in Netflix Eureka without using Netflix Ribbon?
I have tried to find documentation and/or examples that describes how to do that, but I haven't find any.
You can find a sample in the tests of Spring Cloud Loadbalancer.
So what you'll have to do is the following. You'll have to annotate a configuration class with #LoadBalancerClient (or wrap it in #LoadBalancerClients if you want to have multiple clients) where you specify your client's name and its config class.
In that load balancer client's config class you'll need to create a bean which will return a load balancer. In the test it's the RoundRobinLoadBalancer.
You can then use that load balancer bean to pick the next service instance, which in turn can be used to make the call to your other service.
See this test: https://github.com/spring-cloud/spring-cloud-commons/blob/master/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/LoadBalancerTest.java#L132

Disadvantages of using eureka for Service Discovery with kubernetes

Context
I am deploying a set of services that are containerised using Docker into AWS. No matter which deployment solution is chosen (e.g. raw EC2/ECS/Elastic Beanstalk/Fargate) we will face the issue of "service discovery".
To name just a few of the options for service discovery that I've considered:
AWS Route 53 Service Registry
Kubernetes
Hashicorp Consul
Spring Cloud Netflix Eureka
Specifics Of My Stack
I am developing Java Spring Boot applications using Spring Cloud with the target deployment environment being AWS.
Given that my stack is Spring based, spring cloud eureka made sense to me while developing locally. It was easy to set up a single node, integrates well with the stack and ecosystem of choice and required very little set up.
Locally, we are using docker compose (not swarm) to deploy services - one of the containers deployed is a single node Eureka service discovery server.
However, when we progress outside of local development and into staging or production environment we are considering options like Kubernetes.
My Own Assessment Of Pros/Cons
AWS Route 53 Service Registry
Requires us to couple code specifically to AWS services. Not a problem per se, we are quite tied in anyway on other parts of the stack (SNS/SQS).
Makes running the stack locally slightly more difficult as it relies on Route 53, I suppose we could open up a certain hosted zone for local development.
AWS native, no managing service registries or extra "moving parts".
Spring Cloud Eureka
Downside is that thus requires us to deploy and manage a high availability service registry cluster and requires more resources. Another "moving part" to manage.
Advantages are that it fits into our stack well (spring ecosystem, spring boot, spring cloud, feign and zuul work well with this). Also can be run locally trivially.
I presume we need to configure the networks and registry zone to ensure that that clients publish their host address rather and docker container internal IP address. e.g. if service A is on host A and wants to talk to service B on host B, service B needs to advertise its EC2 address rather than some internal docker IP.
Questions
If we use Kubernetes for orchestration, are there any disadvantages to using something like Spring Cloud Eureka over the built in service discovery options described here https://kubernetes.io/docs/concepts/services-networking/service/#discovering-services
Given Kube provides this, it seems suboptimal to then use eureka deployed using kube to perform discovery. I presume kube can make some optimisations that impact avaialbility and stability that might nit be possible using eureka. e.g kube would know when deploying a new service - eureka will have to rely on heartbeats/health checks and depending on how that is configured (e.g. frequency) this could result in stale records whereas i presume kube might not suffer from this for planned service shutdown/restarts. I guess it still does for unplanned failures such as a host failure or network partition.
Does anyone have any advice on this, do people use services like Kubernetes but use other mechanisms for service discovery rather than those provided by kube. Is there a good reason to do one or the other?
Possible Challenges I Anticipate
We could replace eureka, but relying on Kube to perform discovery will mean that we need to run kube locally to deploy whereas currently we have a simple tiny docker-compose file. Also, I'll have to look at how easy it'll be to ensure that ribbon, zuul and feign play nicely with this.
Currently we have ribbon configured with a eureka client so that service A can server to service B just as "service-b" for example and have ribbon resolve a healthy host via a eureka client. I guess we can configure ribbon to not use eureka and use an external Kube service name which will be resolved by Kube DNS at runtime...
Final Note
Thanks in advance for any contribution or advice. I know this might elicit a primarily opinion focused response. But I am hoping someone can provide objective guidance on when one solution might be preferable to another.
Service discovery is something you get out-of-the-box with Kubernetes. So having another external service in your platform will be another application to maintain, deploy and can be a point of failure. So I would stick with the the service discovery provided by Kubernetes.

Difference between service registry and discovery

Like to know the difference between Service Registry and Discovery in Zookeeper in terms of Microsesrvices
This question is not specific to Zookeeper so these principles apply to every implementation (Eureka, Consul, Zookeeper, etc...)
Service registry is the registry where all services register themselves, giving a way to contact them (public API, IP, port).
Service Discovery is the action of retrieving a specific service for your need, basically asking the service registry to get an URL to call.

How is service discovery not a subset of centralized configuration?

I'm looking at consensus-type tools like ZooKeeper, Consul and Eureka and they all seem to market the same set of solutions:
Service discovery
Dynamic, centralized configuration management
Synchronization primitives
Consensus algorithms
However the more I read about these things, the more I struggle to see how service discovery is really any different than a dynamic, centralized configuration management (KV pair) system.
My understanding (so far) of service discovery is that it allows nodes to dynamically search for, find and connnect to remote services. So if an application uses an AuthService for authentication, authorization, it would use service discovery to find an AuthService node at, say, http://auth103.example.org:9103 and use it.
My understanding of dynamic config systems is that they provide a centralized infrastructure for nodes to dynamically receive updates from, as well as publish updates to, config servers. So if an app instance decides it needs to update a configuration for all its other instances, it would contact the config service and update, say, the numPurgerThreads config. The config service would then update all other app instances so that they updated their respective configs properly.
But aren't these exactly the same problem?
In both cases, you:
Connect to a lookup service of some sort
Query it for data; or
Publish data to it, which then ripples out to other nodes
Service discovery is dynamic configuration, right?!?!
What I'm really driving at is: Couldn't I just implement one config service with one of these tools, which coincidentally also solves service discovery? Or is there a reason why I would need to have, say, 1 Consul cluster for config/KV management, and another, say, Consul cluster for service discovery?
Well, if you look at it like that, these are all just flavors of databases, or data stores if you will, as you describe it:
Connect to a lookup service of some sort
Query it for data; or
Publish data to it, which then ripples out to other nodes
All of the use cases you mentioned require some sort of a data store that multiple clients connect to. What makes some of them more optimal then others for different use cases is their interface, data model, consistency guaranties etc.
Specifically, in case of service discovery, a nice feature can be failure detection - e.g. a k/v store that allows removing service data when the service is no longer connected. This way, you can register a service to your service discovery tool and know that when the service goes down or looses connectivity, it will no longer be present in the stored data.
Just to clarify a few terms, (imo) dynamic config systems can update their state at runtime, in contrast to static where everything is defined beforehand (i.e. config files). Centralized CM means there's a single place to store all config data. So centralized CM can both be static or dynamic, right?
IMO, service discovery has a component which CM doesn't and that's a protocol for automatic detection of services.
Guess you'd need a dynamic CM (KV store) to implement service discovery, but you couldn't implement a CM store just using a service discovery (protocol). Take DHCP for example (hope we agree it is a service discovery protocol?) - Dynamic Host Configuration Protocol', so it has a configuration aspect, but also a protocol, which is a bit more than a simple KV store. Btw, it's decentralized, just to illustrate the previous point that CM doesn't have to be centralized..
So service discovery has a configuration aspect, but CM doesn't (necessarily) have a service discovery one. Does this mean SD is a subset of CM? I'd say no.