In a hyper-connected world the concept "Real Time" is used more and more every day. With the traditional Grails architecture it's difficult to achieve this, so we need to use a different approach. The answer is to use message driven architectures that will allow us to achieve the goal and also build fast, decoupled and easy to test applications.
In this talk you'll see a different type of architecture that will help you to serve content in real-time to a lot of clients in a fast and easy to scale way. You'll see some examples of how to achieve this using Spring Integration and integrate with external systems like websockets and XMPP in an easy and decoupled way.
8. Event Drive Architectures
▷ Fire & Forget
▷ Decouple producer and consumer
▷ Immediate action in the consumer
▷ Real-time
9. Traditional architecture
POST /purchase
POST /purchase
- Receive request 5 ms
- Data validation 20 ms
- Save 40 ms
- PDF generation 200 ms
- Send email 80 ms
- Render response 50 ms
Total: 395 ms
11. Event driven architecture
POST /purchase
POST /purchase
- Receive request 5 ms No
- Data validation 20 ms No
- Save 40 ms No
- PDF generation 200 ms Yes
- Send email 80 ms Yes
- Render response 50 ms No
Total: 115 ms ~ 70% better
Can anyone else do it?
12. Event driven architecture
POST /purchase
PDF
Generation
POST /purchase
- Receive request 5 ms
- Data validation 20 ms
- Save 40 ms
- Render response 50 ms
Total: 115 ms
Send email
14. Goals
▷ Loosely coupled architecture, easy to extend
and evolve.
▷ Build high performance and scalable systems
▷ Keep the business logic where “it belongs”
15. What about Grails?
▷ Platform core plugin
▷ Events plugin
▷ Executor plugin
▷ Grails 2.3+ async
16. Synchronous example
// Send confirmation email
def user = new User(params).save()
emailService.sendRegistrationMail(user)
render view:'registerOk'
17. Synchronous example
// Send confirmation email
def user = new User(params).save()
emailService.sendRegistrationMail(user)
render view:'registerOk'
class EmailService {
public void sendRegistrationMail(User user) {
sendMail {
to user.email
subject "Confirm your account"
html g.render(template: "userEmailConfirmation")
}
}
}
18. Asynchronous example
// Platform core
def user = new User(params).save()
event 'sendRegistrationMail', user
render view:'registerOk'
19. Asynchronous example
// Platform core
def user = new User(params).save()
event 'sendRegistrationMail', user
render view:'registerOk'
class EmailService {
@grails.events.Listener
public void sendRegistrationMail(User user) {
sendMail {
to user.email
subject "Confirm your account"
html g.render(template: "userEmailConfirmation")
}
}
}
20. Asynchronous example
// Executor
def user = new User(params).save()
runAsync {
emailService.sendRegistrationMail(user)
}
render view:'registerOk'
class EmailService {
public void sendRegistrationMail(User user) {
sendMail {
to user.email
subject "Confirm your account"
html g.render(template: "userEmailConfirmation")
}
}
}
22. What if we don't want this?
▷ Extract “dependencies” to configuration
▷ Change application behaviour modifying the
configuration
23. Spring Integration
Use inside Spring the
well-know Enterprise
Integration Patterns
http://www.enterpriseintegrationpatterns.com/
24. Spring Integration
▷ Lightweight messaging mechanism for Spring apps
▷ High level abstraction for messaging
▷ External systems integration declaring adapters
32. Summary
▷ Grails standard architecture fits in most of the
cases
▷ It does not scale to infinite (and beyond!)
▷ Think about the application you are building
▷ Keep the information flow in mind