Consul is a free open source tool that provides key-value storage for service discovery, health check, load balancing, and global distribution. In addition, it provides a set of basic elements for building business process workflows and tools. In a microservice architecture, applications typically run across multiple IP addresses and bind to various ports. Service discovery helps you find these different services, regardless of where they are located.

Because multiple instances of the same service often run simultaneously in a microservice architecture, we need a strategy to equally balance all traffic to healthy instances as instance health changes, as instance number changes, and as cluster state changes. That’s what the load balancing layer does. This article discusses several common strategies for load balancing with Consul in microservice architectures.

Use Consul directly

One way to load balance Consul is to use Consul’s built-in load balancing feature. Consul combines health checks with service discovery. This means that an unhealthy host will never be queried back to the service discovery layer. In this mode, every time applications and services want to look up other services in the data center, they talk directly to Consul.

Consider the following configuration files, which include the IP address of a back-end service:

Services: the backend: 10.2.5.391Copy the code

In general, hard coding IP addresses, especially in microservice architectures, is considered a bad practice. As applications run across the system, it becomes difficult to keep this configuration file up to date, especially on clusters of computers. Instead, a better approach is to leverage Consul’s DNS discovery layer.

services: 
  backend: backend.service.consul
Copy the code

Just as “www.hashicorp.com” is a Web address, so is “backend.service.consul”. Here, TLD or domain suffix is configurable, but the default is. The Consul. Any request ending in this TLD will be resolved to Consul. Here the service namespace tells Consul to look up the service (not the node of the machine) and that.backend is the name of the service to look up. Requests to “backend.service.consul” are resolved to a set of IP addresses just as “www.hashicorp.com” is resolved to a set of IP addresses. However, for Consul, this resolution occurs at the service discovery layer and integrates health check mechanisms.

Each time the application or kernel parses the DNS entry, it receives a random round-robin response with a list of IP addresses corresponding to health services in the cluster. The DNS interface provides essentially zero-touch service discovery and can be integrated into any application.

Advantages:

  • Do not rely on external tools or processes
  • There are no other services for monitoring or maintenance
  • Highly available by default
  • As close to real time as possible
  • DNS is easy to use with minimal effort
  • Health checks are distributed with minimal cluster load

Disadvantages:

  • Single point of failure – Even though Consul is highly available by default, this mode does not provide failover if Consul is unavailable or inaccessible
  • Require either direct use of the HTTP API in your application, or a DNS query, assume a port, or two DNS queries to find the address and port
  • Application is strongly coupled with Consul

Fabio

Fabio is an open source tool that provides a fast, modern, zero-configuration load balancing HTTP(S) and TCP router for Consul managed services. Users sign up for service on Consul and provide a health check, and Fabio will automatically route traffic to them. No additional configuration is required.

A user registers a service with a tag starting with urlprefix-, such as:

urlprefix-/my-service
Copy the code

In this example, when a request is made to Fabio on /my-service, Fabio will automatically route traffic to the health service in the cluster. Fabio also supports more advanced routing configurations.

Advantages:

  • Integration with Consul Rich
  • More control over load balancing than DNS methods
  • Strong community support and over 4000 GitHub Star
  • TCP Proxy support
  • Access logging and a host of other complimentary features
  • Integrated HashiCorp Vault
  • Optional Web UI for routing visualization
  • Very detailed open source documentation

Disadvantages:

  • Additional services are required to run and monitor
  • Tightly coupled with Consul and Consul Tag

Nginx/HAProxy with Consul Template

Another way to load balance Consul is to use third-party tools such as Nginx or HAProxy to balance traffic and open source tools such as Consul Template to manage configuration. In this mode, Consul Template dynamically manages the nginx.conf or haproxy.conf configuration file, which defines the load balancer and service list. This list is templated, Consul Template runs as a service to keep templates up to date. Consul Template has an ongoing connection to Consul cluster, and when the service pool changes, Consul Template writes a new configuration file and signals the Nginx or HAProxy process to reload its configuration. Here’s an example of Nginx’s Consul Template Template:

upstream myapp {
{{ range service "myapp" }}
  server {{ .Address }}:{{ .Port }}
{{ end }}
}
Copy the code

In this example, Consul Template will monitor all services named “myApp”. If any of their states change, Consul Template will generate a new profile and instruct the Nginx process to reload. The above template is rendered like this in nginx.conf:

Upstream myapp {server 10.2.5.60:13845 server 10.6.96.234:45033 server 10.10.20.123:18677}Copy the code

It must be noted that in this mode, neither Nginx nor HAProxy knows Consul exists; They simply read their configuration as if the values had been hard-coded by an operator or configuration management tool.

Advantages:

  • Handles applications running on non-default ports without additional API requests
  • Nginx and HAProxy are online proven tools
  • The team may already have the expertise or existing infrastructure for these tools
  • If Consul is offline, there is still a record of the last known good service status
  • Consul Template can also integrate with Vault, making it an ideal solution if the profile has confidential data like A TLS private key or shared password.

Disadvantages:

  • Two additional services are required to manage and monitor -Nginx/HAProxy and Consul Template
  • Inefficient templates can cause significant stress to Consul clusters due to blocking queries
  • Challenges to implementing the “one container one service” paradigm
  • A “flying pig” cluster (a cluster whose service flips between healthy and unhealthy or has a large succession of rapid run-offs) can cause an unstable Nginx/HAproxy configuration

Nginx with Custom Module

Recently, I began experimenting with removing Consul Template, but keeping the time-tested flexibility and familiarity of Nginx. There are some very interesting and innovative practices in society, namely:

  • Dynamic Nginx Upstreams for Consul via lua-nginx-module by Zachary Schneider
  • Nginx upsync module
  • Nginx Pro DNS resolution
  • ngx_http_set_backend which inspired binding Nginx modules in C to Consul in Golang

Ultimately, these methods either involved too many moving parts or included extensions beyond Consul’s basic service discovery. Therefore, I write ngx_http_consul_backend_module to dynamically select upstream for each request to nginx.

It looks like this:

http {
  server {
    listen       80;
    server_name  example.com;

    location /my-service {
      consul $backend service-name;
      proxy_pass http://$backend; }}}Copy the code

For each request, the Consul keyword tells Nginx to delegate to the custom module and select a random healthy back-end service, and then broker the request to that back-end service. There are certainly areas for improvement, but this proof of concept shows that it is possible to connect Nginx and Consul directly without mediation tools.

Advantages:

  • Process applications running on non-default ports without additional API requests
  • No external tools – just run Nginx and point directly to Consul
  • Use HTTP/2, stale Queries, and more provided by the official Consul SDK client library

Disadvantages:

  • Nginx needs to be compiled from source code to install custom modules
  • For each request to the back end, Consul is called (each request consumes both the RTT of the request and the RTT of Consul resolution)
  • Knowledge of Nginx custom modules is required to accomplish the task
  • TLS private keys or shared passwords cannot be integrated with Vault
  • Modules are rigorously tested online (not yet)

HAProxy 1.8

HAProxy 1.8 (the current release candidate at the time of writing this article) adds built-in service discovery capabilities through DNS without using third-party tools or modules. HAProxy has had a built-in DNS solution for some time, but HAProxy 1.8 brings a solution to the port with SRV logging and EDNS support, making it a perfect match for Consul.

Advantages:

  • No external tools – just run HAProxy and point directly to Consul
  • Elegant handling of reloading, TTLs, etc.
  • Also supports Kubernetes and Docker Swarm service discovery

Disadvantages:

  • Need HAProxy
  • Less flexibility for failure scenarios than Consul Template

conclusion

There are a number of load balancing strategies and techniques available for applications that use Consul. This article details some of the most common technologies and hopes to inspire new, exciting ways to integrate industry-standard load balancing tools and Consul. Whether you’re directly using Consul, bridging the Consul template gap, compiling your own custom version of Nginx, or trying out the HAProxy 1.8 release candidate, we look forward to hearing how you load balance your microservices applications.


The original link: www.hashicorp.com/blog/load-b…