├── .circleci └── config.yml ├── README.md ├── discovery-service ├── Dockerfile ├── pom.xml └── src │ └── main │ ├── java │ └── pl │ │ └── piomin │ │ └── services │ │ └── discovery │ │ └── DiscoveryApp.java │ └── resources │ └── application.yml ├── example-service ├── Dockerfile ├── pom.xml └── src │ ├── main │ ├── java │ │ └── pl │ │ │ └── piomin │ │ │ └── services │ │ │ └── example │ │ │ ├── ExampleApp.java │ │ │ └── controller │ │ │ └── ExampleController.java │ └── resources │ │ └── application.yml │ └── test │ └── java │ └── pl │ └── piomin │ └── services │ └── example │ └── ExampleControllerTest.java ├── pom.xml └── renovate.json /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | 3 | jobs: 4 | build: 5 | docker: 6 | - image: 'cimg/openjdk:21.0.6' 7 | steps: 8 | - checkout 9 | - run: 10 | name: Analyze on SonarCloud 11 | command: mvn verify sonar:sonar 12 | 13 | executors: 14 | jdk: 15 | docker: 16 | - image: 'cimg/openjdk:21.0.6' 17 | 18 | orbs: 19 | maven: circleci/maven@2.0.0 20 | 21 | workflows: 22 | maven_test: 23 | jobs: 24 | - maven/test: 25 | executor: jdk 26 | - build: 27 | context: SonarCloud -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Spring Boot Autoscaler Demo Project [![Twitter](https://img.shields.io/twitter/follow/piotr_minkowski.svg?style=social&logo=twitter&label=Follow%20Me)](https://twitter.com/piotr_minkowski) 2 | 3 | [![CircleCI](https://circleci.com/gh/piomin/sample-spring-boot-autoscaler.svg?style=svg)](https://circleci.com/gh/piomin/sample-spring-boot-autoscaler) 4 | 5 | [![SonarCloud](https://sonarcloud.io/images/project_badges/sonarcloud-black.svg)](https://sonarcloud.io/dashboard?id=piomin_sample-spring-boot-autoscaler) 6 | [![Bugs](https://sonarcloud.io/api/project_badges/measure?project=piomin_sample-spring-boot-autoscaler&metric=bugs)](https://sonarcloud.io/dashboard?id=piomin_sample-spring-boot-autoscaler) 7 | [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=piomin_sample-spring-boot-autoscaler&metric=coverage)](https://sonarcloud.io/dashboard?id=piomin_sample-spring-boot-autoscaler) 8 | [![Lines of Code](https://sonarcloud.io/api/project_badges/measure?project=piomin_sample-spring-boot-autoscaler&metric=ncloc)](https://sonarcloud.io/dashboard?id=piomin_sample-spring-boot-autoscaler) 9 | 10 | In this project I'm demonstrating how to scale up and scale down number of running instances of your Spring Boot application by the Jenkins pipeline. Jenkins integrates with discovery based on Spring Cloud Netflix Eureka, and endpoints provided Spring Boot Actuator. 11 | 12 | The example is available in the branch [master](https://github.com/piomin/sample-spring-boot-autoscaler/tree/master). A detailed guide may be find in the following article: [Spring Boot Autoscaler](https://piotrminkowski.com/2018/09/18/spring-boot-autoscaler/) 13 | -------------------------------------------------------------------------------- /discovery-service/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8-jre-alpine 2 | ENV APP_FILE discovery-service-1.0-SNAPSHOT.jar 3 | ENV APP_HOME /usr/apps 4 | EXPOSE 8761 5 | COPY target/$APP_FILE $APP_HOME/ 6 | WORKDIR $APP_HOME 7 | ENTRYPOINT ["sh", "-c"] 8 | CMD ["exec java -jar $APP_FILE"] -------------------------------------------------------------------------------- /discovery-service/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | pl.piomin.services 9 | sample-spring-boot-autoscaler 10 | 1.1-SNAPSHOT 11 | 12 | 13 | discovery-service 14 | 1.1-SNAPSHOT 15 | 16 | 17 | ${project.artifactId} 18 | 19 | 20 | 21 | 22 | org.springframework.cloud 23 | spring-cloud-starter-netflix-eureka-server 24 | 25 | 26 | 27 | 28 | 29 | 30 | org.springframework.boot 31 | spring-boot-maven-plugin 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /discovery-service/src/main/java/pl/piomin/services/discovery/DiscoveryApp.java: -------------------------------------------------------------------------------- 1 | package pl.piomin.services.discovery; 2 | 3 | import org.springframework.boot.autoconfigure.SpringBootApplication; 4 | import org.springframework.boot.builder.SpringApplicationBuilder; 5 | import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; 6 | 7 | @SpringBootApplication 8 | @EnableEurekaServer 9 | public class DiscoveryApp { 10 | 11 | public static void main(String[] args) { 12 | new SpringApplicationBuilder(DiscoveryApp.class).run(args); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /discovery-service/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: discovery-service 4 | 5 | server: 6 | port: ${PORT:8761} 7 | 8 | eureka: 9 | instance: 10 | hostname: localhost 11 | client: 12 | registerWithEureka: false 13 | fetchRegistry: false 14 | serviceUrl: 15 | defaultZone: http://localhost:8761/eureka/ -------------------------------------------------------------------------------- /example-service/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8-jre-alpine 2 | ENV APP_FILE example-service-1.0-SNAPSHOT.jar 3 | ENV APP_HOME /usr/apps 4 | EXPOSE 8080 5 | COPY target/$APP_FILE $APP_HOME/ 6 | WORKDIR $APP_HOME 7 | ENTRYPOINT ["sh", "-c"] 8 | CMD ["exec java -jar $APP_FILE"] -------------------------------------------------------------------------------- /example-service/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 4.0.0 7 | 8 | 9 | pl.piomin.services 10 | sample-spring-boot-autoscaler 11 | 1.1-SNAPSHOT 12 | 13 | 14 | example-service 15 | 1.1-SNAPSHOT 16 | 17 | 18 | ${project.artifactId} 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter-actuator 25 | 26 | 27 | org.springframework.boot 28 | spring-boot-starter-web 29 | 30 | 31 | org.springframework.cloud 32 | spring-cloud-starter-netflix-eureka-client 33 | 34 | 35 | org.springframework.boot 36 | spring-boot-starter-test 37 | test 38 | 39 | 40 | org.springframework.cloud 41 | spring-cloud-starter-openfeign 42 | test 43 | 44 | 45 | 46 | 47 | 48 | 49 | org.springframework.boot 50 | spring-boot-maven-plugin 51 | 52 | 53 | org.jacoco 54 | jacoco-maven-plugin 55 | 0.8.13 56 | 57 | 58 | 59 | prepare-agent 60 | 61 | 62 | 63 | report 64 | test 65 | 66 | report 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /example-service/src/main/java/pl/piomin/services/example/ExampleApp.java: -------------------------------------------------------------------------------- 1 | package pl.piomin.services.example; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class ExampleApp { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(ExampleApp.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /example-service/src/main/java/pl/piomin/services/example/controller/ExampleController.java: -------------------------------------------------------------------------------- 1 | package pl.piomin.services.example.controller; 2 | 3 | import org.springframework.beans.factory.annotation.Value; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | import org.springframework.web.bind.annotation.RestController; 7 | 8 | @RestController 9 | @RequestMapping("/example") 10 | public class ExampleController { 11 | 12 | @Value("${eureka.instance.instanceId}") 13 | private String instanceId; 14 | 15 | @GetMapping 16 | public String test() { 17 | try { 18 | Thread.sleep(1000); 19 | } catch (InterruptedException e) { 20 | e.printStackTrace(); 21 | } 22 | return "I'm " + instanceId; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /example-service/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: example-service 4 | server: 5 | port: ${PORT:0} 6 | eureka: 7 | instance: 8 | instanceId: ${spring.cloud.client.hostname}:${spring.application.name}:${random.int[1,999999]} 9 | client: 10 | serviceUrl: 11 | defaultZone: ${EUREKA_URL:http://localhost:8761/eureka/} 12 | 13 | management: 14 | endpoints.web.exposure.include: '*' 15 | endpoint.shutdown.enabled: true -------------------------------------------------------------------------------- /example-service/src/test/java/pl/piomin/services/example/ExampleControllerTest.java: -------------------------------------------------------------------------------- 1 | package pl.piomin.services.example; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | import static org.junit.jupiter.api.Assertions.assertTrue; 7 | 8 | @SpringBootTest 9 | public class ExampleControllerTest { 10 | 11 | @Test 12 | public void test() throws Exception { 13 | assertTrue(true); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | org.springframework.boot 9 | spring-boot-starter-parent 10 | 3.5.0 11 | 12 | 13 | 14 | pl.piomin.services 15 | sample-spring-boot-autoscaler 16 | 1.1-SNAPSHOT 17 | pom 18 | 19 | 20 | piomin_sample-spring-boot-autoscaler 21 | piomin 22 | https://sonarcloud.io 23 | 2025.0.0 24 | 21 25 | 26 | 27 | 28 | example-service 29 | discovery-service 30 | 31 | 32 | 33 | 34 | 35 | org.springframework.cloud 36 | spring-cloud-dependencies 37 | ${spring-cloud.version} 38 | pom 39 | import 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "config:base",":dependencyDashboard" 5 | ], 6 | "packageRules": [ 7 | { 8 | "matchUpdateTypes": ["minor", "patch", "pin", "digest"], 9 | "automerge": true 10 | } 11 | ], 12 | "prCreation": "not-pending" 13 | } --------------------------------------------------------------------------------