Appengine MemCache resets across multiple runs - java

I m new to app engine. I m using Memcache and running it in eclipse. And every time i run the app the value of memcache resets. And i dont have the old values
MemcacheService memCache= MemcacheServiceFactory.getMemcacheService();
memCache.setErrorHandler(ErrorHandlers.getConsistentLogAndContinue(Level.INFO));

If you mean that you are running the gae development environment locally starting it from inside Eclipse, then what are experiencing is expected behavior. The memcached instance gets started and stopped every time you restart the development environment. It is a memory only caching mechanism? What do you expect it to do?

In GAE development-mode memcached is embedded into your process, so when your process terminates you loose your memcached instance as well.
However, when you deploy on your Goggle GAE account, the memcached instance is independent from your app. instance and cache values can survive your app instance restarts...but memcached instance itsself might be restarted by GAE and its not guaranteed to hold cache values for long time.
Also, you cannot use memcached as a system of record...since its not a persistent cache. If you want more reliable memcached implementation you can use Couchbase that has clustered 24/7 memcached compatible implementation for enterprise level use. It can be used as system of record...e.g. its a "NoSQL DB" ... but its not offered in GAE.

Related

Java Play Framework 1.4x - Development Server

I am interested in what Development Server does Play use under the hood? (Web & Application server)
While developing locally i have huge page load times (5-10 seconds) comparing to deployed application page loads (1-2 sec) . I suppose something is wrong with development server since there is a huge difference in speed.
Is there a specific location of the development server Play! 1.4 uses ? Can i switch development server?
Play uses netty, but the performence difference is because in dev mode all the frameworks (not only play) disable all kind of caches or precompiled things and recompile everything all the time to have a good dev experience, in production things are compiled only once.
Play FW uses a single thread in DEV mode(default) for better debugging. If you have blocking threads (multiple queries being excuted with ajax requests etc), the others will be waiting for that thread to be released . So you will have longer wait times relative to deployed version.
You can change this behaviour to use specified number of threads (e.g. 5), in application.conf like this:
# Default to 1 thread in DEV mode or (nb processors + 1) threads in PROD mode.
# Try to keep a low as possible. 1 thread will serialize all requests (very useful for debugging purpose)
play.pool=5

Distributed Cache Warmup

I have a web application (spring based war) which is deployed in a Tomcat webserver. This web application is served by several server instances each running an instance of Tomcat. I intend to cache some data on a Redis datastore and all application instances contact this datastore to read data. As a pre-step I want some of the data to be cached up in Redis when the application starts.
If I do it via the web-app, all of the nodes will try to initialize the cache. Making one of the instances leader is one of the options, are there any better solutions to this?
Restarting: Indicates : Stop tomcat and then start it again. It could be done for several reasons: deploying a new version of the web app / server (machine) restart / new server being added to the pool. It's unlikely that all of the tomcat instances would be started at the same time but some of them may be started at the near same time.
Cache server is independent of the web-app, but in case it also crashed and the data was lost. I will maintain the "last read" TS in the Cache as well.
You have at least two options here:
Either you warm your cache from inside the application
Or you do it outside
Either approach has its own properties and from here on you can derive a solution.
Warming inside the application
You have inside your application all infrastructure to perform cache warming. If cache warming is idempotent, then it could be fine to have it done by all your instances. If you don't want to deal all of your applications with cache warming, then you need to make a decision:
What will other instances do while the cache is warming?
I have two answers to that question:
Ignore and continue startup
Wait until the cache is warmed
In both cases, you can use Redis CAS (Compare-and-swap) with timeouts to create an expiring, distributed lock so the fastest starting instance will do warming and release the lock once it is done.
You could tackle that challenge also with a process that you deploy the first instance to your servers which perform cache warming. You wait until that application has finished its job and then you're good to go for the other instances.
Warming outside the application
With cache warming outside the application, you don't run into concurrency issues, but that requires some effort on the operating and development side. You need someone (or some process) that runs the cache warming before your application start/deployment. You also need to build that piece of code that will access your data and put it into the cache.
Building leader patterns would also work but require additional code/components. If you can, keep it simple.
HTH, Mark

How to deploy a Java webapp on Amazon EC2 so that you can efficiently use autoscaling?

I'm trying to get my head around a simple WebApp Java deployment case on Amazon Web Services.
I have manually deployed on a single EC2 instance, manually installing Java, Tomcat, MySql on a vanilla RedHat image -- as if I owned the hardware.
Now I'm trying to set up an auto scalable, easy-to-manage, production proof environment:
1 -> n Tomcat instances with a standard Java WebApp deployed,
1 MYSQL database with 1 schema and a few tables (not much), the webapp connects to it.
I understand that autoscaling depends on some trigger (e.g. more than % of usage). However, when the new server is started, my app is not deployed because it's not in the VM image. Something needs to happen so that the new servers run my code.
What is the best option to mass deploy to 1-n autoscaling group of tomcat only servers on amazon?
What is the best option to upgrade your app ? I guess you don't want all the servers to go down in one go...
How about creating a VM image that automatically retrieves the latest build available from my CI (uploaded to a S3 or something else)? I could easily add this script to Tomcat bootstrap / linux startup...
How about commercial tools like Chef or Puppet? Any open-source equivalent?
I reviewed a lot of things on the web and yes, ElasticBeanStalk is the right thing to use as Georges said. Though, it feels like it's quite confusing at start.
First of all, you can run a load balanced / scalable environment on the Free tier using t2.micro instances. What matters is the number of hours in total. You can use 100 servers for 7 hours and it'll be fine. Be careful with Health Check because it pings your environnement all the time. If you run tests / evaluation and don't want to pay, make sure you save / backup and terminate your environment as soon as possible. Data Transfer is not free of charge apparently so make sure you don't use any multi-AZ and multi-zones if you don't want to pay.
That said, BeanStalk is a kind of "black box" that does a lot for you. It is intended to create all the configuration in the console for you. A kind of "super-wizard" for load balanced / scalable environments.
Configuration goes like this : you say you have a war file you want to deploy, you upload it, you pick a container (e.g. linux+tomcat), you set up a database and it will create a basic configuration with all you want : Load Balancing, autoscaling and monitoring. It's easy to change to settings to match your needs.
One tricky thing is database configuration : you need to set environnement variables and use them in your spring configuration as per : https://raymondhlee.wordpress.com/2013/06/01/migrating-a-java-web-app-for-deploy-to-aws-elastic-beanstalk/
Application update can occur in "rolling way" i.e. occurring on limited percentage of your fleet of servers (default is 30%) which means you don't have to worry too much about downtime.
Boxfuse does what you want.
For you Java web application you literally only have to execute:
boxfuse create my-tomcat-app -apptype=load-balanced
boxfuse scale my-tomcat-app -capacity=1-16:t2-micro:cpu25-75
boxfuse run my-tomcat-app-1.0.war -env=prod
This will
Configure your application to use an ELB
Set it to autoscale between 1 and 16 t2.micro instances based on CPU usage (scale in at 25% and below, scale out at 75% and above)
Create AMI with your app and Tomcat set up so they are ready to boot
Create an ELB
Create a security group with the correct ports
Create an auto-scaling group
Launch your instance(s)
Any subsequent update will be done as a zero downtime blue/green deployment.
More info: https://boxfuse.com/blog/auto-scaling
You could make use of the User Data on an EC2 launch configuration. You can use this to pass a shell script to your instance that will run automatically when it is launched for the first time. A common pattern is to have the shell script download and install a build from S3, as you suggested in your question.
With this pattern, upgrading the build on your auto-scaling group is easy. Simply upload a new build to S3. Then, manually terminate instances in the auto-scaling group. The auto-scaling will automatically spin up new EC2 instances, which will download the new build from S3, and presto, your auto-scaling group is updated. If you terminate each instance one at a time, and wait for the new instance to come online before terminating the next one, the impact on your system is minimized.

Java equivalent of .net recycle

What is the Java equivalent of the .net Recycle for web apps in IIS.
This is when using Java on a linux machine outside of IIS.
Is it just to stop and start the application?
Not really - IIS and JVM work in different ways. When you say recycling in IIS, it's basically restarting the Worker process. Each Web Application deployed to IIS is under an application pool and worker process.
In case of java, it's not like that. The whole App server runs on a jvm and you have different Web applications deployed into the App server which runs within the app server.
You could use DB connection pools or Apache commons pool for pooling (Some of your expensive objects you reuse) which can be refreshed but not exactly in a way like IIS.
Even though this would be a nice feature - in reality if you ever
reach a situation of needing to refresh application pool, your
code/dll(may be 3rd party) is the culprit. There would definitely be a
memory leak which needs to be addressed! Also when you recycle the session state might be lost. Apparently users logged in would get logged out (and if they are in the middle of a transaction they might loose data).So it could lead to a very volatile situation!
Update
You could use stuff like Terracotta which handles memory management.
Usually JEE servlet containers offer the option of reloading the application. i.e. Tomcat has a Reload button for each app on the manager console.
It also has a button that triggers a full garbage collection, by the way.

Running webapps in separate processes

I'd like to run a web container where each webapp runs in its own process (JVM). Incoming requests get forwarded by a proxy webapp running on port 80 to individual webapps, each (webapp) running on its own port in its own JVM.
This will solve three problems:
Webapps using JNI (where the JNI code changes between restarts) cannot be restarted. There is no way to guarantee that the old webapp has been garbage-collected before loading the new webapp, so when the code invokes System.loadLibrary() the JVM throws: java.lang.UnsatisfiedLinkError: Native Library x already loaded in another classloader.
Libraries leak memory every time a webapp is reloaded, eventually forcing a full server restart. Tomcat has made headway in addressing this problem but it will never be completely fixed.
Faster restarts. The mechanism I'm proposing would allow near-instant webapp restarts. We no longer have to wait for the old webapp to finish unloading, which is the slowest part.
I've posted a RFE here and here. I'd like to know what you think.
Does any existing web container do this today?
I'm closing this question because I seem to have run into a dead end: http://tomcat.10.n6.nabble.com/One-process-per-webapp-td2084881.html
As a workaround, I'm manually launching a separate Jetty instance per webapp.
Can't you just deploy one app per container and then use DNS entries and reverse proxies to do the exact same thing? I believe Weblogic has something like this in the form of managed domains.
No, AFAIK, none of them do, probably because Java web containers emphasize following the servlet API - which spins off a thread per http request. What you want would be a fork at the JVM level - and that simply isn't a standard Java idiom.
If I understand correctly you are asking for the standard features for enterprise quality servers such IBM's WebSphere Network Deployment (disclaimer I work for IBM) where you can distribute applications across many JVMs, and those JVMs can in fact be distributed across many physical machines.
I'm not sure that your fundamental premise is correct though. It's not necessary to restart a whole JVM in order to deploy a new version of an application. Many app servers will use a class-loader strategy that allows them to discard a version of an app and load a new one.

Categories

Resources