an unexpected solution to microservices ui composition

53
www.autoscout24.com www.autoscout24.com An Unexpected Solution To Microservices UI Composition Munich | 01/12/2016 | Johannes Müller and Arif Wider

Upload: arif-wider

Post on 16-Apr-2017

8.008 views

Category:

Technology


4 download

TRANSCRIPT

Page 1: An Unexpected Solution to Microservices UI Composition

www.autoscout24.com

www.autoscout24.com

An Unexpected Solution To Microservices UI CompositionMunich | 01/12/2016 | Johannes Müller and Arif Wider

Page 2: An Unexpected Solution to Microservices UI Composition

MotivationProject Tatsu

Page 3: An Unexpected Solution to Microservices UI Composition

Project Tatsu: From a .NET-Monolith to AWS-hosted Microservices

3

Page 4: An Unexpected Solution to Microservices UI Composition

Project Tatsu: Goals

4

• Attract talent

• Reduce time to market

• Release new features quickly (for test or production)

• Enable teams to innovate independently

Page 5: An Unexpected Solution to Microservices UI Composition

Autonomous Teams, Loosely Coupled Services

5

Allow for cross-functional teams that are able to independently create, improve, and run their services.

Avoid tight coupling as much as possible!

Page 6: An Unexpected Solution to Microservices UI Composition

Don't Compromise Page Performance

6

• Achieve PageSpeed Insights score of 95+

• Strive for low latency

• Benefit from caching whereever possible

tricky to combine with high team autonomy

Page 7: An Unexpected Solution to Microservices UI Composition

Breaking the MonolithThe API Gateway Pattern

7

Page 8: An Unexpected Solution to Microservices UI Composition

API Gateway Pattern

8

HomeHeader/Footer

Ads

API Gateway

Mobileapps

Page 9: An Unexpected Solution to Microservices UI Composition

API Gateway Pattern - Drawbacks

9

• No independent feature releases possible• Web UI monolith• API monolith

• Danger of adding more and more logic to the API layer

• Duplicated controller logic in the API gateway

Page 10: An Unexpected Solution to Microservices UI Composition

Breaking the Monolith The UI Composition Pattern

10

Page 11: An Unexpected Solution to Microservices UI Composition

UI Composition Pattern

11

HomeAds

Header/Footer

Page 12: An Unexpected Solution to Microservices UI Composition

Challenges of UI Composition

12

• Combine HTML

• Let services deliver their own styles and JavaScript

• HTML and asset versions must be consistent

• Page structure must not break page performance

• Request latency needs to stay low

• Independent and integration testing of UI components

Page 13: An Unexpected Solution to Microservices UI Composition

First AttemptVarnish & ESI

Page 14: An Unexpected Solution to Microservices UI Composition

Varnish & ESI

14

Page 15: An Unexpected Solution to Microservices UI Composition

ESI Include

15

<html> <head> <title>AutoScout24</title> <!-- CSS of page --> <link rel="stylesheet" href="/assets/home/ebacb8194-main.min.css" /> </head> <body> <!-- ESI include of header --> <esi:include src="http://content.as24.com/fragment/header_de_DE" /> Lorem ipsum....

<!-- JavaScript of page --> <script src="/assets/home/66ee72f9-main.min.js"></script> </body></html>

Page 16: An Unexpected Solution to Microservices UI Composition

ESI Include Resolved

16

<html> <head> <title>AutoScout24</title> <!-- CSS of page --> <link rel="stylesheet" href="/assets/home/ebacb8194-main.min.css" /> </head> <body> <!-- CSS of fragment --> <link rel="stylesheet" href="http://content.as24.com/assets/08ffaf28-main.min.css" />

<ul><li>Home</li><li>Search</li><li>Sell</li></ul>

<!-- JavaScript of fragment --> <script src="http://content.as24.com/assets/26ed612f-main.min.js"></script>

Lorem ipsum.... <!-- JavaScript of page --> <script src="/assets/home/66ee72f9-main.min.js"></script> </body></html>

Page 17: An Unexpected Solution to Microservices UI Composition

Multiple ESI Includes

17

<html> <head> <title>AutoScout24</title> <!-- CSS of page --> <link rel="stylesheet" href="/assets/home/ebacb8194-main.min.css" />

<!-- ESI include for header CSS --> <esi:include src="http://content.example.com/fragment/header_styles" /> </head> <body> <!-- ESI include for header --> <esi:include src="http://content.example.com/fragment/header_de_DE" />

Lorem ipsum.... <!-- JavaScript for page --> <script src="/assets/home/66ee72f9-main.min.js"></script>

<!-- ESI include for header JavaScript --> <esi:include src="http://content.example.com/fragment/header_scripts" /> </body></html>

Page 18: An Unexpected Solution to Microservices UI Composition

Multiple ESI Includes Resolved

18

<html> <head> <title>AutoScout24</title> <!-- CSS for page --> <link rel="stylesheet" href="/assets/home/ebacb8194-main.min.css" />

<!-- CSS for header --> <link rel="stylesheet" href="http://content.example.com/assets/08ffaf28-main.css" /> </head> <body> <ul><li>Home</li><li>Search</li><li>Sell</li></ul>

Lorem ipsum.... <!-- JavaScript for page --> <script src="/assets/home/66ee72f9-main.min.js"></script>

<!-- JavaScript for header --> <script src="http://content.example.com/assets/26ed612f-main.js"></script> </body></html>

Page 19: An Unexpected Solution to Microservices UI Composition

Varnish & ESIComposition Issues

19

• Bad page performance because of page structure

• Tries to optimize the page structure led to increased complexity regarding the asset handling

• High burden on the content providing teams

Page 20: An Unexpected Solution to Microservices UI Composition

Varnish & ESIAdditional Issues

20

• Combining assets with ESI adds lots of complexity

• Varnish cannot strong cache assets combined with ESI

• AWS ELB as Varnish backend wasn’t working (multiple short-lived IPs)

Page 21: An Unexpected Solution to Microservices UI Composition

Requirements for a better solution

21

• References to asset URIs need to be included in HTML snippet

• Therefore post-processing of references is required

• Support for combined assets

• Support for inlining CSS/JS

• Support for shared cache between instances

Page 22: An Unexpected Solution to Microservices UI Composition

JigsawHow to solve it

Page 23: An Unexpected Solution to Microservices UI Composition

Jigsaw Components

23

Page 24: An Unexpected Solution to Microservices UI Composition

Request Flow

24

Page 25: An Unexpected Solution to Microservices UI Composition

Request Flow

25

Page 26: An Unexpected Solution to Microservices UI Composition

Request Flow

26

Page 27: An Unexpected Solution to Microservices UI Composition

Request Flow

27

Page 28: An Unexpected Solution to Microservices UI Composition

Request Flow

28

Page 29: An Unexpected Solution to Microservices UI Composition

Pages

29

are publicly accessible

get called from the client

include fragments

could be cacheable

define contracts

are parts of a page

get called from Nginx SSI

could include fragments

should be cacheable

adhere to contracts

Fragments

Page 30: An Unexpected Solution to Microservices UI Composition

SSI Include

30

<html> <head> <title>AutoScout24</title> <!-- Minified and combined css used by this page (not by the fragments) --> <link rel="stylesheet" href="/assets/home/ebacb8194-main.min.css" /> </head> <body> <!--#include virtual="/headerservice/fragment/header_de_DE" --> Lorem ipsum.... <!-- Minified and combined javascript used by this page --> <script type="text/javascript" src="/assets/home/66ee72f9-main.min.js"></script> </body> </html>

Page 31: An Unexpected Solution to Microservices UI Composition

SSI Include Resolved

31

<html> <head> <title>AutoScout24</title> <!-- Minified and combined css used by this page (not by the fragments) --> <link rel="stylesheet" href="/assets/home/ebacb8194-main.min.css" /> </head> <body> <head> <!-- Minified and combined css used by this fragment --> <link rel="stylesheet" href="/assets/headerservice/08ffaf28-main.min.css" /> </head> <ul><li>Home</li><li>Search</li><li>Sell</li></ul> <script type="text/javascript" src="/assets/headerservice/26ed612f-main.js"></script> Lorem ipsum.... <!-- Minified and combined javascript used by this page --> <script type="text/javascript" src="/assets/home/66ee72f9-main.min.js"></script> </body> </html>

Page 32: An Unexpected Solution to Microservices UI Composition

ngx_pagespeed: combine heads

32

<html> <head> <title>AutoScout24</title> <!-- Minified and combined css used by this page (not by the fragments) --> <link rel="stylesheet" href="/assets/home/ebacb8194-main.min.css" /> <link rel="stylesheet" href="/assets/headerservice/08ffaf28-main.min.css" /> </head> <body> <ul><li>Home</li><li>Search</li><li>Sell</li></ul> <script type="text/javascript" src="/assets/headerservice/26ed612f-main.js"></script> Lorem ipsum.... <!-- Minified and combined javascript used by this page --> <script type="text/javascript" src="/assets/home/66ee72f9-main.min.js"></script> </body> </html>

Page 33: An Unexpected Solution to Microservices UI Composition

ngx_pagespeed: Combine CSS & JS

33

<html> <head> <title>AutoScout24</title> <!-- Minified and combined css by pagespeed --> <link rel="stylesheet" href="/assets/home,,_ebacb8194-main.min.css +headerservice,,_08ffaf28-main.min.css" /> </head> <body> <ul><li>Home</li><li>Search</li><li>Sell</li></ul> Lorem ipsum.... <!-- Minified and combined js by pagespeed --> <script type="text/javascript" href="/assets/home,,_ebacb8194-main.min.js +headerservice,,_08ffaf28-main.min.js" defer async /> </body> </html>

Page 34: An Unexpected Solution to Microservices UI Composition

Page Performance of Composed Page

34

Page 35: An Unexpected Solution to Microservices UI Composition

Page Performance of Composed Page

35

Page 36: An Unexpected Solution to Microservices UI Composition

Caching

36

Page 37: An Unexpected Solution to Microservices UI Composition

Recap

37

Page 38: An Unexpected Solution to Microservices UI Composition

Pagespeed Cache

38

• Caches generated assets

• memcached (ElastiCache on AWS)

• state is externalized to AWS

• allows for stateless web server machines

• no cache synchronization

• no cold cache

Page 39: An Unexpected Solution to Microservices UI Composition

nginx Proxy Cache

39

• Caches responses from upstream services

• Respects cache headers from upstream services

• Supports cache key control via Vary Header

• AWS ElastiCache (via ngx_srcache module)

Page 40: An Unexpected Solution to Microservices UI Composition

Jigsaw Caching of Assets

40

Page 41: An Unexpected Solution to Microservices UI Composition

Jigsaw Caching of Assets

41

Page 42: An Unexpected Solution to Microservices UI Composition

Jigsaw Caching of Documents

42

Page 43: An Unexpected Solution to Microservices UI Composition

Jigsaw Caching of Documents

43

Page 44: An Unexpected Solution to Microservices UI Composition

Jigsaw Caching of Documents with Vary Header

44

Page 45: An Unexpected Solution to Microservices UI Composition

Testing

Page 46: An Unexpected Solution to Microservices UI Composition

Local Testing

46

Page 47: An Unexpected Solution to Microservices UI Composition

Jigsaw Docker Container

47

Page 48: An Unexpected Solution to Microservices UI Composition

Jigsaw Best Practice Analyzer

48

• Checks HTML code for anti-patterns

• defer async• page barriers (inline scripts)• CSS outside of <head>• stylesheet refs with different attributes• Assets not located in /assets/

• Can run in a deployment pipeline

Page 49: An Unexpected Solution to Microservices UI Composition

Things yet to be solved

49

• Authentication is not in scope yet

• A/B testing of fragments

• JavaScript integration / interaction

• Bootstrap fragment / common things

• Native mobile apps

Page 50: An Unexpected Solution to Microservices UI Composition

Conclusion

Page 51: An Unexpected Solution to Microservices UI Composition

Features of the UI Composition Solution

51

• Teams are in full control of their service's UI and do not need rely on others when changing it

• Fragments have a simple structure with head, body and script parts

• Page performance is not compromised

• Jigsaw serves as an effective cache layer

• Fragments can be tested in isolation, and in integration with other pages or fragments

Page 52: An Unexpected Solution to Microservices UI Composition

Learnings and Practices

52

• Try to keep composition layer as simple as possible!

• Stick to HTTP protocol use cases

• Allow services to control Jigsaw's caching behavior

• Isolate fragments by CSS and JS packages

• Try hard to have good documentation

Page 53: An Unexpected Solution to Microservices UI Composition

www.autoscout24.com

www.autoscout24.com

Thank you!Questions?Contact:[email protected]@thoughtworks.com