Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fail over

If I use wget to retrieve something from the geonames.org server, it reports two IP addresses, and the first one fails but it gets it from the second:

Resolving ws.geonames.org (ws.geonames.org)... 5.9.41.208, 176.9.107.169
Connecting to ws.geonames.org (ws.geonames.org)|5.9.41.208|:80... failed: Connection refused.
Connecting to ws.geonames.org (ws.geonames.org)|176.9.107.169|:80... connected.
HTTP request sent, awaiting response... 200 OK

But unfortunately I have to access it through perl using LWP::UserAgent and HTTP::Request. How can I make them try the second IP if the first fails?

    my $ua = LWP::UserAgent->new;
my $req = HTTP::Request->new(
    GET =>
      "http://ws.geonames.org/countrySubdivision?lat=$lat&lng=$long&radius=$radius&username=xyzzy");

my $res = $ua->request($req);
like image 683
Paul Tomblin Avatar asked Aug 24 '13 17:08

Paul Tomblin


People also ask

How do you do a failover?

In Object Explorer, connect to a server instance that hosts a secondary replica of the availability group that needs to be failed over. Expand the server tree. Expand the Always On High Availability node and the Availability Groups node. Right-click the availability group to be failed over, and select Failover.

What is the meaning of fail over?

Failover is the ability to switch automatically and seamlessly to a reliable backup system. When a component or primary system fails, either a standby operational mode or redundancy should achieve failover and lessen or eliminate negative impact on users.

What is a failover solution?

What is a failover solution? Failover refers to a system that can quickly replace an important machine, application, or segment of data, in the event of a failure or during times of scheduled maintenance.

What is failover time?

Failover is a backup operational mode in which the functions of a system component are assumed by a secondary component when the primary component becomes unavailable -- either through failure or scheduled down time.


2 Answers

You can do it yourself: get all the IP addresses with the help of Net::DNS::Resolver, and then try all IP addresses until you get a successful response. Note that you have to supply the "Host" header yourself if working with an IP address, in case the server is doing name-based virtual hosts.

Something like the following lines could work. Maybe there's even a CPAN module for this, I did not check:

use Net::DNS;
use LWP::UserAgent;

my @addrs;
{
    my $res   = Net::DNS::Resolver->new;
    my $query = $res->search("ws.geonames.org");
    if ($query) {
        for my $rr ($query->answer) {
            if ($rr->type eq "A") {
                push @addrs, $rr->address;
            }
        }
    } else {
        die "DNS query failed: ", $res->errorstring, "\n";
    }
}

my $ua = LWP::UserAgent->new;

my $res;
for my $addr (@addrs) {
    $res = $ua->get("http://$addr/countrySubdivision?lat=$lat&lng=$long&radius=$radius&username=xyzzy", Host => 'ws.geonames.org');
    last if $res->is_success;
}
like image 97
Slaven Rezic Avatar answered Sep 29 '22 19:09

Slaven Rezic


The solution from Slaven is OK except when the IP addresses are not directly accessible. In that case, the following works for me:

local @LWP::Protocol::http::EXTRA_SOCK_OPTS = (
                                           PeerAddr   => 'my_hostname',
                                           MultiHomed => 1,
                                          );
my $response = $ua->post('https://my_hostname/...', ...);
like image 22
galli2000 Avatar answered Sep 29 '22 21:09

galli2000