1 of 25

Developers

2 of 25

Autoscaling Java

Matt Stephenson

Software Engineer, App Engine Java

3 of 25

Autoscaling

4 of 25

Autoscaling

5 of 25

Autoscaling

6 of 25

Autoscaling

7 of 25

Autoscaling in the JVM

8 of 25

Autoscaling in App Engine

9 of 25

Demo

Autoscaling

10 of 25

Cloud Antipatterns

  • Large Deployments

  • Automatic instantiation of classes

  • Code Generation

  • Managing Shared State

  • Persisting Configuration

11 of 25

Large Deployments

<dependency>

<groupId>org.grails</groupId>

<artifactId>grails-spring</artifactId>

<version>2.2.0.RC4</version>

</dependency>

<dependency>

<groupId>com.mycompany</groupId>

<artifactId>my-framework</artifactId>

<version>0.0.1-SNAPSHOT</version>

</dependency>

pom.xml

<dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>3.2.2.RELEASE</version></dependency>

<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>3.6.7.Final</version></dependency>

12 of 25

Large Deployments

<dependency>

<groupId>com.google.inject</groupId>

<artifactId>guice</artifactId>

<version>3.0</version>

</dependency>

<dependency>

<groupId>com.sun.jersey</groupId>

<artifactId>jersey-core</artifactId>

<version>1.10-b02</version>

</dependency>

pom.xml

<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.2.1</version></dependency>

<dependency><!-- Protip : Use the afterburner module --> <groupId>com.fasterxml.jackson.module</groupId> <artifactId>jackson-module-afterburner</artifactId> <version>2.2.1</version></dependency>

13 of 25

Automatic Class Instantiation

package org.example;

@Service

public class SimpleMovieLister {

private final MovieFinder movieFinder;

@Autowired

public SimpleMovieLister(MovieFinder movieFinder) {

this.movieFinder = movieFinder;

}

}

Java

14 of 25

Automatic Class Instantiation

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:context="http://www.springframework.org/schema/context"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<context:component-scan base-package="org.example"/>

</beans>

XML

15 of 25

Automatic Class Instantiation

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

<bean id="SimpleMovieListener" class="org.example.SimpleMovieListener" />

</beans>

XML

16 of 25

Demo

Automatic class instantiation in a Large application

17 of 25

Code Generation

@Aspect

public class ExceptionLoggingInterceptor {

@Around("execution(public * *(..))")

public Object logExceptions(ProceedingJoinPoint pjp) throws Throwable {

try {

return retVal = pjp.proceed();

} catch (Throwable t) {

logger.debug(t);

throw t;

}

}

}

Java

18 of 25

Demo

Code Generation

19 of 25

Managing Shared State

public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) ... {

Map<String, String> parameters = request.getParameterMap();

if(parameters.containsKey("Foo")) {

Key barKey = KeyFactory.createKey("Bar", parameters.get("Foo"));

try {

Entity entity = datastoreService.get(barKey);

servletRequest.setAttribute("Baz", entity.getProperty("Baz"));

} catch (EntityNotFoundException e) { ... }

}

filterChain.doFilter(servletRequest, servletResponse);

}

Java

20 of 25

Persisting Configuration

private Optional<String> secret = Optional.absent();

@Override

public void init() throws ServletException {

while (!secret.isPresent()) {

try {

Entity entity = service.get(SHARED_SECRET_KEY);

secret = Optional.<String>fromNullable((String) entity.getProperty("TheSecret"))

} catch (EntityNotFoundException e) {

secret = generateSecret();

}

}

}

Java

21 of 25

Persisting Configuration

private Optional<String> generateSecret() {

Transaction transaction = service.beginTransaction();

try {

String secretKey = generateKey();

Entity entity = new Entity(SHARED_SECRET_KEY);

entity.setProperty("TheSecret", secretKey);

service.put(entity);

transaction.commit();

return Optional.of(secretKey);

} catch (ConcurrentModificationException e) {

return Optional.absent();

} finally { ... }

}

Java

22 of 25

Demo

Shared State and Configuration Data Contention

23 of 25

Tools

  • Apache Maven, Gradle, Ivy - Something to manage your dependencies

  • Proguard - Can be tricky to get setup for many older frameworks

  • Apache jMeter - Very useful for load testing

  • AppStats - Useful for profiling RPC calls

24 of 25

Go forth and scale

Matt Stephenson & Ludovic Champenois

Office Hours : Thursday 10:15-11:00am

@ The Cloud Sandbox

25 of 25

Developers