How Fast is Spring?

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
so I'm Dave it's 2018 and it's time to talk about so I'm work that I've been doing actually on and off for quite a while now this is the first time I've presented it to you know an audience like this it's not like I've been doing it in secret so I mean like you might know about it already but it's actually the first time that I've done a sort of formal presentation on this topic so it started it's been a bit of a personal obsession of mine a sense it's driven some people a little bit mad for which I apologise but it was worth doing and it started a while ago because I didn't oh I can't even remember exactly when it was probably more than two years ago we were still working on spring boot 1.2 I think maybe 1.3 and we were having trouble with the Java file format fat jars you know they were a little bit slow at the time so I built a benchmark harness framework thing to measure measure the jar file startup times and we made some improvements and spring boot 1.5 was awesome as a result of that not just as a result of that but you know more awesome as a result of that and so then I just kept going and spring route 2 came along and I you know I was able to give some clear feedback to the spring Blue team when they were in the middle of that cycle that you know things were regressing and so the message I guess is that you know somebody is always there measuring performance in spring boot applications in particular and course correcting you know we've do we've done a lot of work here and so this is my chance to show you a little bit of the results also a little bit of the techniques that we've used to do the measurements and so you can spread the message right how fast is spring so part of that question will be answered if we actually stop to think about how much work at runtime is spring actually going to be doing compared to the real stuff right the business logic the answer is not very much actually when it comes down to it and it was designed that way I'll be talking a little bit about the tools like I said that I've been used to using to measure this stuff some of them were new to me and it's been interesting they might be new to you there will be some comparisons that I can make between various different choices that you make when you build spring boot apps and run them so a different kind of packaging options different kind of you know dependencies that you might choose or not choose and I'm going to talk about how to make it faster I'll just speed it up and I'm mainly going to focus on because this is what I've been looking at and for the last six months to a year mainly going to think about startup time from you know coal startup clean JVM nothing's happening we start a new process how quickly can you get to the point where you're serving traffic on a web endpoint so I mean that's not the only topic of you know speed and spring but it's it's a big one because you know we live on the JVM JVMs were not really optimized for starting up first that's that's you know that's let's throw that out there that's the case so we have to kind of just work with what we've got and the problem really there which you'll see as I show you the the results so the problem there really is it's a very short term thing right at the beginning when the JVM starts it has to load a load of classes you know if you're running a spring boot app with a a web server and serving HTTP you probably need to load at least three four five thousand classes so there's all those classes to come the bites have to come out of jar files they have to come out the right jar file you have to find the right jar file to pull them out of you have to parse the bytes turn them into something that's you know executable and that is at least until the end of this presentation there's nothing nothing much you can do to get away from that right the JVM is always going to have to do that and the only saving grace really is that it only has to do it at once right it just a little blip had startup you need a little bit of more CPU a little bit more resources when you start up then he will when you're running you know in quiescence at least anyway in the long run so the JVM just has that feature and I'll be looking at quite a few things that we've done in spring to make that blip that startup blip as comfortable as possible you know so we get out of the way as quickly as possible and let you start doing the business stuff so I'll talk about how you can do that and I'll talk about and some future looking things and you know what am i planning to do next or what are we working on at the minute I'm some very interesting stuff if I manage to get time I'll show you everything so I think I might just start with a demo actually that's always a good start isn't it so that's eclipse this is my workspace I've got some projects I might show later but at the minute I'm just going to create a new one spring starter projects I'm gonna use spring beat 2:05 to start with okay because I want to show you some developments I guess I'm gonna use neti reactive web and I'll tell you why and what the difference between that and the other web stacks is later so it's just a spring be web flex app so it's going to have a bean four roots Ridgid function of anything and then I can return reader functions dot and I get so this is the home page is a handler that takes a request and just returns an HTTP okay with a body of just hello yes one p okay so that's you lot string dot class okay really simple really basic I need to import that class okay I can run it I just used to come at a keyboard shortcut there maybe I didn't maybe I'll do it this way run as java application okay it is running as it running but can't run because it's got it's already running okay there we go run as java application let's do this cleanly and there it is okay Nettie started on port 8080 in two seconds - it's my laptop it's not great right it's a couple years old if I do this at home I can make you start quicker so there's spring v 2.0 I could fiddle with it probably to improve it but let me show you all the things I can do to improve it by making a copy so I'll call that one old because I'm going to use it later and I'll just take the one that we're running and I'll upgrade it to two point one point zero he dares me to do snapshots that's right one m4 just came out which we will try in four two one zero and four I could I could run that now and I could show that it runs faster it does but there's some other stuff that I can do and since we're kind of short on time in these presentations I'm just going to do a bunch of things and show you the cumulative effect of improvements okay so I'm gonna do some class path exclusions hibernate validator I'm not using it so I don't mind excluding it that was just included with spring beat because I used the starter I'm gonna exclude this one is interesting Nettie has a native handler for the poling leap and I think we'll I'll put that back in in a couple of weeks when we get to the bottom of it this was a regression like between spring boot to 1 0 m2 & 2 & 0 & 3 it's suddenly caught using this caused things to slow down a little bit it's at runtime I can show you where it's low so and I can't understand why yet we haven't been able to identify the source something in spring spring boot nettie or reactor Nettie has changed in the last two months lots of things changed but it's finding out which one actually caused the problem we haven't been able to do that so I'm going to exclude that I'm gonna exclude log back so that's the standard spring be logging starter and I'm gonna exclude Jackson Jackson to be fair isn't a very big culprit here it doesn't it doesn't cost much but it costs a little bit so I'm just gonna exclude it so you can see if you if you want to do this yourself you can try each one individually and see what the effect is for each one and it will be noticeable for everything but not much for Jackson it has to be said so that's almost all I have to do I'll just exclude those things and then because I've excluded log I don't have to put back in an SL f4j of some sort so I'll use the least nice to use but the quickest which is the SD the JDK one okay so then I probably need to just keep your Clips happy so that's your rebuild like project because I changed its parent I'm also going to do a little tweak of the the runtime arguments the vm argument so i'm going to make those go a bit quicker so i'm gonna copy those from one that I created earlier so I'll show you these properly on the slide in a minute so you don't have to read that but it's some JVM arguments and then I run it okay and then when I run it it stops because port 8080 s and use and then I do it again it's a standard demo procedure there we go so it's now down to nearly a second if I do it again a few times I expected it to be a bit faster than that actually saying let's see if there will be yeah so you guess you get it under a second if you do that so that's not bad right that's really not bad at all okay it's a it's a real app is serving real HTTP traffic so it's not it's a little bit of a toy because it's just a demo but it's not stupidly unrealistic it's got a spring boot it's got you know configuration file handling all that the spring big features it's got everything that you would you know need in production probably and it starts quickly so what's the difference it's interesting I only show you some pictures and then I'll come back to that so this is a story of some of the work that we've been doing I guess recently this is a little bit out of date now but it's roughly accurate we started sat down with Andy Wilkinson about I didn't comment but it was probably June not that long ago a few months ago spring boot 2.1 was sort of underway and so we started with a baseline of a demo application that we're starting in this says 1300 milliseconds so I mean that the AB the absolute numbers are actually not that important it's the relative improvements that are good and then we made you know a few little changes so this one shows what happens if you switch on the famous spring component index actually I didn't do that in my little demo there did I so that's a tiny increment but it's measurable okay that component indexes it's not gonna it's not gonna you know bust you down to zero milliseconds but it does have an impact if you want to do play around I'll show you some more of this stuff later if you want to play with lazy initialization you can make all your beam definitions lazy so spring boot creates you know beam definitions that it thinks you might be interested in it's opinionated and I like that but if I'm not going to use them then actually keeping them lazy sometimes that improves things I could have yeah there isn't a feature in spring boot lets you do that with a single switch so I can easily demo that but it works and then we started looking at what was actually happening so really trying to optimize things so up to now that was just sort of playing games but when Andy in particular Andy started looking at something some code in Spring Framework and I'll show you the tools that he used to discover it there was a garbage collection problem in deep in spring like auto wire capable bean factory he's ever even looked at the code for Ottaway i capable bean factory i know a few of you have taylor yeah [Laughter] [Music] so yeah and he just he looked at it he's good at that I think he looked at insane oh wait a minute I think I know what's going on here and I'll try and explain it I'm not sure if I can explain it as well as he could but this is something I didn't know before so if you know about heap right the heap memory and garbage collection and one of the main things that the garbage collector does in the JVM is try to keep your heap as small as it can or within the bounds that you've set it but another thing that garbage collection is responsible for which is actually really important in this phase in particular staffing up is if you're creating lots of temporary objects so you're inside a method and you're creating objects and then using them and then throwing them away again they never escape that stack frame they never get into the heap actually so they're never going to be collected using kind of standard garbage collection but they're taking up memory and the JVM is accounting for them and applying pressure to garbage collection so if you have a lot of temporary objects being created in a tight loop which is what Andy spotted it can lead to a nasty blip on your startup time and not just out of time but also the heap usage ultimately ends up being a blip as well so you sort of have a resource spike and not just CPU but also in memory usage at the beginning of the app so Andy found the one place in spring where we could just get rid of 90% of it there's still some work to do ok and we're still working on it that was amazing and I can I can probably even show you that I kind of live here so because I've got these two apps right the one that I just made from 2.0 and the one from 2.1 so if I run that one again that I ran a run already and I'll copy another command-line argument from one of these so I'm gonna add an agent to do profiling and I'll show you this again in gory detail let me get back to whoops when we get back to slides sorry I just popped that window closed I didn't mean see what I meant to do is just paste that in there so there's an agent called async profiler and this is going to be the two point one so I'm gonna make a file I didn't if you can't read that essay okay I'm gonna make a file called flame two point one assuming I don't crash pictures there we go right so it's that's up a little bit slow because I've put a really tiny sampling interval in for the profiler it's actually quite impressive that it's so good because I'm literally collecting a scan of data there and this is a tool that you can use to analyze your own apps right if you have an app that starts up slow then this is a really good way to investigate why it won't be spring at this point I'm pretty sure it won't be spring is going to be something else so here's flame 2.1 and so these flame drafts are really awesome they actually maybe I should have shown the 2.0 version first let's do the 2.40 version as well and maybe I've got one just there I wanna see might have prepared it earlier save me getting through the rigmarole see if it's still there yeah it's still there in 2.0 it looks like that no that's wrong I don't have to do that again I must've just labeled it wrong I keep under adding these things over and over and I create the file but I didn't necessarily correlate the file with the so now I want to have the old one which means I need a launcher for it come on so I'm running that one again so that I can modify the launch and I want the launcher to be like this one the one that I just did right that that flame graph so I'll make it the same - I'll just copy the whole thing and this time I'm gonna call it 2-0 oops that's gonna crash bigger supports in use yeah you think the number of times I do this I would remember that it's obvious okay so let's see if that changed anything I think it probably did yeah there we go so this is the signature this little orange and red mess down the bottom here and you can hover on them and you can see from the labels that on the flame that this is garbage collection and it's not regular heap garbage collection it's this garbage collection pressure created by temporary objects in spring beat 2.0 because if Spring Framework 5.0 so that's something that we changed in 5.1 and now it looks like that alright and that is the difference that's your two hundred three hundred milliseconds whatever it is it's a big chunk of a tiny app's initial startup time but even more importantly it's reduced a lot the garbage collection pressure so that's the time of previous for spring via 2.1 garbage collection pressure on startup is much lighter so you can do you can generate this kind of graphic which is what Jurgen showed on Tuesday morning so well this is showing you is the blue one is my 2.0 sample the one that I just showed you and what I did was I constrained the heap so - xmx you start with 128 megabytes 64 32 32 vias here actually probably and I just kept shrinking it until and then I measured the startup time okay so it is about you know 1315 hundred milliseconds or something at some point it hits a wall hockey stick out of memory is what happens at that point right so I can't collect any data for a smaller heap for that application I switch to 2.1 and a it starts up a bit faster okay with all the same flags there's nothing hidden there no cheating like I just did this is what's interesting I can push it much further I can get to you know 10 megabytes even eight megabytes of heap with a full spring be application creating all the beam definitions that it really doesn't need and you know all sorts of inefficiencies that I can also stamp on if I'm careful I can get that down to ten or less megabytes of heap this app I'll show you this out later on is starting up even faster twice as fast and I can push it really far like you know I haven't actually seen a hockey stick on this one it just limps along I couldn't find I couldn't run it in four megabytes of heap but I could I could I could see it still running a you know five and six megabytes of heat so that's amazing and that is a fully leaded spring bleed application I'll show you a later on it's just constructed differently than the demos that I just gave you and that's you know that wouldn't have been possible without the analysis that Andy did and the fixes that he proposed and the uragan implemented Jurgen has been great about this you know every time we find a problem and I wasn't the only one there have been a few if there are lots of it reflection optimizations as well caching and avoiding using it where possible so we're working hard on this though the flame graphs actually so the same two pictures I just showed you and the highlight is really the red bit but apart from the red bit you can see they do roughly the same thing right they're the same app so you'd expect that they're just running on a different version of spring beat it's a way to read these is there's a big fat Empire State Building in the middle that's gonna be Nettie and Webb flux actually as a web flux and Nessie is the little skyscraper next to it so most of the work at runtime is doing something that you actually want to be to want to be happening right you do want to start a web server so that's good and these are these phone graphs by the way they're brilliant you can you can do search inside the flame graph so I can for instance this is I know this is going to be an interesting one configuration class post-processor okay I spelt it wrong Eurasian class it's what I'll just search for that there you go that's interesting right that's gonna feed back into some of the expect experiments I do later so that's the cost of processing at configuration in spring be 2.1 you know there's a lot of work for it to do so it's fine but I'll show you what we can do to hammer that down basically this I just generated this didn't I yeah so we've made some improvements already when I started this you know three or four months ago this was even broader than it was than it is now it's getting better all the time okay so it's back to the sides maybe let's see what we've got here so for those of you who just now want to go and have lunch or go and see somebody else's talk this is the too lazy didn't read how do I make my app go faster these are all things that I've found that have okay so in no particular order I'll show you the details of each of them this is just a tldr ain't some class path exclusions you saw me doing that you know hibernate validator if you're not using it you know leave it out the spring context indexer it has a tiny effect on especially on these tiny of apps but if you've got an app with hundreds of beans it's probably gonna be worth it this one's hard to say because actuators are mine and they're my baby but they do slow you down on startup so if you can afford not to use them it's actually worth thinking about I don't I'm not sure if that I know I'm not gonna recommend that but it's I'm pointing out that there are they're a little bit of a sore thumb I'll show you some tricks later on for dealing with that definitely use the latest right because we're working on this stuff all the time spring beauty point one spring five point one in particular has made really big improvements I think we're working on this in spring B but for the minute at least anyway spring dot config dot location is where spring beat looks for your application properties file and it does you know search in various locations for it so if you tell it no only look in one place so if you make an explicit configuration of that and point to a single file then it's much quicker switch off jmx if you don't need it right it's on by default it's nice so have it I actually I mean in production it might be used a useful but not all production environments even support it right so if you're running in you know ideally AWS lambda for instance you're running on a container platform where you don't have access to J max anyway you might as well switch it off lazy beam definitions I'll show you how to do that it's not the feature that we support out of the box yet this one's important so if you're building a container does anybody come to my riff talked yesterday nobody okay if for instance if you're building a container but even if you're not if you can unpack the fat jar and just with Java - CP it's quicker I mean the fat jar is brilliant and it's really convenient but if you want to run it faster you don't start up faster then you know it's it's a little bit of a bottleneck I can show you how much of a bottleneck you forgot I forgot time last year though I was gonna plan to do that JVM flag so the ones that have the biggest impact I did a lot of copy-paste they're the one that had the biggest impact was - no verify that actually probably took my that if I'd done that in my spring be 2.0 app that would have taken it from 2.3 seconds down under 2 seconds probably down to 1.7 or something that was the biggest effect I'm also saying consider tiered stuff let's stop at level 1 because that will interfere with your optimizations later at runtime so it'll quicker to start up but then slower in the long run so you know swings and roundabouts and almost last but definitely not least use functional beam definitions if you can that was the bottom hockey-stick line there wasn't a hockey stick I'll show you what I mean by there we've got some examples coming up and in brackets at the bottom it might be something that you can do in the future build a native image Sebastian has been working very hard on that Jurgen is very cooperative and the grow vm team trying to help us now as well also if you feel like you know you've seen enough and you want to go just here's some messages I'm gonna show you all the gory bits in a minute but these are the messages that I want you to take away all right spring was designed ab initio from the beginning it's always been lightweight it does very little unless you ask it to so just you know think about that it really does very little unless you ask it see we care about it so you know I'm measuring this stuff all the time it's been a little bit of an obsession of mine but I feel like we've had quite a big impact we care about performance we especially Phil Phil Webb he has sleep likes poor guy I mean he cares about you know too many things basically but one of the things he cares about is performance so this is at this point worth making worth making there are many optional features in spring you don't have to use them all so a few you use the less classes where you will load the less classes you will load the less time it will take to get started okay so that's one of the things I was doing removing stuff from the class pass rain I was just kind of really reducing the load packaging okay exploded jar with main application is best I think with the actual application main so there is a jar a main main method in the fat jar if you can still use it and still faster if you unpack the jar but it's not as fast as running it using the kind of native main here's something that people are always surprised about I have tried to find a difference between tomcat Jesse and undertow there isn't one believe me you can't measure it does anybody not believe me talk to me later nettie of course is a bit faster on starter as is undertow if you're only using their native API so if you're not using servlets then you know they can do quicker things because they're basically nettie so in SE and I react to startup this a bit faster you wouldn't notice it in a large app there because you're talking the difference between in my little tiny app right say one second to start Nephi 1.2 to start Tomcat in jetty and undertow it's like you know it's a couple hundred milliseconds you're not gonna really care about that if it starts in 30 seconds anyway right let's face it okay so this is the important thing the more features you use the more classes you load so the more work has to be done and the only thing that will save you from that is native image generation the only thing there are some mitigations and I can show you I'll show you a few of them actually you can improve that even without taking features away but you can't you can't get over the fundamental problem that classes have to be loaded and if you look at the I'll show you the tools if you look at the profiles the profiling data different startups it's all about class loading all of it functional beam definitions I'll tell you what I mean by that if you haven't seen it before it's important and the way to get to less garbage collection and first a startup time is functional beam definitions it makes no difference at runtime once you've got the app running no difference right well it's just about the recipe how do you create the beans in the application and you know you've seen it right I demonstrated it spring B will start up easily in less than a second and less than 10 megabytes of heap so don't let anybody tell you otherwise mmm now might be a good time to do this does anybody know what this is I don't know if the camera can zoom in on it it's a Raspberry Pi thank you Raspberry Pi 3.0 3 plus I think it's called and I've connected to it with a an Ethernet cable and it's alive ok so I can SSH into it shall I make that fund a bit bigger so raspy Perry is a small computer right very small they're very powerful because I can run spring boot applications really easily so actually I should pick one that's most like the demo that I just you just saw oh I'll tell you what I'll do with this one this is a group of demo apps that I put together I see in for barcelona spring i/o this year and I've been working on it a lot so it's evolved but there's some apps here and okay so this is Raspberry Pi I've got Java obviously maven I've done the bills so there's a jar file here I can it's a thin jar file so if you've never seen these before this is kind of cool I can run this jar micro and I can use it to compute a class path so the reason I'm doing this is because I want to run with Java minus CP not with Java - jar Java - jar is always a bit slower that's all so I'm gonna use that to compute the class path it takes a doll you know this is pre computing stuff that otherwise it would have been doing at run time and this is by far the slowest step so it's good that you can pre-compute it there we go it was like amusing snapshots so actually what it was doing was mavin dependency resolution finding the latest snapshot and that's why it took a bit longer if you don't use snapshots it's much quicker now I can do Java minus CP dollar CP and I'm just gonna also copy all of those go-faster flags from my application here oh I deleted those by mistake okay Celsius was everything except the profiling agent put that in the class path and then I'm going to do comm dot um example demo demo application so this is the same app basically it's a web flux app with a single endpoint sorry what that done the - at the beginning okay yeah well done thank you somebody saw that before I even hit return well done there it is I added a custom bean info factory which is what they're all that logging is about and I'll tell you about that later if I get chance that didn't improve the startup time or anything that's just there for other reasons okay so here we are it's home 7 seconds 8 seconds but this is tiny right it's about three times slower than my laptop but I think that's pretty good actually not bad at all if I run one of the other apps in this micro apps collection so there's one called funk bunk which is the orange hockey stick graph that one is a spring boot application that has functional bean definitions and that starts in four seconds actually spring boot says it's only been working for three and a half so that's not bad T right there's another app in there which is not using spring Peas but just to show you it's got the same features it's an HTTP server with an an endpoint that says hello micro application there we go two seconds so am I on my laptop that would literally start in you know 500 milliseconds on I've got a desktop bell tower books at home and it's like 300 milliseconds and that's spring right that's not spring pea with that spring so spring is not itself at all slow okay so some of the tools I've been using benchmarks I've been doing a lot of you know careful don't worry too much about the links I'll show you a link to their slides at the end and then you can click into all of these things jmh is a tool from the jdk team and you can use it to write test harnesses so i wrote one that kind of works with spring pea apps the profiling thing that i showed you with the the flame graphs that was called a sink profiler if you haven't seen that before just google it it's a great little tool it's um it's not just useful for what I showed you can attach it to a running app and if you're not sampling really finely like I was it's it has a very low impact runtime on a running app and you can collect that kind of flame graph data from from a live application without really interfering with it too much the thing that Andy used to discover that garbage question garbage collection problem is flight controller otherwise known as why do they call it JMC Mission Control right so if you look in your Oracle JDK or you're you know open recent build of open JDK you will find a command line tool called JMC and it's that's what we use to measure the garbage collection pressure if I've got time I'll show you that there's a little utility that I wrote which you can maybe I'll just demo at because it will show you the difference between fat jar and exploded so the desire github organization spring boot startup that there's lots of stuff in there that's the first project I ever did like back in spring the 1.2 1.3 whatever it was and it has now this tool that you can use so if I was just back on my laptop so I've got this same mic perhaps what is it I use this one no I'll go into the demo app that we just built dev demo workspace jmo okay maven clean install because I want the jar file I built this from start dot spring dot IO so it's gonna build me a fat jar by default demo there it is 13 megabytes so I could run that or I could run some benchmarks on that using a utility so Java - jar from that benchmarks project so damp dev beat would I keep it startup launcher target so the jar file that you build in that sub project of the startup benchmarks you can run that benchmark and you can give it a another jar file as an argument and it runs a startup benchmark for you oh I'm using the wrong VM just a minute SDK use Java 8 Java 8 is still the fastest by the way I'll get into that later so it's gonna run what it's doing is it's taking that jar file and it's creating a new JVM running it with Java - jar essentially well actually literally running it with Java - jar and it's looking in the law it's following the logs and waiting for it to see that it started up and then it's shutting it down and then starting again so it's a brand-new JVM every time you see this spring boot logo that's a brand new JVM so it's doing the whole thing and so and so these numbers that you're seeing here are the startup times end to end right from the launching the process to seeing the ready message essentially on the terminal and this is the last one coming out now I wanted to do this because some of the slides coming up have got tables of data they look a bit like this so there's a result nicely summarized the first one is the fat jar run natively like Java - jar okay 1.4 seconds second one is exploded jar and then using the jar launcher from within the jar so it's actually strangely a little bit slower right it's because the jar the jar launcher is really optimized for looking inside its own jar it's strangely it's a bit slower I think that's what's happening there and this is the one that I'm interested in so if I explode the jar and run it with the application main 1.2 seconds so that's you remember when I was running it in my IDE it's the same laptop so that was reporting the spring beat startup time was like 900 950 milliseconds or something so there's a little bit of extra overhead here which is JVM taught startup time but I didn't even before spring be started I didn't manage to measure that in the spring beat metrics so that's really end-to-end JVM startup time so that's nice little tool you can reuse that right you just need to build that benchmarks jar and you can run any spring boot jar and you'll be able to you know measure startup time and see if it's a problem most people I find if they have a problem we start at that time it's probably more likely to be in integration tests actually is that what what your experience is you don't really care that much about in production whether it takes 30 seconds or one right that you do when you're sitting at your laptop and you're doing integration test so we are all say we all do we do also think about that problem I'm just not going to have time to demo any tools in that space at the minute so that's a benchmark jar from the benchmark repo class math class profit manipulation is just a something that you can do at run time if you want to you can build your jar and then you can change the class price right and it will still work that's the way that spring boot is very forgiving in that way right if you take stuff off the class path it'll just stop using it so that's useful and I've been using this thin launcher for class Pratt's manipulation hi this is a project that I started and I invite you to go and check it out it's it's something that you can use to build executable jars that do not contain their own dependencies so that the dependencies are get looked up at runtime that you can pre-compute them and the other thing that I've done quite a bit of and I could also recommend you look at is using aspectj to you know intro intercept parts of the spring lifecycle and just see what's happening where by doing logging now old-fashioned debug logging you can get a lot of information that way and aspectj is very powerful there are some utilities that I put together in this this is just a spring boot aspectj demo project that I just threw on github but one of the libraries one of the modules inside there is called timing and that's got some sort of general utility profiling aspects that you can just switch on using low time weaving to look at various things as they start up and you will be able to for instance use that to see if any of your beans like you know if the business logic is doing too much at startup time you'll see that in the in the profile that in the profile logs from that so I found that quite useful okay so this these are some numbers these are the static benchmarks from that repo that I just showed you and so inside that repo desire spring boot starter bench the top level of that repo is mainly focused on two problems we were looking at when I first started it so fat jars and the difference between 1.3 1.4 1.5 if you go inside the static benchmarks I used that to measure this basically so this is a nice plot of the number of classes loaded along the x axis versus start-up time in milliseconds on the y axis and it's not really a straight line you can tell right but it's a very tight correlation and this is you know starting at the bottom here this is the smallest spring app that I could make run right and it literally starts in less than 100 milliseconds probably hundred milliseconds tops and as you move through the sequence here at the top end you've got everything in spring cloud zoom all the Netflix tach hysterics you know it's going to be expensive we know that it's gonna do a lot so it's giving us a lot of features this one here is interesting that one is I believe a a very small hibernate app it's interesting because it look at how low below the correlation it is actually so hibernate is it slows me down because I have it does a lot right it's good gonna load over 10,000 classes to get that out running but you know pound for pound it's good so the over nari go is a well aware of these garbage collection issues on startup they've worked really hard to to get it to there but that also shows that you know probably we can keep keep working on our side we can keep optimizing that kind of thing and things will get better an early version of this had a big blob up the top there it was not seen sitting in the front there it was sleuth every time you put sleuth in an app it went wolf up there and I thought that can't be right it's not doing very much right and it turned out it wasn't sleaze really but you know this lease was introducing the problem in some ways it was aspectj and so I spoke to my friend Andy Clement and he said oh yeah I haven't looked at that for a while and then you know half a day later he had a fix and aspectj 1.8 point 16 or whatever it was was released and then he went back down say isn't actually expensive at startup time at all aspect was and that also now isn't okay so I flashed up the numbers a bit there the I guess the headline here is that this is a sequence from an app with the actuator so this is running on different hardware this is on my faster box at home so it's a little bit faster actuator jdbc there's just the canonical nettie demo that i've just done so a second and then this sequence may takes away various things and at the end I end up with a purely functional beam definition version of this the same app it's got you know an endpoint HTTP endpoint and it's running in you know 600 milliseconds and I'll be showing some of that in a minute that's basically the bank application it's a different in different incarnation of it the difference between demo and slam is sort of interesting if you click into this link you'll see a description of all of these labels the difference between demo and slam is slim doesn't use at enable auto-configuration not much in it I was quite quite surprised about that and I'm actually going to go back and look at that because I didn't quite believe it but the difference between those apps is literally one of them manually in thoughts all of the configuration it's going to use and the other one does at enable auto configuration so Otto configuration isn't all that expensive that's all I'm saying it's much less than you think it would be I think it's more than that but it's much less than you think it would be I also wanted to ask the question what had was the difference between Webb flux and not Webb flux so although that although these ones actually although they were sorry these ones although they were on a different different faster Hardware they're all using Tomcat so they would be even faster if you just were using Netty so then I did the neti testing and this is now we're starting to get into the territory of the micro apps but they're in this spring boot starter bench projects as a sub as a subfolder the main one is the app that I just showed you and the difference between J log and demo is that those classpath and saturn exclusions basically so Jackson and Jackson and log4j not log4j log back and gets you you know 100 milliseconds there that's the difference between J log and demo and these ones are just smaller and smaller micro is the micro app that I ran on the PI just now it took for two seconds didn't it on my box at home you can run it in will look less than 200 milliseconds I mean it's not using spring boot but it is spring and it's using nettie and it's serving you know content on HTTP so if spring isn't really not adding very much it says ring is hardly there it's just you know managing the show you basically I did various jvn tweaks on the demos just now so I had this know verify and teared stuff at level one I talked about it is also still just about worth doing this and I thought I'd put a special mention on the slide about that it used to be a real problem with Tomcat especially in a container because in a container environment you've got to share entropy with all the other containers say it was much faster if you had the non-blocking random secure random they fixed that in Tomcat I believe so that no longer is a real problem but there are still a little bit of entropy needed by spring I can't remember where it is something to do is date time for matter or something like that you end up needing a round of a number I can't even think why that is but it's hard to switch it off anyway so it's it's a minus effect so it's probably not worth it anymore but I'm putting it up there because it used to be so if you hear about it then you could probably say well actually we don't need that anymore it's ugly and we'll leave it out this one's interesting so how many people have heard of open j9 a bunch so we have some friends at IBM they are very active and in the JVM space and they relatively recently I think within the last few years open sourced JVM implementation right so it's etc etc from the hotspot it's not this the Oracle JVM a uses all of the code from open JDK but it's the IBM optimized you know the garbage collection and the JIT compiler and all of that stuff is IBM specific so you can download and use that that's you know free to use open open G open j9 and the thing that they have which is neat is which is what true my attention is class data sharing so you remember I was talking about startup of spring any app any applications to startup have a JVM applications you need to load all the classes and that takes a lot of CPU processing some of that work can be cached and class data sharing was a feature that IBM and Oracle introduced to enable multiple applications packed inside the same application server right in WebLogic and websphere to share memory now I'm not using it for that if I'm just using CD S on a standalone app it's especially if it's in a container it's hardly likely to be sharing that data with anybody but it still does actually improve the startup time and if you want to run multiple apps that have nearly the same class path roughly then CD S is a really nice thing and you can switch it on really easily and nicely in open j9 you just have these like three flags to say this is the size of the cache to use so you can change how much data gets cached and it does have an effect I'll show you the graph I think there so um see if I can highlight this so that the red the red line is open JDK and the see if I can get blue the blue line is open j9 so it's always a little bit faster not a huge effect five 10% maybe but you know the bigger the app that bigger the effect so that's interesting go away okay um yeah I'll come back to that Java 10 jar 11 you might think the be some improvements there might be I don't know I haven't really seen it yet there is class data sharing now in Java 10 and Java 11 it's a little bit more fiddly to deal with than that and it but it has roughly the same effect it used to be a commercial only feature so Oracle used to always had that in then the JDK I don't know when they introduced it but you could definitely use it in Java 8 that you had to switch on commercial features and pay Oracle money to use in production Java 11 isn't any faster than Java 8 it's slower in start-up time I mean it has garbage collection improvements that will probably mean that at runtime you might have better performance but startup time it won't help Java 9 was awful there was some bug in the class loading so it was even slower they fixed that so Java Tannen jar 11 a better than Java 9 but they're not as good as Java 8 Java 8 is where you want to be if you want to start up quickly until such time as we can all try the ahead of time compilation so you've probably seen demos of that I'll do one later on if I've got time there are spring apps that you can build into native images and they do start very quickly in like tens of milliseconds not even hundreds so you know that's a dramatic effect you have to pay for it in some ways and I'll explain that in a minute and the other JVM tweak that you can do is you know make the class path explicit and I've showed you that a couple of times now okay so here's the open j9 that micro app and then if you can read that but it's it's running it was 190 milliseconds in the open JDK it's 150 milliseconds on open j9 so that's you know that's interesting class path exclusions I showed you all the ones that I know about the other one is the net e one that is probably temporary so Jackson it's not terrible but it does some work at startup that you can avoid if you're not using it log back is awful they do lots of they basically because they do dependency injection right they have lots of options that you can inject into loggers and you know for matters and analyzers and stuff like that and it's it's all reflective and it's all a little bit expensive hibernate validator they do a huge amount of reflection it's on when they start up there's nothing you can do about it since static initializers spring boot puts it in a background thread so at least if you've got cpu available you ain't see that on startup if you can avoid it then it'll be quicker and then the actuators yeah I mean I don't like excluding them but I will if I have to other things you can do in spring come to the contact so a spring contacts indexer if you didn't know about it it's just a jar file you include it with your build and it does annotation processing if your components can sew a component scan is instantaneous if you use the index and very fast if you don't yes it's the question of you know it's a small effect but it's sort of visible especially the more beans you have the the the more visible it is okay actuators use spring boot 3.1 spring config location I mentioned spring JMX I mentioned lazy I mentioned but I still haven't shown you it and functional bean definition as I mentioned I still haven't shown you but I will okay so lazy beans this is becoming actually mainstream so in the latest spring data I don't know if I'm gonna have time to do this demo now I've got 10 more minutes ever now we can choose which demo to do in a minute spring data has this new feature so when you do at enable JPA repositories you can say be lazy and spring boot has of course exposed that as a configuration flag so all I have to do is just change a configuration file and that has an amazing effect there are two things you can do in spring data actually if I don't get a chance to do the demo you switch on this flag and then you also configure a task executor which if it's a bean I think spring boot will just pick it up and it uses that to initialize the entity manager so it is all about hibernate stuff that it can in another thread now if you don't have another thread that's not going to help you but if you do if you've got CPU available then that's actually much quicker if I don't have time time to do the demo I'll just tell you it's really really dramatic you can you know if I generate a a stupid application with 400 JPA entities maybe that's not stupid maybe people have apps like that I don't know it would take and 400 JPA repositories in spring boot 2.0 it would take on my laptop it would take like 40 seconds to start so it's kind of a boring demo thing you have to wait for it to do a lot of work and half of that is hibernate and the other half is spring data if you switch to spring be 2.1 switch on the lazy add the task executor that same app will go from 40 seconds down to 2 2 that's you know that's impressive and you can use that right for power and good in your integration tests if that's the thing that's slowing you down an integration test and that will be a killer feature and I guarantee this will be well used the other thing I've played with is so those when I showed you graphs before of lazy and not lazy what I was doing was I was Elling it bean factory post processor that just sets the lazy flag on all the bean definitions and that doesn't have a huge effect if all the beans end up being used at on startup then that's not going to buy you anything that since spring boot for instance will create a rest template it's nice that it does that but if I don't use it then I don't need it to be created on startup so I can turn it on too lazy equals treat might be another thing that you do for integration tests but you you know leave it leave the default setting for production when I've looked at people's real apps that have startup time often they've put at post construct on something that needs to be they thought need to be needed to be done on startup and was turned out to be quite expensive and that's what we're slowing them down it wasn't anything to do with spring it was something that they'd actually put in their spring was calling that method but you know that the work that it was doing was was what was expensive because there is no parallel you can't parallel eyes being definition creation these so because it's quite you know a complex network of graph of relationships profiling with a spec J I also mentioned that already another thing so this is an idea that I'm guess is sort of more forward thinking it's an idea that I've been talking about with people in the spring team I haven't had much traction yet but I did I did produce a little library that you could try out so this is in Rico our maven repository Spring Framework boot experimental spring boot lazy actuator I would have done a demo but I think I'm gonna run out of time so I won't do that now just include that inside your app with actuators and it will be faster it's that's up faster because what it does is it takes the actuator system which is designed basically to be run as you know a separate graph they're all you know health indicators and stuff like that they're all connected to the actuator endpoints but you don't need them until you actually need the endpoints right so if you're not going to ask for a health information on startup you're gonna you know somebody else is gonna do that later if you want to start as quickly as possible you could make that lazy and I think there might be some mileage in this generally right it's not it's not something that I've really implemented properly yet but I think that we'll continue to think about this if you think about an object graph in a spring application is a big sort of you know fingery mess of relationships between beans if there's anywhere where there's a sub graph that is relatively disconnected you could think about you know chopping it off and making it all lazy and I think that might be you know a good future direction for us to look in it will require work on about part of developers right so that subsystem has to be identified like the actuators I can say the actuators are an independent subsystem I can sort of mark them as that you would need to have a tool to be able to do that as a developer in order to implement this kind of pattern and that kinda brings us close to the end so I wanted to talk about a functional beam definitions because they are really important so I thought I'd explain what that is before eggs before I show you anything so if you take your typical apt configuration programming model which we all know and love I've even come to like it I don't think we want to throw that away as a punchline but this is so this is what you're used to at configuration and at beam if you wrote that in the functional style it would look like this right you would have some kind of initializer it doesn't have to be done this way but you want to get hold of this generic application context and register beans on it so registered being registered being registered bean and you can see it's functional because I register a being of type foo and it's a lambda so this is kind of a almost a recipe for turning at configuration into application context initializer right you can tell you that initializer and then you can throw it into your spring boot application there's a specific process that you have to go through to do that there are API is it's not automatic yet there are issues open in the spring boot tracker to provide that as a sort of a convenience like make it automatic it's not automatic yet but you could write your beans that way and it would work and it would be faster for that for those two beans right so the challenge is that if you're using spring boot there are going to be another sixty hundred beans that you need to be done in the same way otherwise it's not going to be not gonna I'm not gonna buy you anything so that's the difference that's the bunk and funk apps in my graphs here so that's the difference between you know twelve hundred milliseconds and six hundred it is actually pretty dramatic especially for these small apps I think probably even for bigger apps and that's why right this purple blodge is at configuration class processing and if you don't do that you don't have to pay that price you know calling a lambda is much quicker than doing that so that's why it's faster I mean it's not gonna be there's no silver bullet right so there's it's not going to be as simple as that but that's in a nutshell what we're showing it to you so some examples of that there is but function bunk in the spring beat micro apps are written in that style sebastianne I think is left because he had another presentation that he's giving but Sebastian's new project spring foo is based on functional bean registration take take a look at that it is converging quite nicely now with this experiment that I've been doing with Andy Clement which I'm afraid I'm not gonna have time to show you but so this is an exam init and spring cloud function since I control that I've been able to insert some functional magic in there as well so there's a little flag there in spring cloud function that you can enable so if you are providing this style of configuration for your java lambdas on AWS and you set that property then you will get the speed up benefits because I'm doing functional registration of all this bring the things that you need in a function so there's more research to do here a lot of the research that we've been doing Andy and I has been to do with converting at configuration because we like the programming model right the fact that there's so much of spring boot is using a configuration users lover what if we could convert those to functional bean registrations and you can do that you can even do that at runtime okay there's a link here to a project that I wrote that where I just I thought okay I can do that reflective but it's it's worth trying just to see if we can do it it's actually surprisingly effective to do it even at runtime so just convert all of the app configuration into suppliers of beans at runtime using reflection Eve that is faster than configuration class post-processor or even better we can maybe think about conversing making the at configuration into an initializer at compile time we have everything we need at compile time you can see what's on the class class you can see what's going to happen so there are some options I'll come to that the other thing you can do is you can you know use spring boot Auto configuration as it as it as if it were some kind of public API and you can sort of hand wire it into functional bean registrations and that's essentially what Sebastian did in spring foo and he at some point will throw that away and replace it with whatever we do automatically okay when we do some compile time options so what are the compile time options well aspectj works already really well like since about 2006 right spring 2 had support for a transactional with aspectj it's really fast really fast so you know that's great but it's not a full it's not a full solution for a configuration it doesn't meet the same needs so to do that we can either use an annotation processor or maybe which is what Andy and I have been working on some bytecode enhancement we just read you read the bytecode at compile time generate application context initializes essentially with functional bean definitions and then they'll be on the class path when you're running basically so I can even if I really think I've run out of time so I don't have time to show that but I will show anybody who comes and asks me so this is the end and then I'm going to just show a big page of links ahead of time compilation it's it's oh it's been a sort of a feature that they announced as part of Java 9 it was I think it's Tilly's marked as experimental and they are using a thing called growl of VM to do that so growl vm is an umbrella project from Oracle which includes there's several capabilities one of which is a JIT compiler so just an optimizer for the for the normal hotspot JVM but also there's this thing that everybody has been excited about called native image you can build native images and you can build a native image for that Bunko application that I showed you so Ravi M has some limitations it's not very good at reflection in fat is terrible at reflection so anyway away we're using reflection in spring you have to find explicit declarations or workarounds or messing around with growl to make it work but this works this one I can run a target bunk and it will start in 10 20 40 milliseconds who cares right it's sometimes it's 10 sometimes it's 40 are there waving at me I know hi but you know that you do lose some benefits and real benefits of the JVM there he went won't be able to debug you won't be able to do JMX you won't be able to do dynamic compilation and optimization you won't be able to do garbage collection I know all of those things valuable things to have it's completely opaque you build a binary image and it either runs or it doesn't if it doesn't you've got no idea no idea why it doesn't work is a downside so it's still a bit early I think to promote that as for general use big page of links take a picture you can find this presentation so with all the links in it if you go to Prezi re SOS desire comm and then click through to all of the tools and stuff and if you want me to show more demos then come and ask me and then we can you know sneak off in the finer room somewhere thank you very much you
Info
Channel: SpringDeveloper
Views: 19,272
Rating: undefined out of 5
Keywords: Web Development (Interest), spring, pivotal, Web Application (Industry) Web Application Framework (Software Genre), Java (Programming Language), Spring Framework, Software Developer (Project Role), Java (Software), Weblogic, IBM WebSphere Application Server (Software), IBM WebSphere (Software), WildFly (Software), JBoss (Venture Funded Company), cloud foundry, spring boot, spring cloud
Id: 97UTDmonq7w
Channel Id: undefined
Length: 75min 24sec (4524 seconds)
Published: Wed Oct 03 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.