Blog je mesto gde možeš da čitaš o navikama IT-evaca, najavama IT dešavanja, aktuelnostima na tržištu, savetima i cakama kako da uspeš na ovom dinamičnom polju.
Mi pratimo trendove, na tebi je da se zavališ u fotelju i čitaš :)

Blog Docker
Tag: Docker (11 rezultata)
07.09.2023. ·
7 min

How I made the Spring Boot startup analyser

It's no secret that Spring applications can sometimes freeze at startup. This is especially noticeable as a project develops: the new service starts quickly and shows great responsiveness, then it acquires some serious functionality, and the final distribution package swells by dozens of megabytes. Now, to simply launch that service locally, you have to wait for half a minute, a minute, two... At such moments of waiting, the developer may ponder: why on Earth is it taking so long? What’s going on? Maybe I shouldn't have added that particular library? Hi, my name is Alexey Lapin, and I am a Lead Developer at Luxoft. In this article, I’ll talk about a web application for analysing the startup phase of Spring Boot services, which uses data from the startup actuator endpoint. This tool may help answer the questions above. Foreword I made this application for myself to understand a new Spring module that I hadn't seen before and practice on the front end. I saw various solutions on the internet, but they either did not work or have not been updated for a long time, and I wanted to create an up-to-date auxiliary tool for the Spring Boot functionality. Spring Boot Startup Endpoint Starting with version 2.4, Spring Boot has an ApplicationStartup metric that records events (steps) that occurred during the service startup and an “actuator endpoint” that makes a list of these events. Here's what it looks like: {     "springBootVersion": "2.5.3",     "timeline": {         "startTime": "2021-09-06T13:38:05.049490700Z",         "events": [             {                 "endTime": "2021-09-06T13:38:05.159435400Z",                 "duration": "PT0.0898001S",                 "startTime": "2021-09-06T13:38:05.069635300Z",                 "startupStep": {                     "name": "spring.boot.application.starting",                     "id": 0,                     "tags": [                         {                             "key": "mainApplicationClass",                             "value": ""                         }                     ],                     "parentId": null                 }             },             ...             {                 "endTime": "2021-09-06T13:38:06.420231Z",                 "duration": "PT0.0060049S",                 "startTime": "2021-09-06T13:38:06.414226100Z",                 "startupStep": {                     "name": "spring.beans.instantiate",                     "id": 7,                     "tags": [                         {                             "key": "beanName",                             "value": "org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory"                         }                     ],                     "parentId": 6                 }             },             ...         ] ….} } A detailed description of all message fields can be found in the Spring Boot Actuator documentation, but I think it’s all in all pretty straightforward. The event has an “id” and a “parentId”, which allows one to have a tree view. There is also a “duration” field, which shows the time spent on the event + the duration of all associated events combined. The “tags” field contains a list of event attributes, such as the name or class of the generated bean. To enable the collection of data on load events, you must pass an instance of the BufferingApplicationStartup class to the setApplicationStartup method of SpringApplication. In this case, a constructor is used that accepts the number of events to record. All events above this limit will be ignored and will not be included in the startup endpoint’s output. @SpringBootApplication public class App {     public static void main(String[] args) {         SpringApplication application = new SpringApplication(App.class);         application.setApplicationStartup(new BufferingApplicationStartup(1000));;     } } By default, this endpoint has a path of /actuator/startup and supports GET methods for receiving events and POST for receiving events and clearing the buffer, so subsequent calls to this endpoint will return an empty list of events Okay, let's go. We will consider the information provided by the startup endpoint as our data for analysis. The analyser web application is a single-page application (SPA) without a back end. It works like magic: you just need to upload the events that occurred during the service startup, and it will visualise them. The uploaded data is neither transferred nor stored anywhere. I chose Typescript as my go-to programming language, as it seemed like a better option for a Java developer compared to Javascript due to its strong typing and object-oriented programming features. I found it very easy to switch from Java to Typescript and quickly write a working code. As my UI framework, I chose Vue.js 3. To be clear, I have nothing against React, Angular and other front-end frameworks, but at that time Vue.js seemed like a good option due to the low entry threshold and excellent preset tools. Then it was time to choose the component library. It needed to be compatible with Vue.js 3 and have components for working with tables. I considered Element Plus, Ionic Vue, and Naive UI, but due to the availability of customisable components for working with tables, I ended up using the PrimeVue library. The application has a navigation bar with Analyser elements (this is the main screen of the application), Usage (user instructions) and a link to the project's GitHub repository. The main page of the application displays a form for entering data, which can be done in three different ways. The first way is to put a link to the deployed Spring Boot service. In this case, an HTTP request will be made to the specified endpoint and the data will be uploaded automatically. This method is applicable for cases when the service is available from the internet or is deployed locally. Note that loading by url may require additional service configuration in terms of CORS headers and Spring Security. The second and third ways are loading a JSON file or its actual content. The deployed application is located at For the analyser demo, I used my own Spring Boot service deployed on Heroku. This service implements the back end of the RealWorld project. The desired endpoint can be found at The service is configured to send correct CORS headers to GET requests from the analyser. Once you load the events using one of the specified methods, the data is visualised in a tree structure. Note that all rows that have child items are hidden. To navigate through this tree, you can use the “>” icons to the left of the item ID, or expand/hide all rows simultaneously using the Expand All / Collapse All buttons. If there are many events, it may take some time to render the expansion of all rows. In the table view, all events are displayed at once. All columns, except for Tags, can be sorted. CI + hosting On one of the previous projects, I was involved in the global DevOps transformation of our client and worked on automating the release cycle processes and building CI/CD pipelines. It was an interesting experience, which now helps me to resolve issues related to writing the source code of products. In this case, as with most of my open-source software projects, I used GitHub as my git hosting, as it provides many useful tools for CI, artefact storage, documentation, project management, static site hosting, etc. For the needs of the analyser, I specifically used Actions and Pages. GitHub Actions is configured to run a workflow on events like “pull request”, “commit to master”, and “push a tag”. Pushing a tag will also deploy the assembled project to GitHub Pages, as well as build the Docker image and send it to Docker Hub. In addition to the analyser’s public instance on GitHub Pages, you can use the Nginx-based Docker image. The latter can be useful, for example, for those cases when Spring Boot services are located on the organisation's internal network, from which there is no internet access, but Docker is available and it is possible to load the image. To start the container, run the following command: docker run -d --name sbsa -p 8080:80 lexlapin/spring-boot-startup-analyzer If you need to access this container through a reverse proxy, then pass the path through the environment variable: (UI_PUBLIC_PATH): docker run -d --name sbsa -p 8080:80 -e UI_PUBLIC_PATH=/some-path lexlapin/spring-boot-startup-analyzer Things to improve In the future, I plan to refine the screen with the analysis results. Plus, it would be useful to add a tab with a summary of event types, their number and total elapsed time, such as the number and total time spent to create beans. Another possible feature is building charts on short pivot tables — especially since PrimeVue provides such an opportunity through the Chart.js library. In tree view and table view, colour coding can be done to highlight long events. Additionally, it is worth adding event filtering — for example, by type. Conclusion The proposed analyser allows one to conveniently visualise the data received from the startup actuator endpoint, estimate in detail the time spent on various types of events that occur during the service startup, as well as generally process startup information more efficiently. The application has a public instance on GitHub Actions and is also available as a Docker image. This application was successfully used on one of Luxoft’s projects to analyse the loading of slowed-down services and helped to detect several classes with suboptimal logic in the constructors.

25.03.2022. ·
3 min

FON Hakaton powered by Levi9 je uspešno završen!

Levi9 je imao čast da podrži i aktivno učestvuje na FON Hakatonu, 24-oro časovnom takmičenju u kreiranju softverskih rešenja na zadati problem. Popularnost takmičenja ove godine pokazuje rekordan broj timova koji su se prijavili za učestvovanje, čak 65! Nakon prvog kruga selekcije koji je podrazumevao rešavanje algoritamskog zadatka, 10 najboljih timova je dobilo svoju “ulaznicu”  za takmičenje. Temu hakatona - Razvoj ekološke svesti i primena principa zaštite životne sredine, definisao je naš PHP Tech Lead, Vuk Stanković koji je ujedno bio i član žirija. Tri ekipe su se istakle kao najbolje -  “Delegacija”, “MIDL” i “It works on my machine”, te su i osvojile 1, 2. i 3. mesto redom. “Devojke i momci ovih timova deluju kao geekovi kojima se programiranje mnogo dopada! Tehničke implementacije ideja su bile jako interesantne za firmu poput naše. Koristili su brojne raznovrsne i moderne tehnologije kao što su React, Angular, Ionic, Typescript, Docker, NodeJS, Java, Kotlin, PHP ali i mnoge druge” podelio je sa nama Vuk. Članovi pobedničkog tima “Delegacija”, radili su na aplikaciji za podsticanje reciklaže. “Razmišljali smo sa aspekta građanina koji želi da bude ekološki odgovoran ali da mu to ne oduzima previše vremena. Naša aplikacija omogućava svima da učitaju bilo koji proizvod i vide od kojih materijala je on napravljen, gde i kako može da se reciklira. Za 24 sata susreli smo se sa problemima koje smo kao tim, uz pomoć stručnih mentora, brzo i efikasno rešili.” Dodali su da im je učešće na takmičenju bio veliki izazov - Najzad smo imali priliku da pokažemo sve što smo godinama učili i testiramo naše sposobnosti rada u timu pod pritiskom. A rezultatima su, verujemo, prezadovoljni! 😊Jedno veliko bravo za Miloša Ninković, Nemanju Pavlovića, Ognjena Pejčića i Aleksu Miletića, kojima je nagrada za uložen trud i vreme za osmišljavanje svog rešenja - prednost prilikom odabira za stručnu praksu u Levi9. Ponosni smo i na Najnere koji su, zajedno sa zaposlenima Fakulteta za organizacione nauke, bili dostupni takmičarima za konsultacije i davali najbolje savete i smernice za razvijanje rešenja, po rečima učesnika. 😊 Hvala Marku Rajeviću, Jeleni Milev i Marku Nikoliću! Dobro znamo da mozak ne može da razmišlja bez dobrog obroka! Zbog toga je Burger House Bros restoran obezbedio posluženje svim učesnicima - i to ne bilo kakvo! Takmičari su imali priliku da probaju dizajniran po specijalnoj recepturi i ukusu Najnera - Hacker Burger by Levi9. Organizacija samog događaja je bila na zavidnom nivou. Predstavnici Udruženja studenata informatike FON-a su bili uvek spremni za dogovor, korektni i tačni! “Od trenutka kad smo poslali prijavu pa sve do proglašenja pobednika, imali smo sjajnu komunikaciju sa svima i zaista je FON Hakaton prevazišao naša očekivanja.” podelili su sa nama svoj utisak učesnici. Jako nam je važno da delimo znanje, mentorišemo i podstičemo mlade u svim koracima na putu njihovog profesionalnog razvoja. Baš zbog toga što znamo koliko je taj put težak i zahtevan, želimo da svojim aktivnostima mladim ljudima zainteresovanim za IT indutriju olakšamo start. Razlog #139: You don’t have to be great to start, but you have to start to be great. To learn more about the company Levi9, visit their profile! 

24.02.2022. ·
3 min

Do frontend and backend have a future together?

Find out how challenging it is to change technologies, what could possibly reconcile frontend and backend and learn how to evolve as a programmer. Pour some coffee, put on some relaxing music and join us for the twelfth episode of The Hüb, where Igor Đurić shares valuable insights that he’s gained working as a Lead Architect at Zühlke Serbia.

31.01.2022. ·
8 min

Fantastic Features and How to Hide Them

Imagine a scenario. You are working on a new complex feature. Your team releases to production every two weeks, but to complete the feature, you need more than that.

14.10.2021. ·
1 min

Novi Levi9 program – Python MasterClass

Poslednja ocena u indeksu, diploma u ruci i shvataš da te tek čeka pravi izazov – da zakoračiš u realne projekte i osetiš radnu atmosferu po prvi put.

27.05.2021. ·
1 min

Za JavaScript programere nema krize

IT tržite nesumnjivo i nezaustavljivo raste, pa je i tražnja za IT kandidatima sve veća. Iako se često može čuti da se pojedine IT pozicije teško zatvaraju, rastuća poseta našem sajtu, kao i porast broja konkurisanja pokazuju da je prisutno veliko interesovanje kandidata. Analizirali smo više od 3000 oglasa za posao objavljenih od početka godine na najvećem sajtu za zapošljavanje IT kandidata,  Poslodavci pretežno traže kandidate sa višegodišnjim iskustvom, pa je u skladu sa tim, 62% oglasa za posao namenjeno je mediorima, 28% seniorima, dok je svega 10% oglasa namenjeno juniorima.

10.05.2021. ·
4 min

Continuous integration i deployment - zašto ih integrisati u svoj projekat?

Znaš onaj momenat u karijeri kad shvatiš da je 30-50% tvog posla moguće automatizovati i da možeš da se isključivo baviš pisanjem koda i ne razmišljaš dalje?

28.04.2021. ·
5 min

Šta zapravo radi DevOps?

Na ovo pitanje još niko nije našao precizan odgovor, i stalno se dešava da na mrežama ili u razgovorima dođe do konflikta kada se postavi ovo pitanje - jer DevOps je mitsko biće sa hiljadu ruku i obaveza i nikako da se definiše šta treba, šta ne treba, i šta zapravo radi jedan čovek na toj poziciji.

26.03.2021. ·
1 min

Sve što je važno za juniore na jednom mestu – HelloJunior kategorija na blogu!

Ni u jednoj oblasti nije lako biti početnik. Imaš puno pitanja, ne znaš kome da ih postaviš, vrebaš prilike na svakom koraku, a one nikako da se pojave, nisi siguran koja oblast rada, koje tehnologije su za tebe pravi izbor...

Da ti ništa ne promakne

Ako želiš da ti stvarno ništa ne promakne, prijavi se jer šaljemo newsletter svake dve nedelje.