JavaOne 2015: 12 Factor App

Post on 16-Apr-2017

2.036 views 0 download

Transcript of JavaOne 2015: 12 Factor App

12 FactorAppBest Practices for Java Deployment

You might not like what I have to say

Modern Java Deployment

.war

Traditional Java Deployment

.jar

Modern Java Deployment

Make JAR

Not WAR

2005 2015

WAR files JAR files

App Servers Microservices

Hot Deploy Continuous Deploy

Server in a closet Heroku/AWS/etc

Joe Kutner@codefinger

JVM Platform Owner

12 Factor Appa methodology

ScalabilityMaintainability

Portability

Immutable Ephemeral Declarative Automated

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

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

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

Use version control

BAD

BAD

App #1 App #2

pom.xml

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

Submodules

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

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

12 Factor App

Never rely on implicit existence of system-wide

packages

Explicitly declare and isolate

dependencies

Don’t check JAR files

into Git

https://bintray.com/

Agent JARs

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>

build.gradle

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

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

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

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…

Configuration should be strictly separated

from code

Don’t check passwords into Git

Configuration belongs in the environment, not in the application

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}"/>

// ...

application.conf

db.default.url=${DATABASE_URL}

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

any credentials?

Litmus Test

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

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

12 Factor App

application.conf

db.default.url=${DATABASE_URL}

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

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

12 Factor App

build, release, run

$ mvn clean install

$ sbt stage

$ ./gradlew build

build

$ heroku deploy:jar -j myapp.war

$ mvn heroku:deploy

$ docker push ...

release

$ java -jar myapp.war

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

run

$ mvn jetty:run

$ service tomcat start

$ cp myapp.war TOMCAT_HOME/webapps/

$ git push heroku masterbuild,

release,& run

DemoTime

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

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

12 Factor App

Processes should be stateless

sticky sessions 😞

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

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

12 Factor App

The twelve-factor app is completely self-contained

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

.war

Traditional Deployment

.jar

Modern Deployment

Dropwizard

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

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

12 Factor App

Relax bro, I got this…

java.util.concurrent

RxJava

java.util.stream

Scale Up

Scale Out

web.1

web.2

worker.1 clock.1

Workload Diversity

Num

ber o

f Pro

cess

es

worker.2

worker.3

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

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

12 Factor App

Graceful shutdown

Quick startup

Resilience to failure

Servers are not pets

Servers are cattle

Application Servers are pets

Application Servers are not disposable

Microservices are cattle

Microservices are disposable

Easy to replace

Decoupled from external infrastructure

Easy to modify

Microservices

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

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

12 Factor App

dev stage prod= =

dev

sqlite

stage

mysql

prod

postgres

=

=

dev

sqlite

postgres

stage

mysql

postgres

prod

postgres

postgres

=

=

=

=

dev

tomcat

jetty

stage

tomcat

jetty

prod

jboss

jetty

=

=

=

=

.jar

disposability⇒reproducibility

parity⇒

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

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

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

Admin tasks should be run

in isolated processes

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

web1

web2

web3

admin

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

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

12 Factor App

http://12factor.net

http://jkutner.github.io

Create a bintray.com account1.

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

Measure your app’s boot time3.

Click a Heroku button4.

What next?

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

Joe Kutner@codefinger

JVM Platform Owner

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