Building and Deploying Microservices with App Engine and Cloud Functions

A coupe weeks ago, I had the chance to talk at Cloud Next 2018, in San Francisco, with my colleague and friend Alexis. We talked about building and deploying microservices with Google App Engine and Cloud Functions. I've been a big fan of App Engine since 2009 when Google released the Java flavor, and have been enjoying doing a bit of Node / JavaScript on Cloud Functions since it came in beta. So I was very happy to be able to talk about those two serverless solutions.

Without further ado, let's start by sharing the video (and slides) of the talk!


Now that I've shared the video, let me tell you a bit more about this session and the demo we built.

First, a few words about the buzzword du jour: serverless. What I particularly like about this approach (which I also liked in the good old times of another old buzzword: PaaS) is how it lets me focus on the idea I want to implement, instead of being bothered from the get go with server or cluster provisioning, OS choice, monitoring/logging/alerting, etc. I can directly start coding something, and quickly deploy my app or function in the cloud and see how well it's working (compared to my dreamed up idea). Additionally, besides the ops-less aspect, I also don't have to think about scaling, as it scales pretty much auto-magically for me. Last but not least, I don't have to pay upfront big costs for renting machines or vms, as it's really pay as you go, and not paying for an idle server (after all, my idea might be just a quick idea not geared towards prime-time success!)


Google Cloud Platform offers various solutions which follow those characteristics, not only for compute with App Engine and Cloud Functions, but also for data storage (like Datastore which I'm using in my demo as my database), or the machine learning APIs (like the Vision API that I also integrated in my app). Database-as-a-Service, Platform-as-a-Service, Function-as-a-Service, Software-as-a-Service often fall into that category for me, if you don't pay for infrastructure, when it takes care of scaling, and if it's price proportionally to your usage.

Cloud Functions

Cloud Functions (or GCF for short) is a great fit for event driven problems: a new picture is stored on Google Cloud Storage? A function is triggered. I get a message on Pub/Sub? Another function is invoked. It's also possible to invoke a function directly via an HTTP call, without requiring any kind of gateway to expose it.

At Next, the general availability of Cloud Functions was announced, with an SLA of 99.5%, additional regions (2 in the US, 1 in Europe, 1 in APAC), and also new runtimes with Node.js 8 and Python 3.7. Further improvements are the ability to get a function hooked to a VPN in order to connect your functions with your VMs, new scaling controls to limit the number of instances serving your function, a direction connection to Cloud SQL to take advantage of GCP's great network instead of going through the wider public Internet, and the availability of environment variables to customize your deployments for example to tackle different environments like dev vs staging vs prod.

App Engine

As I said, I've always been a big fan of App Engine, long before I actually joined Google. This blog you're reading has been running on App Engine Java for many years! GAE (for short) is really a great fit for hosting web frontends or backend APIs, which are generally more long-lived that functions.

With Java 8 in GA last year, Node.js 8 in beta, new runtimes are also coming up: Python 3.7 and PHP 7.2. With the recently released new instance scheduler, you have more control on your scaling which allows you to scale faster and have lower costs too. Deployments of new versions should also be faster with better caching and diff'ing between versions.

During the hallway session, I had a nice conversation with an attendee who was pretty happy with the fact he'd be able to have Python 3.7 for both Cloud Functions and App Engine, which will allow them to have a chance to share some code between projects.

The new runtimes are running on the gVisor sandbox container runtime technology, a lightweight solution to isolate containers securely to run your payloads. A big advantage of gVisor is that App Engine runtimes are not limited anymore with things like the class whitelist which prevented usage of some particular classes.


Back to the topic of microservices, App Engine has this concept of services. In your GCP project, your GAE application can run several services at the same time, potentially with different runtimes (for example a Java service and a Go service), and those services can be deployed with different versions.


Last thing I'll mention here for App Engine, that's the traffic splitting capability. You can easily split traffic (on the command-line or in the web UI) between different versions of a particular service. So for example if you want to do some A/B testing to see if users prefer the new feature or layout of your app, you can say that only 5% of incoming requests will be showing it, whereas the 95% of your users will continue to see the old version. This is also useful for canary deployments or blue / green deployments.


For my demo, I developed a simple picture sharing app. My web frontend is a Vue.js + App Engine Java backend using the SparkJava light framework. When a user takes a picture, it's uploaded to Google Cloud Storage, which triggers a Cloud Function which will store picture metadata in Datastore, and calls the Vision API to get the labels of things found in the picture, as well as check if the picture can be safely published (no racy, adult, spoof, violent content in it), and gives the dominant color in the image. Another function is triggered on at regular intervals to compute the most frequent tags (stored in Datastore), so a snapshot of them can be displayed in the dedicate page of the app.


Scaling down...

Getting to scale down towards our talk conclusion, we also shared a few words about the upcoming serverless containers for Cloud Functions, which we unveiled at the conference and on the GCP blog post. For serverless compute, you can deploy functions and apps, but we're seeing units of compute in the form of containers as well, and sometimes your project might need specific native libraries or particular compute abilities (like GPUs), or you simply want more control over your business logic's environments. So it makes sense to let you serve containers as well, in addition to functions and apps. If you're interested in trying out serverless containers, feel free to request access to the EAP program via g.co/serverlesscontainers.






In the top 20 Java influencers fo 2018!


Just before heading to Google Cloud Next, I was notified I was listed 4th in JAX London's Top 20 Java influencers of 2018 on social media! It's an honor to be listed among famous figures like Josh Bloch, Brian Goetze, Martin Thompson, Arun Gupta, Jessica Kerr, Mario Fusco, Josh Long, Venkat Subramanian, Charles Nutter and many others. You can see the full list of the top influencers here.

I'll definitely continue to advocate for Java (and Apache Groovy) developers around the world, and share whatever I learn along the way through articles or conference talks. I'm looking forward to meeting you, my fellow Java/Groovy developer friends, at an event near you.


The big green button — automating continuous delivery with chatbots

Last month in sunny Napa valley, my awesome colleague Seth Vargo and I had the chance to speak at SwampUp, the devops focused conference organized by JFrog. Our talk & demo were focused on the topic of "ChatOps". But what is ChatOps? Here's what our abstract said:

Heard of ChatOps? It's a movement in the DevOps community to take advantage of Chatbots. 

Chatbots centralize the conversation and history of your daily operations including build status, issue management, deployment, and monitoring, so that you access all the information and actions needed at the whim of a chat message in your team communication solution.

After a quick introduction about the principles and pros&cons of ChatOps, Guillaume Laforge & Seth Vargo will walk you through Dialogflow to design your conversational interface to your CI/CD infrastructure. With the help of demos on the Google Cloud Platform, we’ll see together how chatbots can make you more productive in your DevOps activities.


The video has been published last week:


And you can have a closer look at our slide deck below, but be sure to watch the video if you want to see the demos.

Chatbots, switching to the second gear at DevFest Lille

My buddy Wassim and I were back on stage together to talk about chatbots, with Actions on Google and Dialogflow, at DevFest Lille. I'd like to share with you the slides of the presentation (the video has been recorded and will be available at a later time.)

 

Automating Chrome headless mode on App Engine with Node.JS 8

On the Google Cloud front today, the big news is the release of the new Node.JS 8 runtime for Google App Engine Standard. It’s been a while since a completely new runtime was added to the list of supported platforms (Python, Java, PHP, Go). You could already run anything in custom containers on App Engine Flex, including your own containerized Node app, but now you can have all the nice developer experience on the Standard environment, with fast deployment times, and 0 to 1 to n instance automatic scaling (you can see the difference between those two environments here).


To play with this new runtime, I decided to follow the steps in this guide about using Chrome headless with Puppeteer.


As my readers know, I’m not really a Node person, and usually dabble more with Apache Groovy and Java, but this runtime was interesting to me as there’s a nice integration with native packages. Let me explain.


The App Engine Node runtime includes tons of native package out of the box, without requiring you to install anything (except the Node modules that take advantage of those packages, of course.) For instance, if you need to do any audio / video manipulation, there’s an ffmpeg package. If you want to deal with Git repositories, there’s a git package. Need to manipulate images, there’s ImageMagick, etc. And there are usually nice Node wrapper modules around those native components.


Among those system pre-installed packages, there’s all the necessary ones to run Headless Chrome, ie. running the Chrome browser but without displaying its window basically.


Furthermore, there’s the Puppeteer Node module, which is a library to control Chrome. With those two, you can completely automate the usage of Chrome on the server-side.


What can you do with that? Well, you can:

  • look at / introspect / manipulate the DOM,

  • pre-render content for your single page apps,

  • take screenshots of web pages,

  • watch a particular page and compute diffs between different versions, etc.


Let’s get started!


Without blindly recopying all the steps explained in the tutorial for running Chrome headless, I’ll simply highlight some of key points. The goal is to let puppeteer take screenshots of webpages.


In your package.json, you need the reference the puppeteer module, and potentially express for handling your web requests:


  "dependencies": {
"express": "^4.16.3",
"puppeteer": "^1.2.0"
},

Taking advantage of Node 8’s async capabilities, in your app.js file, you can instantiate puppeteer:


const browser = await puppeteer.launch({
args: ['--no-sandbox', '--disable-setuid-sandbox']
});

Then navigate to the desired page:

  const page = await browser.newPage();
await page.goto(url);

Take a screenshot and render it back to the browser:

  const imageBuffer = await page.screenshot();
res.set('Content-Type', 'image/png');
res.send(imageBuffer);

To deploy to the Node runtime, you also need the app.yaml deployment descriptor:


runtime: nodejs8
instance_class: F4_1G

We specify that we want to use the new node runtime, but also that we want a slightly bigger instance to run our Node app, as Chrome is pretty hungry with RAM!


Then deploy your app with the gcloud CLI.


Be sure to check the whole code on Github for all the details.


One quick remark: although it’s not mentioned in the tutorial, when you’ll first try to deploy the application, it’ll tell you that you need to enable the Container Builder API. The error message will be something like “Container Builder has not been used in project xyz before or it is disabled. Enable it by visiting…” You just need to follow the indicated URL to enable Container Builder. Container Builder is responsible for containerizing your application to be run on App Engine.


Then I was able to navigate to my app, pass it a URL, and get back the screenshot of the web page at that URL. It’s pretty handy if you want to integrate thumbnails of websites you reference in your blog posts, for example, or if you want to see if there are differences between different versions of a web page (for integration testing purposes).


Conclusion


The Java ecosystem has a wealth of libraries for various tasks, but often, there are native libraries which are more fully-featured, and Node generally provides nice wrappers for them. Chrome headless with Puppeteer is one example, but ImageMagick for image manipulation is another great one, where I could not find a good equivalent library in the Java ecosystem. So as they say, use the best tool for the job! In the age of microservices, feel free to use another tech stack that best fit the task at hand. And it’s really exciting to see this new Node 8 runtime for App Engine now being available so that you can take advantage of it in your projects.


 
© 2012 Guillaume Laforge | The views and opinions expressed here are mine and don't reflect the ones from my employer.