Correct way to do redirect

I’d like to do a geo based redirect. Users who initially hit my site
would be given an IP round robin from the DNS servers. Then each node
would test the ip and decide if it would be better to redirect to the
closer node. Only doing this for index.php, eg.

http {

geo $region {
default NA;
include georegions.conf;
}

server {

location ~ ^/index.php {
if ($region = NA)
–> what to write here to redirect to other IP?
}
location ~ .php$ { fastcgi_pass 127.0.0.1:9000; include
fastcgi_params; }
}
… other servers…

Thanks for any help with this.
Chris :slight_smile:

On Sat, Aug 30, 2008 at 05:28:25AM +0700, Chris S. wrote:

   }

}
… other servers…

First it’s better to use more effective location:

  •       location ~ ^/index.php {
    
  •       location = /index.php {
    

Or you may do it for “/” only:

        location = / {

As to redirect, I think it’s better to use something like this:

geo $region  {
    default  "";
    include  georegions.conf;
}

server {
     location = /index.php {

         if ($region) {
             rewrite  ^   http://$region/index.php;
         }

         fastcgi_pass 127.0.0.1:9000;
         ...
     }

The georegions.conf is site specific, i.e, for NA site:

 x.x.x.x/x   "";                # NA net
 x.x.x.x/x   eu.domain.com;     # EU net
 x.x.x.x/x   as.domain.com;     # AS net

for EU site:

 x.x.x.x/x   na.domain.com;     # NA net
 x.x.x.x/x   "";                # EU net
 x.x.x.x/x   as.domain.com;     # AS net

Thank you Igor.

I expected you would know the correct or optimal way to do this.
After posting the question I did more reading and found out that rewrite
will redirect when the rule give http as start of the result. That was
what I didn’t know before.

After playing around I found that loading the smallest geo table I could
make from the country database (converted to continent regions) pushed
the footprint size of nginx up from about 4MB to over 11 MB. I wasn’t
too happy with wasting so much memory just to lookup ips. I’m exploring
now possible use of PowerDNS with geo backend to do geo-direction at the
DNS level. I’d be happier with using a database lookup and saving memory
even it means it’s a bit slower since I only do this mapping once per
visit.

I don’t see any nginx module to do mysql queries or perhaps sqlite.
Something like that could work I think. I have mysql running anyway and
can’t get away from having it swallow a chunk of memory. Oh well, I
wasn’t running my own dns servers but probably should and in that case
it would be little overhead to do it there. Still tinkering with how to
do this in a light memory environment.

Chris :slight_smile:

On Sat, Aug 30, 2008 at 11:10:25PM +0700, Chris S. wrote:

I expected you would know the correct or optimal way to do this.
After posting the question I did more reading and found out that rewrite
will redirect when the rule give http as start of the result. That was
what I didn’t know before.

Yes, you may use

rewrite … http://…;
or
rewrite … … redirect;

After playing around I found that loading the smallest geo table I could
make from the country database (converted to continent regions) pushed
the footprint size of nginx up from about 4MB to over 11 MB. I wasn’t
too happy with wasting so much memory just to lookup ips. I’m exploring
now possible use of PowerDNS with geo backend to do geo-direction at the
DNS level. I’d be happier with using a database lookup and saving memory
even it means it’s a bit slower since I only do this mapping once per
visit.

I think geo-aware DNS is the best choice, notwithstanding to memory
footprint.

I don’t see any nginx module to do mysql queries or perhaps sqlite.
Something like that could work I think. I have mysql running anyway and
can’t get away from having it swallow a chunk of memory. Oh well, I
wasn’t running my own dns servers but probably should and in that case
it would be little overhead to do it there. Still tinkering with how to
do this in a light memory environment.

I have draft mysql module that can login to mysql server, send query,
and
get result, but can not parse it.

As to memory overhead, these extra 5M are shared on the copy-on-write
basis
between nginx workers. As nginx never write there while processing
requests,
these 5M stay shared. I do not think that in modern world 5M is large
memory
footprint, it seems that 128G will become usual hardware in near future:

BTW, probably you may optimize your geo networks if you did simple GeoIP
line by line mapping. You may try to compress networks like this:

192.168.0.0/24 NA;
192.168.1.0/24 NA;

to

192.168.0.0/23 NA;