JavaOne 2015: 12 Factor App

83
12 Factor App Best Practices for Java Deployment

Transcript of JavaOne 2015: 12 Factor App

Page 1: JavaOne 2015: 12 Factor App

12 FactorAppBest Practices for Java Deployment

Page 2: JavaOne 2015: 12 Factor App

You might not like what I have to say

Page 3: JavaOne 2015: 12 Factor App

Modern Java Deployment

Page 4: JavaOne 2015: 12 Factor App

.war

Traditional Java Deployment

Page 5: JavaOne 2015: 12 Factor App

.jar

Modern Java Deployment

Page 6: JavaOne 2015: 12 Factor App

Make JAR

Not WAR

Page 7: JavaOne 2015: 12 Factor App

2005 2015

WAR files JAR files

App Servers Microservices

Hot Deploy Continuous Deploy

Server in a closet Heroku/AWS/etc

Page 8: JavaOne 2015: 12 Factor App

Joe Kutner@codefinger

JVM Platform Owner

Page 9: JavaOne 2015: 12 Factor App

12 Factor Appa methodology

ScalabilityMaintainability

Portability

Page 10: JavaOne 2015: 12 Factor App

Immutable Ephemeral Declarative Automated

Page 11: JavaOne 2015: 12 Factor App

• Codebase• Dependencies• Config• Backing services• Build, release, run• Processes

• Port Binding• Concurrency• Disposability• Dev/Prod Parity• Logs• Admin Processes

12 Factor App

Page 12: JavaOne 2015: 12 Factor App

• Codebase• Dependencies• Config• Backing services• Build, release, run• Processes

• Port Binding• Concurrency• Disposability• Dev/Prod Parity• Logs• Admin Processes

12 Factor App

Page 13: JavaOne 2015: 12 Factor App

Use version control

Page 14: JavaOne 2015: 12 Factor App
Page 15: JavaOne 2015: 12 Factor App
Page 16: JavaOne 2015: 12 Factor App

BAD

Page 17: JavaOne 2015: 12 Factor App

BAD

App #1 App #2

Page 18: JavaOne 2015: 12 Factor App

pom.xml

<project> ... <modules> <module>my-app</module> <module>my-other-app</module> </modules><project>

Page 19: JavaOne 2015: 12 Factor App

Submodules

Page 20: JavaOne 2015: 12 Factor App

• Codebase• Dependencies• Config• Backing services• Build, release, run• Processes

• Port Binding• Concurrency• Disposability• Dev/Prod Parity• Logs• Admin Processes

12 Factor App

Page 21: JavaOne 2015: 12 Factor App

Never rely on implicit existence of system-wide

packages

Explicitly declare and isolate

dependencies

Page 22: JavaOne 2015: 12 Factor App

Don’t check JAR files

into Git

Page 23: JavaOne 2015: 12 Factor App
Page 24: JavaOne 2015: 12 Factor App

https://bintray.com/

Page 25: JavaOne 2015: 12 Factor App

Agent JARs

Page 26: JavaOne 2015: 12 Factor App

pom.xml<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>2.6</version> <executions> <execution> <id>copy-new-relic</id> <phase>package</phase> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <includeGroupIds>com.newrelic.agent.java</includeGroupIds> <includeArtifactIds>newrelic-agent</includeArtifactIds> <stripVersion>true</stripVersion> </configuration> </execution> </executions></plugin>

Page 27: JavaOne 2015: 12 Factor App

build.gradle

task copyToLib(type: Copy) { into "$buildDir/server" from(configurations.compile) { include "jetty-runner*" }}

Page 28: JavaOne 2015: 12 Factor App

• Codebase• Dependencies• Config• Backing services• Build, release, run• Processes

• Port Binding• Concurrency• Disposability• Dev/Prod Parity• Logs• Admin Processes

12 Factor App

Page 29: JavaOne 2015: 12 Factor App

• Resource handles to the database, memcached, and other backing services

• Credentials to external services such as Amazon S3 or Twitter

• Per-deploy values such as the canonical hostname for the deploy

Anything that changes between deployment environments:

(does not include things like conf/routes)

Configuration is…

Page 30: JavaOne 2015: 12 Factor App

Configuration should be strictly separated

from code

Page 31: JavaOne 2015: 12 Factor App

Don’t check passwords into Git

Page 32: JavaOne 2015: 12 Factor App
Page 33: JavaOne 2015: 12 Factor App

Configuration belongs in the environment, not in the application

Page 34: JavaOne 2015: 12 Factor App

applicationContext.xml

<bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" id=“dataSource">

<property name="driverClassName" value="org.postgresql.Driver"/> <property name="url" value=“${JDBC_DATABASE_URL}"/>

// ...

Page 35: JavaOne 2015: 12 Factor App

application.conf

db.default.url=${DATABASE_URL}

Page 36: JavaOne 2015: 12 Factor App

Can you make your app open source at any moment, without compromising

any credentials?

Litmus Test

Page 37: JavaOne 2015: 12 Factor App

• Codebase• Dependencies• Config• Backing services• Build, release, run• Processes

• Port Binding• Concurrency• Disposability• Dev/Prod Parity• Logs• Admin Processes

12 Factor App

Page 38: JavaOne 2015: 12 Factor App
Page 39: JavaOne 2015: 12 Factor App

application.conf

db.default.url=${DATABASE_URL}

Page 40: JavaOne 2015: 12 Factor App

• Codebase• Dependencies• Config• Backing services• Build, release, run• Processes

• Port Binding• Concurrency• Disposability• Dev/Prod Parity• Logs• Admin Processes

12 Factor App

Page 41: JavaOne 2015: 12 Factor App

build, release, run

Page 42: JavaOne 2015: 12 Factor App

$ mvn clean install

$ sbt stage

$ ./gradlew build

build

Page 43: JavaOne 2015: 12 Factor App

$ heroku deploy:jar -j myapp.war

$ mvn heroku:deploy

$ docker push ...

release

Page 44: JavaOne 2015: 12 Factor App

$ java -jar myapp.war

$ build/install/myapp/bin/myapp.bat

run

$ mvn jetty:run

$ service tomcat start

$ cp myapp.war TOMCAT_HOME/webapps/

Page 45: JavaOne 2015: 12 Factor App

$ git push heroku masterbuild,

release,& run

Page 46: JavaOne 2015: 12 Factor App

DemoTime

Page 47: JavaOne 2015: 12 Factor App

• Codebase• Dependencies• Config• Backing services• Build, release, run• Processes

• Port Binding• Concurrency• Disposability• Dev/Prod Parity• Logs• Admin Processes

12 Factor App

Page 48: JavaOne 2015: 12 Factor App

Processes should be stateless

Page 49: JavaOne 2015: 12 Factor App

sticky sessions 😞

Page 50: JavaOne 2015: 12 Factor App

• Codebase• Dependencies• Config• Backing services• Build, release, run• Processes

• Port Binding• Concurrency• Disposability• Dev/Prod Parity• Logs• Admin Processes

12 Factor App

Page 51: JavaOne 2015: 12 Factor App

The twelve-factor app is completely self-contained

The web app exports HTTP as a service by binding to a port

Page 52: JavaOne 2015: 12 Factor App

.war

Traditional Deployment

Page 53: JavaOne 2015: 12 Factor App

.jar

Modern Deployment

Page 54: JavaOne 2015: 12 Factor App

Dropwizard

Page 55: JavaOne 2015: 12 Factor App

• Codebase• Dependencies• Config• Backing services• Build, release, run• Processes

• Port Binding• Concurrency• Disposability• Dev/Prod Parity• Logs• Admin Processes

12 Factor App

Page 56: JavaOne 2015: 12 Factor App

Relax bro, I got this…

java.util.concurrent

RxJava

java.util.stream

Page 57: JavaOne 2015: 12 Factor App

Scale Up

Scale Out

Page 58: JavaOne 2015: 12 Factor App

web.1

web.2

worker.1 clock.1

Workload Diversity

Num

ber o

f Pro

cess

es

worker.2

worker.3

Page 59: JavaOne 2015: 12 Factor App

• Codebase• Dependencies• Config• Backing services• Build, release, run• Processes

• Port Binding• Concurrency• Disposability• Dev/Prod Parity• Logs• Admin Processes

12 Factor App

Page 60: JavaOne 2015: 12 Factor App

Graceful shutdown

Quick startup

Resilience to failure

Page 61: JavaOne 2015: 12 Factor App

Servers are not pets

Servers are cattle

Page 62: JavaOne 2015: 12 Factor App

Application Servers are pets

Page 63: JavaOne 2015: 12 Factor App

Application Servers are not disposable

Page 64: JavaOne 2015: 12 Factor App

Microservices are cattle

Page 65: JavaOne 2015: 12 Factor App

Microservices are disposable

Page 66: JavaOne 2015: 12 Factor App

Easy to replace

Decoupled from external infrastructure

Easy to modify

Page 67: JavaOne 2015: 12 Factor App

Microservices

Page 68: JavaOne 2015: 12 Factor App

• Codebase• Dependencies• Config• Backing services• Build, release, run• Processes

• Port Binding• Concurrency• Disposability• Dev/Prod Parity• Logs• Admin Processes

12 Factor App

Page 69: JavaOne 2015: 12 Factor App

dev stage prod= =

Page 70: JavaOne 2015: 12 Factor App

dev

sqlite

stage

mysql

prod

postgres

=

=

Page 71: JavaOne 2015: 12 Factor App

dev

sqlite

postgres

stage

mysql

postgres

prod

postgres

postgres

=

=

=

=

Page 72: JavaOne 2015: 12 Factor App

dev

tomcat

jetty

stage

tomcat

jetty

prod

jboss

jetty

=

=

=

=

.jar

Page 73: JavaOne 2015: 12 Factor App

disposability⇒reproducibility

parity⇒

Page 74: JavaOne 2015: 12 Factor App

• Codebase• Dependencies• Config• Backing services• Build, release, run• Processes

• Port Binding• Concurrency• Disposability• Dev/Prod Parity• Logs• Admin Processes

12 Factor App

Page 75: JavaOne 2015: 12 Factor App

• Codebase• Dependencies• Config• Backing services• Build, release, run• Processes

• Port Binding• Concurrency• Disposability• Dev/Prod Parity• Logs• Admin Processes

12 Factor App

Page 76: JavaOne 2015: 12 Factor App

Admin tasks should be run

in isolated processes

Page 77: JavaOne 2015: 12 Factor App

$ heroku run bashRunning `bash` attached to terminal... up, run.1594~ $

Page 78: JavaOne 2015: 12 Factor App

web1

web2

web3

admin

Page 79: JavaOne 2015: 12 Factor App

• Codebase• Dependencies• Config• Backing services• Build, release, run• Processes

• Port Binding• Concurrency• Disposability• Dev/Prod Parity• Logs• Admin Processes

12 Factor App

Page 80: JavaOne 2015: 12 Factor App

http://12factor.net

http://jkutner.github.io

Page 81: JavaOne 2015: 12 Factor App

Create a bintray.com account1.

set JDBC_DATABASE_URL=jdbc:postgres://…2.

Measure your app’s boot time3.

Click a Heroku button4.

What next?

Page 82: JavaOne 2015: 12 Factor App

https://github.com/britter/spring-boot-heroku-demo

Page 83: JavaOne 2015: 12 Factor App

Joe Kutner@codefinger

JVM Platform Owner

(http://www.slideshare.net/jkutner/javaone-2015-12-factor-app)http://bit.ly/1PSRxcm