Good default tomcat server.xml for AWS ElasticBeanstalk - performance

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

Related

Can a person add CORS headers using the ELB Application Load Balancer (sitting in front of Solr)?

We have a number of EC2 instances running Solr in EC2, which we've used in the past through another application. We would like to move towards allowing users (via web browser) to directly access Solr.
Without something "in front" of Solr this results in a security risk, so we have opted to try to use ELB (specifically the Application Load Balancer) as a simple and maintenance free way of preventing certain requests from hitting SOLR (i.e. preventing the public from DELETING or otherwise modifying the documents in Solr).
This worked great, but we realize that we need to deal with the CORS issue. In other words, we need to add the appropriate headers to requests that come in from a browser. I have not yet seen a way of doing this with Application Load Balancer but am wondering if it is possible to do someway. If it is not possible, I would love as an additional recomendation the easier and least complicated way of adding these headers. We really really really hate to add something like nginx in front of Solr because then we've got additional redundancy to deal with, more servers, etc.
Thank you!
There is not much I can find on CORS for ALB either and I remember when I used Beanstalk with ELB I had to add CORS support in my java application directly.
Having said that, I can find a lot of articles on how to set up CORS for Solr.
Can it be an option for you?

How can I cache queries with Parse Server?

I have an iOS app that is using Parse Server, and I noticed that a lot of my queries are made on tables that are not changing often.
I would like to know if it's possible to cache (for instance every day) some of these requests using Parse Server in order to limit resources used and improve my capacity.
Thanks for your help.
Cyril
For now we don't provide caching mechanisms, but you could implement it through a reverse proxy or another strategy in the front of your parse-server
For example, you can configure it with nginx, to cache the requests and serve them before you hit your parse-server installation
https://www.nginx.com/resources/wiki/start/topics/examples/reverseproxycachingexample/

How to serve images from Riak

I have a bunch of markdown documents in Riak, which I'm exposing via a small Sinatra API with basic search functionality etc.
Each document has an associated image, also stored in Riak (in a different bucket). I'd like to have a client app display the documents alongside their associated images - so I need some way to make the images available, but as I'm only ever going to be requesting them by key it seems wasteful to serve them via a Sinatra app as I'm doing with the documents.
However I'm uneasy with serving them directly from Riak, because a) even using nginx to limit the acceptable requests, I worry about exposing more functionality than we want to and b) Riak throws a 403 for any request where the referrer is set, so by default using a direct-to-Riak url as the src of an img tag doesn't work.
So my question is - what's a good approach to take for serving the images? Add another endpoint to the Sinatra app? Direct from Riak using some Nginx wizardry that is currently beyond me? Or some other approach I haven't considered yet? This would ideally use Ruby as that's what the team I'm working with are more comfortable with.
Not sure if this question might be better suited to Server Fault - if so I'll move it over.
You're right to be concerned about exposing Riak to any direct connectivity. Until 2.0 arrives early next year, there is no security in the system (although the 403 for requests with a referrer is a security mechanism to protect against XSS), and even with security exposing any database directly to the Internet invites disaster.
I've not done anything with nginx, but all you'd really need to use it properly, I'd think, would be two features:
Ability to restrict requests to GET
Ability to restrict (or rewrite) requests to the proper bucket
Ability to strip out all HTTP headers that Riak includes in its result (which, since nginx is a proxy server and not a straight load balancer, seems like it should be straightforward)
Assuming that your images are the only content in that bucket, nginx feels like a reasonable choice here.

grails serve index.html from CDN

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.

JSON GZIP Design choice

I am working on a web application with dynamic content generated by a servlet running in a JBoss container and static content/load balancing being handled by Apache + mod_jk.
The client end uses jQuery to making AJAX requests to the servlet which processes them and in turn generates large JSON responses.
One thing I noticed is that the original author chose to manually compress the output stream in the servlet using something like below.
gzout = new GZIPOutputStream(response.getOutputStream());
Could this have been handled using mod_deflate on the Apache end? If you can do this, is it considered better practice, can you explain why or why not?
I believe it makes more sense to apply HTTP compression within Apache in your case.
If a server is properly configured to compress responses of this type (application/json, if the server-side code is setting the correct content-type), then it's being wastefully re-compressed after the manual compression anyway.
Also, what happens here if a client that doesn't support gzip makes a request? If you're compressing the response at the server level, it will automatically respond appropriately based on the request's accept-encoding header.
A little additional research shows a couple of good alternatives.
Issue:
There is a network channel that exists between Apache and Jboss. Without compression of any kind on the jboss end you'd have the same latency and bandwidth issues you have between Apache and your clients.
Solutions:
You can use mod_deflate on the Apache and accept uncompressed responses from jboss and compress before delivering to your clients. I could see this making some sense in certain network topologies(Proposed by Dave Ward).
You can apply a Java EE filter. This will filter responses compressing them before they exist the JBoss container. This has the benefit of compression at the JBoss level without a bunch of nasty GZIP related code in your business servlet.
JBoss with by default uses Tomcat as its Servlet engine. If you navigate to $JBOSS_HOME/deploy/jbossweb-tomcat55.sar you can edit the server.xml file to turn 'compression=on' attribute on the HTTP/1.1 connector. This will compress all responses outbound from the container.
The trade-off between 2 and 3 is compressing piece meal for different servlets or compressing all responses.

Resources