diff --git a/README.md b/README.md index 5e2f574..a06760b 100644 --- a/README.md +++ b/README.md @@ -11,13 +11,15 @@ Goals: - 6. Spring Hysterix circuit breaker - support added 7. Spring Hysterix Dashboard - deployed as a docker container 8. Spring ZuulProxy- deployed as a docker container -9. Spring Turbine - deployed as a docker container - works only in none docker envwith http push, it needs additional work as in docker it requires AMQP +9. Spring Turbine - deployed as a docker container 10. mysql - deployed as docker container and populated via script on start up -11. Spring sleuth and Zipkin +11. Spring sleuth and Zipkin - deployed as a docker container +Stretch Goals -- 12. ELK stack 13. Distributed caching -14. Stretch Goal - Async API aggregator written in RxJava -15. Stretch Goal - Jenkins +14. Async API aggregator written in RxJava +15. Jenkins +16. Angular 4 based UI to got with the microservices
I have written install.sh which does the job of CI of building and packaging the Spring boot application and put them in a directory @@ -25,8 +27,9 @@ from where they can be mounted to docker volumes.
install.sh will also take care of bringing all containers using docker-compose. -So clone the project, create a volume directory in your system and modify the install.sh and docker-compose.yml accordingly. Finally run .install.sh. -TODO - modify the install.sh so that it creates the working directory +So clone the project, create a volume directory in your system and modify the install.sh and docker-compose.yml accordingly. Finally run + sudo .install.sh. + Under the hood this is what happens - 1. Builds all microservices, eureka server, config @@ -35,7 +38,12 @@ Under the hood this is what happens - 4. Bring up config server 5. Bring up Eureka Server 6. Bring up microservices - Eureka clients. -7. Add them into one network so that they can communicate +7. Enable Sleuth on microservices +8. Configure microservices so that they send the trace to Spring AMQP +9. Use Spring cloud Zipkin to read the trace from AMQP for timing information +10. Use the trace from AMQP for monitoring in Turbine +11. Add them into one network so that they can communicate +12. Ohh, btw, the Config are externalized using Spring cloud config and are situated at https://github.com/hiteshjoshi1/microservice-docker-cart-config.git Working Endpoints so far :-
@@ -46,7 +54,13 @@ Working Endpoints so far :-
  • Invoice - http://localhost:4444/invoice
  • Config - http://localhost:5555/customer-service/dev
  • Hystrix Monitor - http://localhost:7777/hystrix
  • -
  • Endpoint with a Circuit breaker and fallback - http://localhost:2222/customers/1/orders
  • +
  • Zipkin UI - http://localhost:9411/zipkin/
  • +
  • Example of an endpoint with a Circuit breaker and fallback(GET) - http://localhost:2222/customers/1/orders
  • +
  • POST with Hytrix circuit breaker + +curl -H "Content-Type: application/json" -X POST -d '{"customerId":1,"modePayId":2,"cashierName":"Rambo","items":[{"itemId":1,"quantity":100,"unitCost":10}]}' http://localhost:2222/customers/order + +
  • @@ -59,18 +73,26 @@ Zuul Routes example - You can add Filters on the Zuul Proxy layer. This examples
  • -Docker config - http://localhost:5555/customer-service/docker
    + Hystrix Monitor - We need to provide the application that needs to be montored.
    -Please input - http://localhost:2222/hystrix.stream
    -If you are in docker - input http://172.20.0.7:2222/hystrix.stream
    +Please input in local - http://localhost:2222/hystrix.stream
    +If you are using docker - input http://172.20.0.7:2222/hystrix.stream
    +Final URL should looks like this - http://localhost:7777/hystrix/monitor?stream=http%3A%2F%2Flocalhost%3A2222%2Fhystrix.stream&title=Customer-Hystrix +For turbine based monitoring -
    +http://localhost:7777/turbine.stream?cluster=CUSTOMER-SERVICE
    +In docker-> +http://monitor:7777/turbine.stream?cluster=CUSTOMER-SERVICE
    -Final URL should looks like this - http://localhost:7777/hystrix/monitor?stream=http%3A%2F%2Flocalhost%3A2222%2Fhystrix.stream&title=Customer-Hystrix +Note- + +Spring cloud turbine and Spring cloud zipkin can work over http. But this configuration does not work in a cloud deployement/docker. +For it to work you need to use a messaging service such as kafka or Rabbit AMQP. -for turbine based monitoring -http://172.20.0.7:7777/turbine.stream?cluster=CUSTOMER-SERVICE +I have done installation of Erlang and RabbitMq in my local(windows) and spring connects to it without a hitch. +However in order to run it in a docker based enviornment, you have to explicitly provide connection properties in the application properties. ------------------------------------------------------------------------------------------------------------- diff --git a/customer/pom.xml b/customer/pom.xml index ff42365..5b21273 100644 --- a/customer/pom.xml +++ b/customer/pom.xml @@ -48,10 +48,6 @@ org.springframework.boot spring-boot-starter-actuator - - org.springframework.cloud - spring-cloud-starter-hystrix - org.springframework.cloud spring-cloud-starter-feign @@ -79,11 +75,32 @@ spring-boot-devtools - + org.springframework.cloud - spring-cloud-starter-zipkin + spring-cloud-starter-sleuth + + + org.springframework.cloud + spring-cloud-sleuth-stream + + + + org.springframework.cloud + spring-cloud-starter-hystrix + + + + org.springframework.cloud + spring-cloud-netflix-hystrix-stream + + + + org.springframework.cloud + spring-cloud-starter-stream-rabbit + + diff --git a/customer/src/main/java/com/hitesh/microservices/customer/CustomerApplication.java b/customer/src/main/java/com/hitesh/microservices/customer/CustomerApplication.java index 65df03e..c9eb592 100644 --- a/customer/src/main/java/com/hitesh/microservices/customer/CustomerApplication.java +++ b/customer/src/main/java/com/hitesh/microservices/customer/CustomerApplication.java @@ -27,8 +27,4 @@ RestTemplate restTemplate() { return new RestTemplate(); } - @Bean - public AlwaysSampler defaultSampler() { - return new AlwaysSampler(); - } } diff --git a/customer/src/main/resources/application.yml b/customer/src/main/resources/application.yml index b1a9680..a35932e 100644 --- a/customer/src/main/resources/application.yml +++ b/customer/src/main/resources/application.yml @@ -6,11 +6,17 @@ spring: banner-mode: "off" freemarker: enabled: false # Ignore Eureka dashboard FreeMarker templates - zipkin: - base-url: http://localhost:9411/ + + sleuth: + sampler: + percentage: 1.0 + + server: port: ${customer.port} + + feign: hystrix: # even if eclipse is complaining, this is required enabled: true @@ -45,8 +51,12 @@ spring: datasource: url: jdbc:mysql://localhost:3306/microservices_cust username: root - password: test - + password: test + rabbitmq: + host: rabbitmq + port: 5672 + username: guest + password: guest eureka: client: @@ -54,4 +64,4 @@ eureka: defaultZone: http://eureka:${customer.discovery.port}/eureka/ # using eureka instead of localhost instance: leaseRenewalIntervalInSeconds: 5 # DO NOT DO THIS IN PRODUCTION - preferIpAddress: true \ No newline at end of file + preferIpAddress: true diff --git a/docker-compose.yml b/docker-compose.yml index a7278f6..9620bc8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,7 +13,21 @@ services: - ./init_schema:/docker-entrypoint-initdb.d environment: MYSQL_ROOT_PASSWORD: test - + + rabbitmq: + image: rabbitmq:3-management + container_name: rabbitmq + hostname: rabbitmq + restart: always + ports: + - "15672:15672" + - "5672:5672" + networks: + - microservicesnet + logging: + options: + max-size: "10m" + max-file: "10" eureka: image: hiteshjoshi1/microservice-docker-cart-example container_name: eureka @@ -58,40 +72,45 @@ services: condition: service_started config: condition: service_healthy - invoice1: - condition: service_started + rabbitmq: + condition: service_started - inventory1: + invoice1: image: hiteshjoshi1/microservice-docker-cart-example - container_name: inventory1 + container_name: invoice1 ports: - - "3333:3333" + - "4444:4444" networks: - microservicesnet volumes: - /home/hitesh/jarloc:/data - command: -jar -Dspring.profiles.active=docker -Dspring.datasource.url=jdbc:mysql://docker-mysql/microservices_prod -Dspring.datasource.password=test /data/inventory-0.0.1-SNAPSHOT.jar + command: -jar -Dspring.profiles.active=docker -Dspring.datasource.url=jdbc:mysql://docker-mysql/microservices_invoice -Dspring.datasource.password=test /data/invoice-0.0.1-SNAPSHOT.jar depends_on: db: condition: service_started config: condition: service_healthy + rabbitmq: + condition: service_started - invoice1: + inventory1: image: hiteshjoshi1/microservice-docker-cart-example - container_name: invoice1 + container_name: inventory1 ports: - - "4444:4444" + - "3333:3333" networks: - microservicesnet volumes: - /home/hitesh/jarloc:/data - command: -jar -Dspring.profiles.active=docker -Dspring.datasource.url=jdbc:mysql://docker-mysql/microservices_invoice -Dspring.datasource.password=test /data/invoice-0.0.1-SNAPSHOT.jar + command: -jar -Dspring.profiles.active=docker -Dspring.datasource.url=jdbc:mysql://docker-mysql/microservices_prod -Dspring.datasource.password=test /data/inventory-0.0.1-SNAPSHOT.jar depends_on: db: condition: service_started config: condition: service_healthy + rabbitmq: + condition: service_started + monitor: image: hiteshjoshi1/microservice-docker-cart-example @@ -108,8 +127,8 @@ services: condition: service_started config: condition: service_healthy - customer1: - condition: service_started + rabbitmq: + condition: service_started zuul: image: hiteshjoshi1/microservice-docker-cart-example @@ -137,7 +156,8 @@ services: depends_on: config: condition: service_healthy - + rabbitmq: + condition: service_started networks: diff --git a/inventory/pom.xml b/inventory/pom.xml index d69eb55..e775da9 100644 --- a/inventory/pom.xml +++ b/inventory/pom.xml @@ -42,15 +42,6 @@ org.springframework.cloud spring-cloud-starter-feign - - org.springframework.cloud - spring-cloud-starter-hystrix - - - org.springframework.cloud - spring-cloud-starter-turbine - - mysql mysql-connector-java @@ -74,10 +65,29 @@ org.springframework.boot spring-boot-devtools - + + + org.springframework.cloud + spring-cloud-starter-sleuth + + + org.springframework.cloud + spring-cloud-sleuth-stream + + + + org.springframework.cloud + spring-cloud-starter-hystrix + + + + org.springframework.cloud + spring-cloud-netflix-hystrix-stream + + org.springframework.cloud - spring-cloud-starter-zipkin + spring-cloud-starter-stream-rabbit diff --git a/inventory/src/main/resources/application.yml b/inventory/src/main/resources/application.yml index 2fc4623..7c1e3a4 100644 --- a/inventory/src/main/resources/application.yml +++ b/inventory/src/main/resources/application.yml @@ -46,9 +46,15 @@ spring: jpa: hibernate: ddl-auto: none + rabbitmq: + host: rabbitmq + port: 5672 + username: guest + password: guest + eureka: client: serviceUrl: defaultZone: http://eureka:${inventory.discovery.port}/eureka/ # using eureka instead of localhost - \ No newline at end of file + diff --git a/invoice/pom.xml b/invoice/pom.xml index 4b3c299..8844133 100644 --- a/invoice/pom.xml +++ b/invoice/pom.xml @@ -42,14 +42,7 @@ org.springframework.cloud spring-cloud-starter-feign - - org.springframework.cloud - spring-cloud-starter-hystrix - - - org.springframework.cloud - spring-cloud-starter-turbine - + mysql @@ -76,11 +69,31 @@ spring-boot-devtools - - - org.springframework.cloud - spring-cloud-starter-zipkin - + + + org.springframework.cloud + spring-cloud-starter-sleuth + + + org.springframework.cloud + spring-cloud-sleuth-stream + + + + + org.springframework.cloud + spring-cloud-starter-hystrix + + + + org.springframework.cloud + spring-cloud-netflix-hystrix-stream + + + + org.springframework.cloud + spring-cloud-starter-stream-rabbit + diff --git a/invoice/src/main/resources/application.yml b/invoice/src/main/resources/application.yml index a559cb3..b718234 100644 --- a/invoice/src/main/resources/application.yml +++ b/invoice/src/main/resources/application.yml @@ -31,7 +31,8 @@ spring: password: test jpa: hibernate: - ddl-auto: none + ddl-auto: none + eureka: client: serviceUrl: @@ -49,11 +50,16 @@ spring: password: test jpa: hibernate: - ddl-auto: none + ddl-auto: none + rabbitmq: + host: rabbitmq + port: 5672 + username: guest + password: guest eureka: client: serviceUrl: defaultZone: http://eureka:${invoice.discovery.port}/eureka/ # using eureka instead of localhost - \ No newline at end of file + diff --git a/monitor/pom.xml b/monitor/pom.xml index d1d5a6e..8dfdc2c 100644 --- a/monitor/pom.xml +++ b/monitor/pom.xml @@ -38,14 +38,17 @@ org.springframework.cloud spring-cloud-starter-hystrix-dashboard - org.springframework.cloud spring-cloud-starter-turbine + + org.springframework.cloud + spring-cloud-starter-stream-rabbit + + org.springframework.boot spring-boot-starter-actuator diff --git a/monitor/src/main/resources/application.yml b/monitor/src/main/resources/application.yml index 45519f3..f778a33 100644 --- a/monitor/src/main/resources/application.yml +++ b/monitor/src/main/resources/application.yml @@ -9,7 +9,6 @@ endpoints: server: port: ${hystrix.port} - logging: level: @@ -23,7 +22,9 @@ eureka: spring: profiles: - active: "dev" + active: "dev" + rabbitmq: + host: ${RABBIT_HOST:localhost} --- spring: profiles: dev @@ -33,7 +34,7 @@ eureka: serviceUrl: defaultZone: http://localhost:${discovery.port}/eureka/ # using eureka instead of localhost -turbine: +turbine: appConfig: customer-service,invoice-service aggregator: clusterConfig: CUSTOMER-SERVICE,INVOICE-SERVICE, INVENTORY-SERVICE @@ -41,6 +42,11 @@ turbine: --- spring: profiles: docker + rabbitmq: + host: rabbitmq + port: 5672 + username: guest + password: guest eureka: client: diff --git a/monitor/src/main/resources/bootstrap.yml b/monitor/src/main/resources/bootstrap.yml index 2347eae..a3330d4 100644 --- a/monitor/src/main/resources/bootstrap.yml +++ b/monitor/src/main/resources/bootstrap.yml @@ -14,7 +14,6 @@ spring: config: uri: http://localhost:5555 enabled: true - --- spring: diff --git a/zipkinTimer/pom.xml b/zipkinTimer/pom.xml index 193b678..6754781 100644 --- a/zipkinTimer/pom.xml +++ b/zipkinTimer/pom.xml @@ -26,10 +26,11 @@ - + org.springframework.cloud spring-cloud-sleuth-zipkin-stream + org.springframework.cloud spring-cloud-starter-stream-rabbit @@ -48,12 +49,19 @@ org.springframework.cloud spring-cloud-starter-eureka + + org.springframework.boot + spring-boot-starter-actuator + org.springframework.boot spring-boot-starter-test test + + + diff --git a/zipkinTimer/src/main/java/com/hitesh/microservices/zipkinTimer/ZipkinTimerApplication.java b/zipkinTimer/src/main/java/com/hitesh/microservices/zipkinTimer/ZipkinTimerApplication.java index 1e83eb9..58e1765 100644 --- a/zipkinTimer/src/main/java/com/hitesh/microservices/zipkinTimer/ZipkinTimerApplication.java +++ b/zipkinTimer/src/main/java/com/hitesh/microservices/zipkinTimer/ZipkinTimerApplication.java @@ -2,10 +2,9 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.sleuth.zipkin.stream.EnableZipkinStreamServer; -import zipkin.server.EnableZipkinServer; - -@EnableZipkinServer +@EnableZipkinStreamServer @SpringBootApplication public class ZipkinTimerApplication { diff --git a/zipkinTimer/src/main/resources/application.yml b/zipkinTimer/src/main/resources/application.yml index 9709739..29dd511 100644 --- a/zipkinTimer/src/main/resources/application.yml +++ b/zipkinTimer/src/main/resources/application.yml @@ -7,6 +7,9 @@ spring: freemarker: enabled: false # Ignore Eureka dashboard FreeMarker templates + sleuth: + enabled: false + eureka: instance: leaseRenewalIntervalInSeconds: 5 # DO NOT DO THIS IN PRODUCTION @@ -23,7 +26,7 @@ spring: eureka: client: serviceUrl: - defaultZone: http://localhost:${invoice.discovery.port}/eureka/ # using eureka instead of localhost + defaultZone: http://localhost:${discovery.port}/eureka/ # using eureka instead of localhost @@ -31,10 +34,24 @@ eureka: spring: profiles: docker - + rabbitmq: + host: rabbitmq + port: 5672 + username: guest + password: guest + jpa: + hibernate: + ddl-auto: none + # datasource: + # url: jdbc:mysql://docker-mysql/zipkin + # username: root + # password: test + # initialize: true + # continueOnError: true + eureka: client: serviceUrl: - defaultZone: http://eureka:${invoice.discovery.port}/eureka/ # using eureka instead of localhost + defaultZone: http://eureka:${discovery.port}/eureka/ # using eureka instead of localhost - \ No newline at end of file +