I know this topic has a very narrow audience, but I hope that one or two people out there scratching their heads will benefit from it.
Here’s the itch we’re trying to scratch: is there an easy way to determine hostnames for - let’s say - a database connection? There are many ways to do this, like hardcoding it, providing them through a properties file and so on. All this techniques (maybe aside from fetching it over the network from a central storage) require some modifications on the server once one of the hostnames changes. If you need to maintain a lot of machines, this can get inefficient pretty quickly.
Now let’s step back a second and think about what we’re using anyway in our infrastructure: DNS. Until recently I haven’t heard of the SRV record that you can use to “refer” to other hostnames. The nice thing about this is that you can provide more endpoints and even add weights and and priorities. Let’s look at an example:
_cbnodes._tcp.example.com. 0 IN SRV 20 0 8091 node2.example.com.
_cbnodes._tcp.example.com. 0 IN SRV 10 0 8091 node1.example.com.
_cbnodes._tcp.example.com. 0 IN SRV 30 0 8091 node3.example.com.
Here, based on the “_cbnodes._tcp.example.com.” service information we get to know that there are three nodes configured that belong to this service. They all listen on port 8091
, but have priorities associated with them (10, 20, 30). Lower priorities are considered more important, so you can use that to your advantage. The 0
between the priority and the port is the weight. You can use different weights (which are probabilities) to generate some kind of load-balancing behaviour.
Once this is configured on the DNS server, we can make use of that in our application. Say we want to infer the seed nodes to bootstrap from in our CouchbaseClient
. To make this happen, we need to make use of JNDI. Let’s first create a simple class that will hold those records shown above:
|
|
We provide a custom compareTo
method in order to automatically sort each DnsRecord
by priority. The next step is to write a method that allows us to fetch the actual information:
|
|
Now we have a Set
of sorted DnsRecords
, which we can use however we want to. For example, with Couchbase we can turn them into URI
s:
|
|
If you want to play around with the code and don’t have DNS SRV records set up, I recommend you to use _xmpp-server._tcp.gmail.com
. It exposes Googles GMail XMPP servers and lets
you try the code without much effort. In case you wonder how to mock that thing correctly, I recommend you to mock the DirContext
like so:
|
|
The code shown here (and more advanced features) are part of the official Couchbase SDK, so check out the codebase if you want to learn more!