building a microservice federation with grails

Post on 14-Jan-2017

1.413 Views

Category:

Technology

2 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Building aBuilding aMicroserviceMicroservice

Federation with GrailsFederation with Grails

Grails... microservices...you must be crazy man!

About meAbout me20 years Java

10+ years Spring

6+ years Groovy/Grails

PowerBuilder

C/C++

FORTRAN1st career in aviation/aerospace

twitter: @jackfrosch linkedin: ../in/jackfroschemail: jackfrosch@gmail.com grails.slack.com: @jackfrosch

{ "about-me" :

{ "experience" : [ "20 years Java",

"6+ years Groovy/Grails",

"PowerBuilder, C/C++, FORTRAN"

"Aviation/Aerospace before Software Development"],

"community" : [ "Gateway JUG founder and leader",

"Past DFW GGUG Co-leader",

"Always cookin' up something ..."],

"contacts" : [ {"twitter" : "@jackfrosch"},

{"linkedin" : "../in/jackfrosch"},

{"email" : "jackfrosch@gmail.com"},

{"grails.slack.com":"@jackfrosch"}]

}

}

The Story I'm About to TellThe Story I'm About to TellYou is TrueYou is True

Microservices are coming!Grails plays well in a microservice architectureBuilding a microservice federation with Grails

DemoDemo

Microservices are comingMicroservices are comingFoundational conceptsMicroservice advantagesMicroservice disadvantages

What are microservices?What are microservices?

“ MicroservicesMicroservicesare small,are small,

autonomousautonomousservices thatservices that

work together.work together.

Sam Newman Building Microservices, O'Reilly Media

Small is keySmall is key

Small in functional scope...Small in functional scope...

http://www.whattofix.com/images/ComplexERDExample.gif

Probably not small functional scope...

... not necesarily size... not necesarily size

Smaller is simplerSmaller is simpler

“ Everything shouldEverything shouldbe made as simple asbe made as simple as

possible, but notpossible, but notsimpler*simpler*

* though attributed to Einstein, this simple quote is actually from

Roger Sessions paraphrasing (and simplifying!) a statement by Albert Einstein

Simpler is betterSimpler is better

“ A system that is hard toA system that is hard tounderstand is hard to change.understand is hard to change.

— Eric Evans, Domain-Driven Design

Autonomy is keyAutonomy is key

Development autonomy*Development autonomy*

*Caveat: *Caveat: YouYou can't break can't break mymy stuff stuff

http://www.memes.com/meme/498049

Consumer Driven ContractsConsumer Driven Contracts

http://bit.ly/thoughtworks-consumer-driven-contracts

Testing: How much & what kind?Testing: How much & what kind?

http://famouswonders.com/wp-content/gallery/pyramids-of-egypt/pyramid-of-khafre.jpg

Data AutonomyData Autonomy

http://martinfowler.com/articles/microservices.html

Build/Deploy autonomyBuild/Deploy autonomy

http://www.openmakesoftware.com/images/ReleaseEngineer/CI-CD.png

Scale where the load is...Scale where the load is...

Operational AutonomyOperational Autonomy

https://media.licdn.com/mpr/mpr/p/8/005/083/1a8/257d716.jpg

All this sounds great, but...All this sounds great, but...

...what about our monolith?...what about our monolith?

Identify bounded contexts...Identify bounded contexts...

... and divide along the seams... and divide along the seams

Favor choreography over orchestrationFavor choreography over orchestration

http://kennysilva.net/wp-content/uploads/2010/12/orchestra-conductor.jpg

MonolithMonolith MicroserviceMicroserviceclass Passenger { String accountNo String firstName String lastName Address billingAddress Payment paymentPreference List<Payment> paymentHistory Phone home Phone mobile Phone work BloodType bloodType ...}

What about shared domain?What about shared domain?

// For Trip Managementclass Passenger { String accountNo String firstName String lastName Phone mobile ...}

// For Billingclass Passenger { String accountNo String firstName String lastName Address billingAddress List<Payment> paymentHistory Phone home Phone work ...}

“ The evils of too much coupling between

services are far worse than the problems

caused by code duplication.- Sam Newman, Building Microservices

Microservice FederationMicroservice Federation

LoggingSecurityMetrics and monitoring

First, what's a federation?First, what's a federation?

“ an organization that is made by looselyjoining together smaller organizations

http://www.merriam-webster.com/dictionary/federation

“ the formation of a political unity, with a central government, by a numberof separate states, each of which retains control of its own internal affairs.

http://dictionary.reference.com/browse/federation

In our terms: The formation of an application, with central governance ofcommon infrastructure concerns, by a number of separate microservices,

each of which retains control of its own internal design and implementation.

Real world examplesReal world examples

“ The advancement and diffusion of knowledgeis the only guardian of true liberty.

- James Madison, father of the US ConstitutionKnowledge is power

Logging TipsLogging TipsUse a Correlation IDUse a consistent log message formatUse log aggregation

Logging AggregatorsLogging Aggregators

"ELK Stack"

SecuritySecurityNoneAt the gateway onlyAt every microservice

Security at the gateway onlySecurity at the gateway only

"They're inside the room!" "Yikes!"

"Mmm, you look tasty."

Perimeter security reminds me of the movie, Aliens

Security at every microserviceSecurity at every microservice

Metrics, Monitoring & MoreMetrics, Monitoring & MoreMicroservices need to report metricsResiliency requires monitoring & circuit breakersAutomatic service discoveryGateway / reverse proxyLoad balancing

Spring Boot & Spring Cloud to the rescue!

Spring Boot includes metrics endpointSpring Boot includes metrics endpoint

There are manymetrics out of the box,

but you can createyour own.

http://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-endpoints.html

Spring Boot includes Spring Boot includes manymany endpoints endpoints

http://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-endpoints.html

Spring Cloud provides monitoringSpring Cloud provides monitoring

... and much more... and much more

Service discovery with EurekaService discovery with Eureka

Gateway /Rev Proxy with ZuulGateway /Rev Proxy with Zuul

http://bit.ly/vignette2_wikia_nocookie_net_ghostbusters

Gateway /Rev Proxy with ZuulGateway /Rev Proxy with Zuul

Monitoring & Circuit BreakersMonitoring & Circuit Breakers w/ Hystrixw/ Hystrix

http://martinfowler.com/bliki/CircuitBreaker.html

Microservice ArchitectureMicroservice ArchitectureAdvantagesAdvantages

ScalableAdaptableResilientTestableMore future-proofMore greenfield

Microservice ArchitectureMicroservice ArchitectureDisadvantagesDisadvantages

http://martinfowler.com/bliki/images/microservicePrerequisites/sketch.png

Microservice ArchitectureMicroservice ArchitectureDisadvantagesDisadvantages

Solid domain understandingDevelopment more complicatedMore buildsMore databasesLog aggregation is essentialMetrics, monitoring & more essential

Grails plays wellGrails plays wellGrails full stack developmentGrails RESTGrails plugin architecture

Full stack != monolith

Grails full stack developmentGrails full stack development

Web UI, SQL / NOSQL Database Support, Spring, Hibernate,Security, REST, Java, Groovy...

Create AppCreate App$grails create-app HelloWorld

Hello World app... easy as 1 - 2 - 3Hello World app... easy as 1 - 2 - 3

grails> create-controller demo.Hello

package demo

class HelloController {

def index() { render 'Hello SpringOne2GX 2015!' }}

Full stack CRUD apps are about as easy...

1. Create controller

2. Make it do something

3. See it to believe it!

Create a Domain ClassCreate a Domain Class

Define demo.PersonDefine demo.Person

package demo

class Person { String firstName String lastName String email String twitterHandle

static constraints = { firstName blank:false, maxSize: 32 lastName blank: false, maxSize: 64 email blank: false, maxSize: 128, email:true twitterHandle nullable:true, maxSize:64 }}

Generate Scaffolding...Generate Scaffolding...

.. to bootstrap CRUD app.. to bootstrap CRUD app

After generationAfter generation

Run AppRun Appgrails> run-app

Retrieve Persons ListRetrieve Persons List

Create Person formCreate Person form

Create a Person recordCreate a Person record

Show a Person recordShow a Person record

Retrieve Persons ListRetrieve Persons List

Delete a Person recordDelete a Person record

Test RestTest Rest

$ curl -i -X GET http://localhost:8080/persons

[jfrosch@localhost demo]$ HTTP/1.1 200 OKServer: Apache-Coyote/1.1X-Application-Context: application:developmentContent-Type: text/xml;charset=UTF-8Transfer-Encoding: chunkedDate: Mon, 07 Sep 2015 21:26:16 GMT

<?xml version="1.0" encoding="UTF-8"?><list />

$

Hmm... 200 OK good ... XML bad.

With an IDE...With an IDE...

Besides UI CRUD, what about REST?Besides UI CRUD, what about REST?

package demo

import grails.rest.Resource

@Resource(uri='/persons')class Person { String firstName String lastName String email String twitterHandle

static constraints = { firstName blank:false, maxSize: 32 lastName blank: false, maxSize: 64 email blank: false, maxSize: 128, email:true twitterHandle nullable:true, maxSize:64 }}

grails create-app RestfulCrud

Grails content negotiationGrails content negotiation

$ curl -i -X GET http://localhost:8080/persons.json

HTTP/1.1 200 OKServer: Apache-Coyote/1.1X-Application-Context: application:developmentContent-Type: text/xml;charset=UTF-8Transfer-Encoding: chunkedDate: Mon, 07 Sep 2015 21:26:16 GMT

[]

$

200 OK good ... JSON good.

Grails content negotiationGrails content negotiation

$ curl -i -X GET --header "Accept:application/json" http://localhost:8080/persons

HTTP/1.1 200 OKServer: Apache-Coyote/1.1X-Application-Context: application:developmentContent-Type: text/xml;charset=UTF-8Transfer-Encoding: chunkedDate: Mon, 07 Sep 2015 21:26:16 GMT

[]

$

200 OK good ... JSON good.

Change @Resource to prefer JSONChange @Resource to prefer JSON

package demo

import grails.rest.Resource

@Resource(uri='/persons', formats=['json', 'xml'])class Person { String firstName String lastName String email String twitterHandle

static constraints = { firstName blank:false, maxSize: 32 lastName blank: false, maxSize: 64 email blank: false, maxSize: 128, email:true twitterHandle nullable:true, maxSize:64 }}

Test RestTest Rest

$ curl -i -X GET http://localhost:8080/persons

HTTP/1.1 200 OKServer: Apache-Coyote/1.1X-Application-Context: application:developmentContent-Type: text/xml;charset=UTF-8Transfer-Encoding: chunkedDate: Mon, 07 Sep 2015 21:26:16 GMT

[]

$

200 OK good ... JSON good.

Test RestTest Rest

$ curl -i -X GET http://localhost:8080/persons.xml

HTTP/1.1 200 OKServer: Apache-Coyote/1.1X-Application-Context: application:developmentContent-Type: text/xml;charset=UTF-8Transfer-Encoding: chunkedDate: Mon, 07 Sep 2015 21:26:16 GMT

<?xml version="1.0" encoding="UTF-8"?><list />

$

200 OK good ... XML weird, but you wanted weird

Restfully create a Person...Restfully create a Person...

... yields a 201 created response... yields a 201 created response

Grails REST URI patternsGrails REST URI patterns

What if I want to do more than CRUD?What if I want to do more than CRUD?

package demo

import grails.rest.RestfulController

class PersonController extends RestfulController<Person> { static responseFormats =['json', 'xml']

PersonController() { super(Person) }

def findPersonsWithLastNameLike(String likeness) { respond Person.findByLastNameLike("${likeness}%") }}

class UrlMappings {

static mappings = { "/persons"(resources:'person')

"/persons/search/withLastNameLike/$likeness"(controller: 'person', action: 'findPersonsWithLastNameLike') }}

Building a GrailsBuilding a Grailsmicroservice federationmicroservice federation

Build a Eureka ServerBuild a Eureka Server

Build a Eureka ServerBuild a Eureka Server

Build a Zuul ServerBuild a Zuul Server

/catalog acts as the root of the uri

Build a Zuul ServerBuild a Zuul Server

Zuul MappingsZuul Mappings

Finding Products Using ZuulFinding Products Using Zuul

Finding Product 1 Using ZuulFinding Product 1 Using Zuul

Finding Product 3 Using ZuulFinding Product 3 Using Zuul

This is the default after error in recommendation engine

Hystrix DashboardHystrix Dashboard

Hystrix DashboardHystrix Dashboard

Hystrix DashboardHystrix Dashboard

Hystrix DashboardHystrix Dashboard

Hystrix DashboardHystrix Dashboard

... After killing recommendation engine ...

@HystrixCommand@HystrixCommand

Microservice SetupMicroservice Setup

Microservice SetupMicroservice Setup

SummarySummary

AdaptableScalableResilientMaintainableMonitorableCloud ready

You'd be crazy to adopt amicroservice architecture using

Grails...

unless your applicationneeds to be ...

(even if your company isn't ready for the cloud yet)

ResourcesResourceshttp://projects.spring.io/spring-cloud/

http://cloud.spring.io/spring-cloud-netflix/

http://martinfowler.com/articles/microservices.html

Questions?Questions?

top related