Reactive Spring • Josh Long • GOTO 2019

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

FYI, here's the talk Abstract

Microservices and big data increasingly confront us with the limitations of traditional input/output. In traditional IO, work that is IO-bound dominates threads. This wouldn't be such a big deal if we could add more threads cheaply, but threads are expensive on the JVM, and most other platforms. Even if threads were cheap and infinitely scalable, we'd still be confronted with the faulty nature of networks. Things break, and they often do so in subtle, but non-exceptional ways. Traditional approaches to integration bury the faulty nature of networks behind overly simplifying abstractions. We need something better.

Spring Framework 5 is here! It introduces the Spring developer to a growing world of support for reactive programming across the Spring portfolio, starting with a new Netty-based web runtime, component model and module called Spring WebFlux, and then continuing to Spring Data Kay, Spring Security 5.0, Spring Boot 2.0 and Spring Cloud Finchley.

Sure, it sounds like a lot, but don't worry! Join me, your guide, Spring developer advocate Josh Long, and we'll explore the wacky, wonderful world of Reactive Spring together.

👍︎︎ 6 👤︎︎ u/goto-con 📅︎︎ Jul 19 2019 🗫︎ replies

so Spring 5 brings their own react/angular like framework? that could be interesting if it allows a better coupling of component and server than through ajax or websockets

👍︎︎ 1 👤︎︎ u/DonUdo 📅︎︎ Jul 19 2019 🗫︎ replies
Captions
[Music] thank you okay everybody very good I appreciate that thanks for joining me today as usual we have very little time I was hoping for a few hours they didn't got they did not in in reality actually gave me a few hours so we have very little time and a lot to get through before we get too far down the road I would encourage you to join my masterclass thing is that possible can they register for that thing later they can so join my master class session thing which is on one of the days between now and the end of the conference or maybe it's just after the conference I don't know that'll be fun that's like eight hours of stuff so enjoy me for that it's on the schedule I don't know when the actual proper date is but that said we do have a lot to get through in the next whatever it is 50 minutes so I would encourage you as always to take note of the stuff in the slide to take note of the stuff in the slide for your own edification for reference for later on there you'll find first of all chief among the things you see on this side you'll find the code that we're gonna go through today for your own reference for identification and you're gonna find my coordinates online so if you should have questions when you have questions don't hesitate to find me online I'm happy to answer obviously I'm on Twitter just curious I'm always curious about this how many of you by show of hands are on twitter twitter twitter okay the rest of you you know get on it so it's a great place to be it's the new IRC it's where all the developers that drive the open source that powers your businesses are so do that what about email what about emails anybody here on email email e-mail no good moving on I'm not really a big email fan although if I'm honest I much prefer to slack right I've got a friend James ward that said that while he's not entirely sure he suspects that based on CPU activity alone slack is mining for Bitcoin something that I I expect is probably true okay a little bit about me my name is Josh long I'm a spring developer advocate on the spring team I I'm on WeChat for those of you or who are in China you're not in Chicago but that said I have videos on Safari a lot of different videos these are all like five six seven eight hours of content detailed sessions on these different things I've got a book called cloud that's now available in a proliferation of different languages I do a podcast every Friday called the butiful podcast which is available wherever find podcasts are pervade I do screencast every Wednesday called spring tips which is me diving into some corner of the spring ecosystem these are you know me and a keyboard doing a hot take 30 minutes to an hour on a given topic a very focused specific look at a particular topic and of course I've got a new book a new book on which I'm working which is now available for pre-sale and you can already start reading it now it's called a reactive spring and this book looks at a lot of the stuff that we're going to focus on in this session it's a look at how to build applications that take advantage of reactive programming but in you know through the lens of the spring ecosystem and this book is I think the longer form of what we're gonna talk about today so maybe I've just negated your need to buy the book but it's okay it's worth understanding that reactive programming is a new response to an old problem that is to say the question that people struggle with these days as they move to microservices as they move to big data as I move to IOT Internet of Things into no sequel and to these scenarios where they're conducting increasingly large increasingly large amounts of data over the network the question that they struggle with is how do i scale that out and the reason that they start to appreciate that this is difficult is because a lot of the traditional approaches to doing input and output with which we're familiar starts to you know starts to crumble in the face of this new scale what do I mean by that well suspend suppose you have a traditional JVM based application using Java IO input streams and output streams you've got something you've got a server socket parked on port 8080 and you're reading you're waiting for the next connection to arrive when the next connection arrives you want to produce a response so you get the input stream you produce some bytes and you send it in the output stream what happens in that in that span of time well the client thread on which all that input now put is happening is blocked you're not able to do anything with it so how do you scale it out you create new threads is that an infinitely scalable solution can you just create new threads in perpetuity the jvm in 2019 the the you know TLD art no right you can't do that for a number of reasons first of all threads are expensive they have about a megabyte of of state that's associated with bookkeeping with the managing of the native process and the operating system that's managed by the operating system that process but the thread that's the first thing it's expensive so if you have a thousand threads which is a crazy high you know number but suppose you had a thousand threads you'd have an extra gig of of ramp before you've done anything just as the JVM starts up you've already got that right for each thread you've created now could you actually schedule a thousand things discreetly at the same time per second well of course not right unless you have a thousand cores which is as I understand it just enough to run slack unless you have a thousand course that's not going to be great it's not going to be it's not going to be what you expect too because what you have is scheduling it's an illusion you're moving work from one CPU to another one core to another hoping to be able to simulate the illusion of a thousand things happening at the same time but that's not real so the question is how do I handle a thousand requests at the same time and the clear answer is that we can't do it with threads so the pragmatic answer something with which we're all I expect no doubt familiar the answer that is emerged in the last 10 yard years in the move to the cloud there's exodus to the cloud is you just scale out horizontally and this is a very pragmatic answer right we we've all talked about 12 factor micro services and cloud native applications and this idea that you remove as much state as much cost associated with scaling or horizontal ensemble as possible right we talk about the cloud native architecture right this idea that you can put a bunch of stateless web servers into a load balancer and then just start distributing load across them right either web servers or Kafka consumers or something either way you're scaling out horizontally and the cost of doing so because you have no state to replicate it's cheap it's nil they're all dented basically they're all stateless so this this is a pragmatic approach and allows us to get to the scale that we need to get to without making any hard concessions this is certainly a worthy option especially if you have code written in yesteryear that doesn't do better than what we wanted to do but it's it it's a little expensive it's a little inefficient we can do better one way to do better is if we can find opportunities in our code itself where we are doing something inefficient that is to say where we are denying ourselves the opportunity for scale one place where we might be doing that is with input and output right that input and output is it takes a long time and when we're sat there on that thread doing that input output we can't reuse that thread we can't repurpose it and the reason is because as we're doing reads and writes with those input streams and those output streams we're sitting there waiting for the bytes to come where's the next byte come on I gotta go come on right we're queueing waiting for those bytes to arrive that delay means at that time that we're spending there on that thread is wasted time because a lot of times it's not that the bytes aren't there it's just that there's a network outage or there's delay or some sort of failure or something like that right it's not that there's just a huge amount of data a lot of times it's just the sort of uncertainty of the network so we've got this distributed system and we're experiencing uncertainty who could have predicted this right so the question that is how do we build systems that don't waste time waiting for bytes when they're not there and allow us to repurpose those threads if we move to asynchronous i/o we can do this asynchronous i/o is kind of like synchronous i/o you get data in you can send data out except that with asynchronous i/o you ask for the data and then you get an interrupt a callback later on when the data is available this allows you to make the request and then immediately move off of the thread as soon as you've made the request the the bytes will come later but in the meantime you're gonna get off that thread and allow somebody else to use it right and because of this you're not sitting on any thread for more than a few you know milliseconds hopefully this allows you to do the handle more requests because you can handle more incoming requests and start the process of waiting for bytes and then you ask the operating system to actually manage that dispatch the the managing of incoming streams to user code that can be done much more scalable than us in our in our user code creating threads to do that waiting that scalable process allows us to handle thousands of requests per second right if you've ever seen the the C 10k for a C 10 K problem this is problem of how can I handle 10,000 concurrent requests at the same time you can't do it with threads but you can do it with this if what you're doing is IO bound if what you're doing is is limited based on your ability to do input and output and you move to asynchronous IO then you can reasonably expect to scale to that high to those kinds of levels this is not a new idea right asynchronous IO has been around for a long time it's been around for decades and all the major operating systems it's so prolific and so so obviously useful that it's been in all the major major operating systems for so long that his intern also been in Java since Java 1.4 type of 1.4 came out in 2002 in the very beginning of the year it's been more than 17 years well when it's in Java that means there's a way to do it in a consistent way across all the operating systems on which Java runs even Windows Windows imagine so the point is we've got this thing in Java 1.4 we've got it there since 17 years ago are we all reading code using Java and IO do you all write code using Java niño and I expect that the answer is no of course not you're not gonna write code using Java n io because most of us don't spend our time at that lower level we don't think about the code in terms of input and output for synchronous or none or asynchronous code right we don't write our code in terms of Java io input stream and output stream either no no we think about the world in terms of computational metaphors that allow us to map our business domain to the underlying input and output abstraction in most of our code that abstraction that that metaphor is something like a Java collection full of type T or T is your business entity and you use technologies that support these abstractions things like spring and hibernate but imagine that we we had a new metaphor that have supported this new asynchronous this new potentially unbounded world that metaphor would be would need to be pervasive everything that that we do would need to be able to support that metaphor and this is why we you know it's very important that we have something that everybody agrees on imagine for an instance just to just suppose it's just just a hypothetical that for whatever reason 10 years ago these technologies with which you were familiar that you had become accustomed to using these technologies that supported what you're trying to do technologies like hibernate and spring imagine that for whatever reason they were just really hostile just absolutely hostile to java.util collections right imagine that when you try to do a one-to-many relationship in your hibernate entity and you use the Java util list type us an ArrayList for example imagine that for whatever reason whenever you used a Java util list subtype or Java util collection subtype for whatever reason you didn't just get an exception on the console no no no it actually printed an ask a middle finger and then seg faulted the machine right and you would you continue to use this if you can if you knew you could expect that kind of abuse would you continue down that path if you knew that was a result and the answer I think is of course not you use whatever hibernate told you to use to get to the root desired result you're not gonna stop shipping software right if they're if the path of least resistance is to use this new thing called a hibernate list thing whatever then you're gonna use that because that gets you to production and that's what matters here so the same that same thing is here true with the reactive sort of types that we need these types that allow us to map this asynchronous i/o whatever we choose whatever we depend on has to be supported across all the different technologies that we care about and so this is why in 2015 a number of different organizations the people at on pivotal where I work which is where part of the sponsor the lead sponsor of spring the people at Netflix the people that akka lie pinned in a typesafe the people in the clips Foundation and a number of others we all got together and we create something called the reactive stream specification the reactive stream specification are just for very simple types and they provide these very very simple types that allow us to describe potentially unbounded asynchronous latent streams of data there so obviously useful these types that they're actually they have been they have been since incorporated into the JDK they're in Java 9 now so these types are very very useful they're they fill a particularly significant hole in the GT okay that that was a at the point at that point unplugged on top of which there's still a need for some operators to support streaming of data processing data how do you how do you map over data how do you filter these kinds of things so we have projects like reactor and rx Java 2 and aqua streams and and so on these different projects sit on top of that layer providing these operators they all speak these reactive streams types they all understand these basic types but they go a little further providing pipelines and on top of that well then what are we done can we go home yet and I'd say the answer is still no what good are these types if the frameworks if the technologies with which we work don't understand them and so this is why the big sort of did you know the big moment for all of us for in this on the spring team was in September 2017 when we leased Spring Framework of five the first release to support natively project reactor and the reactive streams types that I just described on top of which we have since released spring data K Springs security five spring boot to that o spring cloud Finchley and so much more so what we're gonna do today my friends is we're gonna look at that journey we're gonna write code that takes advantage of this sort of holistic approach to building reactive applications and we're gonna do that of course at my second favorite place on the Internet my second favorite place on the internet after production I loved production you should love production you should go as early and often as possible bringing the kids bring the family the weather is amazing it's the happiest place on earth it's better than Disneyland but if you haven't already been there you can begin your journey here it's starting that spring that i/o if you need inspiration in the early morning before a cup of tea or coffee preferably purchased here intelligent a coffee start that spring that i/o if your children are restless and can't sleep start that spring today oh and if you suffer from indigestion after a long night of alcohol abuse and PHP start that spring that I oh so what we're gonna do is we're gonna build a new application my friends are gonna take advantage of the latest and greatest spring boot snapshot releases because Yolo we're gonna build a new service called the reservation - service we're gonna use the dependencies that we want I'm going to choose more options to bring in Java 11 this is really really the only sane choice these days I can't wait for the day when this is the default we're gonna bring in the reactive web support we're gonna bring in Lombok we're gonna bring in the dev tools we're gonna bring in the reactive MongoDB support we're gonna use our socket and I think that's it I think that's probably enough for our purposes here and now that said there's other things we could have liked to include and I encourage you to take a look at that list at your leisure at your own discretion later on you can just do that by by clicking on dependencies see all and you'll be given this long list of options okay all right I'm happy with my choices I'm gonna go ahead and hit generate that'll give us a new project a project that I'm going to open up in my IDE and we're just gonna go ahead and and use that to demonstrate some of these concepts today all right so we have a brand new application a Springwood application and we're going to create a new application that manages data it's gonna persist the data into the database and so I'm gonna create an entity an ORM kind of like entity they're gonna map to documents that is to say a single record in the database in MongoDB and I've got MongoDB in the background here and I'm gonna use MongoDB to save data into the database I'll say a tidy at document and that's my basic entity definition but this is Java and I still need getters and setters and all that kind of stuff and so obviously I could just get her and set on my way to production like that equals equals equals hash code blah blah blah so productive so modern look at that nonsense so instead of doing that instead of doing that I'll use Lombok right long buckets on the compiled it's a compile time annotation processors on the class path and all I got to do is annotate my types and I get the synthetic getter setters to string equals hash code etc with that I want to create a repository in a repository is an object that's going to let us handle the tedious soil and Island the boring read write and update delete life cycle the the life cycle of data okay and so we've got this repository from spring data it's a reactive code repository if we click on the interface you can see that the methods are fairly straightforward what's gonna happen is spring is gonna create an implementation of this interface that supports these methods we don't have to do anything more than the interface these methods are straightforward we have save save all save all find buy ID delete check if it exists count you know flush all these kinds of normal crud style data management lifecycle manipulators are all there these methods are straightforward but the signatures I suspect might be a little weird for you first of all what is a publisher well a publisher is a thing from the reactive streams these are one of the four types that I just described to you in the reactive stream specification a publisher publishes items of type T where T is anything it could be a single byte it could be a byte buffer it could be a string it could be a customer or an order a line item whatever it publisher publishes an item of type T to the subscriber and the subscriber consumes that item in the on next method so the publisher will have one or zero or a trillion or an infinite number of Records and as they become available it publishes them to the subscriber the subscriber then consumes them in the on next method when the data is available if it's available if there are any errors then that error is communicated through the on error method here this is to say that when you have an error in your processing code you handle it in the same way with the same kind of operators as you would regular data errors contrary to the Java language designer spec are not exceptional they don't require separate control flow they're just another kind of data and so you are forced to confront that when you write reactive code in this way reactive code is a bit more functional than regular code we also have the oncomplete method which gets called when processing has completed non exceptionally okay now I skipped over this most important of methods because I wanted to drill down on this and just spend a few seconds this on subscribe' method is where we are given a link a reference to the subscription a subscription is the link between the producer and the consumer it's how the consumer tells the producer to slow down we do that by saying I want to request X number of Records if you specify it long maxvalue you'll be given an unlimited number of records but if you specify anything less than that then you'll be given you know as much as is available up to that point right so long that max value means give me as much as possible if you've got ten give me all ten if you've got a billion give me them all as fast as you can and if you give it if you specify X then it'll give you no more than X it doesn't matter how long it might be X records over X years or might be x2 echo 2 over X nanoseconds right there's no stipulation there about what that means and if you want to stop the production of data you can cancel it as well now this isn't a particularly controversial idea we're telling the producer to slow down we need to do this because our there are discrepancies between the rate of production and the rate of consumption this is something with which we've all no doubt been exposed or to which we've all but no doubt been exposed if we've had to build Network protocols right if you've ever had to think about basic networking you have to think about the reality of some things being faster than others when you get that mismatch when you get that sort of that that discrepancy then things get bad right things start to overwhelm each other this creates unstable systems this is why you can this is why it's possible to denial-of-service certain kinds of protocols like HTTP but this isn't this isn't like a new idea right if you've ever built Network protocols you've had to think about this in the context of networking from the moment we had one computer connected over a network to another we call that flow control it's a sixty plus year old idea right not even close to controversial we just call it flow control in the world of back and the world of reactive programming of course where everything that is old is new and has been rebranded by marketing the world of the word flow control has been turned into back pressure okay so when you see the word back pressure we're just talking about flow control we're talking about having a way for the producer to ask or sorry for the consumer to ask the producer to please slow down okay now we've got these three types I did say there are four there's a fourth type called a processor and a processor is just that it's a bridge it's a source and a sink it's a consumer and mr. a subscriber and a publisher if you understand those four types than your already you know you already made great progress congratulations you're certified reactive go to Silicon Valley start a new company getting millions in venture capital startup and throw different terrible parties and burn out after six months you're already halfway there that said there are some other types that support operations on these streams of data these types include mono mono comes from reactor this is not a reactive streams sort of type this is one of our types from our project to built on top of reactive streams it's an implementation of publisher from their active streams but a mono is a publisher that produces at most one value it's like a completable future that is asynchronous and also supports back pressure okay so at most it'll have one value a flux under the hand is a publisher just like mono but it's a publisher that produces 0 to n values where n is potentially unbounded it's a like it's like a Java 8 stream but it supports back pressure ok so now we have these basic types we have these types with which we can work and we have these interfaces now we can use that to write some sample data to the database oh I'll do that right here sample data initializer we're just gonna create a bean that listens for events when the application starts up initialize and we're going to initialize it by injecting a repository into our onto our object here and I'm going to use Lombok here to create a constructor for the required field so I've just created a constructor that has an argument of type reservation repository spring will see that it'll see that it can resolve this dependency by by looking in the context and it'll inject that reference for us so there we go we've got this now what I want to do is I'm create a li a publisher with some names in it so I'm Josh it's so nice to meet you I've got some other names I'm gonna add here as well and I've seen dr. Sawyer I've got viola I've got who else who else do we have we've got [Music] Stefon good we've got oh we've got my door and I need one more name one more name sorry good idea Sebastian thank you so there's some names okay we've got some names in our application and I'm gonna just turn this into an like a hard-coded list of names it's just a publisher with some names resident in memory and what I want to do is I wanna visit each one of those names and turn them into a new publisher so a new reservation rather I'm gonna write that reservation to the database and I'll store that as an intermediate type of type reservation so it's a publisher of reservations and now we're going to visit each one of those and turn it into an object that gets written to the database so here's the reservation okay all right a new reservation that we're gonna write to the database reservation deposit at save passing in our E and we're gonna save that as another publisher so what I've done is I've called flatmap instead of map and the reason is because save returned to mano so it's a publisher of publisher is what I would get normally if I used map then this would actually result in a publish of flux of mano of T and that's - that's one publisher you know level too much instead I want to I want to just one level so I could do this I could say publisher like that publisher and that would be clumsy right it'd be hard to sort of navigate that if I used map so instead I'm going to use flat map and I'll unpack that intermediate type I'll unpack the result of the save operation okay so there we go there's my four Bret there's my three levels my three pipelines and I want to run this code if I ran this code right now though you would find that there's no data in the database and the reason is because this stream this pipeline is cold you have to activate it you have to actually trigger the execution and you do that by calling subscribe which we saw earlier so I could I could call subscribe like this and it would work and that'd be fine but the problem is if I ran this code as it is I would get the same data in the database after a few runs you'd see the same data and successive runs so what I want to do is I want to create one pipeline but I want to delete everything first so I'm going to say first of all say this Asian repository repository dot delete all then we turn a mono so then I want to say run this saved pipeline and then I want to say find all the data in the database like this and then fine I'm gonna subscribe and just use a consumer Java eight consumer here to log out the results I'm going to use the Lombok annotation here to inject a logger field so log4j log info new reservation actually can just log it like this there we go now we can turn this into a lambda good stuff log that out turns it into a method reference good stuff and I've got this whole pipeline but in point of fact you don't actually need to stage these different levels as separate intermediate variables I just did that for own reference so we could kind of follow the action here but really I've just got one pipeline one stream here so I'm gonna create a publisher of type reservation called saved and in fact it's Java 11 so I can just do var okay so there we go there's my my pipeline and what I've done is I'm I'm now gonna write all the data after I've deleted everything the deletion will happen before everything else it's guaranteed to happen before everything else and remember these things can execute on different threads there's no guarantee that what happens here happens on the same thread as this and the reason is because there is a scheduler behind the scenes I can exert control over the scheduler I can say subscribe on for example subscribe on and I can provide a scheduler like this providing an executor service right executors even I can do that if I want but I don't need to in fact I wouldn't I would recommend not doing it if you find yourself doing that you should only do it for interactions with blocking code right the reason is because by default you're gonna have one event loop per core the scheduler will have one event loop for every core in the machine that is to say it'll be fine as long as you don't sit there and block the thread as long as you're doing your work and getting off that thread as quickly as possible then the default configuration will work just fine so let's see what happens if I run this program as written right now all right look at that it worked huh how about that of course it worked it was a demo what were you expecting this was always going to work this data was always going to work but I wanted to talk to you about as always and the main reason I'm here is because of this this is the ASCII art work in spring boot this art work took a long time to get right but we on the spring team have many people who are doctors PhDs people who in their previous lives worked in nuclear physics and so it's for this reason I want to take a brief moment to talk about what I consider it to be a glaring and serious deficiency in the IntelliJ branch product for a while I'm a fan I consider this to be particularly short-sighted do you see this check box this one this one right here this one do you see it this one right here this check box do you see it are you seeing this you seen the check box before you this check box once clicked don't click it suppresses the output of the ASCII art work what the hell why is this here that's a dumb feature nobody even asked you IntelliJ so I did what all people would have done in the same situation I'm not a hero I'm not a medic hero you don't have to thank me I went on the internet and I cried and I was sent a message of hope from my friend Jana Braun this is Jana Braun right here this is this is he on right here Boop this is him he's a software developer by passion at JetBrains and he sent me this message of hope which I share with you that today or not slow clap now he's a friend of mine he's a friend of mine and I want to believe him when he says that I want to believe him that it's gonna be real but you know what I'm starting to think that maybe just maybe just maybe he's not exactly on the level I'm not sure why it's taken so long but whatever anyway the point is I've got date in the database I've got my app reactive application that's all well and good I want to build a rest controller to talk to the database so I'll say reservation rest controller okay at rest controller and I'm going to inject my repository their reservation repository and I'll create an endpoint I'll say required args constructor to create a to synthesize a constructor there and I'm just gonna create an endpoint that returns a publisher of all the data okay so reservation returned this dot reservation applause did it find all good stuff and now if I restart the application we'll see that its pin up in port 8080 and I'll have an endpoint here reservations Oh voila hello come on did I miss something there it is so there's my data that's been produced for me in the reactive pipeline okay now this is it looks like spring and me see if you've ever used p.m. you see this should be very familiar but it is not spring MVC and there are some subtle differences here first of all there's no servlet API here this is built from the ground up the on top on top of MIDI okay we're not using a Tomcat or anything like that and because of that we can do some things that are fundamentally different I'm returning a publisher and everything but a fault is a publisher in spring web flux so even things that would have otherwise been sort of difficult to express because they're asynchronous and potentially unbounded like service and events even things like that become very easy to express in this brave new world of reactive streams okay so I'm going to create a service and event endpoint this is a content type of type text event stream that when the client sees it it'll know to connect and then not disconnect it'll just keep reading for the data it won't ever disconnect so it's very efficient it's gonna do polling on the client and in order to do that I'm going to create a an ongoing stream of data ok interval a message producer publisher of types String produce and I'm gonna say flux dot from stream stream generate new supplier and the suppliers gifts can return hello name at instant now and this string will be a parameter in the method here and I'm gonna stagger each production of elements each result that comes out will be staggered with delay elements so there's my my single component my little service thing that's gonna produce new greetings okay greetings or better yet I'll create an entity I'll create some types greetings request private string name okay at data arts instructor no roads constructor great and class greetings response okay and that's just gonna be a string greeting good stuff so there we go all rights constructor nor its constructor good stuff so I'll say whenever somebody says I want a greeting I'll produce a stream of greetings responses like so okay so named get name and I'm gonna turn each element in that stream into a new greetings response like so alright so there's my my little service I'm going to use that here to return the data I'll say greetings a service an event stream of greetings responses this dot where's my interval publisher there we go private final interval message producer I am P okay and I'll say this dot I MP dot British greetings and this the path variable here is a string I'm gonna say new greetings request and and that's it so I'm just gonna return that stream back to the client it's a reactive stream though it's gonna keep going it's gonna produce a new value every second so we just have to go to the browser on port 8080 SS II /ja SH like that and then we get a stream that produces a new record every one second and as we're producing new records we're not blocking the server we're not stuck on that thread producing that new value that thread is free in between the raindrops to handle other requests so you can see that this makes life very simple right you have this very sort of reactive sort of ongoing way of thinking about data and the code is not much more complicated than then in the case when we just had eight records it's the same metaphor you don't have a completely different programming model if you wanted to do WebSockets you could you would just do the same thing you'd create a publisher right that's all all you have to do is to use publishers if you want to do service and events you create a publisher if you want to just return eight streams of eight elements of data use a publisher when you're not sure use the publisher right that's a very simple way to think about it now I have been using MongoDB but and I like MongoDB it's a very nice example of a reactive driver our data support here is built on natively reactive drivers okay so this is not just a facade on top of existing synchronous blocking database abstractions we are using natively asynchronous natively non-blocking i/o underneath the hood here and MongoDB is a good example of a driver that's done right it takes advantage of reactive api's and it works nicely if you want to do Tayla both queries for example in MongoDB then that's nice it's well supported you can do transactions in MongoDB and that's supported even in the reactive API that we built on top of that so you have all the sophistication but let's be honest MongoDB is not the the biggest game in town right I think most of us are probably using some sort of sequel database who's using a sequel database somewhere in your architecture alright so it would be weird for me to say oh just ignore sequel and all the decades of experience on that and that's a very reasonable sort of response to the question of or to the proposition of reactive programming something that people pose to me all the time is how do I use a sequel database and the answer up until now hasn't been great it hasn't been very consistent because unfortunately most people are aware of JDBC and JDBC is a synchronous and blocking API so what we wanted to support was a non-blocking sort of approach for sequel data access that goes beyond what we are what we understand with JDBC um by the way I should before I move on I should also mention that while I did this using spring MVC style endpoints you can also do this using a functional reactive endpoint that we've introduced in Spring Framework five that might be more your cup of tea depending on what you like to do so this same endpoint that I just created I could have described using this as well okay routes am I okay goodbye to you and you so route rather functions out that get four slash reservations new handler function that build and so you just returned a lambda and the lambda contains the body and I'm gonna create that body by using the reservation repository I'm gonna stipulate as much by saying it's a reservation type so there's my rewritten handler function and there's some different you know different opinions about why you would use this versus that I'll leave it to you to sort of explore but the main benefit here is that we have this programmatic way of introducing functionality into the application you can it's a builder so you can actually dynamically add things to the writer functions if you like you can programmatically decide to register not register endpoints it's a it's a nice like that depends on your style you can mix and match as well there's no one one way or another anyway back to our saying we have this this this MongoDB application I like MongoDB but it's not the only game in town and we want to build to support sequel so we on this pivotal we have created a project called r2 DBC which is an open source abstraction that's designed to support not now sure remind me later what okay it's called RTD BC and RTD BC is it opens it's an abstraction that allows us to describe asynchronous non-blocking database drivers for sequel and there's a number of different implementations that implement the spi there's PostgreSQL there's Microsoft sequel server there's h2 and there's even a third party one supported by something called jaw sync that supports my sequel so there's four so far there are more coming and of course if Oracle's a DBA thing ever starts to get real then we have a binder than an adapter that will work with that as well so the point is you can use our TBC on top of anything that supports this kind of work and we use our TBC in your application but it's not yet GA it's not finished and because it's not yet GA I want to cautious caution you I want to warn you I'm gonna advise you to regard it with the same skepticism a remote nay hesitation with that you regard something like PHP I did never the two shall meet never production in PHP should ever meet right this is production production here's PHP never the two shall come together I want you to think about this RTB C in the same way and because it's not yet GA and because it's not yet production worthy I want to I have to add the configuration myself I have to do that manually so I'm going to do that over here Desktop misc depths are 2 DB c PB copy ok so I'm gonna add these dependencies this is for PostgreSQL I've got the dependency management section here and I don't need that so I'm adding spring data are 2 DB C and RT BC Postgres to my application and I'm just gonna drop out the MongoDB support here we go ok goodbye and now I need to read write my application to support this brand new world the only things that are you know the top-level things they have to do I'm changing it from a UUID to a monotonically incrementing primary key in my database and of course I have to update the repository to reflect that and and then in the not-too-distant future there's no reason to expect that this wouldn't be enough but for the moment it's not enough you need to actually configure our to DBC itself because there is no auto configuration in spring boot just yet not yet ok so we're gonna create a connection factory like so and that connection factories job is to connect to our post goes instance I'm going to use a builder to do the the hard work of configuring this now normally you'd keep this kind of information in a property file but hash tag alone so here we are ok localhost and database name equals orders and there we go there's my connection my connection information and you can see that this information is in MongoDB you can see I've got you you IDs there now let's see what happens when I we started Oh enable our TV serial posit orry's good okay so now you can see I've got a monotonically incrementing primary key value there right ID equals you know two three eight two three nine etc so that's talking to a post cos instance in the background not to MongoDB and you can see that here piece equal minus you orders orders delete from reservation okay select all from reservation good nothing in it we start and go so there's my data in the database right so you can see I'm actually talking to post guys as well so you know we can now do interesting things we can have talked to a good number of systems using the active api's I've built an HTTP service I like HTTP and don't quote me on this this might be a bit controversial but I truly believe the HTTP has a future it's gonna be big one day that said that said it's not exactly a great application level protocol is it it's a great document retrieval protocol but if all sort of application level concerns for a number of different use cases use cases that witch that were by the way well supported twenty plus odd years ago right we actually had in some ways more freedom and more flexibility as developers as engineers back in the 80s in the client-server era right in the 90s as well things like fire-and-forget how do you do fire-and-forget architectures how do you say to the server don't bother sending up setting up the machinery to produce a response I don't need it how do you how do you do server-side push all right how do I initiate a discussion from the server to the consumer from the producer to the consumer instead of having it be request for pie all the time how do i do long-lived connections one option might be service and events but server sent events is text-based if you want to do any kind of binary data you have to base64 your image or your your stream or whatever it's not very efficient right what about WebSockets well WebSockets are a bit better but that is a separate protocol first of all and second of all you don't have headers right WebSockets don't have the concept of a header how do you do security alright how do you propagate a token these are basic just super super basic concerns that every application ever written we'll always have every time and yet h-tpa fails to dress all of it right so so it's a bit of a bummer because we have to add these things we have to sort of fill in these very obvious gaps and so one example for WebSockets as we stomp right stomp is a way of encoding the message header and the payload as part of the payload for the WebSocket right it's a convention and if both producer and consumer don't know about that convention then it doesn't work it's a bit of a bummer and that's separate and apart from the payload of the stop message itself so you've got two levels of contracts that need to line up before you can even agree on how to communicate using WebSockets so these things are I think just a bit of a bummer and then like I said there's other message exchange patterns like server-side initiated there's request of a stream and response for a stream there's requests a single value and get a stream back there's a request reply with a single value in and a single value out and there's fire-and-forget where you send a single value in but you get nothing back these kinds of interactions are natural to express using TCP and UDP but they're not so natural to express using HTTP which only supports one of them requests response not to mention HC P 1 dot X supports text based communication right it's not binary by default and so this is a one of those things that gets fixed in HTTP 2 but you still have all those other limitations the result is that in order to communicate binary data you have to base64 encoded send it back to the client and then the client on you know unencoded it's very inefficient because the data started off is binary in the first place we just mule it across the wire as text to be able to use HTTP so a number of different companies have faced these limitations and many others and they've decided that while HTTP is great for the open web it's not great for sort of homogeneous application level integration Google very famously created J RPC G RPC is a whole whole technology stack dedicated to solving and fixing some of these limitations in it it requires that you communicate everything in terms of Google protocol buffers so that's a bit of a bit of a bummer as well because you might want to use other kinds of encoding x' and it's not by default reactive it's asynchronous but it's not reactive salesforce created a compiler plugin for pro talk which is the erp c compiler they can create a compiler plugin that will code generate reactor base 2 services for you right so they're using reactor in salesforce using GRP c+ reactor from from pivotal right to scale there's another fairly big website that one day I think has a future maybe called Facebook there are kept aside based in California that uh I don't know what they do but the point is it's apparently they're very popular and they want you know so in order for them to scale they hired a number of engineers a lot of whom came from Netflix and the team from Netflix that they hired in particular worked on rx Java and they worked on their active stream specification they went to Facebook and they were trying to solve the problem of how do the services communicate with each other and so they created a protocol called our socket it's an open protocol and it has a number of different implementations it's a wire protocol that is natively reactive by default out of the ground out of the box it has in the protocol ways to do different kinds of message exchanges its payload agnostic it doesn't care whether it's text or binary or whatever and it has concepts like headers and it even has concepts like uptime how do you communicate how do i as a server as a service communicate to my client my load my uptime my availability if you're using spring then you've no doubt heard about the actuator the actuator communicates this thing but it's sort of a thing that we do by convention isn't it it's an out-of-band thing that the client needs to know to look for on the service right and that way they can figure out what's your availability what's your uptime if I make a request to you will I get a response back so we can use our socket now we have native support for our socket in in spring in Spring Framework 5.2 which is coming out this year so what I'm gonna do is I'm going to build a new client here okay that's gonna be our socket or sari client I'm just gonna use our socket to to to Lombok reactive web and that's it here we go quick as possible so the goal here is to make this as simple as easy and easy as possible our socket is payload agnostic but it doesn't support routing right it doesn't know about routing so in Spring Framework 5.2 we've got support for that you can say add controller class our socket greeting controller okay I'm gonna create a message mapping endpoint that does routing for you this is spring and it's gonna be a publisher or a flux in this case of type readings sponsz greet and we'll be agreeing requests okay there's be the payload request and our socket is easy to integrate in spring because of course the Facebook team that that worked on Netflix wanted to choose a Java library to build their Java client and it's only natural natural I say that they would choose of course reactor from pivotal so they did that and so it was very easy for us to integrate so we've got this can we've got this server-side thing I'm gonna say proves the greetings taking in the request so I'm just gonna send back this reactive stream that's never-ending reactive stream I'll send it back to the client as fast as I can our socket here we go is gonna be port 80 or 8000 I'm gonna restart here and on the client side when I create a very simple client that will just start up and produce the data it'll stream the data back to the client using service and events I'm going to create a thing that uses spring web flux and then it in turn calls using our socket in order to do that I need to create an our socket object here okay our socket return our socket factory connect dot data mime type mime type utils application checks value frame decoder payload decoder zero copy Transport TCP client transport I'm going to talk on port which port do we say we said port 8000 support 8000 dot start dot block okay there's my our socket client and I'm going to create a beam of type our socket requester this is the like the web client or the react or the rest template if you will of our socket from spring okay so I'm gonna inject this and we say our socket strategies dot that's alright our socket client requester dot create passing in this dot our socket passing in mime type application JSON and passing in strategies okay so there's right our socket client and all I'm gonna do is I'm gonna create a simple endpoint an HTTP endpoint that's a service end of an endpoint that's going to communicate the streaming data across the wire here okay so getting mapping SSE no greetings name and actually here static class greetings rest controller at controller and publisher of greetings response I'm gonna do something terrible something that you should never ever do ever I'm gonna copy and paste some code here we go where is that code here we go go go go paste there's my type so that I have those four communication greetings response greet okay return and this is the type let's just clean this up a little bit here for getting crazy good okay so I'm going to use the our socket requester our socket requester required args constructor and I'll say this dot requester dot grew out greetings dot data and the data that comes in will be the path variable that I'm gonna turn into a our socket greetings request new greetings request passing in the name and in and then the data that comes back will be a stream right so retrieve a greetings response dot class and it's going to be a service in event just like before so I'll say it produces media type text event stream value equals this if other okay so there's my name there's my greeting request I'm sending it to the server I'm getting a stream back I'm going to spin it back to the HTTP client okay oh this will be on the wrong port server dot port equals 8081 restart go go go localhost 8080 one and we called this endpoint sse greetings n go to no handler for destination greetings what did I call it over here come on they're greeting Santa Maria so reading all right there we go my friends so you can see we used our socket to communicate one from one service to another we did it in a binder way it's super efficient we don't have to worry about the communication we don't have to worry about how it's encoded in this case it can be JSON but can also be protocol buffs or thrift or whatever um I hope you see that there's a lot of opportunities here a lot of potential I want to thank you so much for your time and I would encourage you to join me in my master class later this week thank you so much so much go - I appreciate it Cheers [Applause] you
Info
Channel: GOTO Conferences
Views: 40,181
Rating: 4.8965516 out of 5
Keywords: GOTO, GOTOcon, GOTO Conference, GOTO (Software Conference), Videos for Developers, Computer Science, Programming, GOTOchgo, GOTO Chicago, Josh Long, Pivotal, Spring 5, Spring Framework, microservices, Spring Boot, #Spring Security, Reactive Spring
Id: 1F10gr2pbvQ
Channel Id: undefined
Length: 53min 42sec (3222 seconds)
Published: Tue May 28 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.