I have many versions of appengine instances that are active but not used because they are old. What are the costs they can generate? How do you behave with the old versions of appengine instances? Do you delete them or deactivate them?
On the documentation I don't find any reference to the costs of the old instances.
https://cloud.google.com/appengine/pricing?hl=it
UPDATE:
(GAE STANDARD)
Thank you
It's a poorly documented aspect of App Engine. What you describe as versions that are "not used" are more specifically versions that don't receive traffic. But depending on your scaling configuration (essentially defined in your app.yaml file), there may not be a 1:1 relationship between traffic and the number of active instances serving a version.
For example, I'm familiar with using "automatic_scaling" with min_instances = 1. This will prevent a service to scale to zero instance and have latency to serve an incoming request after some idle time, but it also means that any version until deleted will generate a baseline cost of 1 instance running 24/7.
Also, I've found that the estimated number of instances displayed in the dashboard you screenshotted can be misleading (more specifically, it can show 0 instance while there is actually one running).
Note that if you do not have scaling related configuration in your app.yaml file, you should check what are the default values currently considered by App Engine.
It's tricky when you get started and I'm sure I'm not the only one who lost most of the free trial budget because of this.
There is actually a limit of versions you can have depending on your app's pricing:
Limit
Free app
Paid app
Max versions
15
210
It seems that you can have them active in case you want to switch between versions migrating or splitting the traffic between them, but they won't charge you for them if you don't reach more than 15 versions.
Related
This is a wrap-up of several open questions in the vaadin forum (which is moving to stack-overflow) - see 2, 3, 4, ...
The basic question is: "How can one run a (recent V14 LTS or V19/20) vaadin-flow application reliably on google app engine (GAE manual or automatic scaling) standard environment (i.e. no docker, no google compute engine), without experiencing constant refreshing of components"
Vaadin has a tutorial for deploying vaadin applications to GAE flexible (not standard as for this question). This tutorial doesn't mention that one might run into trouble when GAE switches the server-instance. Even GAE mentiones Vaadin as one of the supported frameworks.
Old Vaadin 8 release notes state, that support for GAE has been dropped.
According to the questions in the vaadin forum, vaadin-flow at GAE will lead (or at least has led in older versions of vaadin) to constant refreshing of components and/or loss of session-state.
If one uses manual scaling, ones applications can rely on the state of the memory over time, so vaadin-flow applications should not be bothered with switches of the server-instance (which will eventually occur when an instance is shut down due to an error or maintenence reasons).
So the first question is: "When running a vaadin-flow application on GAE standard with manual scaling, will it lead to constant refreshing of componends and/or loss of session-state even when the instance is not switched?"
If that works, than vaadin-flow is fine on GAE standard when one needs neither dynamic scaling nor high availability. It that does not work, vaadin-flow on GAE standard would be a NOGO for any type of application (and one needs to switch to another provider or to GAE flexible and docker).
The next question is: "What has to be done to make vaadin-flow application on GAE standard run reliably, even when instances are scaled or switched due to maintenance?"
The following suggestions were stated in the forum - but noone ever confirmed that they work:
One could have set <sessions-enabled>true</sessions-enabled> for java 8. This setting no longer exists for java 11. Even when when nr. of instances is changing or instances are restarted, this could have been the solution since session data is stored in memcache which is available over all instances.
When instances are moved or shut down, google sends a shutdown notification -> one could implement a shutdown-hook and try to serialize all session-state (if vaadin provides a way to serialize it manually and automatically de-serialize it when another instance takes over).
Has anyone found a reliable solution for this?
I think it's not possible.
According to https://stackoverflow.com/a/10640357/377320 GAE uses Datastore to store the session informations and only synchronizes objects set via session.setAttribute(). However, according to https://mvysny.github.io/vaadin-14-session-replication/ Vaadin doesn't call setAttribute(), moreover Vaadin does that on purpose.
That means that GAE won't synchronize the state properly but the requests will land on random nodes (since session affinity/sticky sessions is not supported on GAE), causing the requests to land on nodes with obsolete Vaadin state. That leads me to believe that the most likely outcome is that Vaadin components will constantly lose state, and Vaadin will try to frequently attempt to resync the UI state by performing browser reloads.
Vaadin Flow works best with sticky sessions and long-running servers while GAE sounds like an opposite of that.
I believe your best bet is to use Vaadin Fusion with a stateless server.
Regarding serializing all session state (eg. on a shutdown hook): this requires that all of your stateful objects, like all of your data beans, Vaadin Flow views, compositions etc., are serializable. In other words, all classes must implement java.io.Serializable. This can be done, as all classes from Vaadin should be serializable, but it's up to the application developer to make sure that all custom instantiable classes in the codebase (and any instantiable classes in the dependencies) can be serialized and deserialized. Based on practical experience, this is not a trivial requirement - it usually drives the application's architecture by limiting or changing the design patterns used in the code. Making an existing codebase fully serializable will likely incur significant refactoring work. This is one of the big reasons why sticky sessions (which are not available in GAE) are the recommended approach for deploying Vaadin Flow applications in multi-node environments.
My application is running since months now and I must say, that it worked just fine. BUT we never needed more than one instance (basic_scaling: max_instances: 1), so no sticky-sessions were needed and my conclusions might not be valid if one needs more than one instance:
both F- and B- instance-class worked fine - not a single switch has occurred in the past, no sessions were lost
if the instance needs to be re-started due to idle-timeout, this is just a matter of ~10 seconds which is ok for the test-instance. For production I would recommend manual scaling with 24 instance-hours per day (so the instance will never be re-started)
Session-affinity can be set in app.yaml according to https://cloud.google.com/appengine/docs/flexible/java/using-websockets-and-session-affinity. So it might as well work with multiple instances
I have a GAE application that's set up as a flexible instance, which is expected to be restarted on a weekly basis (and a continually unhealthy instance can be restarted): https://cloud.google.com/appengine/docs/flexible/java/how-instances-are-managed
However, we're seeing this restart ("npm run build" command) several times per week! For example in the past three weeks we've had 9 restarts, and I've confirmed that the log entries leading up are successful 200 responses (no sign of trouble)- all for the active version serving traffic (and not for the other versions that are stopped).
Has anyone seen this symptom before or know of something else that can cause frequent restarts?
Let me know if any other info would be helpful.
An instance restart in the Google App Engine flexible environment can occur for several reasons:
According to the GAE documentation, there is no guarantee that an instance runs indefinitely, it can be restarted due to hardware maintenance, software updates or unforeseen issues. Besides that, as you stated, all instances are restarted on a weekly basis.
An instance can also be restarted if it fails to respond to a specified number of consecutive health check requests.
In case that you observe a unusual number of restarts I recommend you to open a ticket in Google Cloud Platform Support. They have internal tools that are able to check what is going on in the instance and figure out why the restarts are happening.
#DianeKaplan's comment:
Contacting GCP support has given me some a few helpful nuggets so far:
The automatic weekly restart of an instance due to maintenance can occur around different times (so it may only be 5 days since the last one, for example)
our deployments (which result in new GAE versions) make Google Builds
In some cases, a VM was being created overnight and then immediately deleted, where it didn't look like autoscaling was needed. Still looking into this, but was pointed towards the Google Cloud Console section Home > Activity as a good place to find clues
I'm very new to using Google cloud services. As I can see Google App Engine has two way of deployment. The first one is using App Engine sandbox and the second is managed VM.
So I'm interested in pricing. Is there any difference in price? For example if I choose managed VM instead sandbox.
Pricing for the Sandbox can be found on the App Engine Pricing page.
Pricing for the Managed VM's can be found on the Compute Engine Pricing page:
While in beta, pricing is based on Compute Engine Pricing for each VM. Pricing will change in the future.
Based on the linked Price pages:
The Minimum cost for a Sandboxed instance: $0.05 / hour (F1 class, 128MB RAM, 600MHz CPU)
The Minimum cost for a Managed VM: $0.063 (n1-standard-1, 3.75GB RAM, 2.75GCEU CPU)
For other classes of sandbox instances see this page: Adjusting Application Performance
Before jumping to the conclusion that Managed VMs are cheaper: each app gets 28 free instance-hours per day for Sandbox, so chances are good you won't even have to pay for any. Also with further configuration you can achieve to only pay for further "used" instance hours (e.g. you can play with min_idle_instances and max_idle_instances in your module config so additional instances only count toward instance hour billing when they are active (serving requests)).
Notes:
Price shouldn't be the only (or most important) reason to chose one over the other. They are for different things with quite different characteristics.
Sandbox instances are primarily for your application front-end: they can automatically scale as your traffic changes/grows. Many restrictions are enforced.
Managed VMs are good for background operations which can be long or CPU consuming, most of the restrictions are not applied.
In a nutshell: MVMs are for the same price about 10x more powerful.
Default GAE instances are F1: 600Mhz, 128MB, $0.05/h
Comparable MVM: 2500Mhz, 3.75GB, $0.05/h (typical use)
It's not about price, it's about environment. You would not have SQL or root FS on GAE, you can't open ports. Your code base would be hard to migrate to another VPS. As a trade-off you get zero cost maintenance and effortless instant scaling.
I'm doing a prototype backend and in the near future I expect little traffic but while testing I consumed all my 300$ free trail.
How can I configure my app to consume the least possible resources? I need things like limiting the number of instances to 1, using a cheap machine, sleep whenever possible, I've read something about Client vs Backend intances.
With time I'll learn the config that best suits me, but now I need the CHEAPEST config to get going.
BTW: I am using managed-vms with Dart.
EDIT
I've been recommended to configure my app.yaml file, what options would you recommend to confront this issue?
There are two train of thought for your issue.
1) Optimization of code: This is very difficult for us as we are not privy to your App's usage and client-base and architecture. In general, it depends on what Google App Engine product you use the most, for example: Datastore API call (fetch, write, delete... etc...), BigQuery and Cloud SQL. Even after optimization, you can still incur a lot of cost depending on traffic.
2) Enforcing cheap operation: This is easier and I think this is what you want. You can manually enforce a daily budget (in your billing setup page) so the App never cost more than a certain amount per day. You can also artificially lower the maximum amount of idling instances to 0 and use the smallest instance possible (F1 for frontend).
For pricing details see this article - https://cloud.google.com/appengine/pricing#Billable_Resource_Unit_Costs
If you use managed VM -- you'll be billed for Compute Engine Instance prices, not for App Engine Instances, and, as I know, the minimum possible instance to use as Managed VM is "g1-small" which costs you $0.023 per hour full sustained usage (if it will be turned on all month), so you minimum bill will be 0.023 * 24 * 30 = $16.56 only for instance hours. Excluding disk and traffic. With minimum amount of datastore operations you may stay on free quota.
Every application consumes resources differently. To minimize your cost, you need to know what resources used the majority of your expenses and go from there.
If it is spent on extra instances that were just sitting there - then trim the number of instances to the minimum required and use a lower class instance. If you are seeing a lot of expense on datastore calls - then look at optimizing your entities and take advantage of memcache.
Lowest Cost for a simple app:
Use App Engine Standard. It scales to zero instances, so will not cost anything if there is no traffic. With App Engine Flex you will pay for the instance hours and the Flex (GCE) instances are bigger.
Use autoscaling with max instances, F1 instance class:
With autoscaling you do not need to guess how many instances you need. F1 are the smallest instances. Set the max instances in case you get DoS'd or more traffic than you can afford.
Stop Instances:
You can stop the App Engine versions when you do not expect the app to be used. The will be no charge for instance hours for either Standard or Flex. For Flex there will be disk charges. The app will be ready to go when you need it again.
App Engine Version Cleanup:
Versions are easy to create and harder to remove. Here is a post on project cleanup. See this post on App Engine cleanup
https://medium.com/google-cloud/app-engine-project-cleanup-9647296e796a
When we switch the server code to a new version in google app engine console, lots of new instances need to be spawned. Because of that, we see some 500 errors and long response time.
What is the best practice to mitigate those problems?
500 responses have not always occurred to requests during a deployment. Previously the new version of your app was able to take over traffic from the old without interruption, however that seemed to stop quite some time ago. These 500s don't appear to go to your application at all (as in no requests will show in your logs, and they won't be served by your applications 500 page). The time window also seems to vary from between none, to up to a minute.
I'm not aware of any indication that the appengine team is looking at solving this, although it seems like a bug (or at the least a reasonable feature request).
To get around this issue, we generally deploy to a different version and switch that to be the default version. Once that is serving traffic, we deploy to the previous version, then switch it back to default. This allows customers to be served uninterrupted, but it does require (at least in java land) a new build.
In addition to the other persons answer re: warmup requests, you should also look at traffic splitting - "App Engine's Traffic Splitting tool allows you to roll out features for your app slowly over a period of time, similar to what Google does when rolling out a new feature over a few days or weeks. Traffic Splitting also allows you to do A/B Testing. Traffic Splitting works by splitting incoming requests to different versions of your app."
docs here https://developers.google.com/appengine/docs/adminconsole/trafficsplitting
Set up warmup requests to load your application before actual traffic is directed to the instance:
Python: https://developers.google.com/appengine/docs/python/config/appconfig#Warmup_Requests
Java: https://developers.google.com/appengine/docs/java/config/appconfig#Warmup_Requests
Go: https://developers.google.com/appengine/docs/go/config/appconfig#Inbound_Services
PHP: https://developers.google.com/appengine/docs/php/config/appconfig#Warmup_Requests