I would like my grails app to be deployed in the root of my domain:
www.example.com
instead of
www.example.com/myapp
However www.example.com/index.html is going to be static (static html, images, etc). I'm concerned about performance of having the the application server serve up the homepage. Can I configure my grails app / the cdn to serve index.html and it's content, and have the application server handle the dynamic pages?
I am using grails 2.2.4
I will be using Amazon S3 + ElasticBeanstalk + CloudFront.
Or should I be worried about performance at all? I am new to grails but it's my understanding that static content should be served by the webserver (Apache). Since there is no apache, I'm looking for another option to keep the load off of the webserver. The CDN seems like a good idea.
You certainly can do that. My personal recommendation would be to keep your images on S3 and use Cloud Front on top of that. Unless your static HTML itself is excessively large, it would be my recommendation to let Grails be Grails and take advantage of using Grails Resources for your JS and CSS as typical Grails projects do - even if your index page won't be doing anything dynamic right now. The more you break off the Grails conventions, the more complex things like builds and continuous integration can become. Look at using caching, minifying plugins and performance is very good.
As for deploying to the root "/" context, you can either do this by "prod war ROOT.war" for your Tomcat (or wherever) deployment OR you can build it as "whateverapp.war" and handle the routing rules with Apache mod_jk for more complex situations.
I've done probably a dozen Grails projects and use a very similar architecture now.
The simplest thing to do is to serve your entire domain from CloudFront and then serve the home page from your Grails app. You can configure CloudFront to cache requests to the home page so you will minimize the number of requests to Grails. You can map CloudFront directly to the ELB running in your Elastic Beanstalk environment.
The default Elastic Beanstalk configuration doesn't give you any way of serving static files from Apache; all the requests to Elastic Beanstalk are proxied to Tomcat. You can use advanced configuration to set this up though (using the .ebextensions mechanism).
You can also set up the Cache plugin to set up full page caching on the server side (I recommend using the Cache EhCache plugin as well). Combining server-side caching with CDN caching will get you a long way.
BTW, another good option for serving static content is to use S3 itself to serve pages. If you aren't doing anything too complicated it will save you the work of setting up and running a web server, although with Elastic Beanstalk there's not much to do.
Related
I have an application on Google App Engine. I used to store images within Ndb blobs, and serve them from GAE. Then all this relatively static seemed to put needless load on the application, and I switched to storing all images (including user-uploaded) within a GCS bucket, made publicly available through http://static.mysite.com, and served directly from there.
This is working great. Until I consider switching the application to SSL.
Setting up SSL for my GAE application went OK, but then I get security warnings because images are not served through SSL. So I need an SSL access to my GCS images, but GCS does not support SSL, and I see no plans for it in the future.
What are the options ? Storing images in GCS seems to be the recommended choice, and going SSL is now recommended for most websites, but the two seem to be incompatible.
I see Google CDN could be one approach that would (maybe) support SSL, but it's kind of overkill in my case.
I'm trying out HTTP/2 and would like to know if there's any best practices for making a web application take advantages of the new protocol in both:
Server side and
Client side
And... where (and when?) should I start? What are the least effort changes to take effort of HTTP/2
Update:
Assumption : Users are already using browser that support HTTP/2.
Update 2:
Some good resources on this topic:
https://http2.github.io/faq/
https://www.nginx.com/blog/7-tips-for-faster-http2-performance/
https://www.smashingmagazine.com/2016/02/getting-ready-for-http2/
You don't need any changes to your apps to deploy HTTP/2: most things will work out of the box.
That said, here are a few tips that apply mostly if you are starting from scratch:
Start developing your application using HTTPS. You don't want to have problems with your URLs when you deploy your application because fetching some resources over http:// (e.g. Google fonts or any other CDN resources) does not work anymore. It takes five minutes with some tools (just google "Five minutes to HTTPS development URLs").
Consider if you want to host some resources that you would normally link to a public CDN in your own server. The main performance reason with HTTP/2 for linking to some assets in a CDN, if you are not hosting your entire site on that CDN, is that those resources may be already in the user's cache. If they are not, opening a new connection takes in average half a second.
Don't set up bundling. Set up instead HTTP/2 Push. And then go and grab your favourite module manager. Give a try also to web components and PolymerJS. They are simply awesome when you are not concerned about bundling and round-trips.
If you are using a server that uses machine learning for configuring HTTP/2 Push automatically (e.g, ShimmerCat), then a third tip is to keep the structure of your web pages predictable.
I created a sinatra app and I'm trying to put it on github pages. I can run my app on localhost, but I don't know how to push it to the actual web.
I have tried googling and searching stackoverflow and I keep seeing people use heroku. Is this required? Is there anyway to push directly from sinatra to the web? I can get a simple index.html file to run on github pages, but I don't know how to get my sinatra app to run. Any help would be great.
As Sirajus says, Github pages only serve static HTML pages. Sinatra is a framework for producing code that produces web pages. It's really there for sites that require some server side processing (i.e. dynamic), but can serve static pages too (a wise decision).
It doesn't serve the pages itself, it runs on a Rack compliant application server (like Thin, Puma, Unicorn or Webrick) and when asked, it builds the page, gives it to the server and the server gives it to you.
Entirely static sites like Github pages or those served via Amazon's S3 are just a collection of HTML files sitting behind HTTP file servers (those of the Apache and Nginx variety). They're static because they're not generated on the fly… dynamically. They don't change, there's no extra processing needed to serve them. They're just sat there wait to be served. You could use things like Sinatra and Thin to do this, but the added complexity adds maintenance work, security issues, costs extra money, time… and crucially, slows the serving speed down. If your site is essentially all static, by which I mean there's no need for the server to process anything, then you may be better off using something that generates static pages from the off. There are many libraries to help with this, Middleman (based on Padrino and hence Sinatra) and Jekyll come to mind, as does Nanoc.
You can emulate what these libraries do by saving the output of each route and uploading that, if it's appropriate. There are libraries that help with this, like Sinatra Static and its fork, Sinatra Export. You could use cURL to save the pages with a command like curl http://localhost:9292/ > index.html for every single path if you wanted. I did something like this for my own blog the other day.
If it's not appropriate to do this or you can't be bothered, set up some server hosting. A lot of these services are free to start with so it won't hurt to give them all a try, you'll learn a lot from doing each.
To run your sinatra app you need to host it with a server. Github pages only run html page not a ruby web application.
To host your sinatra app you can use heroku/ digital ocean.
My setup is a WAR deployed though elasticBeanstalk on a Tomcat7/Java7 app. I'm doing basic HTML with Servlets, and REST. Nothing fancy.
I would like to replace the default server.xml for Tomcat7/Java7 under my elasticBeanstalk.
http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/customize-containers.html
I'm a bit confused.
I'm looking for reasonable performance tuning numbers for the parameters there.
Looking for good defaults for security as well
Should I touch the AJP connector? (every request goes to a servlet) what should I configure?
Does this setup have Apache as a front-end, or do the HTTP requests go directly to Tomcat?
My instance is choking after a relatively low amount of concurrent users, with ~9% CPU, and plenty of DB connections. Am I jumping to conclusions with server.xml?
Thanks..
AJP is not necessary as you have mentioned that most of the URL requests are servlet based. You can use AJP incase if you have more static contents to serve.
Most of the cases the performance tuning needs to be done at the web frontend part. Below are my suggestions.
Use gzip compression for web contents.
Make your pages cachable by using cache related HTTP headers (Etag, Expires, Cache-control,). By doing so you will reduce the number of unwanted HTTP requests.
JS and CSS can be minified inorder to reduce their sizes.
Check if you are getting more traffic from web crawlers. If you are getting more traffic from those try to reuse web sessions with Crawler_Session_Manager_Valve.
Try to index key tables of your database.
Make sure you are using DB connection pooling instead of opening new connections for every new request.
Avoid unwanted URL redirections (302, 304).
Incase if you are looking for a good book that can help you optimize your website refer High Performance Web Sites for O'Reilly
There is this example on amazon, a high traffic web application. I noticed that they are using S3 as their content delivery method. I was wondering if I need to have a Web Server for the content delivery and a Web App for my application. I don't understand why they have 2 web servers and 2 web app in the diagram.
And what is the best way to set up a website that serves images and static contents through S3 and the rest of the content through the regular storage.
My last question is, can I consider S3 as a main storage, reliable enough that I can only keep my static content there and don't have a normal storage as a backup ?
That is a very general diagram, specific diagrams will vary depending on the specifics of the overall architecture.
Having said that, I believe the Web Server represents something like Apache or Nginx and the App Server represent something like Rails, Rack Server, Unicorn, Gunicorn, Django, Sinatra, Flask, Jetty, Tomcat, etc. In some cases you can merge the Web Server and the App Server together like for example deploying Apache with python mod_wsgi to run your Django app. (So depends on Architecture)
what is the best way to set up a website that serves images and static
contents through S3 and the rest of the content through the regular
storage.
There's no really best way other than just point your dynamic content to your Databases (SQL and NoSQL) and point your static files to an S3 bucket (images, css, Jquery code, etc) You can also use third party modules depending on your application stack. For example you can accomplish this in Django with the django-storages module. You can find similar modules for other app stacks like Rails.
My last question is, can I consider S3 as a main storage, reliable
enough that I can only keep my static content there and don't have a
normal storage as a backup ?
S3 is pretty reliable, they provide a 99.999999999% reliability of your data. That goes down if you use their RRS (Reduced Redundancy Storage), but if you want to use it you probably want to back up your data in a non RRS bucket anyways. Anyhow, if it's extremely critical data, you are more than free to backup your data somewhere else just in case.
Notice in the diagram that they also recommend using CloudFront for your static files and this is especially useful if your users will be accessing your application from different geographical areas.
Hope this helps.