How to get haproxy to use a specific cluster computer via the URI - linux

I have successfully set haproxy on my server cluster. I have run into one snag that I can't find a solution for...
TESTING INDIVIDUAL CLUSTER COMPUTERS
It can happen that for one reason or another, one computer in the cluster gets a configuration variation. I can't find a way to tell haproxy that I want to use a specific computer out of a cluster.
Basically, mysite.com (and several other domains) are served up by boxes web1, web2 and web3. And they round-robin perfectly.
I want to add something to the URL to tell haproxy that I specifically want to talk to web2 only because in a specific case, only that server is throwing an error on one web page.
Anyone know how to do that without building a new cluster with a URI filter and only have one computer in that cluster? I am hoping to use the cluster as-is but add something to the URI that will tell haproxy which server to use out of the cluster.
Thanks!

Have you thought about using different port for this? Defining new listen section with different port, because, as I understand, you can modify your URL by any means?

Basically, haproxy cannot do what I was hoping. There is no way to add a param to the URL to suggest which host in the cluster to use.
I solved my testing issue by setting up unique ports for each server in the cluster at the firewall. This could also be done at the haproxy level.
To secure this path from the outside world, I told the firewall to only accept traffic from inside our own network.
This lets us test specific servers within the cluster. We did have to add a trap in our PHP app to deal with a session cookie that is too large because we have haproxy manipulating this cookie to keep users on the server they first hit. So when the invalid session cookie is detected, we have the page simply drop the session and reload the page.
This is working well for our testing purposes.

Related

Single domain on multiple server

I have a domain with multiple active users with several applications hosting on it.
Domain: www.domain.com and running on server IP: XXX.XXX.XXX.1
I want to run www.domain.com/business on server IP: XXX.XXX.XXX.2
and similarly to run www.domain.com/hosting on server IP: XXX.XXX.XXX.3
It is very similar to Google scenario:
www.google.com runs on XXX.XXX.173.1 - XXX.XXX.185.1
www.google.com/+dinesh on XXX.XXX.186.1 -XXX.XXX.187.1
I have seen a lot of articles to manage DNS and virtual entries but unable to get correct answer.
Another way to do this is to make the host portions slightly different, i.e.:
business.domain.com/business
hosting.domain.com/hosting
You would then use these links where you are currently putting www.domain.com/business and www.domain.com/hosting. It's then a simple matter to have those different hostnames point at different addresses.
In general, it's not possible to have URLs with the same host point to different IP addresses on the basis of the stuff after the hostname. I cannot seem to verify your Google example (from where I'm looking, they both go to the same set of addresses). If you've more information on how you determined those addresses, please post that and maybe something else can be suggested.
You can manage it through Load balance rather than run on different server
Please use a reverse proxy in front of the application servers.
Consider using nginx or Apache Httpd.
These can be configured to route (technically proxy) to the desired app servers by inspecting the context path in URL.
If you choose to use nginx, see this post on how to configure nginx for such a use case.
Nginx configuration page for additional details: config

Run Ghost as an NPM module on a subdomain using Node.JS

Is there any way to run Ghost on a subdomain using Node.JS? I am able to run it normally on Node.JS like:
App.Modules.Ghost = require('ghost'); /**< Ghost module. */
App.Apps.Ghost = App.Modules.Ghost({ config: '/Assets/Ghost/Config.js'.LocalFilePath }); /**< Create Ghost app. */
Then, I am then able to go to http://example.com/ghost/ and view my blog. Although this works for now, I want to be able to view my blog at http://blog.example.com/ using Node.JS.
Sadly, the way networking works prevents this in the context you desire. In order to achieve that sort of functionality, you would need a proxy server to go in front of the entire application. I would suggest NginX for this ability, due to its speed and wide-spread use.
Why is this not possible?
In this sense, networking is the system where you bind to an IP and a port. When you bind, nothing else can bind to that same IP/port. Since a domain (and subdomain) simply point to an IP address, there is no way that you can separate these connections at the networking level. This is why the Host HTTP header was added.
How does NginX do it?
NginX parses the Host header and can send the connection to your Ghost server as you wish it to be forwarded to. This also allows you to forward the main domain (http://example.com) to whatever website you like, therefor using different applications and such on the same IP and port.
This answer contains the best directions on how to achieve this functionality.

How to use Node js in conjunction with Webmin

I have a server running webmin (different domains pointing to different app/directories). Currently I can have my php app running from a directory and all I need to do in order to make it live is get webmin to direct that domain to that specific directory.
Can I do the same with a node js app? If not, how can I use node and webmin in the same box?
I know you didn't say this specifically, but assuming you're hosting the other web stuff through, say, Apache, you would need to leverage that, but you can probably get the effect you want. Basically, it sounds like you want to be able to use "host header" separation for services, rather than having a separate IP address for, say, Apache and Node.js to each use.
So, if you let Apache bind to the main port you're using (80/443/both), then you would run ode and have it configured to listen on a different port (say 8080 as in the example you left in another comment). You can then use mod_proxy in Apache and have it route request with certain domain names to Node. Here's a: more concrete example of this but really the idea is not specific to Node. It can apply to any other process that wants to respond to HTTP requests on your server (or even on a different server).

About DNS polling

Currently we use DNS polling for four web servers.
The problem we met is that: When the user refreshes, he might go to other web servers. This feels very bad when a user has already logged in. Because we use a session to remember login status, but when refreshing to other web servers, the session is lost.
So the best solution should be to make the user still be on the same web server when he refreshes. Is there a way out?
Ok, I believe you mean "Round Robin DNS". Well, what you describe is a very common problem and there is no "right" solution for it, since the possible answers depend on many variables: are you trying to provide automatic failover or just load balancing? Are you willing to spend time and/or money in a load balancer? What technologies are you using? Java EE? PHP? Apache? IIS?
Having said that, if you're just after load balancing and failover is not much of an issue you may want to use different names for each server (www1,www2,www3 and so on) and redirect to them from your "main" web server (www) upon first access. It's simple (and simplistic) but practical in a few settings.
Can the web servers use a common database server to store the session information?
I know that certain hardware based load balancers will create a "sticky" relationship between a user and a server to avoid this type of problem.
You have quite a few options.
You can store sessions in a key:value storage, f.e. memcached (my personal favorite)
You can store sessions in a database
You can put reverse-proxy loadbalancers like in DNS and Your servers in the back. Then set it to make all requests from the same IPs go to the same servers, regardless of which loadbalancer they go through. In HAProxy this option is called balance source. Beware: if the number of node changes, the sessions can be lost. You can use the cookie or url_param features to avoid this.
See the HAProxy documentation. It's worth reading, really.
Are the four web servers all on the same site and network, or are they distributed?
If the former, you can include a server ID somewhere in the HTTP response, such that a reverse proxy in front of the real servers can identify which server is responsible for the session.
A DNS server that can respond based on the location of client could solve this problem. PowerDNS with the geoip module or GeoIPdns are some examples. You would need to make sure that the IP address sets were non-overlapping so a client always got the same response.
This would not provide any sort of fail over on its own.

DNS-based strategies for showing a nice "Currently Offline" page when the server is down

How can I make that a site automagically show a nice "Currently Offline" page when the server is down (I mean, the full server is down and the request can't reach IIS)
Changing the DNS manually is not an option.
Edit: I'm looking to some kind of DNS trick to redirect to other server in case the main server is down. I can make permanent changes to the DNS, but not manually as the server goes down.
I have used the uptime services at DNSMadeEasy to great success. In effect, they set the DNS TTL to a very low number (5 minutes). They take care of pinging your server.
In the event of outage, DNS queries get directed to the secondary IP. An excellent option for a "warm spare" in small shops with limited DNS requirements. I've used them for 3 years with not a single minute of downtime.
EDIT:
This allows for geographically redundant failover, which the NLB solution proposed does not address. If the network connection is down, both servers in a standard NLB configuration will be unreachable.
Some server needs to dish out the "currently offline page", so if your server is completely down, there will have to be some other server serving the file(s), so either you can set up a cluster of servers (even if just 2) and while the first one is down, the 2nd is configured only to return the "currently offline page". Once the 1st server is back up, you can take down the 2nd safetly (as server 1 will take all the load).
You probably need a second server with 100% uptime and then add some kind of failover load balancer. to it, and if the main server is online redirect to that and if it isn't redirect to itself showing a page saying server is down
I believe that if the server is down, there is nothing you can do.
The request will send up a 404 network error because when the web address is resolved to an IP, the IP that is being requested does not exist (because the server is down). If you can't change the DNS entry, then the client browser will continue to hit xxx.xxx.xxx.xxx and will never get a response.
If the server is up, but the website is down, you have options.
EDIT
Your edit mentions that you can make a permanent change the IP. But you would still need a two server setup in order to achieve what you are talking about. You can direct the DNS to a load balancer which would be able to direct the request to a server that is currently active. However, this still requires 100% uptime for the server that the DNS points to.
No matter what, if the server that the DNS is pointing to (which you must control, in order to redirect the traffic) is down, then all requests will receive a 404 network error.
EDIT Thanks to brian for pointing out my 404 error error.
Seriously, DNS is not the right answer to server load-balancing or fail-over. Too many systems (including stub clients and ISP recursive resolve) will cache records for much longer than the specified TTL.
If both servers are on the same network, use routing protocols to achieve fail-over by having both servers present the same IP address to the network, but where the fail-over server only takes over if it detects that the (supposedly) live server is offline.
If the servers are Unix, this is easily done by running Quagga on each server, and then using OSPF as the local routing protocol. I've personally used this for warm standby servers where the redundant system was actually in another data center, albeit one that was connected via a direct link to the main data center.
Certain DNS providers, such as AWS's Route 53, have a health-check option, which can be used to re-route to a static page. AWS has a how-to guide on setting this up.
I'm thinking if the site is load balanced the load balancer itself would detect that the web servers it's trying to redirect clients to are down, therefore it would send the user to a backup server with a message dictating technical problems.
Other than that.....
The only thing I can think is to control the calling page. Obviously that won't work in all circumstances... but if you know that most of your hits to this server will come from a particular source, then you could add a java script test to the source, and redirect to a "server down" page that is generated on a different server.
But if you are trying to handle all hits, from all sources (some of which you can't control), then I think you are out of luck. As other folks are saying - when a server is down, the browser gets a 404 error when it attempts a connection.
... perhaps there would be a way at a point in between to detect 404 errors being returned by servers and replacing them with a "server is down" web page. You'd need something like an HTML firewall or some other intermediate network gear between the server and the web client.

Resources