Getting started with Spring Cloud by Josh Long

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
well hi everybody oh that's pathetic really hi everybody thank you much better well hi welcome to what are we talking about today the beautiful micro-service I haven't been here in a while so I'm super happy to be here thanks for having me a couple of things we're going to talk about code today I love code code is great so if you want to follow along please do but there's also the code on line you know roughly what we're gonna do is on line on github they're a little bit about me my name is Josh long I'm a spring developer advocate on the on the spring team at pivotal author of you know five almost books now on spring and distributed systems and cloud native computing a Java champion that's new I wasn't one of those when I was here last an open source contributor to the likes of things like spring boot and spring cloud both of which we'll talk about here today and at your service ok I'm forever at your service so I'm online if you have questions if you have comments if you want to take this discussion further or forward above and beyond this room if you leave this room more confused than when you entered you have recourse don't hesitate to find me how many of you are on the Twitter's Twitter its 2015 how many of you are on Twitter 2015 2015 Twitter okay awkward awkward what about email how many of you are on email email email no one okay well if you have questions via either of those channels please don't hesitate hesitate to reach out to me I do have one important sort of perfunctory thing that we must absolutely address up front and from the get-go lest we lest we forget I need all of you in the most concerted cheerful way you can to say open source on my prompt so I can take an epic devoxx e or what I'm now calling a selfie at devoxx okay now you don't have to - like it but do smile okay so here we go here we go this is gonna be great now just just hold still this is basically why I come here is for the dev oxys okay so on my mark say open-source I'll take it thank you very much right so I work in a small company a startup called pivotal how many of you have heard of pivotal pivotal so we're we're a start-up in the valley we're the new home of lots of great open-source technologies how many of you have heard of Tomcat Tomcat anybody know one okay awkward what about what about rabbit MQ rabbit MQ Redis it's a distributed data structure server used by some small mom-and-pop shops like a like Twitter Twitter okay what about what about spring how many of you've heard of spring what about spring boot okay what about Cloud Foundry so Cloud Foundry is an open source platform you know it's optimized for the continuous and safe delivery of applications into production right Cloud Foundry is an open source project so you can deploy your own data center but there are distributions by other vendors sort of like the Linux kernel relationship to two companies like red hat and a boon - right we are the fount we provide the base image that community provides the base image and then companies build upon that so there are some very very promising upstart companies that are building their distributions on top of on top of Cloud Foundry how many of you've heard of IBM I IBM I B M no one okay what about HP HP no no 1s s a PS AP okay well that is discouraging well anyway you watch the space those those are going to be some big companies uh and again we all we all agree that getting applications to production is a very important thing we at pivotal love production we love moving apps to production we think it's one of the most important things we can do is to help customers and users deliver software safely and quickly to production we think about production all the time at pivotal we have brochures most companies you'll see people with little brochures the dream getaway to Hawaii or something like that at pivotal we have brochures for that dream getaway to production we love production we think it's the happiest place on earth better than Disneyland right production is awesome and we've seen our users and our customers and and the community at large struggle with how to get there faster and it's not just us it's it's been this way for last several I don't know almost 10 years now right we understand that we want to get code to production but there are things that frustrate our ability to do that we've seen organizations where you have a large code base and the code base has lots of developers well of course each time you make a commit each time you change some code you have to wait for the entire team and all these different people to stabilize and synchronize their code in order to be able to deploy it we've also seen that there's a large workflow a sort of waste that happens in your average organization where a team of developers will be but one station in a long sort of factory or conveyor belt of of stations the first of which of course is product management and then user experience people then the developers and then you throw that beautiful code you've worked on so hard and most of us are doing agile of course as developers but we take that beautiful code that we've worked on so hard throw it over the wall and and then we give it to the QA people and then the you know the various administrators and network administrators the operations people and this cueing from one station to another it creates clock time it creates waste in in lean manufacturing we talk about waste this inventory that we get by queuing work from one place to another creates clock time that means that even if the developers are doing agile development it may take weeks even if the developers only took days to get we're into production we call this very odd phenomenon water scrum fall right we've got you've got a waterfall process sandwiching agile otherwise agile developers and this is a problem because it means you as developers and we as developers cannot get software into production where it can do the most good remember most of us are in a software business the W Edwards Deming talks about that he's a one of the original luminaries of the DevOps world he says change is not required nobody says you have to survive right our ability to change in the marketplace to be able to react to those forces as a software business is the first thing we can do to help the business and if we frustrate that process with all these different wasteful you know slow inventory points then we lose the ability to react so a lot of people a lot of organizations have been looking for ways to do smaller batches of code smaller batches of services and this of course implies moving to something like micro services so you take a large monolithic codebase make it smaller so that I can write code test it certify it and then ship it as quickly as possible also we've seen organizations move to this new paradigm where instead of having operations and so on that just becomes some sort of automatic platform something like Cloud Foundry right this shortens the turnaround time from an idea to production this is very very important and it's what large companies like high-performance organizations like Netflix and Etsy and so on these are the things that they have championed is respawn quicker and you can deliver better value even if it's at the time more expensive it's cheaper to do something more expensive quicker than it is to do something less expensive over time most of the time right so now you've agreed we we need to do micro services because we want to move faster right that's the fundamental reason why we should embrace micro services there are some other technological benefits of course sure you get better run time scale because now you can load balance and you can scale up just to individual bits that you care about that's one true benefit of course another benefit of course is that by formalizing the boundaries between each service you've made the domain in turn consistent Eric Myers are Eric Evans rather in his canonical tome domain-driven design calls this a bounded context and it's actually good hygiene for your data right so you want that as well but this does invite complexity right by moving to this micro-services world you've now moved squarely into the camp of distributed computing and that is not a fun place to be unless you have support for the problems you're going to run into in that world what we're going to talk about today is spring cloud which build the top spring boot spring cloud codifies the sort of patterns the things you're going to need in order to build applications and handle these non-functional requirements so we're going to work first with spring boot how many of you have seen you talk about Spring boudoir or I've heard of it or or even maybe know somebody who knew somebody who fell down and hit somebody else who knew spring boots anybody okay so we're going to start with spring boot that's my slides I worked very hard on those what do you think of my slides best ever they were pretty good one thing okay so we're going to go to my second favorite place on the web here this is after production of course this is start spring that I oh and I love startup spring trail after production into my favorite place like I say keep it under your pillow if every rerun at a sort of an unease you can go to start that spring rail if you're lacking inspiration start that spring today or if your kids are restless and you want them to sleep start that spring that i/o if you have indigestion and you want to feel better start that spring today oh now this is a great place to go start your adventures with spring okay so I'm going to choose the artsy ones because I'll show you some cool stuff I think we have enough time we've got 15 minutes I'm going to go fast by the way my friends this is not to teach you how to do any one thing along the way here it's to teach you that it's all possible that you can pull it down by looking at the code and by looking at starts out to pringle a oh don't be don't worry about catching all the details we're going to go fast that's the goal here is to go fast and and just pile on as much as we can so I'm going to build a service my typical service I'm going to build a service that uses an h2 embedded database it will use JPA because I make poor life decisions so JPA I'm going to create a REST API so I'll use rest repositories I'll bring an actuator support for operationalizing my application I also want to bring in the config client only for the side effect of having brought in a repository and I'm going to bring in eureka discovery support ok I'm going to name this reservation service and I'm going to hit generate now I should mention that there are other options here right you can choose the description the package name the version of the language you like to use Java or groovy and of course this one right if you want to use a jar or a war a jar or a war now we are all about choice on the spring team we believe in that very firmly we have these both here if you are by some fluke of physics stuck in the distant past unable to move forward to the present which is actually just today so it's not even really the future then choose water but if you're here with me today in 2015 then choose jar now this is part of my personal philosophy of make jar not war now you have choices you have choices you have options we care about them they're both supported ok right on good so I have generated my first loli service here I'm going to open this up in my IDE you can use whatever you want I'm going to use a IntelliJ this works and everything actually works really nicely in everything you can use the stock Eclipse because it's just maven in Java you can use a spring tool suite of course which is our distribution with some extra bits on top of Eclipse you can use NetBeans that works great you know is what if you like so I have a stock standard maven build here I won't go over the details too much but suffice it to say we have opinionated dependencies these dependencies in turn bring in everything else we need so we don't have to play whack-a-mole with version ranges I'm going to comment out a few things because we don't need them just yet and the goal here is to stand up a quick REST API that we're going to talk to what ok with go away so let me see we're going to say reservation service application I'm going to build a application that simply manages entities of type reservation this is going to be sort of like a restaurant reservation you know there's an app called open table have you have you played with open table I love it because it's a very simple domain and to me it seems a little pointless but I I think we should you know create a reservation in that way the idea is that you can go to the application and find a restaurant click on sometimes log in create an account you know certify that your you check click on the confirmation email and then finally if you're lucky you'll have a reservation at the restaurant or you can just call and say I'll be there at 8:00 but either way you get the work done right so I'm going to create a reservation entity that I'll just be something we'll use to store I don't really care about the domain model we're not interested in the domain model so much as we are the fact that I have an entity right so so there's that ok give me a JP entity like so I'll say at entity and I need to string naturally so this is that ok here we are good and I want to repository something I can use to make short work of the common crud style stuff create read update and delete so I'm going to say JP a repository extending a JP repository from spring data to handle entities of type reservation whose primary keys of type long naturally there are other repositories in spring data like Cassandra and you know MongoDB and neo4j and so on but I'm going to use JP a I can even define custom finder methods here so I'm going to say find by reservation name string RN and what I want to do is I want to handle exporting the state of my business entities to track the mutations that these business entities are going to go through creation reading updating and deleting I want to stand it up and export it as a REST API to map HTTP verbs to those state transitions so I'm going to say at rest resource path is by name and I'll say I want this to be a repository that'll be exported to HTTP REST using spring data rest and whoops I'm going to go ahead and install some some dummy data okay so here we go component class dummy data CLR implements command line runner and I'm going to it's a callback interface so when spring boot starts up it's going to see this command line Runner interface and it's going to call the run method passing in the string argument array from public static void main string args so I'm going to say stream of Dave Stephan Nina Oliver a stiff is that the right one maybe one I think there we go mark right so there are some names I'm going to say for each name in that collection let's call this thought this starts a reservation with positive I'm going to inject the repository that I want to use here and I'm going to say call reservation repository dot save new reservation passing in the name ok and then I'm going to go down here I'm going to say find all of the records and then print them out just so we can confirm that the records have been saved to database are in memory database and just for for a fun I'm going to also find my good friend mr. hazel here for each and then print line that one as well okay now where we start and we'll confirm that the data has been written to the database okay there it is so there's the data there right so that of course works right this is a demo naturally that was going to work local host reservations for go to 8080 for such reservations you can see I have a very simple hypermedia reddit REST API right how-tos this is a hyper media as the engine of application state the idea is that every rest resource should I have information enough for the client to be able to further navigate that REST API without any a priori knowledge right so here I have a payload that shows me all the reservations in the reservations collection and then for each one I have a collection of links that tell me if I want to get back to the current record I go to self if I want to add other links I can add that as well and the idea is that I can be very very smart about state I can say oh well if you have a shopping cart and I have items in the shopping cart that haven't been paid for I won't show them a link to get a refund right the client navigates by the links it doesn't navigate by deep knowledge of the links right deep links and this decouples the client from the URL structure which means that if you wanted to change the URL structure you can as long as they can follow the breadcrumbs from forward-slash look at the links go to the URL for reservations see that there's even more links here there's links to the search engine for example the search page and what do I want to do on the search page well I can find an endpoint to search by reservation name so I'm going to say RN equals Oliver and did I call the wrong endpoint did I even enter oh I forgot to do this well that was would have been cooler if it worked wouldn't it okay so that's there now I've got a basic REST API now obviously if you build a REST API in the forest and no one connects to it there's an existential question here did you actually build it right in a distributed systems world you want to be able to connect to these things and when you start creating more than one service you run into these patterns that aren't so problem or pains that aren't so problematic in limited in a limited scope but they become a big problem we have more than one service and you want to manage them so this is all fine we have an API now that is easy to use thanks to spring boot and the actuator I also get insight into what the application is doing I can go to forward slash metrics for example and I can see the state of the application go to E and V to see the properties and so on I get I get to see what the application is doing but I want to manage certain things like for example configuration what about you know we know that spring boots supports 12 factor style configuration where you externalise passwords and and so on using environment variables or - t arguments but that becomes a little untenable in the distributed system when you have more than one service suppose I want to pass in a password do I really want passwords unencrypted being passed and invisible in PSA UX of course not right what about you know supporting symmetric decryption and encryption so if I have a cipher I can have to password and then in times it decrypt it and then use it in the application how do I change a password or change properties for a service in one place and then update multiple versions of it right so I have to log into every node and we start and we you know update the properties what about live or feature Flags that kind of thing where you want to change certain things at runtime without having to restart all the processes there's a lot of different use cases that while spring boot provides a good start we need a little bit more when it comes to a distributed system so we're going to use spring clouds config server and I'm going to go back here to start that spring nao and I'll stand up an instance of it I'll just RM RF this stuff here and we are I'm going to say config server and I'll rename this config server and hit generate okay now this is going to be a REST API in front of a repository of configuration a repository that I want to be able to journal I want to be able to see what happened if let's suppose josh finishes his talk and goes off to beer central and has too much Kwak beer and then logs into production starts making changes how do we see what happened when something goes south how do we journal that how do we audit it and see what happened then if necessary rollback we can do all sorts of things and there's some discipline required but it turns out that things like get are very good at solving that exact problem right so what we want to do is stand up a REST API that will sit in front of a repository of configuration files for us so I'm going to go to my code here and I'll say at naval config server then I'm going to go to application up properties I'm going to tell spring boot can you all see that type up there yet fairly large I'm going to tell spring boot where to find the configuration so spring cloud config server get your I equals and this could be anything it could be a github URL a get lab URL anything on the HTTP or your local file system in my case I happen to have I happen to have a directory full of config files here on my desktop so I want to act these config files and I wanna make it want to make them available I'm going to say /home forward slash desktop forward slash config and finally I'm going to tell this server to stand up and listen import 8888 here we are alright good stuff thank you so localhost 8888 forward slash reservation service for slash master what I'm what I'm showing you here is the REST API that we just stood up alright this is a REST API that it's going to sit in front of our repository of configuration files and for a service of the name reservation - service looking for the master profile it will get two sets of configuration files the configuration file reservation service type properties which in this case has certain well-known properties these three keys and values and as a fall through application up properties so for every micro service no matter what its name or identification those services will get the properties that are defined in application net properties but only the micro service that identifies itself as reservation service type properties will get the configuration in reservation service type properties should there be a conflict as there's in this case the more specifically named reservation service type properties overrides the general application type properties so server type port is defined here and it's defined here the more specific wins okay now if we have a REST API and this is a natural place to do symmetric encryption decryption it's a natural place to do a lot of great things by decoupling the client away from the the the repository of configuration let's connect our reservation service to talk to this okay we're also going to take advantage of this message I've got a string here a message and I want to be able to inject it and reference it for my reservation service that we've just stood up so I'll go back here and I'm going to stand up a new rest api site at rest controller class message rest controller and I'm going to inject the value here I'll say message private string message and I'm just going to expose an end point that will just parrot the value of the string whenever I ask for it okay so here we are returned this dot message now this is using Springs properly placeholder resolution mechanism it's just going to provide the message key from some configuration source in this case the spring cloud config server in order to talk to that spring cloud config server I need to act as a client so I'm going to go back and reintroduce the spring cloud startup config dependency which is going to bring in the bits that I need to be able to talk to a config server I'm also going to make it so that when I want to re-evaluate this message I can by triggering a refresh now in order for the config server to to talk to the the in order for the client to talk to the server I need to tell it what its name is so I can find the right properties and I need to tell it where the config server lives so I'm going to say spring that application name equals reservation - service and spring cloud configure eyes HTTP localhost 8888 now this property file that I'm using here by default spring boot will look in application up properties and it'll load all the keys and values in there and make them available for injection but what I'm trying to do is something a little bit more crafty I'm trying to tell spring boot to call a REST API to get its configuration keys and values when it starts up naturally this configuration has to be read before the rest of the configuration so we put it by convention in the text file called bootstrap properties and that is basically the only you know key in value that you'll have those two properties are the only thing you're going to have when you create more microservices so if that's working then I should be able to restart this and without adding any more configuration to the mix here I should be able to see the message key from the reservation service a properties file here where it says message and if I go back to my application localhost first of all 8000 right so we change the port that's in the property file there's that and now forgot a message I get the message from the property file but this message isn't really this isn't a great message it's a good message I tried it it says the name of the conference that's a start but I think it lacks that genesect quoi you know it needs a little bit more oomph so I'm going to open this up I'm going to add more exclamation marks because that makes the opinion more valid on reddit okay I'm going to say git commit - M Yolo okay now when I go to the config server you can see the config server is immediately aware of my stronger opinion but my actual application has no idea of what just happened I have to tell it what has changed in order to do that I need to trigger a refresh so I'm going to say curl - D HTTP localhost 8004 slash refresh so what I'm doing is I'm telling the application that I wanted to call all the beans and annotated without refresh scope and we configure the beans discard the internal proxy pull down the configuration so there's that and then refresh right and the new values are visible immediately alright so this lets me do feature flags I can do live reload you like that that's cool I'm a fan cool so that that's one property that you're gonna need to support distribute can you know configuration centralized configuration naturally as you start to build more services you create a web right you have a lot of services that talk to each other there's a a complexity cost that arises how do you discover where these services are you could of course use DNS but this is a poor fit in a micro services world where services tend to mmm pardon the pun spring to life you know as calm as demand and capacity dictate so you want to be able to decouple where service lives and from what the service is right the name of it the IDE logical mapping of that service to its home in place especially if you have more than one instance of a service you could put a service or two behind a load balancer but how does a client know if a service that it's about to call is sick and just haven't been you know jettisoned from the load balancing ensemble right so this information is something that you don't want to let a load balancer handle for you additionally even if you are using a load balancer in DNS with remember DNS has time to live cache expiry you know problems and the load balancer only has so many settings that can support if I'm trying to do load balancing across ten different services and I want to do round-robin your typical load balancer will support that but what if I want to do for example multi-tenancy what if I want to route to a specific set of nodes given a certain set of ID's or what if I want to do low availability zone awareness I want to route to certain zones based on the the lat you know Amazon Web Services zone or whatever your cloud provider zone is right what if I want to do something sticky perhaps I'm streaming a video or something and I want to route all nodes to the Status endpoint on a specific node for a given token a security token right all these kinds of requirements are beyond what your average checkbox on your average load balancer will do so to support this use case we're going to introduce a Sturbridge registry okay we're going to use eureka which is a service registry from Netflix though there are others right so we're going to use the eureka discovery naturally there's zookeeper there's console and so on right we're going to introduce a abstraction to we're gonna use an abstraction to talk to these service registry naturally we're going to stand it up first so this is what I'm gonna do is I'm going to use the start at Spring Rio and I'm going to install an instance of Eureka now you because from Netflix who by the by also use spring cloud and spring boot how many of you've heard of Netflix Netflix Netflix so they're they're pretty big now I saw an interesting thing that suggested that on the internet there are three the three largest video categories are number one is pornography just the entire category right number two is Netflix and number three by less than half is YouTube which is crazy it's crazy it's huge something like eighty percent of the bandwidth on the internet apparently is you know lazy Americans sitting on their couch watching Netflix every evening you know drooling right that's a big thing it's in and out it's here it's now too everywhere right so they're building on spring cloud to to sort of move faster as well so I've got this application I'm going to go ahead and you wreak a service application I'll say at enable you recast server ah wrong dependency starter you weak a server at enable auto import and here we are okay so what I'm doing is I'm selling spring boot that this node is going to act as a registry it's going to be the same kind of thing as before I'm going to give it a name I'm going to say your name is eureka service and it's going to talk to the config server running on port 8888 and it needs to be a bootstrapped up properties so i'll rename it thusly and now restart sorry you eke a server application the configuration that I have in the config server says that it's going to run import 87-61 absent any specific value so I can go to localhost 87-61 and i get the config server oh here we go service did I add the config client can fix server rats sad so there we are so that'll come up and that's a service registry now while that's doing that I want to go back and teach my reservation service to be aware of this discovery service of this registry what I want is for one service to be able to find another and not be aware of its DNS entry or of its host in port so there's a little bit of decoupling here by giving a logical ID like for example reservation service I want to be able to discover where other applications live hello mmm-hmm Eureka service spring clouds start a yoga service what is the problem server on the arica server hmm let's try that okay restart so anyway there it is and all of its service registry glory now what I want to do is I want to teach my services to register themselves here there's a REST API as well as this wetware screen the REST API is will talk to the API but of course we we we bits of wetware can look at this console to see what's happening so now let's go back to our reservation service here and add and restore a dependency on the spring cloud started eureka what this is going to do is it's going to enable the discovery client abstraction and the abstraction is just a it's an interface that can be used to talk to a discovery service like your week or Netflix or zookeeper or console whatever so all I'm going to do is I'm going to add at enable discovery client now the discovery client abstraction is read-only right it doesn't specifically imply that you're going to do writing because remember not all service registries require you to do writing in this case what I want to do is I want to say when the reservation service starts up I want it to volunteer that I'm here if you need me I'm here my host importer is are as follows and my name is Reza no reservation - service but if you're using a cloud platform like for example Cloud Foundry it already knows where a given service lives given its logical mapping right you don't have to tell it that that service is available at this host import' it already knows so it's read-only in that case so we don't imply that in the contract now if I go back here and refresh you'll see that reservation service is here and it says that it's on this IP or this ID at this port and now I want to build a client now okay when you build a client to talk to our service and this is where we're going to have some fun so I'm going to build a new service here a reservation client that's going to act as an edge service it's going to use you make a discovery of course it'll use config client it'll use hystrix for circuit breakers it'll use what else do I want I want stream support with rabbim cue I want distributed tracing with Zipkin I want hypermedia write the hypermedia api for the support for that actuator naturally good so now I've built my my client and what we're going to do here is we're going to build edge service so when we talk about edge services in a distributed system there are two different types of edge services one is an api gateway which is good for api protocol api or protocol translation from an outside service an outside client like a phone or something into some sort of back-end call you're going to call the suite of micro services as registered in the registry or just a simple micro proxy right and depends on your use cases but we're going to show a little bit of both here right so let's take for example the first use case I've got this application it's a client to my back-end micro service it's going to call the reservation service and and get data the reason we stand up API gateways like this is because is because we have clients like iPhones or watches or Android devices or Playstations or Roku or whatever we have different types of clients that speak different protocols for security they have different use cases they want to get different views on the same data etc take for example html5 html5 requires that you don't run afoul of cross origin request skipping you know restrictions so you have to channel everything through the same most important or you can optionally add a policy document to every service saying that I accept requests from this endpoint but imagine something like Netflix where they have 600 different micro services for them the option of retrofitting every single micro service every single time each client needs a new change or a specific you know new policy document it's not an option they don't have the time to redeploy 600 different services just because there's an html5 client so instead they stand up as specific Android or html5 edge service in HTML in the HTML 5 use case it might be it might be enough just to I might be enough just to proxy requests what if I just have one service that forwards all requests so the registered micro services in the backend alright so I'm going to go back to my build here I'm going to make sure that I have Zul okay now if you are good on your Ghostbusters mythology how many of you are good on ghost ghostbusters how many of you remember Zul the cutest little monster you've ever seen that's the gatekeeper the guardian of the underworld right Zul is the door doorman or door monster in this case not to be racist Zul it's the door monster that guards access to the underworld and so what we want to do is win and stand up a proxy that'll take requests from the outside and forward them to the backend micro-services that we've registered in our registry so I'm going to go ahead and say at Naval auto import and I'll say spring cloud starters ool and then we're going to go ahead and start the application up okay now what this is going to do is just going to forward the request very simply so if we have an html5 client we might add HTTP basic authentication some SSL and then we're done maybe that's enough right that would be a certainly a good start so localhost this is running on port nine nine nine nine right forward slash reservation - service forward slash reservations okay I've got to give it this stuff didn't I bootstrap client go faster come on Oh registering way okay what is disabled thank you buddy there we are so while this is restarting I was just reminded of something that I wanted to take issue with I think we're friends here we can talk about this openly and not have any grievances so I'm a big IntelliJ fan and I think you'll notice that we have really really amazing ASCII art work in spring boot now now this ASCII art work I think is one of our defining features there's a lot of great stuff for the ASCII art work really helps bridge the communities to bridge the gap so I think that we should start a petition I'm just saying what the hell is that why is that there right we should get that removed that's that doesn't help anybody so anyway whatever so there's my service okay $99.99 for slash reservation service for such reservations now this is the registered service in the registry if I had a service called food service than I could call foo - service for slash whatever and I proxy directly to that I've got a little bit of indirection here like I said if I add basic authentication or OAuth or something maybe SSL I'm done that would be enough but of course that would be a terrible demo so I'm not done right let's talk about API gateways or API translation right so in this case we're just doing a direct proxy direct forward to the registered service and if I want to do the composition or or aggregation whatever in the client in JavaScript for example I can but it's nice to somehow sometimes stand up a middle API an API that will sit and do translation for whatever reason so in this case I want to stand up a rest controller I'll say at rest controller class reservation API gateway gateway rest controller and I'm going to map it to request mappings forward slash reservation so I'm going to stand up an endpoint that forwards requests to the back-end services maybe one or more maybe does an aggregate view or something and does some sort of basic translation the first endpoint will simply Spahn - HTTP GET and it'll return /name so i can go to for such reservations forward slash names and get a collection of strings for the reservation names so I'll say get reservation names and I'm going to use the rest template here the auto configured rest template which already knows about our service registry to make the call now the rest template is an HTTP client that makes short work of common HTTP in exchanges you know delete get posted tetra I'm going to say that I want to call HTTP colon forward slash four slash H to be a reservation - service for such reservations mind you that is not DNS that's the service ID as we registered in Eureka this bring the spring cloud auto configuration add an interceptor that will take all HTTP requests resolve the the service by its ID go to Eureka or whatever find all the instances one or n instances and pass it to something called ribbon now ribbon is a software-defined load balancer it's the component that I described earlier that lets you programmatically make the decision about which nodes to route the request to this gives you more flexibility because now you conversion test and then deploy the routing you need for your service even if other services get something else so I'm going to say I'm going to leave the default which is by the way in this case to do round-robin I'm going to leave that there I'm going to say that it's gonna be an HTTP GET call since it's a get call there's no body and I need to tell Java what value I want back from the HTTP call now here I'm going to use the parametrized type reference okay so parameterised type reference of type resources from spring how do s of type reservation now what I'm doing is I'm giving the rest template a type token this is a a pattern to capture generic parameters at runtime right because of type of a sure you can't capture generic parameters of instance variables that's why you're forced to capture them in the subclass that's what we're doing here this is an abstract class I'm forced to subclass it which effectively bakes this generic argument into the instance which I can then pass to this and that'll tell the rest template via reflection that I want a response that has the spring hypermedia resources object with the body and the links as well as the reservation object now this may make you wonder what reservation object remember we're building a client to a service in theory and again this is hypothetical right I mean I have never seen this demonstrated to my satisfaction but in theory that service that we're calling could be built using something besides spring in Java now again big hypothetical right and because of that we don't want to be coupled to the implementation of the service registry representation of that of that entity so I'm going to create a client-side mirror here I'm just going to say class reservation and I'll say private long id private string reservation name and I'll create some getters voila and there we go so now I've got spring hyper hyper media and the reservation entity I'm passing that there it's going to give me a return value like that and I'm going to say that I want to return exchange dot and I can call the I get the status code I can get the that body the headers etc I want to get the body then I want to get the content which is a collection of resources then I want to stream and map from reservation to reservation name and I'm going to collect the results and return them now this is a great use of Java age lambdas and functional programming if I were using calling more than one service naturally I would want to use something like rx Java or whatever to concurrently call these services and then zip the results back up and send them back that way but since I'm only calling one service I'm just going to do the work here and a very imperative style this is going to give me an endpoint that will return a subset of the data it's an API translation and this will work this is you know very very simple but it'll work so we are here reservations forward slash names faster I say there we are so there's my names coming from the reservation service reading via rest is a very good way to go but naturally in a distributed system when you want to write you can't really trust on rent you can't really trust rest of to be the you know the guarantee that you need if you write something and you in the rest services down what are you going to do right you don't want to be coupled to the availability of that service so it lazy architect at this point would reach for something like distributed transactions avoid this urge at all costs protip instead the high-performance high-performing organizations use messaging or asynchronous writes they use something like C curettes which optimizes for the fact that writing via messaging is very very fast and it's safe right it's eventually consistent so we support that with spring cloud stream right so spring cloud stream is a way of logically composing micro services in the same way that we're using the Eureka service registry to compose micro services via rest we can use messaging to compose streams of messaging flows using their service IDs instead of being too worried about the you know where services are registered and so on so i've got spring cloud stream on the class path here I've added spring cloud starter stream rabbit so this is going to talk to rabbitmq I could as easily talk to Redis or Kafka or whatever right but what I want to do is I want to write messages to the service so I'm going to go back to my code here now what I'm trying to do in my reservation client is to create another API gateway endpoint to write data I'm going to say post and I'm going to just say any posts to the reservations endpoint will call you know write request body reservation I'm going to say that I want to send a message to some other system to handle the write eventually write state synchronization via messaging is a very very powerful thing remember even the banks don't use distributed transactions right there's it's too in performance so you want to scale you use messaging so what I'm going to do I'm going to inject a message channel a spring integration message channel to send a message from the client to the service I want that wiring to happen implicitly using spring cloud streams I'll say at enable binding and I'll say that this is a source component so I'm going to bring in sprinkler Stream messaging source class this is an interface you can use any interface you don't even have to use this the only redeeming quality is that it's got an interface definition message channel output and a qualifier notation saying output spring cloud stream is going to implicitly create that channel which is just a named pipe it's a conduit through message through which messages are sent the benefit of this is that our client code can work with the type the message channel type and we don't have to worry about it too much the wiring of how those services communicate with each other is left to configuration so if we go to the config service and the reservation service here's reservation client master you can see that I've got spring cloud stream bindings output equals reservation so for the lot for the local ID of output I'm going to meet I'm going to send a message to some exchange or destination called reservations what does that mean in terms of the messaging subsystem it depends in this case it's going to be an exchange on RabbitMQ called reservations and we're going to let spring cloud talk to rabbit queue which is running on my docker image here and I've got spring that RabbitMQ dot host equals docker IP so that's already configured for me so all I'm going to do is I'm going to say whenever somebody injects that message channel go ahead and send the message to message channel that output and then right so here we go so I'll say at Auto wired private message channel and I'll use the qualifier I'll say at output source output that's the qualifier the string I'm saying give me the one message whose channel is identified it like that I'm gonna say this dot message channel dot write or send message builder dot with payload or get reservation name and then build and then send okay so that's the client side of the discussion I want to do the same trick on the server side so on the service that's going to respond to the requests so I'll go to the reservation service here which is here I'll say at enable binding and I'm going to bring in spring cloud stream as well here so I'll bring in the same dependency from this one config server configuration client spring cloud starter stream rabbit okay a table binding is going to be a source so a source is the opposite it's an output channel okay okay and a sync is an input channels can receive data and I'm going to say that I want to use Springs messaging subsystem here I'll say at enable or enable messaging messaging components can integration component there we go so that's going to turn on the support for messaging based components like met you know asynchronous messaging driven components I'm going to create a message endpoint here I'll say that the endpoint is going to receive reservations message acceptor and it's going to respond to all messages that come in on the channel provided by the sync right so input channel equals sync input same trick as before I'm going to say public void accept and the response the the method the payload will be a string and then I'll just pass it to my repository and actually write the data to the database so I'll say private message or sorry reservation repository this that reservation net repository at save equals new reservation passing in RN so that should be everything I need to be to be able to do this let's see I'm going to restart the service and then we start the client of course it doesn't really matter and we should be able to go let's see if everything's still working let's see here we go starting go go go looks ok now we go back to our service here and you can see on port 9999 4 / reservations here are the names that we have so far I want to post another record to the 9999 for such reservations in point and the JSON I'm going to use is this I'm going to add Dave using application JSON to this endpoint okay so if I do that oops I should see Dave so that was done by messaging alright so now I've got the ability to write and then to read but even the reading is a little flimsy don't you think I mean what happens in in the case of one two more one to end service instances if that service should fall down that it'll still work right as long as I have one or more instances of that service it'll route to another available instance what happens if I have zero instances of the reservation service when I'm doing my reads I want to be resilient right there's a guy named Fred George does a great talk out of the UK and when she likens microservices or the human body he likens them to microservices he suggests the very amazingly apropos idea if you cut your finger do you just blue screen right of course not right you gracefully degrade as should your system so let's go back to our let's go back to our service here and revisit this end point here that we turned the sorry the reservation client let's revisit this endpoint that returns the string names I want to fall back want to do something graceful if this service is not available so I'm going to say at naval circuit breaker now a circuit breaker is just what its name suggests it's a component a stateful component that will see when something has failed and route traffic to some other end point it's just like a circuit breaker in their home I'd much rather lose the light if there's an overwhelm or a surge of power than to lose the whole house because of a fire right so I'm going to say at hystrix command I'm going to say fallback method equals and I'm going to give this a fallback method that will do something sort of trivial and safe right I mean Netflix does this all the time they'll say oh well the search is down for example but here are some recommendations from across the web instead so you'll get something you won't you can't just send a stack trace back to your iPhone clients right that doesn't work so we're going to teach their little service here to do the right thing when this when the service is down I also want to be able to visualize when things are happening you know when when it calls are made from one service to another in the distributed system if if I call one service and that service calls another and the middle one dies how do I correlate which requests caused the trouble how do i trace the flow of traffic through a system and for that you need visualization right so we're going to bring in something called spring cloud sleuth which is a distributed tracing Zipkin it's a distributed tracing framework it's part of spring cloud and it works by adding a correlation ID across common ingress and egress points so HTTP message calls messaging MVC calls proxying whatever and you need to tell it of course which records to trace and for our purposes since this is a demo we're going to tell it to always sample everything to trace everything I'm going to do the same thing in the service here I'll say trace everything but of course in a real production system you definitely don't want to trace everything right you know if you have a bug and there's problems with requests across multiple services you'll see that bug with 20% of your traffic you don't need to trace everything you'll quickly overwhelm the system now I also want to visualize this right I don't want just point in type numbers so I'm going to use something called Zipkin from Twitter which is a distributed tracing tool it's a great visualization that's running on another port as well here we go so now let's see what happens this should be up and running soon here's my registry we'll see what comes back up to life reservation client is up first no service no okay here we go come on there we go so there's the service now if I go to this endpoint does it work no it fails to fall through because it hasn't yet seen that does new service for registered so that's the distributed that's the fall through the circuit breaker working automatically got an empty collection it fell back and gave us the empty collection instead of throwing an exception or blowing chunks as the service comes back online and the client sees that the registry is now registered the new instance it'll eventually heal right and if you're running on a cloud platform like Cod foundry or or Heroku or whatever it'll automatically restart that instance so now you've got services that will automatically do the right thing they'll gracefully degrade and then the service the platform will make sure that the services are running but I still want to be able to visualize the flow of messages from one system to another so I've you know that's why I've installed Zipkin here right so there's my endpoint you can see it's failing I now want to go to my Zipkin service here echo darker IP P beat copy I'm going to say colon 8080 for slash and this is Zipkin from Twitter okay this is a way of visualizing requests across different nodes and it shows you a waterfall graph so their service is now healed I can go here and say okay show me all calls be it from HTTP reservations or HTTP reservations names find traces show me everything from like later on today please there we go so there's the latest this is the latest BAM here's from less than a minute ago when I click on this it shows me HTTP reservation names I made this call if I click on that I can see the HTTP headers and the inbound and outbound requests and the time it took from each service and then I can see that it landed in HTTP reservation service on the service itself so now I have the ability and this works for messaging as well all right so if I go to here and send another post request which will trigger another HTTP call I can now go back and view in Zipkin I can view that the client has made a call a reservation client and to tow service there you go here's the message input find the traces this is about a minute ago and you can see that it shows the HTTP reservation call being made and then the message landing in rabbitmq and the headers and so on there so that gives you the ability to visualize what the system is doing and we also saw that with the circuit breaker I was able to gracefully degrade and do the right thing when the service came back online so what have we covered not very much let's be honest not a lot we've talked about just a small fraction of the things we support in spring cloud including Service registration discovery centralized configuration we've talked about messaging and CQRS style workflows we've talked about distributed tracing using spring cloud sleuth and Zipkin we haven't talked about single sign-on using spring cloud security which lets you effortlessly protect using oauth each of your individual rest services we haven't talked about the history dashboard which you can use to visualize the flow of requests into different systems and see the circuits as they if they fall if they open you get a dashboard that shows you that um what do you think yes maybe pretty good okay um I'm I've got 30 seconds left should I do I don't have 30 seconds anymore I want to say thank you so much for your time I hope this was worth it if you have questions I'm available outside or we're at the pivotal booth I'm on the Twitter's like I said so please join us is it to reach out to me thank you so much everybody
Info
Channel: Devoxx
Views: 43,363
Rating: undefined out of 5
Keywords: DevoxxBE15, Devoxx, DevoxxBE
Id: SFDYdslOvu8
Channel Id: undefined
Length: 61min 14sec (3674 seconds)
Published: Thu Nov 12 2015
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.