building a microservice federation with grails
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: [email protected] 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" : "[email protected]"},
{"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?