Is there a recommended way how to configure an IdentityServer for high availability? What are pros/cons for one solution over the other.
Currently I use ARR for it, but I've some issues and I'm not sure if it is the best solution anyhow?
It's not really a question specific to ASP.Net Core or IDS4 and to do it to a degree where it really is truly HA is quite hard.
That said, if not talking about Amazon/Azure stuff... I'd do something like this:
Two sets of servers, each in geographically separate sites, combined with a multi-site SQL Server AlwaysOn High Availability Group using synchronous commits and automatic fail-over and the app configured to suit (i.e. MultiSubnetFailover=true).
In front of the each set of web servers have a traffic manager (with its own HA) with health checking enabled and then in front of that have active DNS failover via a service like Dyn (https://dyn.com/active-failover/)
This would allow you to suffer an entire data centre going down or any individual server and carry on like nothing happened.
Related
I have a single back-end running node/express providing API endpoints and 2 static (react) front-ends. The front-ends interact with the users and communicate with the back-end.
I need to use https through-out once enter production stage.
The front-ends will require their own domain names.
I’ve been thinking on the simplest way to have these configured and have come up with Option 1 (see diagram). Node.js API server running on one VPS and as the front-ends are static sites these can be loaded on separate servers (UPDATE- Mean't to say hosting providers) hence get their own domains. As an option, and I’m unsure if its needed, add cloudflare to the front-end to provide a layer of security.
This will allow front-ends to have separate domain names.
As this is a start-up project and doubt a large number of visitors, I’m wondering if the above is over-engineered and un-necessarily complicated.
So I’m considering Option 2 of hosting back-end api app and the two front-ends on the same linux vps. As the front-ends are static, I added the front-ends into the public folder of node.js. This allowed me to access the front-ends as http://serverIP:8080/siteA
As I want to access front-end as http://siteA.com I’m assuming I require a reverse proxy (nginX)
The questions to help me decide between the two options are:
For a start-up operation and given he above scenario which option is best ?
I understand that node.js requires a port number regardless to work, for the API I don’t mind having a port number (as its not applicable for end users i.e. http://10.20.30.40:3000), however the two front-ends require their own domain names (www.siteA.xom, www.siteB.com), therefore will I need to employ a reverse proxy (nginX) regardless if they are static sites or not ?
I’m concerned that someone could attack API end-points (http://10.20.30.40:3000). In this case, is it true with Option 2 is safer than 1 - that I could potentially block malicious direct API calls as all sites are hosted on the same VPS and the API can be easily be secured, this is not exposed to the outside world?
My developer once upon a time told me that option 1 is best as nginX adds un-needed complication, but not sure what he meant – hence my confusion, to be honest I don’t think he wanted to add nginX to the server.
I’m looking at a high-level guidance to get me on the right track. Thank
This is - as you have also doubted - unnecessarily complex, and incorrect in some cases. Here's a better (and widely used across the industry) design. I'm strongly recommending to drop the whole VM approach and go for a shared computing unit, unless you are using that machine for some other computation and utilizing it that way is saving your company a lot of money. I strongly doubt this is the case. Otherwise, you're just creating problems for yourself.
One of the most common mistakes that you can make when using Node.js is to host the static content through the public folder (for serious projects) Don't. Use a CDN instead. You'll get better telemetry depending on the CDN, redundancy, faster delivery, etc. If you aren't expecting high volumes of traffic and performance of delivering that static content isn't outrageously important at the moment, you can even go for a regular hosting server. I've done this with namecheap and GoDaddy before.
Use a direct node-js shared - or dedicated depending on size - hosting for your app and use CI/CD to deploy it. You can use CNAMEs to map whatever domain name you want to have your app on (ex: https://something.com) to map to the domain name of the cloud-hosting provider url for your app. I've used multiple things, Azure, Heroku, Namecheap for the apps and primarily Azure DevOps to manage the CI/CD pipeline, although Jenkins is super popular as well. I'd recommend Heroku - since it provides a super easy setup.
When designing any API on HTTP, you should assume people will call your API directly. See this answer for more details: How to prevent non-browser clients from sending requests to my server I'm not suggesting to put something like CloudFlare, but you may be overthinking it, look into your traffic first. Get it when you need it. As long as you have the right authentication / authorization mechanism in place, security of the API shouldn't be a big problem on these platforms. If you deploy it on one of these platforms, you won't have to deal with ports either. Unless you reach absolutely massive scale, it will definitely be cheaper for you operate with high-reliability this way.
You won't need to deal with nginx anymore.
We have a website which provides services for people based in particular city.
We want to scale and provide it for more cities but we want to remain separated IT within the city realm: one webhost, cloud service , database etc for one location. It does not only enables us to scale individually (some cities are bigger than other several times) but most significantly it improves our code-base and db queries to not use city's predicates - despite the fact it is more expensive in general.
At the same time we do not want to use subdomain. User can switch city through dropdown and request should go to appropriate VM without url being changed so the routing should work seamlessly.
Based on Azure documentation we are still not sure what solution would meet our needs, Traffic Manager, Load balancer or custom redirects.
How you accomplish this is ultimately up to you, but from an Azure-specific perspective, the only multi-region built-in load-balancing service is Traffic Manager. This operates in one of three routing modes:
Primary/failover
Round-robin
Closest (based on latency, not physical distance)
For any other type of routing (such as letting the user choose location, per your question), you'd need to implement this on your own or via 3rd-party service (and how to accomplish that would be a matter of opinion/debate/discussion, which is off-topic for StackOverflow).
Since you're looking to have a separate DB, cloud-role and webhost per city, I do not see how you can get away from doing subdomains.
Do you not want subdomains because of SEO? If so, it'd be easier to find another way to solve SEO problem.
But whatever Traffic Manager or other DNS based routing solution you use, it'll be splitting users by where they come FROM and not where they're going TO.
The destination problem is solved thru separate sub-domains
What are the benefits of using Fastly versus simply having my own self-hosted Varnish? Are there additional benefits and features that Fastly provides that regular Varnish does not, or is it simply that Fastly is managed Varnish in the same way that CloudAMQP is hosted and managed RabbitMQ?
I just stumbled across this question, I know you asked this a while ago but I'm going to try and answer it for you regardless.
You are correct in assuming that Fastly manages the Varnish instances for you, so you don't have to deal with manually managing your servers. It is a slightly different concept than CloudAMQP however; CloudAMQP is a managed RabbitMQ system that lives in a specific datacenter, perhaps with Multi-AZ enabled for failover purposes.
Fastly is a full blown content delivery network which means they have machines running Varnish all over the world which could significantly increase your user's experience because of lower latency. For example if an Australian user visits your website he will be retrieving the cached content via Fastly's Australian machines, whereas if he were to connect to your own Varnish instance he'd probably have to connect to an instance in the U.S. which would introduce a lot more latency. On top of that it wouldn't only improve speed, but also reliability. Your single Varnish instance having a failure is quite likely, Fastly's global network of 1000s of machines running Varnish collapsing is very unlikely.
So to sum it up for you:
Speed
Reliability
Regards,
Rene.
I have an azure traffic manager configured to route traffic over two data centres based on performance (latency). The two DCs are replicas of each other, and is engineered in this way so that our global customers are givin a good performance no matter where they are connecting from.
The application tiers do not hold state, and the data tiers are set up using SQL merge replication on a 1 minute timer to keep the DBS in sync as to provide service continuity in the event of a Datacenter failover.
The issues that I have found is that the traffic managers routing is slightly erratic. I have observed registering a user under one Datacenter only to find the login has bee routed to the other one - the SQL replication hasn't synced at this point and the second DC isn't aware that the user exists. Even though the user both registered and logged in from the same location! The DCs are in the West US and South east asia.
I'm looking at a few options to fix this. Solution A is to Silo the users data to a specific data center, therefor whatever DC the user registers to is used thereafter. I wouldn't have syncing issues but I lose the advantage of continuity that the SQL replication provides.
Solution B is to use a different more predictable global load balancer. But first I want some opinions and to perhaps see if I am doing something wrong or perhaps my architecture is flawed.
Thanks for advice.
My solution had challenges using the traffic manager also, although slightly different to yours. The traffic manager is a great value solution if it can work for you. As far as I am aware no configuration in traffic manager allows it to be aware of sessions, therefore it is blinkered to its config setting of performance in your case. This means its acting erratic based on your expectation for it to use sessions to be persistent to an endpoint subject to it being available.
In terms of your solution, it is very much Enterprise. To move backwards with solution A probably doesn't fit the requirement given what you went to the effort of building. Solution B brings many more features that Traffic Manager lacks and one of them will resolve your issue. For other reasons I am looking at
http://kemptechnologies.com/uk/server-load-balancing-appliances/virtual-loadbalancer/loadmaster-azure
It is designed for Azure and is available as a pre-installed VM. There are others available but this has been my choice and what I would use if I were in your position and wanted to keep the level of resilience you currently have.
Hope this helps.
I'm interested in cross-colo fail-over strategies for web applications, such that if the main site fails users seamlessly land at the fail-over site in another colo.
The application side of things looks to be mostly figured out with a master-slave database setup between the colos and services designed to recover and be able to pick up mid-stream. I'm trying to figure out the strategy for moving traffic from the main site to the fail-over site. DNS failover, even with low TTLs, seems to carry a fair bit of latency.
What strategies would you recommend for quickly moving traffic between colos, assuming the servers at the main colo are unreachable?
If you have other interesting experience / words of wisdom about cross-colo failover I'd love to hear those as well.
DNS based mechanisms are troublesome, even if you put low TTLs in your zone files.
The reason for this is that many applications (e.g. MSIE) maintain their own caches which ignore the TTL. Other software will do a single gethostbyname() or equivalent call and store the result until the program is restarted.
Worse still, many ISPs' recursive DNS servers are known to ignore TTLs below their own preferred minimum and impose their own higher TTLs.
Ultimately if the site is to run from both data centers without changing its IP address then you need to look at arrangements for "Multihoming" via global BGP4 route announcements.
With multihoming you need to get at least a /24 netblock of "provider independent" (aka "PI") IP address space, and then have that only be announced to the global routing table from the backup site if the main site goes offline.
As for DNS, I like to reference, "Why DNS Based Global Server Load Balancing Doesn't Work". For everything else -- use BGP.
Designing networks in order to load balance using BGP is still not an easy task and I myself certainly am not an expert on this. It's also more complex than Wikipedia can tell you but there are a couple interesting articles on the web that detail how it can be done:
Load Balancing In BGP Networks
Load Sharing in Single and Multi homed environments
There is always more if you search for BGP and load balancing. There are also a couple whitepapers on the net which describe how Akamai does their global loadbalancing (I believe it's BGP too.), which is always interesting to read and learn about.
Beyond the obvious concepts you can use software and hardware to achieve, you might also want to check with your ISP/provider/colo if they can set you up.
Also, no offense in regard to your choice of colo (Who's the provider?), but most places should be setup to deal with downtimes and so on, they should not require you to take actions. Of course floods or aliens can always strike, but in that case I guess there are more important issues. :-)
If you can, Multicast - http://en.wikipedia.org/wiki/Multicast or AnyCast - http://en.wikipedia.org/wiki/Anycast