I have an application which uses app engine auto scaling. It usually runs 0 instances, except if some authorised users use it.
This application need to run automated voice calls as fast as possible on thousands of people with keypad interactions (no, it's not spam, it's redcall!).
Programmatically speaking, we ask Twilio to initialise calls through its Voice API 5 times/sec and it basically works through webhooks, at least 2, but most of the time 4 hits per call. So GAE need to scale up very quickly and some requests get lost (which is just a hang up on the user side) at the beginning of the trigger, when only one instance is ready.
I would like to know if it is possible to programmatically scale up App Engine (through an API?) before running such triggers in order to be ready when the storm will blast?
I think you may want to give warmup requests a try. As they load your app's code into a new instance before any live requests reach that instance. Thus reducing the time it takes to answer while you GAE instance has scaled down to zero.
The link I have shared with you, includes the PHP7 runtime as I see you are familiar with it.
I would also like to agree with John Hanley, since finding a sweet spot on how many idle instances you have available, would also help the performance of your app.
Finally, the solution was to delegate sending the communication through Cloud Tasks:
https://cloud.google.com/tasks/docs/creating-appengine-tasks
https://github.com/redcall-io/app/blob/master/symfony/src/Communication/Processor/QueueProcessor.php
Tasks can try again hitting the app engine in case of errors, and make the app engine pop new instances when the surge comes.
Related
I'm working on a simple chat application that uses this frameworks, libraries: react, socket.io, express.
When a user opens the web app for the first time, he sees a login form, and after login, the server retrieves the list of all users and sends it to the client. When someone writes a new message, the server sends the message to all the clients.
As you can see, every part of the app depends on the server.
Does it make sense to use a service worker? Can it be at all?
As far as I know, a service worker is good at storing images, css, js files, and it help the users to use the app while they don't have internet connection.
But I do not know when everything depends on the server what can be done.
You have a great question.
You can most certainly use a Service Worker but most likely not to the extent some other apps could use it. You have outlined the problem yourself: your website depends on the server so it's not possible to make it offline or so. Some other websites could be made offline or could be made mostly offline showing some content without network connection and giving the full experience when connectivity comes back, but that doesn't sound like to be the case for your website.
Based on the description you've given, there's still something you could easily use Service Worker for, however. You've understand correctly that SW is very good at storing (caching) static assets and serving them from the device's cache without any network connectivity. You could use this feature and make your site faster. You could use a SW to proactively cache all the static assets of your site and have the SW return them from the local cache without requesting anything from the network. This would make your site a bit or much faster, depending on the user's connectivity (if the user has a slow 3G connection, then the SW would make the site super fast; if the user has a steady fiber or whatnot, then the difference wouldn't be that huge).
You could also make your site available offline without any internet connectivity. In that situation you would of course show the user a message saying "Hey, it seems like you're offline! Shoot! You need connectivity to use the app. We'll continue as soon as we get the bits flowing!" since this would probably make the user experience nicer.
So, in conclusion: you can leverage SW to make the initial loading of the site faster but you most likely won't get as much out of a SW configuration as some other site would get.
If you have any other questions or would like to have some clarifications, just comment :)
Sure you can benefit from having a Service Worker, it is universal enough to have an application for all kinds of applications and I don't agree it is only good for static assets.
It all depends on the actual requirements for you application, obviously. But technically there is no limitation that would prevent you from caching your users response in the Service Worker.
Remember that "offline" is a condition that happens in multiple circumstances - not only being far from the network coverage, but also outages, interferences, lie-fi or going through a tunnel. So it can as well happen intermittently during your app operation and it might make sense to prepare for it.
You can for example store your messages for offline in IndexedDB and for messages sent during that time, register a Background Sync event to send it to the server when the connectivity is back. This way users might still be able to use the app in the limited fashion (read the previously exchanged messages and post their own messages to be sent out later).
I'm attempting to create a microservice on Google App Engine that is not intended to handle HTTP requests.
Instead, I was hoping to have a continuously running Python script that monitors a remote queue--RabbitMQ, to be precise--and sends out an api-call to another service as tasks are pushed to the queue.
I was wondering, firstly, is it possible to run a script upon deployment--one that did not originate with a user action/request?
Secondly, how would I accomplish this?
Thanks in advance for your time!
You can deploy your "script" as a manually scaled module -- see https://cloud.google.com/appengine/docs/python/modules/ -- with exactly one instance. As the docs say, "When you start a manual scaling instance, App Engine immediately sends a /_ah/start request to each instance"; so, just set that module's handler for /_ah/start to the handler you want to run (in the module's yaml file and the WSGI app in the Python code, using whatever lightweight framework you like -- webapp2, falcon, flask, bottle, or whatever else... the framework won't be doing much for you in this case save the one-off routing).
Note that the number of free machine hours for manual scaling modules is limited to 8 hours per day (for the smaller, B1 instance class; proportionally fewer for larger instance classes), so you may need to upgrade to paid-app status if you need to run for more than 8 hours.
Like #brant said, App Engine is designed to handle HTTP requests. It's not a perfect fit for background jobs, unless you try to wrap your logic into one http request.
Further, App Engine will emit an error when the response timeout, depending on your scaling settings. If you want to try it, consider basic or manual scaling.
For this type of workload, I would suggest you use a VM.
I think there are a few problems with this design.
First, App Engine is designed to be an HTTP request processor, not a RabbitMQ message processor. GAE is intended for many small requests, not one long-running process.
Second, "RabbitMQ should not be exposed to the public internet, it wasn't created for such use case."
I would recommend that you keep the RabbitMQ clients on the same internal network as the RabbitMQ broker, and have the clients send HTTP requests to App Engine.
I planning to create a NodeJS program, that work 24/7, that ping and make requests to an external server (outside of google cloud) every minute. Just to see that it the external services are are live.
If there is any error it will notify me by SMS & Email.
I don't need any front-end for this app, and no one needs to connect to it. Just simple NodeJS program.
The monitoring and configuration will be by texts files.
Now the questions:
It looks like it will cost me just $1.64. It sounds very cheap. Am I missing something?
It needs to work around the clock, I will request it to start it once, and it need to continue working, (by using setInterval). Is it will be aborted?
What it is exactly mean buy 1 instance. What an instance can do? Only respond to one request or what?
I tried to search in Google: appengine timeout, but didn't found anything that helps.
Free Quota
If you write your application in Python, PHP, Go or Java it can fit in free usage quota:
https://cloud.google.com/appengine/docs/quotas
So there will be absolutely no costs to run it on Google App Engine platform.
There are limit of 657,000 UrlFetch API Calls per day (more than 450 calls per minute in 24/7 mode) for free apps. 4GB traffic may also be sufficient for this kind of work.
Keep in mind there is no SMS sending services provided by Google App Engine and you will need to spend additional UrlFetch API calls to use external SMS services.
Email sending is also limited to 100 Emails per day (or 5000 Emails to admin address), so try not so send repeated notifications about same monitored server every minute, or you'll deplete your Email quote in 1.5 hours.
Scheduled Tasks
There is no way to run single process indefinitely without interruption on App Engine. But you don't have to!
You'll need to encapsulate all the work you're planning to execute in every iteration into single task and then schedule it to run every minute with Cron. See this documentation for Python: https://cloud.google.com/appengine/docs/python/config/cron
It is recommended to have some configuration page where you can set some internal configuration or see monitoring statistics, at least manage flag to temporarily pause tasks execution without redeploying your app.
I've recently started having coldstarts on nearly every call to my appengine app. Initially I thought this was an issue with Cloud Endpoints, however now I believe it is an appengine issue, or something else in my code.
This started on my most recent deployment. I'm at a loss right now as to what is going on. It has made my app useless. I have tried 1.7.4 and 1.7.5 and both have this problem.
The requests work other than being extremely slow! Any help would be greatly appreciated, as I can not continue with 10-15 request times!
Update: By looking at my running instances I see NO instances running even after making a request. Previously instances would remain running after requests were made. It appears when a request is made an instance is spun up, serves the request, and then dies. There are no errors in my logs. No changes have been made to my app settings or billing. This app does have billing enabled.
Update 2: I have adjusted my idle instance settings(which up to this point have worked and have been left untouched). I set to a min of 1 and max of 2. The instances are staying alive and serving requests as normal. Previously it was set to automatic-1. Not sure what is going on here, perhaps Google adjusting the request scheduler or something. Not COOL!
I have found an open issue on code.google.com. Apparently this is a real appengine issue that is effecting some, if not all apps at the moment. I do not have a solution at this time other than setting the idle minimum instances to 1 (or greater). Even doing this, the new dynamic instances that are spun up die almost immediately after serving a request. Just waiting on a fix from google at this point.
http://code.google.com/p/googleappengine/issues/detail?id=8844
I know that when your Google App Engine (GAE) app has 0 instances running (because it has been idle for a bit), and a user requests a page, the user has to wait for the instance to boot up and do all of the instantiation which can cause the user to wait a significant amount of time.
My question is about the situation when your GAE app already has 1 instance running, but begins to experience heavy load and starts booting up a second instance.
In this case, which will happen:
Will a user end up having to wait for the second instance to instantiate before getting their request responded to?
Will no requests be sent to the second instance until it has fully instantiated, thus not making a user wait an extended amount of time?
EDIT: Its unfortunate that currently the answer to this is #1. However, there is a feature request to change the behavior to be #2. Please star this feature request( http://code.google.com/p/googleappengine/issues/detail?id=2690) to help get it to the attention of the App Engine developers
This blog post may give you some hints. Shortly speaking, the answer seems to be 1)