Alright, welcome. How do you like our little Duke rock stars here? So there's stickers
going around somewhere so you can get some of these stickers. I think we have four different
rock stars or something. Anyway, let's talk about Quarkus, obviously. Who am I? I'm a
developer advocate at Red Hat. My name is Kevin Dubois. You can find me on Twitter or
Macedon. So I know we've already talked in a few sessions today about, you know, traditional
Java and the startup time and all that stuff, so I'll do that some more. So we'll talk
about traditional Java. So traditional Java is, can I see the little hand? Traditional
Java is designed for, let's say, different times, not designed for cloud-native workloads,
necessarily. It's designed for running kind of long time. And what's important in traditional
Java is throughput at the expense of footprint. So footprint can be quite large, right? You
typically have traditional Java applications running on pretty beefy servers. And they're
designed to be long running and you have dynamic loading and all that stuff with mutable systems.
But in the cloud-native world, your throughput, you get that mostly through scaling. Your
workloads are ephemeral, which means that, you know, like if you think of containers,
when you scale up a container, when you start up a new application, those containers are
going to start up and then maybe they're going to get rescheduled on a different node. And
so containers kind of come and go. They're not going to be around. And if you change
something in a container, that change is not going to last, right? Because that container,
whatever you change inside, that's going to be gone when that container gets removed.
So in that sense, we have to think of Java in a different way. We need to think about
the footprint of it because we want smaller containers that we can schedule across different
servers. You know, if you are familiar with Kubernetes and clusters, there's usually multiple
servers on which it schedules containers. So, you know, we need to be able to handle
that. And so that's where Quark has started, was kind of invented, I guess, because it's
a framework that uses Java. But it's, you know, we call it supersonic because it starts
up very fast. Subatomic because it's very small, like subatomic smaller than an atom.
And it's still Java. So if we think, if we look at Quarkus in terms of startup time and
in terms of memory usage, you can see here, this is a test that they did with a relatively
small application running on a traditional cloud native stack. It took 136 megs of memory
running the same application, you know, with Quarkus, you already got, you know, pretty
good gain in memory, right? And that's running on the JVM. So it's the exact same application
running on the JVM. And then, you know, compiled down to a native with Grail VM, you get,
of course, even less memory usage. And you can see here, too, Quarkus starts up quite
a bit faster than a traditional cloud native stack, which is ideal when we're talking about,
you know, cloud native. We're talking about containers, talking about serverless, where
we need to start up really fast so we can react quickly to, you know, changing loads.
So startup time is one thing. There's also the warmup issue. I don't know if issue is
the right word, but actually, when an application starts up, it takes a while with Java before
you get your maximum throughput as well. So here we can see that, you know, like a traditional
Java application, this is actually the point, and I think this is like 13 seconds or something,
or it's actually able to be working at maximum throughput, which, you know, for this particular
use case, it needed a certain amount of throughput to be able to handle load enough. And then
you can see here with Quarkus, it goes quite a bit faster. Now, Quarkus isn't just about
fast startup time, it's not just about memory, but it is kind of a nice feature of Quarkus.
So if we think of containers and Kubernetes nodes, traditional Java applications, running
on EAP or WebSphere or whatever, running on a Kubernetes node, you can see they take
up quite a bit of space. Let's say that in this case, only four instances of the application
can run, which isn't so ideal because if one of the pods, one of the containers goes down,
that means you lose 25% of your workload, right? If you look at Quarkus, on the JVM,
you already have quite a bit more density, which means that if one of these guys goes
down or needs to be rescheduled or whatever, you still have, you know, what is it, maybe
70% or something, that's still up. And, you know, we can compare that to Node.js or
a Go or something, where Go has quite a smaller footprint and with Quarkus native, we can
actually be very comparable with Go, which is nice because that means that we can use
our Java skills and not have to, you know, change languages and reinvent the wheel and
still get all the benefits in the cloud native world of having fast startup and everything.
So how does that work? So a traditional Java application, basically build time is when
you do your packaging and then as it starts up, it loads config files and then does class
pass scanning and build kind of its model of the world and everything, but this is when
it starts up. So if you think of containers, again, that means that this all happens when
the container starts up and that takes a while. And then, so with Quarkus, what we try to
do is instead of doing all that, you know, at runtime, at startup time, we're trying
to do all of this or as much as we can during build time before the application actually
gets packaged, which means that during runtime, we have a lot less to do, right? So it starts
up quite a bit faster. So that's kind of the cool thing about Quarkus. And then, so you
can use Quarkus on JVM or you can compile it down to native, of course, just like most
other frameworks. But there's some cool things about native compilation with Quarkus as well
that we'll get into in just a second. So this is my favorite part about Quarkus. It's not
necessarily, I mean, yes, it's nice that it starts up fast. It's nice that it has a small
memory footprint. But what's really cool about Quarkus is that it has a bunch of different
ways of making the experience of working with Java and Quarkus a lot more fun. So one of
them is, you know, so of course, it's based on standards. So Quarkus uses, you know, your
Java EE standards, the Java standards, uses, you know, Vertex and all that good stuff.
So if you're used to that, hey, great. You basically already know Quarkus for 99%. What's
really cool with Quarkus is that there's this dev mode. This basically, you can start Quarkus
on your local machine in dev mode. It's going to start up. And it's going to just keep checking
to see if you make changes in the class path. And so every time you make a change, it's
going to automatically reload when you, you know, let's say go into your browser or whatever
you make a new request. It's going to automatically reload your application so you don't need
to recompile, redeploy every time you want to test something. Quarkus does that automatically
so you can just go to your browser, hit refresh, and it's there. So make a code change, refresh,
it's there. Which, you know, if you're a developer of a couple, you know, of some other language
where that just happens, then that's not so cool. But in Java, that's pretty cool, right?
So we've got our little guy here that says, wait, so you just save it and your code is
running and it's Java? And the guy says, I know, right? Super Sonic Java. So that's,
that's pretty cool. Another cool thing with Quarkus is that it has this concept of developer
services. So who knows test containers? So basically it uses test containers built into
Quarkus. So let's say that I'm developing an application and I'm adding an extension
to use Postgres database or a Kafka, a Kafka topic or something. Actually, well, of course
you have to have a Docker or Podman or something running on your local machine. But Quarkus
will look and see, hey, you've got, you've got this dependency on a database. Do you
have something configured on your local machine? Do you have a database running on your local
machine? Is that configured in your application properties? If not, no worries, I'm just
going to start up a container with that dependency, for example, a Postgres database and wire
that up. So it's going to, you know, set the configuration so that it connects to that
database automatically. And then you can even go and see, you know, what exactly that configuration
is and then copy it down. Anyway, so that's the developer services. So Kafka or, yeah,
there's a whole bunch of different developer services that you can use just out of the
box, which is pretty nice because otherwise, you know, having to configure a database on
your local machine or Lord forbid, a Kafka instance with all your zookeepers and all
that stuff, that's not so easy. You also, you know, so you have live coding, you also
have continuous testing. So kind of the same concept. So if you have unit tests, you start
your continuous testing. So every time you make a code change, it knows, hey, this class
is related to this unit test. So I'm going to rerun this unit test every time I make
a change here or vice versa. If you're making a change in a unit test, it knows, you know,
this is what I need to rerun. So it gives you quick and immediate feedback every time
as you're developing, which, yeah, again, it's pretty handy. It also has a dev UI. So
it has a UI in your browser where you can go and look at all these different, you know,
developer services that are running, what Quarkis is doing. So again, I was talking at the start
about Quarkis doing some optimization, right? So during the compilation time, so in the
dev UI, you can actually see, you know, what it's doing, how it's optimizing and what it's
going to remove from the class path because Quarkis does, you know, some introspection
to make sure that, hey, this is used or this actually isn't used by your code. So I'm going
to remove all that from the compilation. There's a Quarkis CLI, which, again, it's
not super crazy, but so you can either use Quarkis with Gradle or Maven, or you can just
use the Quarkis CLI, which means that you can do, like, Quarkis dev or Quarkis build
or whatever. You can even use, you can say Quarkis image build or image push, and it's
going to build your application. So build your application, build a container, and you can
even push it automatically all, you know, from one command, which is kind of handy,
right? And then one of the last, but not least, is unification of imperative and reactive
programming. So Quarkis has a lot of reactive programming kind of built in underneath. Now,
me, for example, I'm not a super deep expert in reactive programming, but what's nice with
Quarkis, too, is that I can write imperative code, right? So just, you know, every statement
gets handled one at a time and it blocks every time, whereas with reactive, you've got these
event loops. But you can use both at the same time in the same, even in the same code in
the same class. So for those who are familiar with reactive, usually you kind of have to
decide, hey, if I'm going to build a reactive application, that means I have to decide before
I start writing this code, you know, that this framework that I'm going to use is reactive
and I can't combine the both. But with Quarkis, you can, which is nice. And best of all, it's
still Java, right? So you get all these kind of features. And at the end of the day, if
you're, you know, if you're familiar with Java, this is really not reinventing the wheel
at all. So it uses micro-profile, vertex, rest easy, you know, like, and if you want
to add extensions, you can interact directly with Kubernetes. So you can push your code
directly to Kubernetes. You can create config maps or secrets directly from Quarkis. You
can, you know, you can work really easily with Kafka and OpenShift, of course, patchy
camel and all that. So in terms of native compilation, I think we've already had a few
sessions about that. So I'm not going to go too deep into that other than, you know, if
you can run Quarkis on the JVM and probably for 70 to 80 percent of the use cases, that's
probably a good way to go. If you really want to have the fastest startup time and the smallest
footprint, then you can, you know, do a native build of your Quarkis application with Quarkis,
by the way, that's really easy because if you create a new Quarkis application, it already
automatically has a native profile built in. So you can decide, you know, as you're doing
your compilation, whether you want to do a native build or not. But yeah, so Red Hat
is on the GrowlVM advisory board and then there's the mandrel project, which is a downstream
distribution of GrowlVM specifically for building Java native builds. So, and that's what Quarkis
uses to, for example, if I do a native build and I don't have GrowlVM installed on my local
machine, Quarkis will again pull down a container, it's really good at pulling down containers
to do a native build inside a container on your local machine. So again, then you don't
need to have GrowlVM installed and configured on your local machine. So it really tries
to make, you know, your life as easy as possible and, you know, kind of have the benefits of,
you know, a lot of the things. So if you're thinking of, you know, should I do a native
build or just run on the JVM? This is kind of an opinionated scoring. But, you know, if
you want the maximum developer joy, the, you know, the best and easiest monitoring peak
throughput and reduced max latency, then you want to run it on the JVM. If, for you, it's
important to have the lowest memory footprint, a small packaging, and a very fast startup
time, then a native build is probably the way to go.
So what do you want to use? You know, what can you use Quarkis for? Virtually anything.
So, you know, there are Quarkis-based Kubernetes operators. So there's an operator framework
where you can create, you know, these automatic components in Kubernetes that manage resources
in Kubernetes. You can create GitHub actions with Quarkis. You can create, you know, just
regular jobs. Yes, you can build traditional Java applications, even monoliths with it.
So this is, of course, the sweet spot of Quarkis is cloud-native applications, so event-driven
applications, reactive systems, microservices, and serverless and functions. So that's about
it for my session. So if you want to check out Quarkis more, developers.redhat.com has
a ton of resources on Quarkis, on a lot of developer stuff. This dn.dev slash Quarkis
tutorial is just a, you know, kind of a nice, lightweight introduction to Quarkis where
you can create an application from scratch and then, you know, kind of add some components
as you go. You add a database and then, you know, check out the live, the dev mode and
all that stuff. And, you know, so it's a pretty nice thing. Yeah. And like I said, if you
want to keep up to date, you can follow me on Twitter or Macedon. I try to post interesting
stuff, but I don't know if that's really true, but we'll see. All right. And that's it for
me. Thank you. Any questions? Yes.
One of the first slides you compared startup time and peak performance and, like, the crowd
time. I don't, yeah, I don't remember exactly the numbers on there. Yeah. So that, yeah,
so the, yeah, definitely. So the peak throughput time, there was a slide about, you know, the
three graphs. So, yeah, I think with the native compilation, you're not going to have necessarily
more throughput than on the JVM, but you do get the startup time, you know, like the time
it takes to get to the maximum throughput is faster when you're, when you're native.
Yeah. Yeah. Yeah. We can look at it later. Yeah. Yes.
Yeah. That's it. Yeah.
Yeah. So the question was how easy is it, is it to migrate to Quarkus from, for example,
spring boots? So Quarkus has spring compatibility extensions. And so that makes it relatively
easy because basically you're, for the most part, you won't have to change your code. You
just have to add the, you know, add the spring extensions. Of course, in your palm, you're
going to need to make some changes, but it's fairly straightforward. My colleague, Eric
D'Andrea, he wrote a book on spring, let's say, Quarkus for spring developers. And he
does, he does talks too, but if you want on that developers.ridhat.com, you can find,
you know, there's a section about books and you can find that book. But it's, yeah, overall
pretty, pretty straightforward. So like I said, there are extensions so that you can
keep using your spring annotations. Now, would I recommend you just migrating your application
and keeping all your spring dependencies? Probably not. But it's kind of a nice way
to migrate without too much work and then afterwards maybe migrate further. All right.
Any more questions? Yes.
So, so the question, if I understand correctly, right, so your, the question is, why, why
should you use native compilation? Because on the JVM, you have all the kind of capabilities
that the JVM brings, right? So in terms of, you know, garbage collection, in terms of
throughput and everything, JVM is very optimized to do that. When you do a native build, the
GralVM compiler is going to do kind of an opinionated approach of how to do your native
build, but then that's also it. It's not going to be able to optimize afterwards like the
JVM does. So, kind of depends. Yeah. I think we're out of time. But if anybody has any
more questions?
Any questions, you'll be up there.
Yeah, yeah.
Great. Thank you so much.
All right. Thank you so much.