Skip to main content

How to get heapdump for any microservice running in Docker container in Google App Engine

Getting heapdump for our services is very important for doing any memory profiling to debug any leaks or performance issues. Unfortunately it is not that straight forward. Fortunately, it is not impossible either!
We need to SSH in the container in which our service is running. Go to App Engine → Instances page and select your service from the 'services' dropdown.


SSH into any of the instances:

Ignore this and SSH into VM.



Once you SSH, you should be able to see cloud shell as below. If you are logging in for the first time, there may be some questions asking for SSH key. You can leave the key blank and continue.

This shell is the Linux VM on which our docker image is running. We need to find out more details about it before we can do anything with it. 

There are a bunch of images running. We are interested in the first one ('us.gcr.io/.....') running in a container named 'gaeapp'. Now we need to go inside this docker container running our service. Below command executes '/bin/bash' command in the container and we get a bash shell inside container. (Call it VMception!)


Create a directory here to be able to store the dump in and give it all access.
mkdir dump_dir.
chmod 777 dump_dir
We will use it later.
Now in this VM we can check the processes running and the users running those. Give 'top' command on the shell and you see this:

As we can see 'jetty' user is running a java process. This is what we are interested in. We would now try to get heapdump of this process. For this we need to connect as the user 'jetty'. Currently we are logged in as user 'root' and we can't take the dump. Press Ctrl+C to exit this screen and get back to the shell. 
su - jetty
/bin/bash
We get to the shell now as 'jetty'.


Goto the directory we created earlier.
cd jda/scripts/dump_dir
All set to take the dump! Here we need to give the PID of the java process we found above (50 in this example)
jmap -dump:live,file=dump_dir/ 50
If all is well, you should be able to get the hprof file created in this directory. Stage 1 is now over. Stage 2 is getting this file to your VM.
Write 'exit' on the bash shell to exit from the bash shell of jetty user.
Write 'exit' again on the prompt to exit from the jetty user.
Write 'exit' again on the bash shell to exit from the root user and from the docker.
Now you are on the VM where you logged first. Copy the file to this vm file system from the docker file system and give it all access.
docker cp gaeapp:/jda/scripts/dump_dir/ .
chmod 777 filename.prof
Stage 2 is now over. Stage 3 is now getting this file to your local machine. (I know, this seems like a never ending process but please stay with me!)
On a shell on your local machine give following commands. Second command is optional if you have already a default project configured.
gcloud auth login
gcloud init
gcloud app instances scp --service  --version  :/<filename> 
For example, in my case above command looks like this:
gcloud app instances scp --service metadata-service --version v171 aef-metadata--service-v171-qhl0:/home/abhishek_asthana/dump_hprof.bin dump.hprof
And with this Stage 3 is also over. You have finally got the hprof file on your machine and can now use any memory profiler for analysis.

Comments

Popular posts from this blog

How to upload to Google Cloud Storage buckets using CURL

Signed URLs are pretty nifty feature given by Google Cloud Platform to let anyone access your cloud storage (bucket or any file in the bucket) without need to sign in. Official documentation gives step by step details as to how to read/write to the bucket using gsutil or through a program. This article will tell you how to upload a file to the bucket using curl so that any client which doesn't have cloud SDK installed can do this using a simple script. This command creates a signed PUT URL for your bucket. gsutil signurl -c 'text/plain' -m PUT serviceAccount.json gs://test_bucket_location Here is my URL: https://storage.googleapis.com/test_sl?GoogleAccessId=my-project-id@appspot.gserviceaccount.com&Expires=1490266627&Signature=UfKBNHWtjLKSBEcUQUKDeQtSQV6YCleE9hGG%2BCxVEjDOmkDxwkC%2BPtEg63pjDBHyKhVOnhspP1%2FAVSr%2B%2Fty8Ps7MSQ0lM2YHkbPeqjTiUcAfsbdcuXUMbe3p8FysRUFMe2dSikehBJWtbYtjb%2BNCw3L09c7fLFyAoJafIcnoIz7iJGP%2Br6gAUkSnZXgbVjr6wjN%2FIaudXIqA

Running Apache Beam pipeline using Spark Runner on a local standalone Spark Cluster

The best thing about Apache Beam ( B atch + Str eam ) is that multiple runners can be plugged in and same pipeline can be run using Spark, Flink or Google Cloud Dataflow. If you are a beginner like me and want to run a simple pipeline using Spark Runner then whole setup may be tad daunting. Start with Beam's WordCount examples  which help you quickstart with running pipelines using different types of runners. There are code snippets for running the same pipeline using different types of runners but here the code is running on your local system using Spark libraries which is good for testing and debugging pipeline. If you want to run the pipeline on a Spark cluster you need to do a little more work! Let's start by setting up a simple standalone single-node cluster on our local machine. Extending the cluster is as easy as running a command on another machine, which you want to add to cluster. Start with the obvious: install spark on your machine! (Remember to have Java a

java.lang.IllegalArgumentException: Malformed \uxxxx encoding

I was getting this exception during build while running ant. Googling didn't help much and I was flummoxed because the same code was running fine till now. My code reads a text file and does some operations on the basis of values read. It was only when I saw the text files I understood the error. I had copied the text in wordpad and saved it as .txt file. Wordpad had put lot of formatting information before and after the content. Also there was "\par" after every line, which was giving this error. So moral of the story: if you get this exception check your properties file (or any other file that your code might be reading.)