SlideShare ist ein Scribd-Unternehmen logo
CLOUD NATIVE & JEE
FREUND ODER FEIND?
Josef Adersberger ( @adersberger)
★ Design for Distribution: Container, Microservices, API-getriebene Entwicklung
★ Design for Performance: Responsive, nebenläufig, ressourcenschonend
★ Design for Automation: Dev- und Ops-Aufgaben automatisieren
★ Design for Resiliency: Fehlertolerant und selbst-heilend
★ Design for Elasticity: Dynamisch skalierbar und reaktiv
★ Design for Delivery: Kurze Roundtrips und automatisierte Provisionierung
★ Design for Diagnosability: Cluster-weite Logs, Metriken und Traces
2
Mehr Ordnung: Cloud Native Maturity Model (https://de.slideshare.net/Pivotal/the-cloud-native-journey-58445711)
Mehr Lösung: The Twelve-Factor App Methodology (https://12factor.net)
Design-Prinzipien für Cloud Native Applications
JEE
CLOUD

NATIVE
+ =
CLOUD

NATIVE

JEE
instagram.com/toby_littledude
JEE IST AKTUELL WEDER HÄSSLICH NOCH REIN AUF MONOLITHEN AUSGELEGT
▸ Die JEE API ist modular und in vielen Teilen leichtgewichtig

(unter uns: manchmal fühlt sich Spring schwergewichtiger an)
▸ Neben den klassischen Application Servern sind nun auch JEE Micro Container
verfügbar, mit denen JEE-Anwendungen in Microservices geschnitten werden
können
▸ Das Wissen ist breit verteilt, wie Enterprise Anwendungen auf Basis JEE
entwickelt werden können
▸ Die JEE API ist standardisiert und reif. Die Implementierungen sind “battle
proven”.
▸ … aber leider werden auch in JEE 8 die Design-Prinzipien von Cloud Native
Applications noch zu wenig berücksichtigt. Mit Hilfe von Open-Source-
Bausteinen gelingt dies aber trotzdem.
JEE
CLOUD

NATIVE
+ =
CLOUD

NATIVE

JEE
instagram.com/toby_littledude
SICHT DES ARCHITEKTENS
CLOUD NATIVE JEE
WIR NEIGEN DAZU, JEE-ANWENDUNGEN IN SCHWERGEWICHTIGEN
APPSERVERN ALS AUSFÜHRUNGSMONOLITHEN LAUFEN ZU LASSEN
DESIGN CODE RUN
startup-cluster.sh
JEE Impl.
JEE App Server
JEE MICRO CONTAINER ERMÖGLICHEN JEE AUSFÜHRUNGSKOMPONENTEN
(MICROSERVICES) IN EINER MAßGESCHNEIDERTEN AUSFÜHRUNGSUMGEBUNG
DESIGN CODE RUN
main()
JEE impl. parts
EINE CLOUD AN JEE MICROSERVICES! MISSION ERFOLGREICH?
image: https://www.dreamstime.com
eine Cloud ist nicht nichts
CLOUD NATIVE STACK
JEE MICROSERVICES
CLUSTER VIRTUALIZATION (computing, network, storage, memory)
CLUSTER RESOURCE MANAGER
CLUSTER ORCHESTRATOR
APPLICATIONS
CONTAINER
CLUSTER RESOURCES
MICROSERVICE PLATFORM

API Gateway
Micro Container
Configuration & Coordination
Diagnosability &

Monitoring
Infrastructure-as-a-Service Bare Metal Local Host
Service

Client
Service Discovery
DevOps Interface
•deploy
•rollback
•scale
•configure
Diagnose Interface
•analyze logs
•analyze metrics
•analyze traces
Edge Interface
•request service
•authenticate
CLUSTER VIRTUALIZATION (computing, network, storage, memory)
CLUSTER RESOURCE MANAGER
CLUSTER ORCHESTRATOR
APPLICATIONS
CONTAINER
CLUSTER RESOURCES
MICROSERVICE PLATFORM

API Gateway
Micro Container
Configuration & Coordination
Diagnosability &

Monitoring
Infrastructure-as-a-Service Bare Metal Local Host
Service

Client
Service Discovery
DevOps Interface
•deploy
•rollback
•scale
•configure
Diagnose Interface
•analyze logs
•analyze metrics
•analyze traces
Edge Interface
•request service
•authenticate
Wie können den Containern
die passenden Ressourcen
zugewiesen werden?
Wie entkoppelt man von
physischer Hardware?
Wie führt man containerisierte
Anwendungen im Cluster aus?
Wie entdeckt man
Laufzeitanomalien und ihre
Ursachen?
Wie ruft man resilient und
responsive andere
Microservices auf?
Wie führt man einen Microservice
aus?
Wie erzeugt man cluster-weiten
Konsens zu Konfigurationswerten

etc.
Wie exponiert man Services in das
Internet?
Wie verwaltet man
zentral die verfügbaren
Services und Endpunkte?
goo.gl/xrVg3J
CLUSTER VIRTUALIZATION (computing, network, storage, memory)
CLUSTER RESOURCE MANAGER
CLUSTER ORCHESTRATOR
APPLICATIONS
CONTAINER
CLUSTER RESOURCES
MICROSERVICE PLATFORM

API Gateway
Micro Container
Configuration & Coordination
Diagnosability &

Monitoring
Infrastructure-as-a-Service Bare Metal Local Host
Service

Client
Service Discovery
DevOps Interface
Diagnose InterfaceEdge Interface
DER ZWITSCHER CLOUD NATIVE JEE SHOWCASE
ZWITSCHER-APP-HISTORY ZWITSCHER-APP-WIKIPEDIAZWITSCHER-APP-CHUCK
ZWITSCHER-APP-BOARD
Keyword Resultat + Keyword-Historie
random joke

(weil jeder Chuck
Norris Witz auf jedes
Keyword matched)
JDBC Open API
ZWITSCHER-APP-CHUCK
fallback
https://github.com/adersberger/cloud-native-zwitscher-jee
SICHT DES ENTWICKLERS
CLOUD NATIVE JEE
MICRO
CONTAINERDEPENDENCY INJECTION
APPLICATION LIFECYCLE
ENDPOINT EXPOSITION
DAS JEE MICRO CONTAINER ÖKOSYSTEM
http://wildfly-swarm.io
https://ee.kumuluz.com
http://microprofile.io (to come)
http://tomee.apache.org
http://www.payara.fish/payara_micro
EMBEDDED
implements (unstable)
JEE MICRO CONTAINER IM VERGLEICH
Payara Micro Wildfly Swarm TomEE kumuluzEE
Servlets et al. x x x x
WebSockets x x x
JSF x x x
JAX-RS x x x (TomEE+) x
JAX-WS x x (TomEE+)
EJB *2 x x x
CDI x x x x
JTA x x x
JCA x x (TomEE+)
JMS x x (TomEE+)
JPA x x x x
Bean Validation x x x x
JBatch x x
Concurrency x x
JCache x x
JEE Version JEE 7 Web Profile JEE 7 JEE 6, JEE 7 teilw.*1 JEE 7 teilw.
Packetierung WAR + JAR JAR JAR classes + JARs
Startup-Dauer 4s 4s 2s 1s
Referenz-Größe 57MB 83 MB 44 MB 15 MB
*1) http://tomee.apache.org/javaee7-status.html
*2) http://stackoverflow.com/questions/13487987/where-to-use-ejb-3-1-and-cdi
@Path(“/joke") @RequestScoped

public class ChuckJokeResource {

@Inject

private IcndbIntegration icndb;

@GET

@Produces("application/json")

public Response getJoke() {

Map<String, String> json = new HashMap<>();

json.put("message", icndb.getRandomJoke());

return Response.ok(json).build();

}

}
@ApplicationPath("/chuck")

public class ChuckJokeApplication extends ResourceConfig {

public ChuckJokeApplication() {

super();
register(ChuckJokeResource.class);

}

}
JAX-RS MIT CDI
bean-discovery-mode="all"
public class Main {



/**

* Starts the microservice container.

*

* Requires environment variable "PORT" according

* on what port to listen.

*

* @param args no arguments evaluated

*/

public static void main(String[] args) {

com.kumuluz.ee.EeApplication.main(args);

}

}
JEE MICRO CONTAINER STARTUP
SERVICE CLIENTSERVICE DISCOVERY
LOAD BALANCING
REQUEST MONITORING
CIRCUIT BREAKING
SERVICE CLIENT MIT JERSEY, RXJAVA UND HYSTRIX
•Circuit Breaker (Resiliency)
•Request Monitoring
•JAX-RS 2.0 REST Client•Parallele und asynchrone

Ausführung 

(Responsive)
SERVICE CLIENT MIT JERSEY, RXJAVA AND HYSTRIX
@RequestScoped

public class IcndbIntegration implements IChuckNorrisJokes {



@Override public String getRandomJoke() {

IcndbIntegrationCommand cmd = new IcndbIntegrationCommand();

return cmd.observe().toBlocking().toFuture().get();

}



private class IcndbIntegrationCommand extends HystrixObservableCommand<String> {



IcndbIntegrationCommand() {

super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("zwitscher"))

.andCommandPropertiesDefaults(HystrixCommandProperties.Setter()

.withExecutionTimeoutInMilliseconds(3000)));

}



@Override protected Observable<String> construct() {

return RxObservable.newClient()

.target("http://api.icndb.com").path("jokes/random").request(MediaType.APPLICATION_JSON_TYPE)

.rx().get()

.map(response -> {

Map<String, Map<String, String>> json = response.readEntity(Map.class);

return json.get("value").get("joke");

});

}

}

}
•Asnc bis zum Client mit dem Async-Support ab Servlet API 3
•Mehr Nebenläufigkeit ein Y-Stück Observable
FALLBACK WITZE
@RequestScoped

public class IcndbIntegration implements IChuckNorrisJokes {
@Inject @Named("chucknorrisjoke-chucknorrisio")

private IChuckNorrisJokes fallback;
@Override public Observable<String> getRandomJokeObservable() { 

return new IcndbIntegrationCommand().observe();
}



//…



private class IcndbIntegrationCommand extends HystrixObservableCommand<String> {



//…



@Override

protected Observable<String> resumeWithFallback() {

return fallback.getRandomJokeObservable();

}

}

}
MONITORING &
DIAGNOSABILITYMETRIKEN
LOGS
TRACES
DASHBOARDS & ALERTING
DAS MAGISCHE DREIECK DER DIAGNOSTIZIERBARKEIT
Metriken
Logs Traces
Cluster-wide

Diagnosis
DIAGNOSTIZERBARKEIT: METRIKEN
DROPWIZARD
METRICS
JERSEY
HYSTRIX
MICRO
SERVICE
PROMETHEUS
SERVLET
METRICS
SERVLET
HYSTRIX
SERVLET
Dashboard / Turbine
Health 

Checks
Service

Lookup
INSTRUMENTIERUNG
@ApplicationPath("/chuck")

public class ChuckJokeApplication extends ResourceConfig {

public ChuckJokeApplication() {

super();

//Instrument application with metrics

MetricRegistry METRIC_REGISTRY = MetricsProvider.getMetricRegistryInstance();

register(new InstrumentedResourceMethodApplicationListener(METRIC_REGISTRY));

HystrixPlugins.getInstance().registerMetricsPublisher(

new HystrixCodaHaleMetricsPublisher(METRIC_REGISTRY));

//Register Prometheus metric exporter

CollectorRegistry.defaultRegistry.register(new DropwizardExports(METRIC_REGISTRY));

}

}
Die eingehenden
REST-Aufrufe
instrumentieren
Die ausgehenden
REST-Aufrufe
instrumentieren
Alle Metriken
für Prometheus
bereitstellen
Die
MetricRegistry
holen
(Singleton)
Cloud Native und Java EE: Freund oder Feind?
HYSTRIX DASHBOARD
SERVICE DISCOVERYSERVICE REGISTRATION
SERVICE LOOKUP
SERVICE HEALTH CHECKING
& API GATEWAYAPI EXPOSITION & REQUEST ROUTING
AUTHENTICATION & AUTORISATION
LOAD BALANCING & SHEDDING
RATE LIMITING
REQUEST MONITORING & AUDITING
DAS BIG PICTURE
MICRO
SERVICE
SERVICE DISCOVERY
Services

registrieren
Interne 

Services

registrieren &

auflösen
Web Requests
Routen ermitteln

(per Polling)
API GATEWAY
Health

Checks
java.security.Security.setProperty("networkaddress.cache.ttl", "3" );
Web Request
SERVICE REGISTRATION IN EINEM JEE MICROSERVICE
@ApplicationPath("/chuck")

public class ChuckJokeApplication extends ResourceConfig {



@Inject

public ChuckJokeApplication(

@ConsulFabio IServiceDiscovery serviceDiscovery) {

super();

//Register service

serviceDiscovery.registerService(
"zwitscher-chuck", "/chuck/joke");

}

} Service-Name URL-Pfad zum Service-Endpunkt
SERVICE REGISTRATION: HEAVY LIFTING
/**

* Registeres a service

*

* see https://github.com/eBay/fabio/wiki/Service-Configuration

*/

public synchronized void registerService(String serviceName, String servicePath) {



String applicationHost = getOutboundHost();

int applicationPort = getOutboundPort();

HostAndPort consulEndpoint = getConsulHostAndPort();

logger.info("Will register service on host {} and port {} at consul endpoint {}",

applicationHost, applicationPort, consulEndpoint.toString());



//generate unique serviceId

String serviceId = serviceName + "-" + applicationHost + ":" + applicationPort;

String fabioServiceTag = "urlprefix-" + servicePath;



//point healthcheck URL to dropwizard metrics healthcheck servlet

URL serviceUrl = UrlBuilder.empty()

.withScheme("http")

.withHost(applicationHost)

.withPort(applicationPort)

.withPath("/metrics/ping").toUrl();



// Service bei Consul registrieren inklusive einem Health-Check auf die URL des REST-Endpunkts.

logger.info("Registering service with ID {} and NAME {} with healthcheck URL {} and inbound ROUTE {}",

serviceId, serviceName, serviceUrl, fabioServiceTag);



//use consul API to register service

ConsulClient client = new ConsulClient(consulEndpoint.toString());

NewService service = new NewService();

service.setId(serviceId);

service.setName(serviceName);

service.setPort(applicationPort);

service.setAddress(applicationHost);

List<String> tags = new ArrayList<>();

tags.add(fabioServiceTag);

service.setTags(tags);

//register health check

NewService.Check check = new NewService.Check();

check.setHttp(serviceUrl.toString());

check.setInterval(ConsulFabioServiceDiscovery.HEALTHCHECK_INTERVAL + "s");

service.setCheck(check);

client.agentServiceRegister(service);

}



public static String getOutboundHost() {

String hostName = System.getenv(HOSTNAME_ENVVAR);

String host = System.getenv(HOST_ENVVAR);

if (hostName == null && host == null) return DEFAULT_HOST;

else if (host != null) return host;

else {

File etcHosts = new File("/etc/hosts");

List<String> lines;

try {

lines = Files.readLines(etcHosts, Charset.defaultCharset());

} catch (IOException e) {

return DEFAULT_HOST;

}

for (String line: lines){

if (!line.trim().startsWith("#") && !line.trim().isEmpty()) {

String[] etcEntry = line.split("s+");

if (etcEntry[1].equals(hostName)) return etcEntry[0];

}

}

return DEFAULT_HOST;

}

}



public static int getOutboundPort() {

String portEnv = System.getenv(PORT_ENVVAR);

if (portEnv == null) return DEFAULT_PORT;

return Integer.valueOf(portEnv);

}



public static HostAndPort getConsulHostAndPort() {

String consulEnv = System.getenv(CONSUL_ENVVAR);

if (consulEnv == null) return HostAndPort.fromString(CONSUL_DEFAULT_HOSTANDPORT);

else return HostAndPort.fromString(consulEnv);

}
@ConsulFabio

@ApplicationScoped

public class ConsulFabioServiceDiscovery implements IServiceDiscovery {
den Host-Namen und Port ermitteln, den Consul sieht
den Health-Check Endpunkt ermitteln (MetricsServlet)
Metadaten für Fabio erzeugen
Service bei Consul registrieren

(ebenso wie Diagnose- und Doku-Endpunkte)
ET VOILA: CONSUL MIT 3 REGISTRIERTEN SERVICE-INSTANZEN
ET VOILA: FABIO DIREKT AUS CONSUL BEDIENT
SICHT DES APPOPS
CLOUD NATIVE JEE
DIE SICH SELBST AUSLIEFERNDE SOFTWARE
RUNNING

TESTED

SOFTWARE

INCREMENT
EVERYTHING AS CODE:
•die Anwendung
•die Tests
•die Infrastruktur
•der CD-Workflow{
WICHTIG SIND KURZE ROUNDTRIP-ZYKLEN
In-Process
Local Cluster
Remote Cluster
•längere Roundtrips
•aber: realistischer
Vollständiges Deployment:
Einzelne Services:
https://github.com/qaware/gradle-cloud-deployer
MARATHON APP DEFINITION
{

"id": "/zwitscher",

"groups": [

{

"id": "/zwitscher/infrastructure",

"apps": [

{

"id": "consul",

"cpus": 1,

"mem": 256,

"disk": 0,

"instances": 1,

"cmd": "/bin/consul agent -server -ui -advertise=$HOST -config-dir=/config -data-dir=/tmp/consul -bootstrap-expect=1 -node=consul-server -client=0.0.0.0",

"container": {

"docker": {

"image": "gliderlabs/consul-server:0.6",

"forcePullImage": true,

"privileged": false,

"network": "HOST",

"portDefinitions": [

{ "port": 8300, "protocol": "tcp", "name": "server-rpc" },

{ "port": 8301, "protocol": "tcp", "name": "serf-lan" },

{ "port": 8302, "protocol": "tcp", "name": "serf-wan" },

{ "port": 8400, "protocol": "tcp", "name": "cli-rpc" },

{ "port": 8500, "protocol": "tcp", "name": "http-api" },

{ "port": 8600, "protocol": "udp", "name": "dns" }

],

"requirePorts" : true

}

},

"env": {

"GOMAXPROCS": "10"

},

"healthChecks": [

{

"protocol": "HTTP",

"port": 8500,

"path": "/v1/status/leader",

"intervalSeconds": 10,

"timeoutSeconds": 10,

"maxConsecutiveFailures": 3

}

]

},

{

"id": "fabio",

"cpus": 1,

"mem": 256,

"disk": 0,

"instances": 1,

"env": {

"registry_consul_addr": "consul.infrastructure.zwitscher.marathon.mesos:8500"

},

"container": {

"docker": {

"image": "magiconair/fabio:latest",

"forcePullImage": true,

"privileged": false,

"network": "HOST",

"portDefinitions": [

{ "port": 9998, "protocol": "tcp", "name": "web-ui" },

{ "port": 9999, "protocol": "tcp", "name": "proxy-port" }

],

"requirePorts" : true

}

},

"acceptedResourceRoles":["slave_public"],

"healthChecks": [

{

"protocol": "HTTP",

"port": 9998,

"path": "/health",

"intervalSeconds": 10,

"timeoutSeconds": 10,

"maxConsecutiveFailures": 3

}

]

}

]

},

{

"id": "/zwitscher/services",

"apps": [

{

"id": "zwitscher-chuck",

"cpus": 1,

"mem": 256,

"disk": 0,

"instances": 1,

"container": {

"docker": {

"image": "adersberger/zwitscher-app-chuck:1.0.0-SNAPSHOT",

"forcePullImage": true,

"privileged": false,

"network": "HOST",

"portDefinitions": [

{ "port": 12340, "protocol": "tcp", "name": "rest-api" }

],

"requirePorts" : true

}

},

"env": {

"PORT": "12340",

"CONSUL": "consul.infrastructure.zwitscher.marathon.mesos:8500",

"CONFIG_ENV" : "zwitscher"

},

"args": [

"-Xmx256m"

],

"healthChecks": [

{

"protocol": "HTTP",

"port": 12340,

"path": "/metrics/ping",

"intervalSeconds": 10,

"timeoutSeconds": 10,

"maxConsecutiveFailures": 3

}

],

"dependencies": [

"/zwitscher/infrastructure/consul"

]

}

]

}

]

}
marathon-appgroup.json
/zwitscher
/infrastructure
/consul
/fabio
/service
/zwitscher-chuck
dependency
"healthChecks": [

{

"protocol": “HTTP", "port": 9998, "path": "/health",

"intervalSeconds": 10, "timeoutSeconds": 10, "maxConsecutiveFailures": 3

}

]
Health Checks:
"network": "HOST",

"ports": [9998, 9999],

"requirePorts" : true
Networking:
"acceptedResourceRoles":["slave_public"]
API Gateway auf den Public Slaves:
"env": {

"PORT": "12340",

"CONSUL": "consul.infrastructure.zwitscher.marathon.mesos:8500"

},

"args": ["-Xmx256m"]
Konfiguration:
"container": { "docker": {

"image": "adersberger/zwitscher-app-chuck:1.0.0-SNAPSHOT",

"forcePullImage": true
Immer das aktuelle Docker Image bekommen:
"dependencies": [ "/zwitscher/infrastructure/consul"]
Startup-Abhängigkeiten (eher zu vermeiden):
FAZIT
CLOUD NATIVE JEE
FAZIT
▸ Cloud Native JEE Anwendungen entwickeln ist möglich und macht Spaß
▸ Die JEE API ist per se noch nicht Cloud Native und wird dies auf absehbare
Zeit auch nicht sein, kann aber entsprechend ergänzt werden, z.B. mit
unserem JCloudEE Mini-Framework:











▸ Kurze Roundtrip-Zeiten sind essenziell für die produktive Entwicklung von
Anwendungen. Bei Cloud Native Applications ist dabei die volle Portabilität
von lokaler Ausführung bis auf ein Cluster in der Cloud essenziell.
45
CompletableFuture<SoftwareArchitektIn> ich =
CompletableFuture.supplyAsync(()
-> erfindergeist()
.handwerksstolz()
);
CompletableFuture<Projekthaus> qaware =
CompletableFuture.supplyAsync(()
-> professionalität()
.lässigkeit()
);
Erfolg start = qaware.thenCombine(ich,
(i, q) -> i.sendeBewerbung(q))
.join();
Weiter Details unter http://www.qaware.de/karriere/#jobs
https://www.qaware.de
https://slideshare.net/qaware
https://github.com/qaware
&
josef.adersberger@qaware.de
@adersberger
https://github.com/adersberger/cloud-native-zwitscher-jee

Weitere ähnliche Inhalte

Andere mochten auch

Presentación etica rosa pereira
Presentación etica rosa pereiraPresentación etica rosa pereira
Presentación etica rosa pereira
Rosa Pereira
 
Startup Bootcamp - Session 1
Startup Bootcamp - Session 1 Startup Bootcamp - Session 1
Startup Bootcamp - Session 1
Avi Bhatnagar
 
Principiodelechatelier
PrincipiodelechatelierPrincipiodelechatelier
Principiodelechatelier
Ramón Olivares
 
Criterios de desarrollo para empresas en mercados abiertos1
Criterios de desarrollo para empresas en mercados abiertos1Criterios de desarrollo para empresas en mercados abiertos1
Criterios de desarrollo para empresas en mercados abiertos1
Juan Padron
 
2017 U.S. Marine Corps Aviation Plan
2017 U.S. Marine Corps Aviation Plan2017 U.S. Marine Corps Aviation Plan
2017 U.S. Marine Corps Aviation Plan
Tom "Blad" Lindblad
 
Water harvesting
Water harvestingWater harvesting
Water harvesting
Md Faiz Ali
 
Программа 31.03.2017
Программа 31.03.2017Программа 31.03.2017
Программа 31.03.2017
Dimov Viasheslav
 
Presentación1
Presentación1Presentación1
Presentación1
Angie Prada Polanco
 
Probabilidad estadística
Probabilidad estadísticaProbabilidad estadística
Probabilidad estadística
Marielba Perez Acosta
 
Ai論文サイト
Ai論文サイトAi論文サイト
Ai論文サイト
Masato Nakai
 
Top Artificial Intelligence (AI) Startups Disrupting Retail
Top Artificial Intelligence (AI) Startups Disrupting RetailTop Artificial Intelligence (AI) Startups Disrupting Retail
Top Artificial Intelligence (AI) Startups Disrupting Retail
NVIDIA
 
Karla roman
Karla romanKarla roman
Karla roman
karla BEJARANO
 
Luz y color
Luz y colorLuz y color
Luz y color
Maria Pascale
 
Teori belajar behavioristik_kelompok _4
Teori belajar behavioristik_kelompok _4Teori belajar behavioristik_kelompok _4
Teori belajar behavioristik_kelompok _4
nazar riati
 
Introducción a la informática
Introducción a la informáticaIntroducción a la informática
Introducción a la informática
Jatniel Nuñez
 

Andere mochten auch (15)

Presentación etica rosa pereira
Presentación etica rosa pereiraPresentación etica rosa pereira
Presentación etica rosa pereira
 
Startup Bootcamp - Session 1
Startup Bootcamp - Session 1 Startup Bootcamp - Session 1
Startup Bootcamp - Session 1
 
Principiodelechatelier
PrincipiodelechatelierPrincipiodelechatelier
Principiodelechatelier
 
Criterios de desarrollo para empresas en mercados abiertos1
Criterios de desarrollo para empresas en mercados abiertos1Criterios de desarrollo para empresas en mercados abiertos1
Criterios de desarrollo para empresas en mercados abiertos1
 
2017 U.S. Marine Corps Aviation Plan
2017 U.S. Marine Corps Aviation Plan2017 U.S. Marine Corps Aviation Plan
2017 U.S. Marine Corps Aviation Plan
 
Water harvesting
Water harvestingWater harvesting
Water harvesting
 
Программа 31.03.2017
Программа 31.03.2017Программа 31.03.2017
Программа 31.03.2017
 
Presentación1
Presentación1Presentación1
Presentación1
 
Probabilidad estadística
Probabilidad estadísticaProbabilidad estadística
Probabilidad estadística
 
Ai論文サイト
Ai論文サイトAi論文サイト
Ai論文サイト
 
Top Artificial Intelligence (AI) Startups Disrupting Retail
Top Artificial Intelligence (AI) Startups Disrupting RetailTop Artificial Intelligence (AI) Startups Disrupting Retail
Top Artificial Intelligence (AI) Startups Disrupting Retail
 
Karla roman
Karla romanKarla roman
Karla roman
 
Luz y color
Luz y colorLuz y color
Luz y color
 
Teori belajar behavioristik_kelompok _4
Teori belajar behavioristik_kelompok _4Teori belajar behavioristik_kelompok _4
Teori belajar behavioristik_kelompok _4
 
Introducción a la informática
Introducción a la informáticaIntroducción a la informática
Introducción a la informática
 

Ähnlich wie Cloud Native und Java EE: Freund oder Feind?

Steinzeit war gestern! Wege der cloud-nativen Evolution
Steinzeit war gestern! Wege der cloud-nativen EvolutionSteinzeit war gestern! Wege der cloud-nativen Evolution
Steinzeit war gestern! Wege der cloud-nativen Evolution
QAware GmbH
 
Steinzeit war gestern! Wege der Cloud-nativen Evolution.
Steinzeit war gestern! Wege der Cloud-nativen Evolution.Steinzeit war gestern! Wege der Cloud-nativen Evolution.
Steinzeit war gestern! Wege der Cloud-nativen Evolution.
QAware GmbH
 
A Hitchhiker's Guide to the Cloud Native Stack
A Hitchhiker's Guide to the Cloud Native StackA Hitchhiker's Guide to the Cloud Native Stack
A Hitchhiker's Guide to the Cloud Native Stack
QAware GmbH
 
A Hitchhiker’s Guide to the Cloud Native Stack. #ContainerConf
A Hitchhiker’s Guide to the Cloud Native Stack. #ContainerConfA Hitchhiker’s Guide to the Cloud Native Stack. #ContainerConf
A Hitchhiker’s Guide to the Cloud Native Stack. #ContainerConf
Mario-Leander Reimer
 
Steinzeit war gestern! Wege der Cloud-nativen Evolution.
Steinzeit war gestern! Wege der Cloud-nativen Evolution.Steinzeit war gestern! Wege der Cloud-nativen Evolution.
Steinzeit war gestern! Wege der Cloud-nativen Evolution.
QAware GmbH
 
Enterprise Cloud Native ist das neue Normal
Enterprise Cloud Native ist das neue NormalEnterprise Cloud Native ist das neue Normal
Enterprise Cloud Native ist das neue Normal
QAware GmbH
 
Fische im Rechenzentrum – Was genau ist eigentlich dieses Redfish und wozu br...
Fische im Rechenzentrum – Was genau ist eigentlich dieses Redfish und wozu br...Fische im Rechenzentrum – Was genau ist eigentlich dieses Redfish und wozu br...
Fische im Rechenzentrum – Was genau ist eigentlich dieses Redfish und wozu br...
BOSTON Server & Storage Solutions GmbH
 
Dataservices - Data Processing mit Microservices
Dataservices - Data Processing mit MicroservicesDataservices - Data Processing mit Microservices
Dataservices - Data Processing mit Microservices
QAware GmbH
 
Kontinuierliches (Nicht)-Funktionales Testen von Microservices auf K8s
Kontinuierliches (Nicht)-Funktionales Testen von Microservices auf K8sKontinuierliches (Nicht)-Funktionales Testen von Microservices auf K8s
Kontinuierliches (Nicht)-Funktionales Testen von Microservices auf K8s
QAware GmbH
 
Cloud Native Migration: Wie IT-Landschaften ihren Weg auf eine Cloud-Native-P...
Cloud Native Migration: Wie IT-Landschaften ihren Weg auf eine Cloud-Native-P...Cloud Native Migration: Wie IT-Landschaften ihren Weg auf eine Cloud-Native-P...
Cloud Native Migration: Wie IT-Landschaften ihren Weg auf eine Cloud-Native-P...
QAware GmbH
 
Applikationsmodernisierung: Der Weg von Legacy in die Cloud
Applikationsmodernisierung: Der Weg von Legacy in die CloudApplikationsmodernisierung: Der Weg von Legacy in die Cloud
Applikationsmodernisierung: Der Weg von Legacy in die Cloud
Aarno Aukia
 
Domain-Driven Design in der Praxis
Domain-Driven Design in der PraxisDomain-Driven Design in der Praxis
Domain-Driven Design in der Praxis
Michael Mirold
 
Microservices mit Rust
Microservices mit RustMicroservices mit Rust
Microservices mit Rust
Jens Siebert
 
Cloud Connectivity - Herausforderungen und Loesungen
Cloud Connectivity - Herausforderungen und LoesungenCloud Connectivity - Herausforderungen und Loesungen
Cloud Connectivity - Herausforderungen und Loesungen
Daniel Steiger
 
Architektur und Automation als Enabler für DevOps
Architektur und Automation als Enabler für DevOpsArchitektur und Automation als Enabler für DevOps
Architektur und Automation als Enabler für DevOps
matfsw
 
Per Anhalter durch den Cloud Native Stack. #SEACONHH
Per Anhalter durch den Cloud Native Stack. #SEACONHHPer Anhalter durch den Cloud Native Stack. #SEACONHH
Per Anhalter durch den Cloud Native Stack. #SEACONHH
Mario-Leander Reimer
 
Enterprise Cloud Native ist das neue Normal
Enterprise Cloud Native ist das neue NormalEnterprise Cloud Native ist das neue Normal
Enterprise Cloud Native ist das neue Normal
QAware GmbH
 
Schlanke Webarchitekturen nicht nur mit JSF 2 und CDI
Schlanke Webarchitekturen nicht nur mit JSF 2 und CDISchlanke Webarchitekturen nicht nur mit JSF 2 und CDI
Schlanke Webarchitekturen nicht nur mit JSF 2 und CDI
adesso AG
 
Basta 2016 - Test- und Releaseumgebungen in der Cloud
Basta 2016 - Test- und Releaseumgebungen in der CloudBasta 2016 - Test- und Releaseumgebungen in der Cloud
Basta 2016 - Test- und Releaseumgebungen in der Cloud
Marc Müller
 
Migration von Aftersales Systemen auf eine Cloud Plattform
Migration von Aftersales Systemen auf eine Cloud PlattformMigration von Aftersales Systemen auf eine Cloud Plattform
Migration von Aftersales Systemen auf eine Cloud Plattform
QAware GmbH
 

Ähnlich wie Cloud Native und Java EE: Freund oder Feind? (20)

Steinzeit war gestern! Wege der cloud-nativen Evolution
Steinzeit war gestern! Wege der cloud-nativen EvolutionSteinzeit war gestern! Wege der cloud-nativen Evolution
Steinzeit war gestern! Wege der cloud-nativen Evolution
 
Steinzeit war gestern! Wege der Cloud-nativen Evolution.
Steinzeit war gestern! Wege der Cloud-nativen Evolution.Steinzeit war gestern! Wege der Cloud-nativen Evolution.
Steinzeit war gestern! Wege der Cloud-nativen Evolution.
 
A Hitchhiker's Guide to the Cloud Native Stack
A Hitchhiker's Guide to the Cloud Native StackA Hitchhiker's Guide to the Cloud Native Stack
A Hitchhiker's Guide to the Cloud Native Stack
 
A Hitchhiker’s Guide to the Cloud Native Stack. #ContainerConf
A Hitchhiker’s Guide to the Cloud Native Stack. #ContainerConfA Hitchhiker’s Guide to the Cloud Native Stack. #ContainerConf
A Hitchhiker’s Guide to the Cloud Native Stack. #ContainerConf
 
Steinzeit war gestern! Wege der Cloud-nativen Evolution.
Steinzeit war gestern! Wege der Cloud-nativen Evolution.Steinzeit war gestern! Wege der Cloud-nativen Evolution.
Steinzeit war gestern! Wege der Cloud-nativen Evolution.
 
Enterprise Cloud Native ist das neue Normal
Enterprise Cloud Native ist das neue NormalEnterprise Cloud Native ist das neue Normal
Enterprise Cloud Native ist das neue Normal
 
Fische im Rechenzentrum – Was genau ist eigentlich dieses Redfish und wozu br...
Fische im Rechenzentrum – Was genau ist eigentlich dieses Redfish und wozu br...Fische im Rechenzentrum – Was genau ist eigentlich dieses Redfish und wozu br...
Fische im Rechenzentrum – Was genau ist eigentlich dieses Redfish und wozu br...
 
Dataservices - Data Processing mit Microservices
Dataservices - Data Processing mit MicroservicesDataservices - Data Processing mit Microservices
Dataservices - Data Processing mit Microservices
 
Kontinuierliches (Nicht)-Funktionales Testen von Microservices auf K8s
Kontinuierliches (Nicht)-Funktionales Testen von Microservices auf K8sKontinuierliches (Nicht)-Funktionales Testen von Microservices auf K8s
Kontinuierliches (Nicht)-Funktionales Testen von Microservices auf K8s
 
Cloud Native Migration: Wie IT-Landschaften ihren Weg auf eine Cloud-Native-P...
Cloud Native Migration: Wie IT-Landschaften ihren Weg auf eine Cloud-Native-P...Cloud Native Migration: Wie IT-Landschaften ihren Weg auf eine Cloud-Native-P...
Cloud Native Migration: Wie IT-Landschaften ihren Weg auf eine Cloud-Native-P...
 
Applikationsmodernisierung: Der Weg von Legacy in die Cloud
Applikationsmodernisierung: Der Weg von Legacy in die CloudApplikationsmodernisierung: Der Weg von Legacy in die Cloud
Applikationsmodernisierung: Der Weg von Legacy in die Cloud
 
Domain-Driven Design in der Praxis
Domain-Driven Design in der PraxisDomain-Driven Design in der Praxis
Domain-Driven Design in der Praxis
 
Microservices mit Rust
Microservices mit RustMicroservices mit Rust
Microservices mit Rust
 
Cloud Connectivity - Herausforderungen und Loesungen
Cloud Connectivity - Herausforderungen und LoesungenCloud Connectivity - Herausforderungen und Loesungen
Cloud Connectivity - Herausforderungen und Loesungen
 
Architektur und Automation als Enabler für DevOps
Architektur und Automation als Enabler für DevOpsArchitektur und Automation als Enabler für DevOps
Architektur und Automation als Enabler für DevOps
 
Per Anhalter durch den Cloud Native Stack. #SEACONHH
Per Anhalter durch den Cloud Native Stack. #SEACONHHPer Anhalter durch den Cloud Native Stack. #SEACONHH
Per Anhalter durch den Cloud Native Stack. #SEACONHH
 
Enterprise Cloud Native ist das neue Normal
Enterprise Cloud Native ist das neue NormalEnterprise Cloud Native ist das neue Normal
Enterprise Cloud Native ist das neue Normal
 
Schlanke Webarchitekturen nicht nur mit JSF 2 und CDI
Schlanke Webarchitekturen nicht nur mit JSF 2 und CDISchlanke Webarchitekturen nicht nur mit JSF 2 und CDI
Schlanke Webarchitekturen nicht nur mit JSF 2 und CDI
 
Basta 2016 - Test- und Releaseumgebungen in der Cloud
Basta 2016 - Test- und Releaseumgebungen in der CloudBasta 2016 - Test- und Releaseumgebungen in der Cloud
Basta 2016 - Test- und Releaseumgebungen in der Cloud
 
Migration von Aftersales Systemen auf eine Cloud Plattform
Migration von Aftersales Systemen auf eine Cloud PlattformMigration von Aftersales Systemen auf eine Cloud Plattform
Migration von Aftersales Systemen auf eine Cloud Plattform
 

Mehr von Josef Adersberger

Into the cloud, you better fly by sight
Into the cloud, you better fly by sightInto the cloud, you better fly by sight
Into the cloud, you better fly by sight
Josef Adersberger
 
Serverless containers … with source-to-image
Serverless containers  … with source-to-imageServerless containers  … with source-to-image
Serverless containers … with source-to-image
Josef Adersberger
 
The need for speed – transforming insurance into a cloud-native industry
The need for speed – transforming insurance into a cloud-native industryThe need for speed – transforming insurance into a cloud-native industry
The need for speed – transforming insurance into a cloud-native industry
Josef Adersberger
 
The good, the bad, and the ugly of migrating hundreds of legacy applications ...
The good, the bad, and the ugly of migrating hundreds of legacy applications ...The good, the bad, and the ugly of migrating hundreds of legacy applications ...
The good, the bad, and the ugly of migrating hundreds of legacy applications ...
Josef Adersberger
 
Patterns and Pains of Migrating Legacy Applications to Kubernetes
Patterns and Pains of Migrating Legacy Applications to KubernetesPatterns and Pains of Migrating Legacy Applications to Kubernetes
Patterns and Pains of Migrating Legacy Applications to Kubernetes
Josef Adersberger
 
Istio By Example (extended version)
Istio By Example (extended version)Istio By Example (extended version)
Istio By Example (extended version)
Josef Adersberger
 
Docker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-PatternsDocker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-Patterns
Josef Adersberger
 
The Good, the Bad and the Ugly of Migrating Hundreds of Legacy Applications ...
 The Good, the Bad and the Ugly of Migrating Hundreds of Legacy Applications ... The Good, the Bad and the Ugly of Migrating Hundreds of Legacy Applications ...
The Good, the Bad and the Ugly of Migrating Hundreds of Legacy Applications ...
Josef Adersberger
 
Dataservices - Processing Big Data The Microservice Way
Dataservices - Processing Big Data The Microservice WayDataservices - Processing Big Data The Microservice Way
Dataservices - Processing Big Data The Microservice Way
Josef Adersberger
 
Time Series Processing with Solr and Spark
Time Series Processing with Solr and SparkTime Series Processing with Solr and Spark
Time Series Processing with Solr and Spark
Josef Adersberger
 
JEE on DC/OS
JEE on DC/OSJEE on DC/OS
JEE on DC/OS
Josef Adersberger
 
Time Series Processing with Apache Spark
Time Series Processing with Apache SparkTime Series Processing with Apache Spark
Time Series Processing with Apache Spark
Josef Adersberger
 
Big Data Landscape 2016
Big Data Landscape 2016Big Data Landscape 2016
Big Data Landscape 2016
Josef Adersberger
 
Clickstream Analysis with Spark
Clickstream Analysis with Spark Clickstream Analysis with Spark
Clickstream Analysis with Spark
Josef Adersberger
 
Software-Sanierung: Wie man kranke Systeme wieder gesund macht.
Software-Sanierung: Wie man kranke Systeme wieder gesund macht.Software-Sanierung: Wie man kranke Systeme wieder gesund macht.
Software-Sanierung: Wie man kranke Systeme wieder gesund macht.
Josef Adersberger
 

Mehr von Josef Adersberger (15)

Into the cloud, you better fly by sight
Into the cloud, you better fly by sightInto the cloud, you better fly by sight
Into the cloud, you better fly by sight
 
Serverless containers … with source-to-image
Serverless containers  … with source-to-imageServerless containers  … with source-to-image
Serverless containers … with source-to-image
 
The need for speed – transforming insurance into a cloud-native industry
The need for speed – transforming insurance into a cloud-native industryThe need for speed – transforming insurance into a cloud-native industry
The need for speed – transforming insurance into a cloud-native industry
 
The good, the bad, and the ugly of migrating hundreds of legacy applications ...
The good, the bad, and the ugly of migrating hundreds of legacy applications ...The good, the bad, and the ugly of migrating hundreds of legacy applications ...
The good, the bad, and the ugly of migrating hundreds of legacy applications ...
 
Patterns and Pains of Migrating Legacy Applications to Kubernetes
Patterns and Pains of Migrating Legacy Applications to KubernetesPatterns and Pains of Migrating Legacy Applications to Kubernetes
Patterns and Pains of Migrating Legacy Applications to Kubernetes
 
Istio By Example (extended version)
Istio By Example (extended version)Istio By Example (extended version)
Istio By Example (extended version)
 
Docker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-PatternsDocker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-Patterns
 
The Good, the Bad and the Ugly of Migrating Hundreds of Legacy Applications ...
 The Good, the Bad and the Ugly of Migrating Hundreds of Legacy Applications ... The Good, the Bad and the Ugly of Migrating Hundreds of Legacy Applications ...
The Good, the Bad and the Ugly of Migrating Hundreds of Legacy Applications ...
 
Dataservices - Processing Big Data The Microservice Way
Dataservices - Processing Big Data The Microservice WayDataservices - Processing Big Data The Microservice Way
Dataservices - Processing Big Data The Microservice Way
 
Time Series Processing with Solr and Spark
Time Series Processing with Solr and SparkTime Series Processing with Solr and Spark
Time Series Processing with Solr and Spark
 
JEE on DC/OS
JEE on DC/OSJEE on DC/OS
JEE on DC/OS
 
Time Series Processing with Apache Spark
Time Series Processing with Apache SparkTime Series Processing with Apache Spark
Time Series Processing with Apache Spark
 
Big Data Landscape 2016
Big Data Landscape 2016Big Data Landscape 2016
Big Data Landscape 2016
 
Clickstream Analysis with Spark
Clickstream Analysis with Spark Clickstream Analysis with Spark
Clickstream Analysis with Spark
 
Software-Sanierung: Wie man kranke Systeme wieder gesund macht.
Software-Sanierung: Wie man kranke Systeme wieder gesund macht.Software-Sanierung: Wie man kranke Systeme wieder gesund macht.
Software-Sanierung: Wie man kranke Systeme wieder gesund macht.
 

Cloud Native und Java EE: Freund oder Feind?

  • 1. CLOUD NATIVE & JEE FREUND ODER FEIND? Josef Adersberger ( @adersberger)
  • 2. ★ Design for Distribution: Container, Microservices, API-getriebene Entwicklung ★ Design for Performance: Responsive, nebenläufig, ressourcenschonend ★ Design for Automation: Dev- und Ops-Aufgaben automatisieren ★ Design for Resiliency: Fehlertolerant und selbst-heilend ★ Design for Elasticity: Dynamisch skalierbar und reaktiv ★ Design for Delivery: Kurze Roundtrips und automatisierte Provisionierung ★ Design for Diagnosability: Cluster-weite Logs, Metriken und Traces 2 Mehr Ordnung: Cloud Native Maturity Model (https://de.slideshare.net/Pivotal/the-cloud-native-journey-58445711) Mehr Lösung: The Twelve-Factor App Methodology (https://12factor.net) Design-Prinzipien für Cloud Native Applications
  • 4. JEE IST AKTUELL WEDER HÄSSLICH NOCH REIN AUF MONOLITHEN AUSGELEGT ▸ Die JEE API ist modular und in vielen Teilen leichtgewichtig
 (unter uns: manchmal fühlt sich Spring schwergewichtiger an) ▸ Neben den klassischen Application Servern sind nun auch JEE Micro Container verfügbar, mit denen JEE-Anwendungen in Microservices geschnitten werden können ▸ Das Wissen ist breit verteilt, wie Enterprise Anwendungen auf Basis JEE entwickelt werden können ▸ Die JEE API ist standardisiert und reif. Die Implementierungen sind “battle proven”. ▸ … aber leider werden auch in JEE 8 die Design-Prinzipien von Cloud Native Applications noch zu wenig berücksichtigt. Mit Hilfe von Open-Source- Bausteinen gelingt dies aber trotzdem.
  • 7. WIR NEIGEN DAZU, JEE-ANWENDUNGEN IN SCHWERGEWICHTIGEN APPSERVERN ALS AUSFÜHRUNGSMONOLITHEN LAUFEN ZU LASSEN DESIGN CODE RUN startup-cluster.sh JEE Impl. JEE App Server
  • 8. JEE MICRO CONTAINER ERMÖGLICHEN JEE AUSFÜHRUNGSKOMPONENTEN (MICROSERVICES) IN EINER MAßGESCHNEIDERTEN AUSFÜHRUNGSUMGEBUNG DESIGN CODE RUN main() JEE impl. parts
  • 9. EINE CLOUD AN JEE MICROSERVICES! MISSION ERFOLGREICH? image: https://www.dreamstime.com
  • 10. eine Cloud ist nicht nichts
  • 11. CLOUD NATIVE STACK JEE MICROSERVICES
  • 12. CLUSTER VIRTUALIZATION (computing, network, storage, memory) CLUSTER RESOURCE MANAGER CLUSTER ORCHESTRATOR APPLICATIONS CONTAINER CLUSTER RESOURCES MICROSERVICE PLATFORM
 API Gateway Micro Container Configuration & Coordination Diagnosability &
 Monitoring Infrastructure-as-a-Service Bare Metal Local Host Service
 Client Service Discovery DevOps Interface •deploy •rollback •scale •configure Diagnose Interface •analyze logs •analyze metrics •analyze traces Edge Interface •request service •authenticate
  • 13. CLUSTER VIRTUALIZATION (computing, network, storage, memory) CLUSTER RESOURCE MANAGER CLUSTER ORCHESTRATOR APPLICATIONS CONTAINER CLUSTER RESOURCES MICROSERVICE PLATFORM
 API Gateway Micro Container Configuration & Coordination Diagnosability &
 Monitoring Infrastructure-as-a-Service Bare Metal Local Host Service
 Client Service Discovery DevOps Interface •deploy •rollback •scale •configure Diagnose Interface •analyze logs •analyze metrics •analyze traces Edge Interface •request service •authenticate Wie können den Containern die passenden Ressourcen zugewiesen werden? Wie entkoppelt man von physischer Hardware? Wie führt man containerisierte Anwendungen im Cluster aus? Wie entdeckt man Laufzeitanomalien und ihre Ursachen? Wie ruft man resilient und responsive andere Microservices auf? Wie führt man einen Microservice aus? Wie erzeugt man cluster-weiten Konsens zu Konfigurationswerten
 etc. Wie exponiert man Services in das Internet? Wie verwaltet man zentral die verfügbaren Services und Endpunkte?
  • 15. CLUSTER VIRTUALIZATION (computing, network, storage, memory) CLUSTER RESOURCE MANAGER CLUSTER ORCHESTRATOR APPLICATIONS CONTAINER CLUSTER RESOURCES MICROSERVICE PLATFORM
 API Gateway Micro Container Configuration & Coordination Diagnosability &
 Monitoring Infrastructure-as-a-Service Bare Metal Local Host Service
 Client Service Discovery DevOps Interface Diagnose InterfaceEdge Interface
  • 16. DER ZWITSCHER CLOUD NATIVE JEE SHOWCASE ZWITSCHER-APP-HISTORY ZWITSCHER-APP-WIKIPEDIAZWITSCHER-APP-CHUCK ZWITSCHER-APP-BOARD Keyword Resultat + Keyword-Historie random joke
 (weil jeder Chuck Norris Witz auf jedes Keyword matched) JDBC Open API ZWITSCHER-APP-CHUCK fallback https://github.com/adersberger/cloud-native-zwitscher-jee
  • 19. DAS JEE MICRO CONTAINER ÖKOSYSTEM http://wildfly-swarm.io https://ee.kumuluz.com http://microprofile.io (to come) http://tomee.apache.org http://www.payara.fish/payara_micro EMBEDDED implements (unstable)
  • 20. JEE MICRO CONTAINER IM VERGLEICH Payara Micro Wildfly Swarm TomEE kumuluzEE Servlets et al. x x x x WebSockets x x x JSF x x x JAX-RS x x x (TomEE+) x JAX-WS x x (TomEE+) EJB *2 x x x CDI x x x x JTA x x x JCA x x (TomEE+) JMS x x (TomEE+) JPA x x x x Bean Validation x x x x JBatch x x Concurrency x x JCache x x JEE Version JEE 7 Web Profile JEE 7 JEE 6, JEE 7 teilw.*1 JEE 7 teilw. Packetierung WAR + JAR JAR JAR classes + JARs Startup-Dauer 4s 4s 2s 1s Referenz-Größe 57MB 83 MB 44 MB 15 MB *1) http://tomee.apache.org/javaee7-status.html *2) http://stackoverflow.com/questions/13487987/where-to-use-ejb-3-1-and-cdi
  • 21. @Path(“/joke") @RequestScoped
 public class ChuckJokeResource {
 @Inject
 private IcndbIntegration icndb;
 @GET
 @Produces("application/json")
 public Response getJoke() {
 Map<String, String> json = new HashMap<>();
 json.put("message", icndb.getRandomJoke());
 return Response.ok(json).build();
 }
 } @ApplicationPath("/chuck")
 public class ChuckJokeApplication extends ResourceConfig {
 public ChuckJokeApplication() {
 super(); register(ChuckJokeResource.class);
 }
 } JAX-RS MIT CDI bean-discovery-mode="all"
  • 22. public class Main {
 
 /**
 * Starts the microservice container.
 *
 * Requires environment variable "PORT" according
 * on what port to listen.
 *
 * @param args no arguments evaluated
 */
 public static void main(String[] args) {
 com.kumuluz.ee.EeApplication.main(args);
 }
 } JEE MICRO CONTAINER STARTUP
  • 23. SERVICE CLIENTSERVICE DISCOVERY LOAD BALANCING REQUEST MONITORING CIRCUIT BREAKING
  • 24. SERVICE CLIENT MIT JERSEY, RXJAVA UND HYSTRIX •Circuit Breaker (Resiliency) •Request Monitoring •JAX-RS 2.0 REST Client•Parallele und asynchrone
 Ausführung 
 (Responsive)
  • 25. SERVICE CLIENT MIT JERSEY, RXJAVA AND HYSTRIX @RequestScoped
 public class IcndbIntegration implements IChuckNorrisJokes {
 
 @Override public String getRandomJoke() {
 IcndbIntegrationCommand cmd = new IcndbIntegrationCommand();
 return cmd.observe().toBlocking().toFuture().get();
 }
 
 private class IcndbIntegrationCommand extends HystrixObservableCommand<String> {
 
 IcndbIntegrationCommand() {
 super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("zwitscher"))
 .andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
 .withExecutionTimeoutInMilliseconds(3000)));
 }
 
 @Override protected Observable<String> construct() {
 return RxObservable.newClient()
 .target("http://api.icndb.com").path("jokes/random").request(MediaType.APPLICATION_JSON_TYPE)
 .rx().get()
 .map(response -> {
 Map<String, Map<String, String>> json = response.readEntity(Map.class);
 return json.get("value").get("joke");
 });
 }
 }
 } •Asnc bis zum Client mit dem Async-Support ab Servlet API 3 •Mehr Nebenläufigkeit ein Y-Stück Observable
  • 26. FALLBACK WITZE @RequestScoped
 public class IcndbIntegration implements IChuckNorrisJokes { @Inject @Named("chucknorrisjoke-chucknorrisio")
 private IChuckNorrisJokes fallback; @Override public Observable<String> getRandomJokeObservable() { 
 return new IcndbIntegrationCommand().observe(); }
 
 //…
 
 private class IcndbIntegrationCommand extends HystrixObservableCommand<String> {
 
 //…
 
 @Override
 protected Observable<String> resumeWithFallback() {
 return fallback.getRandomJokeObservable();
 }
 }
 }
  • 28. DAS MAGISCHE DREIECK DER DIAGNOSTIZIERBARKEIT Metriken Logs Traces Cluster-wide
 Diagnosis
  • 30. INSTRUMENTIERUNG @ApplicationPath("/chuck")
 public class ChuckJokeApplication extends ResourceConfig {
 public ChuckJokeApplication() {
 super();
 //Instrument application with metrics
 MetricRegistry METRIC_REGISTRY = MetricsProvider.getMetricRegistryInstance();
 register(new InstrumentedResourceMethodApplicationListener(METRIC_REGISTRY));
 HystrixPlugins.getInstance().registerMetricsPublisher(
 new HystrixCodaHaleMetricsPublisher(METRIC_REGISTRY));
 //Register Prometheus metric exporter
 CollectorRegistry.defaultRegistry.register(new DropwizardExports(METRIC_REGISTRY));
 }
 } Die eingehenden REST-Aufrufe instrumentieren Die ausgehenden REST-Aufrufe instrumentieren Alle Metriken für Prometheus bereitstellen Die MetricRegistry holen (Singleton)
  • 33. SERVICE DISCOVERYSERVICE REGISTRATION SERVICE LOOKUP SERVICE HEALTH CHECKING & API GATEWAYAPI EXPOSITION & REQUEST ROUTING AUTHENTICATION & AUTORISATION LOAD BALANCING & SHEDDING RATE LIMITING REQUEST MONITORING & AUDITING
  • 34. DAS BIG PICTURE MICRO SERVICE SERVICE DISCOVERY Services
 registrieren Interne 
 Services
 registrieren &
 auflösen Web Requests Routen ermitteln
 (per Polling) API GATEWAY Health
 Checks java.security.Security.setProperty("networkaddress.cache.ttl", "3" ); Web Request
  • 35. SERVICE REGISTRATION IN EINEM JEE MICROSERVICE @ApplicationPath("/chuck")
 public class ChuckJokeApplication extends ResourceConfig {
 
 @Inject
 public ChuckJokeApplication(
 @ConsulFabio IServiceDiscovery serviceDiscovery) {
 super();
 //Register service
 serviceDiscovery.registerService( "zwitscher-chuck", "/chuck/joke");
 }
 } Service-Name URL-Pfad zum Service-Endpunkt
  • 36. SERVICE REGISTRATION: HEAVY LIFTING /**
 * Registeres a service
 *
 * see https://github.com/eBay/fabio/wiki/Service-Configuration
 */
 public synchronized void registerService(String serviceName, String servicePath) {
 
 String applicationHost = getOutboundHost();
 int applicationPort = getOutboundPort();
 HostAndPort consulEndpoint = getConsulHostAndPort();
 logger.info("Will register service on host {} and port {} at consul endpoint {}",
 applicationHost, applicationPort, consulEndpoint.toString());
 
 //generate unique serviceId
 String serviceId = serviceName + "-" + applicationHost + ":" + applicationPort;
 String fabioServiceTag = "urlprefix-" + servicePath;
 
 //point healthcheck URL to dropwizard metrics healthcheck servlet
 URL serviceUrl = UrlBuilder.empty()
 .withScheme("http")
 .withHost(applicationHost)
 .withPort(applicationPort)
 .withPath("/metrics/ping").toUrl();
 
 // Service bei Consul registrieren inklusive einem Health-Check auf die URL des REST-Endpunkts.
 logger.info("Registering service with ID {} and NAME {} with healthcheck URL {} and inbound ROUTE {}",
 serviceId, serviceName, serviceUrl, fabioServiceTag);
 
 //use consul API to register service
 ConsulClient client = new ConsulClient(consulEndpoint.toString());
 NewService service = new NewService();
 service.setId(serviceId);
 service.setName(serviceName);
 service.setPort(applicationPort);
 service.setAddress(applicationHost);
 List<String> tags = new ArrayList<>();
 tags.add(fabioServiceTag);
 service.setTags(tags);
 //register health check
 NewService.Check check = new NewService.Check();
 check.setHttp(serviceUrl.toString());
 check.setInterval(ConsulFabioServiceDiscovery.HEALTHCHECK_INTERVAL + "s");
 service.setCheck(check);
 client.agentServiceRegister(service);
 }
 
 public static String getOutboundHost() {
 String hostName = System.getenv(HOSTNAME_ENVVAR);
 String host = System.getenv(HOST_ENVVAR);
 if (hostName == null && host == null) return DEFAULT_HOST;
 else if (host != null) return host;
 else {
 File etcHosts = new File("/etc/hosts");
 List<String> lines;
 try {
 lines = Files.readLines(etcHosts, Charset.defaultCharset());
 } catch (IOException e) {
 return DEFAULT_HOST;
 }
 for (String line: lines){
 if (!line.trim().startsWith("#") && !line.trim().isEmpty()) {
 String[] etcEntry = line.split("s+");
 if (etcEntry[1].equals(hostName)) return etcEntry[0];
 }
 }
 return DEFAULT_HOST;
 }
 }
 
 public static int getOutboundPort() {
 String portEnv = System.getenv(PORT_ENVVAR);
 if (portEnv == null) return DEFAULT_PORT;
 return Integer.valueOf(portEnv);
 }
 
 public static HostAndPort getConsulHostAndPort() {
 String consulEnv = System.getenv(CONSUL_ENVVAR);
 if (consulEnv == null) return HostAndPort.fromString(CONSUL_DEFAULT_HOSTANDPORT);
 else return HostAndPort.fromString(consulEnv);
 } @ConsulFabio
 @ApplicationScoped
 public class ConsulFabioServiceDiscovery implements IServiceDiscovery { den Host-Namen und Port ermitteln, den Consul sieht den Health-Check Endpunkt ermitteln (MetricsServlet) Metadaten für Fabio erzeugen Service bei Consul registrieren
 (ebenso wie Diagnose- und Doku-Endpunkte)
  • 37. ET VOILA: CONSUL MIT 3 REGISTRIERTEN SERVICE-INSTANZEN
  • 38. ET VOILA: FABIO DIREKT AUS CONSUL BEDIENT
  • 40. DIE SICH SELBST AUSLIEFERNDE SOFTWARE RUNNING
 TESTED
 SOFTWARE
 INCREMENT EVERYTHING AS CODE: •die Anwendung •die Tests •die Infrastruktur •der CD-Workflow{
  • 41. WICHTIG SIND KURZE ROUNDTRIP-ZYKLEN In-Process Local Cluster Remote Cluster •längere Roundtrips •aber: realistischer Vollständiges Deployment: Einzelne Services: https://github.com/qaware/gradle-cloud-deployer
  • 42. MARATHON APP DEFINITION {
 "id": "/zwitscher",
 "groups": [
 {
 "id": "/zwitscher/infrastructure",
 "apps": [
 {
 "id": "consul",
 "cpus": 1,
 "mem": 256,
 "disk": 0,
 "instances": 1,
 "cmd": "/bin/consul agent -server -ui -advertise=$HOST -config-dir=/config -data-dir=/tmp/consul -bootstrap-expect=1 -node=consul-server -client=0.0.0.0",
 "container": {
 "docker": {
 "image": "gliderlabs/consul-server:0.6",
 "forcePullImage": true,
 "privileged": false,
 "network": "HOST",
 "portDefinitions": [
 { "port": 8300, "protocol": "tcp", "name": "server-rpc" },
 { "port": 8301, "protocol": "tcp", "name": "serf-lan" },
 { "port": 8302, "protocol": "tcp", "name": "serf-wan" },
 { "port": 8400, "protocol": "tcp", "name": "cli-rpc" },
 { "port": 8500, "protocol": "tcp", "name": "http-api" },
 { "port": 8600, "protocol": "udp", "name": "dns" }
 ],
 "requirePorts" : true
 }
 },
 "env": {
 "GOMAXPROCS": "10"
 },
 "healthChecks": [
 {
 "protocol": "HTTP",
 "port": 8500,
 "path": "/v1/status/leader",
 "intervalSeconds": 10,
 "timeoutSeconds": 10,
 "maxConsecutiveFailures": 3
 }
 ]
 },
 {
 "id": "fabio",
 "cpus": 1,
 "mem": 256,
 "disk": 0,
 "instances": 1,
 "env": {
 "registry_consul_addr": "consul.infrastructure.zwitscher.marathon.mesos:8500"
 },
 "container": {
 "docker": {
 "image": "magiconair/fabio:latest",
 "forcePullImage": true,
 "privileged": false,
 "network": "HOST",
 "portDefinitions": [
 { "port": 9998, "protocol": "tcp", "name": "web-ui" },
 { "port": 9999, "protocol": "tcp", "name": "proxy-port" }
 ],
 "requirePorts" : true
 }
 },
 "acceptedResourceRoles":["slave_public"],
 "healthChecks": [
 {
 "protocol": "HTTP",
 "port": 9998,
 "path": "/health",
 "intervalSeconds": 10,
 "timeoutSeconds": 10,
 "maxConsecutiveFailures": 3
 }
 ]
 }
 ]
 },
 {
 "id": "/zwitscher/services",
 "apps": [
 {
 "id": "zwitscher-chuck",
 "cpus": 1,
 "mem": 256,
 "disk": 0,
 "instances": 1,
 "container": {
 "docker": {
 "image": "adersberger/zwitscher-app-chuck:1.0.0-SNAPSHOT",
 "forcePullImage": true,
 "privileged": false,
 "network": "HOST",
 "portDefinitions": [
 { "port": 12340, "protocol": "tcp", "name": "rest-api" }
 ],
 "requirePorts" : true
 }
 },
 "env": {
 "PORT": "12340",
 "CONSUL": "consul.infrastructure.zwitscher.marathon.mesos:8500",
 "CONFIG_ENV" : "zwitscher"
 },
 "args": [
 "-Xmx256m"
 ],
 "healthChecks": [
 {
 "protocol": "HTTP",
 "port": 12340,
 "path": "/metrics/ping",
 "intervalSeconds": 10,
 "timeoutSeconds": 10,
 "maxConsecutiveFailures": 3
 }
 ],
 "dependencies": [
 "/zwitscher/infrastructure/consul"
 ]
 }
 ]
 }
 ]
 } marathon-appgroup.json /zwitscher /infrastructure /consul /fabio /service /zwitscher-chuck dependency "healthChecks": [
 {
 "protocol": “HTTP", "port": 9998, "path": "/health",
 "intervalSeconds": 10, "timeoutSeconds": 10, "maxConsecutiveFailures": 3
 }
 ] Health Checks: "network": "HOST",
 "ports": [9998, 9999],
 "requirePorts" : true Networking: "acceptedResourceRoles":["slave_public"] API Gateway auf den Public Slaves: "env": {
 "PORT": "12340",
 "CONSUL": "consul.infrastructure.zwitscher.marathon.mesos:8500"
 },
 "args": ["-Xmx256m"] Konfiguration: "container": { "docker": {
 "image": "adersberger/zwitscher-app-chuck:1.0.0-SNAPSHOT",
 "forcePullImage": true Immer das aktuelle Docker Image bekommen: "dependencies": [ "/zwitscher/infrastructure/consul"] Startup-Abhängigkeiten (eher zu vermeiden):
  • 44. FAZIT ▸ Cloud Native JEE Anwendungen entwickeln ist möglich und macht Spaß ▸ Die JEE API ist per se noch nicht Cloud Native und wird dies auf absehbare Zeit auch nicht sein, kann aber entsprechend ergänzt werden, z.B. mit unserem JCloudEE Mini-Framework:
 
 
 
 
 
 ▸ Kurze Roundtrip-Zeiten sind essenziell für die produktive Entwicklung von Anwendungen. Bei Cloud Native Applications ist dabei die volle Portabilität von lokaler Ausführung bis auf ein Cluster in der Cloud essenziell.
  • 45. 45 CompletableFuture<SoftwareArchitektIn> ich = CompletableFuture.supplyAsync(() -> erfindergeist() .handwerksstolz() ); CompletableFuture<Projekthaus> qaware = CompletableFuture.supplyAsync(() -> professionalität() .lässigkeit() ); Erfolg start = qaware.thenCombine(ich, (i, q) -> i.sendeBewerbung(q)) .join(); Weiter Details unter http://www.qaware.de/karriere/#jobs