Spring Boot—Production Boost

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
there's no place like production there's no place like production there's no place like production getting your boot apps to josh long's favorite place on the internet is made safer with certain techniques our next talk spring boot production boost will teach you all about them please welcome thomas vitale hi everyone welcome i hope you're having a great day here at spring one i'm thomas vitale i work as a software engineer in a systematic danish software company i'm really really passionate about spring boots in particular i really like working with cloud native technologies and even writing a book about it it's called clown native spring in action where i talk about how to build modern applications like microservices using springboot and deploying them in production with kubernetes today i'd like to go through five main areas in order to boost your journey to production it's very important to uh move fast and uh be in the market with the product that our users can really love and use i'm gonna go through five areas jvm and containers data integration configuration testing monitoring and management and we'll do that in a very practical way we're gonna build a small application that can be used by to manage books in a catalog it's been it's called book service it will expose a rest api to users and it will store data in a postgresql database so let's get started our first stop is at start.spring.io from the spring initializer application we can start a new project in particular i want to start a new gradle project using java the latest springboot version the application will be called book service and i want to use java 16. now to expose a rest api i will use spring web i'm going to build an imperative application and use tomcat as the embedded server then i need the driver for postgresql this is the database that i'm going to use next i have two options provided by spring data in order to implement the data layer of my application i can use spring data jpa which is a very popular choice based on the jpa specification and hibernate and another option is spring data jdbc it's a newer option i really like it because it's based on the principles of domain driven design and i think it's an excellent choice for microservices so that's what i'm gonna use today next since we want to go in production we need to take good care of our databases because our data are really important so what i want to use as well is flyway flyway will let us version control our database but we'll see a minute its power then we need to think about how we can test the application it's extremely important that we write autotest before going in production and we can leverage the test containers library finally uh cloud native applications need to be observable so we we need to get visibility into its internal state when they run in production so for that goal i'm gonna add spring boot actuator that's it these are all the dependencies that we're gonna use so i'll move to the ide and we'll start implementing the book service application here we have a standard springboot application and i want to start by implementing the domain model i can do that with records so i'll define a record for books with two fills an id field of type log and the title field of type string the id will also be the primary key in the database so i'll use the id annotation to mark it next i'll define a book repository interface which extends the credit repository interface provided by spring data it's a repository to fetch books which have a primary key of type block and here i want to pause a second because i'm really amazed by by this like we can implement the data layer of an application with just two lines combining the power of spring data which will automatically uh implement this interface for me providing all the methods to run a crowd operation so to create read update and delete books and also i can use records because spring data jdbc encourage using immutable objects so with two lines we have our data layer implemented i really like that then we need to expose the rest api to manage books so i will create a rest controller this controller will handle a request to the slash books endpoint let's call it book controller like that so first of all i need to inject book repository because that's how i access the database and i'll use constructor injection which is the recommended way of doing this then i'll create a method to return all the books in the catalog so i'll return a hydrable of book objects get all books and i'll return this dot book repository dot find all this is one of the methods which are provided by spring data through the crowd repository interface then i want a method to add new books to the catalog so i'll use the post mapping annotation returns a book so add new book and the book is specified in the request body like that and then i'll use another method once again provided by the spring data repository which is saved and this is all i need to do to implement my logic we have the data layer with the domain model and the repository and we have a controller to expose a rest api the next step is making sure that when we start the application in the database there's actually a table to store book data and for that we're going to use flywhip now if you think about your application source code it's now a given that we use version control so track all the changes in a git repository where each change is represented by a commit now in a similar way we can use flyway and each change applied to the database is registered as a migration that's how flyway names it so in the resources folder i can create an sql script this will be the first change that i apply to the database so i'll call it v1 this is the naming convention from flywith and we'll use it to initialize the schema we can write migrations both in standard sql like i'm doing now or in java so create table book this new table will have two columns an id column of type big serial which is also the primary key and then we have a column with the title of the book these two types big serial and virtual will be mapped to long and stream in java using flyway is really convenient and i think it's important to use a tool like flyway for production because then we can really keep track of all the changes that you apply to a database and we can reproduce the state so this is the first version of our database but maybe in the next release of book service i want to add a new column to the book for example to store the author of the book and at that point i can create a new migration script it will be version 2 in order to create this new column so when the application starts up flyway will check uh all the migration scripts and if any of them has not been run yet he will run it so it will ensure that the state of the database is always consistent and it's always healthy the final thing we need to do is configuring springboot to interact with a specific postgresql instance that in this case i have running on my computer so i'll open the property file and i'll configure the url i'm using jdbc it's a postgresql database the instance is running on my localhost on port 5432 and the database is called book catalog then i also need to define the username and the password very secure like that and that's it this completes the implementation of our application most of the work has been uh done through the spring boot auto configuration and through the power of spring data this is really important because time the time to market is a strategic advantage for organizations so we really want to go to production fast that's where our application brings value to customers users and to the business we don't know if the application works so we need to write some autotest because we want to have a high quality code and we have a few different choices of course we could run we could write some unit tests they wouldn't be different than with any other java application using junit and mokito in that case there's no spring involved and we could also write integration test integration test and you get an example when you initialize a project from stardust spring.io it can be configured through the spring boot test annotation by using this annotation i can set up a full spring context including a web environment exposing its services through a random port random because i don't care where it's running because my focus will be on testing the application and i can do that in different ways one of the options is using the webtest client utility which is a client that i can use to call the book service application and test for example that i can add a book to the catalog correctly so what i'll do here is first of all creating a book the id will be handled by the framework and the database so i'll just pass null and then the title for example the hobbit then i can use web test client and send a post request to the uri slash books this is what we defined in the rest controller then i want to pass the book to create in the request body and then i'll send the request at this point i expect to get back a successful response so i can use expect status is 200 successful and also i expect to get back the book that has just been created so it should be of type book.class and i also want to check what is inside so i'll i'll define the actual book here and first of all i want to assert that now the book created in the database has an id so the id should not be null and then i want to assert that the book title is the same as the one that i previously specified so it should be equal to book to create dot title like that so now i could run this test but it wouldn't work and the reason why is that this the application running in the test context would try to call the postgresql database through this url but we need to uh do something because this postgresql database is running on my computer so how can i make sure that the test is self-contained i can use test containers which is a great tool built on top of junit that provides containers for all your all your external dependencies so you can write integration test using the actual external dependency and that guarantees the environment parity because then if in production we're using postgres it's important that we use postgres also for our autotest because we make them reliable if we use something else like the h2 embedded database it would still work but it wouldn't be 100 reliable because it's a different database compared to what we use in production so what we need to do is uh overriding this value and pointing to an instance of postgresql provided by test containers so i can do that in a few different ways a very convenient one is using the test property source annotation and from here i will overwrite the property spring data source url and the new value will be jdbc then tc which stands for test containers this is a convention used by test containers the database should be postgresql version 13. and i'm missing a column yes then under the hood when i run the test now test containers will initialize a new postgresql container specifically for the test and springboot will run the test against that instance when the test is over then the container will be will be shut down so let's see now the result of the test and the screen this is great we can run this test now everywhere as long as we have a container runtime and we can be sure that it's reliable because it's using the same database that we're using in production now i'd like to point out something this application is an imperative application if you're working with a reactive spring you need to be aware that flyweight which is also run as part of the test doesn't support the r2dbc driver for uh reactive applications so what you have to do in that case besides defining the data source for uh yeah for your postgres you also need to configure flyway explicitly because it will use a different driver but everything else will work the same both for imperative and reactive applications perfect so we are almost close to be ready to deploy the application in production we need to think about what will happen once it's uh up and running there we need to have a way to get visibility into how the application is doing how it's behaving and that's why we added the spring boot actuator uh to the dependencies list of the project spring boot actuator exposes different endpoints with different information now for this presentation i will expose them all but i recommend you only expose the ones that you actually need there are different endpoints a very useful one is the health endpoint which provides information about the health of the application by default it just returns an up or down status but you can configure it and show more details so we can add information about the components used by the application more details and if you're running on kubernetes you can also enable the probes now they are actually enabled by default if the application is running in kubernetes since i'm running it on my local computer i need to enable them explicitly having said that let's run the application we can first ensure that it works fine of course the the business logic that we implemented for the book catalog and then we checked the springboot actuator endpoints the application is running perfect so what i'll do now first i want to create a new book the parodies 8080 slash books and the book will be the lord of the rings and is created correctly just to double check we can also send a get request to the same endpoint and this endpoint returns the full catalog of books of course we have only one so that's the one that we are getting then all the spring boot actuator endpoints are prefixed with slash actuator so for example i can get information about the health with slash actuator slash health for example you can see that the database is up so the integration of spring boot with postgres is okay and you have also information about the liveness and readiness states these two states are really important for uh kubernetes and you can get them through specific endpoints so the liveness state if it returns a down status then kubernetes will restart the container because it means that entered a faulty state instead if the application is not ready it means that we cannot handle more requests so kubernetes will stop sending traffic to that specific instance other useful endpoints for our case the book service application are flyway slash actuator slash flyway from here we can see all the information regarding the migrations that we read this information is stored in the database i can show you i switch to the database view you can see that flyway will create automatically a flyway schema history table and in here it will store the status of all the migrations that have been run there's also a few more endpoints that i'd like to show you one is the prometheus endpoints which returns useful metrics about the application so you can scrape them from a prometal server and show them in dashboards for example using rafana and if you are dealing with uh memory leaks which are a really uh yeah annoying bugs that we might have in our code uh it might be uh useful getting a hyptum so a snapshot of the hip memory from your application so that you can investigate further where is the memory leak and fix performance issues at this point we really have everything we need to go to production so we need to prepare the application to be uh deployable we have two main options one is packaging the application as a jar and this jar is a fat jar is standalone so it includes all the dependencies needed by the application to run correctly there's no external dependency except for the java virtual machine so i can run it with java dash jar and i can take it and deploy it to platforms like cloud foundry like heroku or to make the application even more portable and deployable on platform like kubernetes as easily i can package the application as a container image and there's a task both for gradle and for maven the springboot plugin under the hood uses cloud-native buildbacks which is a specification to convert application source code into container images without the need to provide a dogger file it's really great in particular spring roots is using the pacquiao buildbacks implementation which produce production ready images which follow all the best practices in terms of security and are optimized both for building and running and my favorite feature is a component called java memory calculator which is included in the final image and that it will configure the javascript machine running in your container at startup time so you don't have to do that explicitly configuring the heap and all the non-hip memory areas and that's great and it helps us in our journey to go to production uh fast and here it is we got a container image back this is ready to go in production in any containerized platform i'd like to point out a few things that are useful when you do that so i'll go back to my slides now first of all it's about how to configure the application because we used property files for our local development environment but there are different strategies you can adopt in the spring ecosystem you really have many different options that fit any data you might have a strategy that i'd like to share with you today is the following i would use property files to define default values and values that in general you would use in your development environment like we did earlier with the url for the local postgres instance then for all configuration data which are not related to the infrastructure you might use a configuration service like spring cloud config so things like connection pools timeouts feature flags and it can be any configuration service either run by you or managed by a platform or even provided by the platform as a service for example if you're running applications on azure you could use azure keyboard and integrate it with boot through the spring cloud azure project finally if you're running on kubernetes i would use config knobs and secrets which by the way are supported natively by springboot you don't need anything else to make that work i would use them for kubernetes specific properties so for example service names of other services running in kubernetes or which profiles to activate in a springboot application talking instead about configuring the container itself so not the application it's important to take care of how we assign cpu and memory to each container now notice that the cpu is a compressible resource so when the limit is hit the process is throttled the application would still run but maybe with lower performance instead memory is a non-compressible resource if we hit the limit then the application dies with a dreadful out of memory killed error we don't want to do that so pay attention to how you configure both requests and limits for both memory and cpu in particular memory it's important to set both the requests which are the minimum value assigned to the container and the limits and for jvm containers we usually assign them equal because that guarantees the best performance with the jvm and the cpu if you want to get some performance boost especially at startup you could omit the limit since we know that it's a compressible resource so the application will still run it will just be throttled the final thing remember to use the liveness and readiness probes that we have just configured in a springwood actuator so you can use them and kubernetes will manage the container in a nice way this was our little journey to production we went through these five different areas i really thank you for joining this presentation i hope you liked it and i wish you a great rest of the conference i also want to thank the organizers that make this possible thank you very much thomas that was great really appreciate it josh you made josh long proud in helping many many people get applications more securely into production so really appreciate it i'm glad to hear that thank you after this be sure to click on the join the the conversation link to join slack where you can find the q a link when you do go to slack make sure you also check out our sponsor channels and show them some love they help keep the videos coming and make all this possible our next talk will be at how to improve stability in your integration test capabilities so you can stop ignoring those broken builds we'll start the next talk at 105 eastern
Info
Channel: SpringDeveloper
Views: 3,777
Rating: 4.8780489 out of 5
Keywords: Core Framework, Data/Databases, Kubernetes
Id: gMvAp_qGyyE
Channel Id: undefined
Length: 26min 10sec (1570 seconds)
Published: Wed Sep 22 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.