12 Factor App: Best Practices for JVM Deployment

69
12 Factor App Best Practices for JVM Deployment

Transcript of 12 Factor App: Best Practices for JVM Deployment

12 Factor AppBest Practices for JVM Deployment

12 Factor AppBest Practices for JVM Deployment

Java doesn’t suck when you do things this way

Java Servlet API 2.2 includes one new feature so significant it may change the way the Web works. That feature: Web applications.

- Javaworld.com, 1999

“”

With Web apps, the entire application can be contained in a single archive file and deployed by placing the file into a specific directory.

- Javaworld.com, 1999

“”

.war

Traditional JVM Deployment

.war

Modern JVM Deployment

JavaDoesn’t

Suck

12 Factor App

Joe Kutner@codefinger

JVM Langs Owner@Heroku

Joe Kutner

12 Factor Appa methodology

ScalabilityMaintainability

Portability

The 12 Factors• Codebase

• Dependencies

• Config

• Backing services

• Build, release, run

• Processes

• Port binding

• Concurrency

• Disposability

• Dev/prod parity

• Logs

• Admin processes

The 12 Factors• Codebase

• Dependencies

• Config

• Backing services

• Build, release, run

• Processes

• Port binding

• Concurrency

• Disposability

• Dev/prod parity

• Logs

• Admin processes

Graceful shutdown

Quick startup

Resilience to failure

| Disposability |

Application Servers…

| Disposability |

Application Servers are not disposable

| Disposability |

| Disposability |

Microservices are disposable

| Disposability |

Microservices

JavaGroovy

ScalaClojure

Scala Scala

Bootable ➤ Disposable

| Disposability |

The 12 Factors• Codebase

• Dependencies

• Config

• Backing services

• Build, release, run

• Processes

• Port binding

• Concurrency

• Disposability

• Dev/prod parity

• Logs

• Admin processes

dev

sqlite

postgres

stage

mysql

postgres

prod

postgres

postgres

=

=

=

=

| Disposable | Parity |

dev

files

files

stage

files

files

prod

war

files

=

=

=

=

| Disposable | Parity |

dev

jetty

jetty

stage

tomcat

jetty

prod

jboss

jetty

=

=

=

=

| Disposable | Parity |

| Disposable | Parity |

dev

jetty

{}

stage

tomcat

{}

prod

jboss

{}

=

=

=

=

.war

Traditional JVM Deployment

.jar

Modern JVM Deployment

Reproducible ➤ Parity

| Disposable | Parity |

Reproducible ➤ Disposable

| Disposable | Parity |

The 12 Factors• Codebase

• Dependencies

• Config

• Backing services

• Build, release, run

• Processes

• Port binding

• Concurrency

• Disposability

• Dev/prod parity

• Logs

• Admin processes

Configuration belongs in the environment,

not in the application

Configuration should be strictly separated

from code

| Disposable | Parity | Config |

Linux

Tomcat

WAR

server.xml

context.xml

web.xml

/etc/...

| Disposable | Parity | Config |

Environment

Java Application

PATH

DATABASE_URL

AWS_ACCESS_TOKEN

JAVA_OPTS

| Disposable | Parity | Config |

Containerless ➤ Separation

| Disposable | Parity | Config |

Containerless ➤ Parity

| Disposable | Parity | Config |

Containerless ➤ Disposable

| Disposable | Parity | Config |

Containerless ➤ 12 Factor App

| Disposable | Parity | Config |

Containerless Containerless Containerless

| Disposable | Parity | Config |

The container is deadLong live the container

DockerHeroku

Docker+Heroku

Application Server

Servlet Container

Docker

Host OS

Gue

st O

S

App

Gue

st O

S

App

Traditional Virtualization

Hypervisor

Host OS

App App App App

Docker Containers

Con

tain

er

Con

tain

er

Con

tain

er

Con

tain

er

Docker Engine

App App App App

Host OS

Dyn

o

Dyn

o

Dyn

o

Dyn

o

Heroku Dynos

Heroku

App App App App

Host OS

Dyn

o

Dyn

o

Dyn

o

Dyn

o

Heroku Dynos

HerokuSlug

Host OS

App App App App

Docker Containers

Con

tain

er

Con

tain

er

Con

tain

er

Con

tain

er

Docker EngineImage

Dockerize!

FROM heroku/cedar:14

...

RUN /opt/heroku/bin/setup.sh /opt/heroku

...

ENTRYPOINT /opt/heroku/bin/run.sh

Dockerfile

https://github.com/jkutner/heroku-java-docker

REPRODUCIB

LE

Base Image ➤

InstallJava

Run App ➤

web: java -cp target/app.jar com.foo.Main

Procfile

https://github.com/jkutner/heroku-java-docker

BOOTABLE

@Configuration@EnableAutoConfiguration@ComponentScanpublic class Main { public static void main(String[] args) { SpringApplication.run(Main.class, args); }}

CONTAINERL

ESS

import org.eclipse.jetty.server.Server;import org.eclipse.jetty.servlet.*;

public class Main { public static void main(String[] args) throws Exception { Server server = new Server(); ServletContextHandler context = new ServletContextHandler( ServletContextHandler.SESSIONS); context.setContextPath("/"); server.setHandler(context); context.addServlet(new ServletHolder(new App()), "/*"); server.start(); server.join(); }}

(defn -main [& [port]] (jetty/run-jetty (site #'app) {:port port :join? false}))

// Play example does not require any code

Dropwizard

Demo…

Host OS

Docker EngineImage

$ docker build ...

Host OS

Docker EngineImage

App

Con

tain

er

$ docker run ...$ docker build ...

Host OS

App

Con

tain

er

Docker EngineImage

App

Con

tain

er

App App

Con

tain

er

Con

tain

er

$ docker run ...$ docker build ...

$ docker run ...

Host OS

Docker Engine

$ docker run ...$ docker build ...

$ docker run ...

The 12 Factors• Codebase

• Dependencies

• Config

• Backing services

• Build, release, run

• Processes

• Port binding

• Concurrency

• Disposability

• Dev/prod parity

• Logs

• Admin processes

| Disposable | Parity | Config | Admin |

Admin tasks should be run in isolated processes

web1

web2

web3

admin

| Disposable | Parity | Config | Admin |

The 12 Factors• Codebase

• Dependencies

• Config

• Backing services

• Build, release, run

• Processes

• Port binding

• Concurrency

• Disposability

• Dev/prod parity

• Logs

• Admin processes

| Disposable | Parity | Config | Admin | Concurrency |

Scale UpAND

Scale Out

| Disposable | Parity | Config | Admin | Concurrency |

web.1

web.2

worker.1 clock.1

Workload Diversity

Num

ber o

f Pro

cess

es

worker.2

worker.3

TAKE AWAYS!

• Install the JDK• Clone the SCM repo• Run the app

1) Three Steps to Setup

• Get a stopwatch• Time your app’s startup• Get it under 30 seconds

2) Make Startup Quick

• Provision a new environment, deploy the app,handle requests

3) Deploy in One Step

http://12factor.net

Joe Kutner@codefinger

JVM Languages Owner@Heroku