Separating service and front-end in AppEngine causes latency - java

I have a set of Java AppEngine apps structured as follows:
REST service
Web Frontend
These two components are hosted on 2 separate AppEngine instances (paid), this is a standard way to design you application, and makes sense for me since I access the REST service from other clients too (mobile apps, etc.) so I'd like to keep it separate.
The issue I have is that, even though if I access the REST service directly (GET from browser or mobile apps) responsiveness is always good, when accessing the REST service from my AppEngine front-end response time is sometimes very erratic.
I ran a bunch of tests and while doing GETs from the browser to the REST service always returns reasonably fast, calls from my AppEngine front-end to the REST service could go from returning as fast as from the browser to taking up to >10 seconds (causing time-outs etc.) with not so reasonable response-times in general (secs instead of 100s of msecs).
If there was latency in general, I can understand everything would on average take pretty much the same time to get a response, but what I don't understand is this difference between calling the service from anywhere else and calling it from an AppEngine instance.
I have to say this does not happen always, goes well for weeks and then there are some very bad days (today does't really count as it was a full blow outage), and, even though in general I am very happy about app-engine, makes me sometimes wonder if I made a mistake investing on this platform.
I am looking for an explanation: is this some kind of inherent AppEngine limitation when queuing this kind of pretty standard http-requests outgoing from an AppEngine instance?
Also I have been thinking about possible work-arounds - maybe I should host the service into the same instance as the front-end, but I really don't wanna do that and I am leaving it as last resort.
Any advice appreciated.

I can see 2 reasons
1.External Access to your REST Service , caching is optimized as the client(s) are various versions of browsers. Your FrontEnd application which is internally accessing REST Service might not implemented a very good caching mechanism.
2.Does AppEngine bill for Internal Traffic ? if Not, then that might be reason for giving extenal IPs priority than internal??

Related

GAE/GWT server side data inconsistent / not persisting between instances

I'm writing a game app on GAE with GWT/Java and am having a issues with server-side persistent data.
Players are polling using RPC for active games and game states, all being stores on the server. Sometimes client polling fails to find game instances that I know should exist. This only happens when I deploy to google appspot, locally everything is fine.
I understand this could be to do with how appspot is a clouded service and that it can spawn and use a new instance of my servlet at any point, and the existing data is not persisting between instances.
Single games only last a minute or two and data will change rapidly, (multiple times a second) so what is the best way to ensure that RPC calls to different instances will use the same server-side data?
I have had a look at the DataStore API and it seems to be database like storage which i'm guessing will be way too slow for what I need. Also Memcache can be flushed at any point so that's not useful.
What am I missing here?
You have two issues here: persisting data between requests and polling data from clients.
When you have a distributed servlet environment (such as GAE) you can not make request to one instance, save data to memory and expect that data is available on other instances. This is true for GAE and any other servlet environment where you have multiple servers.
So to you need to save data to some shared storage: Datastore is costly, persistent, reliable and slow. Memcache is fast, free, but non-reliable. Usually we use a combination of both. Some libraries even transparently combine both: NDB, objectify.
On GAE there is also a third option to have semi-persisted shared data: backends. Those are always-on instances, where you control startup/shutdown.
Data polling: if you have multiple clients waiting for updates, it's best not to use polling. Polling will make a lot of unnecessary requests (data did not change on server) and there will still be a minimum delay (since you poll at some interval). Instead of polling you use push via Channel API. There are even GWT libs for it: gwt-gae-channel, gwt-channel-api.
Short answer: You did not design your game to run on App Engine.
You sound like you've already answered your own question. You understand that data is not persisted across instances. The two mechanisms for persisting data on the server side are memcache and the datastore, but you also understand the limitations of these. You need to architect your game around this.
If you're not using memcache or the datastore, how are you persisting your data (my best guess is that you aren't actually persisting it). From the vague details, you have not architected your game to be able to run across multiple instances, which is essential for any app running on App Engine. It's a basic design principle that you don't know which instance any HTTP request will hit. You have to rearchitect to use the datastore + memcache.
If you want to use a single server, you can use backends, which behave like single servers that stick around (if you limit it to one instance). Frankly though, because of the cost, you're better off with Amazon or Rackspace if you go this route. You will also have to deal with scaling on your own - ie if a game is running on a particular server instance, you need to build a way such that playing the game consistently hits that instance.
Remember you can deploy GWT applications without GAE, see this explanation:
https://developers.google.com/web-toolkit/doc/latest/DevGuideServerCommunication#DevGuideRPCDeployment
You may want to ask yourself: Will your application ever NEED multiple server instances or GAE-specific features?
If so, then I agree with Peter Knego's reply regarding memcache etc.
If not, then you might be able to work around your problem by choosing a different hosting option (other than GAE). Particularly one that lets you work with just a single instance. You could then indeed simply manage all your game data in server memory, like I understand you have been doing so far.
If this solution suits your purpose, then all you need to do is find a suitable hosting provider. This may well be a cloud-based PaaS offer, provided that they let you put a hard limit (unlike with GAE) on the number of server instances, and that it goes as low as one. For example, Heroku (currently) lets you do that, as far as I understand, and apparently it's suitable for GWT applications, according to this thread:
https://stackoverflow.com/a/8583493/2237986
Note that the above solution involves a bit of fiddling and I don't know your needs well enough to make a strong recommendation. There may be easier and better solutions for what you're trying to do. In particular, have a look at non-cloud-based hosting options and server architectures that are optimized for highly time-critical, real-time multiplayer gaming.
Hope this helps! Keep us posted on your progress.

when web services should be used?

I have a web based enterprise application. One problem we are facing is that the backend is tightly coupled with our front end. Now we want to come up with mobile apps plus a desktop client for our software. For this we decided to move our backend to web services so that multiple front end clients can use the same function calls. But still wondering if this is a right move? or any other approach could help? Any pitfalls of using webservices? One thing that concerns me most is the speed. Are webservices inherently slower?
Appreciate your help.
Most web services (SOAP, REST) are used to create platform-independent services. What I'm trying to say is that the Web Service can be accessed by applications written in java, .NET platform, etc. without worrying about interoperability between the language use and technology.
Also, most have multiple applications that needs to access the same data, so writing a data abstraction layer for each application is not OO.
In your case, Web Services will be necessary as you will have plenty presentation layers (Desktop, Mobile and Web application) that will access your system through a network protocol. In this case, I would suggest a web service as you can easily write the business logic/rules inside the service and the client will just do a request/response process to get/post data).
It depends on the type of information your passing back and forth but in the broader scheme of things a SOA is the way to go if you looking to have one 'back end' system. I'm sure you'll be happy with the performance and even in some cases surprised. It most cases the database calls are still the bottle necks. I've lead the charge of implementing a SOA on a lot of projects. In a lot of cases the applications have preformed even faster with web services, not because the calls are that much faster but because it will lead you to better design and to take advantage of other technologies like local and remote caching.
I would say there are generally two pitfalls of using web services as the back end.
1.) How they are implemented. Read some books and do some testing before you start writing the real thing. Develop standards and try to stick to them.
2.) Single point of access is a good thing, but not in a unstable or quickly changing environment. Have some redundancy and a backup plan as well as a sandbox and staging area.
Depends on what you do understand with 'webservices'. SOAP, REST, all technologies like this?
SOAP services have the big advantage, that they have a well defined contract through the WSDL as well as the clients can easily generate stubs. On the other hand, SOAP services can also bring a lot more work (e.g. if using them on a client which has no soap client (e.g. iOS, plain html app)). Additionally the webservice stuff brings a lot of overhead, which could play a role if you intend to deliver large data e.g. to mobile devices.
There you must take into consideration that the clients could have limited bandwith (speed and data volume). Furthermore it must process the hole XML document, whereas a json could be more easier for example.
It does not degrade perfomance(speed).Because websevice is soap over http.I think ,In your case The backhand should be exposed as webservice,It would be feasible to invoke the service by multiple client.And more over you can introduce the extra security also if you need....

Advice around Web Service consuming another Web Service

I'm designing an application and trying to do some research on how it should work and any tips etc that I could use.
I need to develop a middleware Web service running on Tomcat 6.
Client program consumes my webservice.
My Webservice in turns needs to run a number of searches, 10, based on information from the client. These searches are using an 3rd Party web service. 3rd Party supply Java Stub Classes.
Can/Should I write my web service to be multi-threaded so each thread is created and used for a search and results collated and returned to client?
Searches can take a while to complete approx 200-500ms
All advice is gratefully received,
I'm a bit uncertain as to what your needs are exactly. Are the searches able to be run in parallel? If that is the case it may not be a bad idea to use multi-threading for executing them.
We have something similar in an application I'm working on - a long-running search is run in a separate thread, so that other processing can continue, and then when it is finished the results are sent back to the client.
There is no problem with this, we run on Tomcat 6 and it works fine. Obviously the usual caveats with multi-threading apply, we're using the Java 6 java.util.concurrent library which is really useful.
There do seem to be potential benefits here in having several back-end queries running in parallel, so some kind of multi-threading seems like a good idea.
There are a few issues that occur to me:
The direct spawning of threads in a Java EE container is not generally recomended - Java EE containers like to be in control of that - so there are specifically supported APIs for doing that in the Java EE world (see this answer for more on this topic.) I don't know whether Tomcat supports such APIs these days, if not then perhaps something like this may work.
You need a good strategy to deal will broken and slow responses. Suppose you have 7 out of 8 responses and the 8th seems to take a very long time is it better to give a rapid partial responses. Best to think about this up front.
Which leads to is it better to have some kind of "noticebaord" approach, send a request, come back later to collect interim results, come back yet later to collect more complete results.
Some back end systems might react badly to excessive requests from the same source. You may need to throttle request freuqencies both to be "sociable" and also to avoid any black-listing policies.

Opinions/headers for splitting an application into front-end/back-end (not user/admin, but ui/logic)

I am building a new web application and playing around with the architecture and would like some opinions about splitting UI and business logic and running them on separate servers.
This means that if someone requests a page, the front end will itself request the data from a back-end server and then not actually perform any calculations/logic but just use the data to populate a template and then respond with that.
Back-End: Java + JAX-WS
Front-End: Kohana 3.1 (PHP)
Data Interchange Format: JSON
Advantages:
clear separation of logic and UI
ability to choose language/framework best suited for either end
possibility to add logic/UI servers depending on which one is the bottleneck in case of performance issues
possibility to make the API publicly available without any extra work (pseudo-internal requests will go to the same API as requests from third-part applications)
ability to change (if need be) the framework/language of either side without having to edit the other
ability to specify different server hardware according to the needs of the logic/UI application
better security (if API private) (??)
Disadvantages:
latency (??)
more servers
So what do you think? Is this a good idea? I haven't been able to find much information so far but my guess is that many big sites do it this way, right? How will performance be affected (I am thinking of running it on EC2)? What are further advantages/disadvantages? Any thoughts on the languages/frameworks choices?
A similar architectural pattern is often employed, though generally the UI part is often moved to the client. So you have a backend that responds with JSON, a quick http server with full-blown caching (and that can use html5 app caching as well) and a rich javascript client which requests the JSON from the backend and builds the UI.
More on this pattern: http://www.metaskills.net/2008/05/24/the-ajax-head-design-pattern/
The main negative of the approach is that is generally more work in the beginning - if you don't need an external API then using a simpler architecture will be easier to program.
You also might want to employ the idea of keeping your servers stateless and let the client side handle any state.
This simplifies the whole load-balancing and fail-over stuff and makes you think about a more resource-oriented architecture.
And if you are set on JSON already, you might want to explore the idea of NOT mapping POJOS to your data and use a document store like MongoDB or CouchDB to access JSON data directly.

Expose webservice directly to webclients or keep a thin server-side script layer in between?

I'm developing a REST webservice (Java, Jersey). The people I'm doing this for want to directly access the webservice via Javascript. Some instinct tells me this is not a good idea, but I cannot really explain that instinct. My natural approach would have been to have the webservice do the real logic and database access, but also have some (relatively thin) server-side script layer (e.g. in PHP). Clients would talk to the PHP layer which in turn would talk to the webservice. (The webservice would be pretty local to the apache/PHP server and implicitly trust calls from the script layer. The script layer would take care of session management.)
(Btw, I am not talking about just hiding the webservice behind an Apache which simply redirects calls.)
But as I find myself at a lack of words/arguments to explain my instinct, I wonder whether my instinct is right - note that while I have been developing all kinds of software in all kinds of languages and frameworks for like 17 years, this is the first time I develop a webservice.
So my question is basically: what are your opinions? Are there any standard setups? Is my instinct totally wrong? Or partially? ;P
Many thanks,
Max
PS: I might add a few bits of information about the planned usage of the whole application:
will be accessed by different kinds of users, partly general public, partly privileged
thus, all major OS/browser combinations can be expected as clients
however, writing the client is not my responsibility
will potentially have very high load/traffic
logic of webservice will later be massively expanded for another product which is basically a superset of the functionality of the current project
there is a significant likelihood that at some point an API should be exposed which can be used by 3rd party developers - obviously, with some restrictions
at some point, the public view of the product should become accessible via smartphones, too (in other words, maybe a customized version of the site to adapt to the smaller display and different input methods)
I don't think that accessing a REST webservice directly via e.g. JavaScript is
generally a bad idea, because that what the REST architecture is designed
for. For your usecase you might have some implications to consider:
Your webservice will have to take care of user management. Since the REST architecture does not support a server side session state you will have to do authentication and authorization on every request. Users will have to maintain their state on the client side.
Your webservice implementation will have to take care of issues like caching and load balancing and all the other things you might have assigned to e.g. the PHP "proxy" script
For your requirements:
all major OS/browser combinations can
be expected as clients
Since you webservice will only deliver data (e.g. JSON or XML) this should not be a problem. The JavaScript part just has to take care to issue the correct requests.
will potentially have very high
load/traffic
If you strictly follow the REST architecture you can make use of http caches. But keep in mind that the stateless nature will always cause more traffic.
logic of webservice will later be
massively expanded for another product
which is basically a superset of the
functionality of the current project
The good thing about open webservices is that you can loosely couple them together.
there is a significant likelihood that
at some point an API should be exposed
which can be used by 3rd party
developers - obviously, with some
restrictions
Again, with RESTful webservice you already have an API exposed for developers. It is on your clients to decide if this is a good or a bad thing.
at some point, the public view of the
product should become accessible via
smartphones
Another pro for making your REST webservice publicly accessible. Most smartphone APIs support HTTP requests, so you will just have to develop the GUI for the specific smarphone platform that makes direct calls to the webservice.
Firstly I am just extending on what Daff replied above. I am extending Daff's answer from the point of my learning or designing and implementing RESTful WebServices and please note that I am still learning.
When I started learning RESTful WS with Java, Jersey (0.3 IIRC), I had similar questions and the primary cause for that is "Total" mis-conception about RESTful Architecture. The most "Grave" mistake I performed was using JAXB for XML and Jackson for JSON (de)serialization directly from/to the persistence beans. This totally violates the REST principal and hence creating some vital issues in creating a high performance, highly available, scalable web service.
My mistake was, thinking in terms of API a.k.a Service, when we think RESTful WS we should forget "API" and think Resources. We should take great care in interlinking resources. My understanding of this only came after reading this, I suggest it to anyone wanting to create their own web service. My conclusion is what is Resource is to RESTful WS/Architecture what API to a native interface or SOAP Web Service. So I would suggest design your resources with care and understand that there is no limit in how resources your WebService may have.
So here comes how I concluded in implementing systems exposing an "API" through RESTful WS. I create an API which deals communicating with business entities, for example, PersistentBook, which contains either Id of PersistentAuthor or the object itself. All business logic considering persistent entities lie in the API implementation layer.
The web service layer uses the API layer to perform its operations on resources. Web service layer uses persistent entities to generate representations of beans and vice versa, the key feature here would be PersistentBook's representation would have a URI to the PersistentAuthor. If I want to use automated (de)serialization I create another domain layer, e.g. Book, Author etc.
Now as Daff mentioned caching would be inevitable, my checkpoints for them are -
Support for 'Cache-Control', 'Last-Modified', 'ETag' response headers and 'If-Modified-Since', 'If-Match-None' request headers are key. Note from my more recent learnings - use 'Vary' header in case of varying representations (content negotiation) based on 'Accept' header.
Using a server side caching such as Squid, Varnish in case clients do not use caching. One thing I learnt having all the right header support counts for nothing if clients do support them and in fact increases the cost in terms of computation and badnwidth ;)
Use of Content-Encoding.

Categories

Resources