Eine Client-Server-Architektur stellt besondere Anforderungen an die Client-Server-Kommunikation. Einerseits wird Sparsamkeit angestrebt, andererseits absolute Flexibilität, Wiederverwendbarkeit und Wartbarkeit. Gerade im GWT-Umfeld fehlen clientseitig eine vollwertige JVM und das Reflection-API. Hinzu kommt noch der teilweise ungewohnte Umgang mit den asynchronen Aufrufen. In diesem Vortrag wird das Command Pattern vorgestellt. Es werden konkrete Lösungsansätze für Batching, Caching, Security und Journaling vorgestellt.
5. !
eb t
w en
sic pm
las elo
c v
de
Server
Browser
user action
e
ons
html resp
full
user action
po
l html res
ful
nse
user action
po
l html res
ful
nse
6.
eb ent
w
IA pm
R lo
ve
de
Server
Browser
first reques
t
e
l respons
full htm
event
event
event
data reque
st
data
event
data reque
data
st
7. Honor the A in
JAX
does
‣ Javascript it
not block !
Get over
‣ Latency is not a myth
‣ Results must not arrive in the call
order
13. GWT-RPC
is a good
solution if
handled
with care
GWT-RPC
binds many
methods
into one
interface
SomeResult someMethodName(SomeParameter spo)
Interface
Versioning
is a
monstrous
thing
14. this will be an object
SomeResult someMethodName(SomeParameter spo)
this will be an object too
15. the method names bind the requests to the result
SomeResult someMethodName(SomeParameter spo)
typesafety all the way
24. aka DTOs
type safety
Reusable
public class TerminLoadAction
implements Action<DataResult<TerminData>> {
!
!
!
}
public class DataResult<DATA extends Data>
implements Result {
!
private String terminId;
public TerminLoadAction(String terminId) {
this.terminId = terminId;
}
!
!
public String getTerminId() {
return terminId;
}
!
!
private DATA data;
public DataResult(DATA data) {
this.data = data;
}
public void setData(DATA data) {
this.data = data;
}
public DATA getData() {
return data;
}
}
Action
Result
25. <A extends Action<R>, R extends Result>
void execute(A action, AsyncCallback<R> callback)
dispatch.execute(
!
new TerminLoadAction(terminId),
new AsyncCallback<DataResult<TerminData>>() {
!
@Override
public void onFailure(Throwable caught) {
}
!
!
!
);
@Override
public void onSuccess(DataResult<TerminData> result) {
}
}
26. Server side
type safety
handler to
action
mapping
public interface ActionHandler
<A extends Action<R>, R extends Result> {
!
!
!
!
!
action
execution
Class<A> getActionType();
R execute(
A action,
ExecutionContext context)
throws DispatchException;
!
}
declared
exception
hiearchy
Execution context for
server side command
execution
27. Server side
custom
annotation
spring
@ActionHandlerBean
@Transactional
public final class TerminDataLoadHandler
implements ActionHandler<TerminLoadAction, DataResult<TerminData>> {
!
access to
backend
type safe
result
!
!
!
!
!
!
!
}
@Autowired
private TerminDAO terminDao;
@Override
public DataResult<TerminData> execute(
TerminLoadAction action,
ExecutionContext context) throws DispatchException {
TerminBean termin = …
TerminData data = …
return new DataResult<TerminData>(data);
}
@Override
public Class<TerminLoadAction> getActionType() {
return TerminLoadAction.class;
}
business
logic,
etc…
36. • one batch call is better than
10 single calls
• less data
• less roundtrip latency
• avoid connection
bottleneck
• ensure server side execution
order
• less roundtrips
solving common
problems
45. Caching
• Introduce cacheable interface
• simple marker interface,
• or more elaborate version with cache id,
expiration time, etc…
• Implement caching (client or server side)
48. Ensure „only last“ result
action 1
action 2
„smart
dispatch“
action 1
handler
last action is:
action
result 2
result 1
result 1
check result
deliver if last!
result
49. Re-Auth
• If server exception is security exception, try to
reauth and than re-execute commands
51. GWT scaling is easy...
• Every client brings his own CPU power
• The client does the page rendering
• GWT provides different ways to reduce number
of requests even more
• The server must „only“ authenticate the user
and provide the data, perform the actions
requested by the client
53. LETS TALK HIGH TRAFFIC...
HIGH TRAFFIC IS WHEN ONE SERVER IS NOT ENOUGH
54. HIGH TRAFFIC
PROBLEMS
• Bandwith issues
• Connection pool bottlenecks
• Thread pool bottlenecks
• CPU bottlenecks caused by reflection API calls
• High JVM garbage collection CPU usage
59. IMPLEMENT REAL LOAD BALANCING
EACH REQUEST GOES TO THE NEXT AVAILABLE SERVER
60. SCALING HOW-TO
• Don‘t stick a session to a server.
Why send a user over and over again to a
possible overloaded server?
• Don‘t store anything on the HTTP session. Share
session content outside web container
• Session replication is expensive and does not
scale well
• Let the load balancer distribute calls to available
servers
62. Session state could contain user
id, client id, session id, user roles
Session Cache
If session cache becomes
bottleneck, use distributed cache
Session Cache
Session Cache