There are a variety of ways to install Spring Cloud CLI, and you can find all of them here.
The easiest way, however, is to use Homebrew (requires a Mac environment).
Using Homebrew simply execute these few commands:
$ brew tap pivotal/tap
$ brew install springboot
This installs the Spring Boot CLI. After that, you need to install the Spring Cloud CLI plugin like this:
$ spring install org.springframework.cloud:spring-cloud-cli:2.1.0.RELEASE
To check the installed Spring Boot CLI version and the available Spring Cloud services you can start up locally, run the following commands:
$ spring version # print the version of the Spring Boot CLI
$ spring cloud --list # print the available services you can start with Spring Cloud CLI
To bring up a service via the CLI, you can type:
$ spring cloud eureka # bring up a Eureka service registry locally.
For more information see the Spring Cloud CLI documentation.
Many of the services of this project use Spring Cloud Sleuth with an integration with Zipkin to write trace logs in order to trace requests analyse latencies.
Trace logs generated by a service are sent to a Zipkin server instance expected to be running (by default) on http://localhost:9411/zipkin. The easiest way to run a Zipkin server is to use Docker:
docker run -p 9411:9411 --name zipkinServer openzipkin/zipkin
... or ...
./scripts/startZipkin.sh
This will pull and start a Zipkin server container and once it is started you can access its UI using the link http://localhost:9411/zipkin.
As services will be making requests and logging traces, you will see them in the Zipkin UI. This allows you not only to see which requests are being sent and received but also how long they took and if they were successful or not.
Note, that Spring Cloud Sleuth and Zipkin also work for message-based communication, e.g. using RabbitMQ. See the Spring Cloud Sleuth documentation for details.
See also:
- Distributed Tracing with Spring Cloud Sleuth and Spring Cloud Zipkin
- Micrometer - Spring Boot 2's new metics collector (also nice distinction between tracing and metrics)
docker run -d --hostname my-rabbit --name rabbitBroker -p 15672:15672 -p 5672:5672 rabbitmq:3-management
... or ...
./scripts/startRabbit.sh
Once started you can access its UI using http://localhost:15672/#/.
Username: guest
Password: guest
Required startup order (ideally):
- Zipkin server
- RabbitMQ
- service-registry
- config-server instances
- services (i.e. service-registry clients)
For 1. - 3. the order does not really matter. They can be started in any order and will find one another. Services need to be started last, as they will require configuration for startup coming from the config-server.
This project was created with Spring Starter using the following dependencies:
- Config Server
- Zipkin Client
- Eureka Discovery Client
- Spring Boot Actuator
- Cloud Bus (Adds
spring-cloud-bus
) - Spring for RabbitMQ (adds
spring-boot-starter-amqp
, andspring-cloud-stream-binder-rabbit
for Spring Cloud Bus)
Project config-server
is a Spring Boot application that acts as a central configuration server.
It uses Spring Cloud Config Server to serve configurations that are stored in a GitHub repository.
- Bootstraps its own configurations by loading them from GitHub.
- Uses Zipkin / Sleuth to report tracing information.
- Is a Eureka client, i.e. registers itself with service registry.
- Services find / lookup config-server via Eureka.
- Allows more than one config-server instances to run and be addressed by one logical service name.
- config-server (and all its potential instances) need to start before any service that reads configuration is started. (See this Spring Cloud Config issue.)
- Configs are loaded using the following URL pattern
/{name}/{profile}/{label}
where- name: service ID
- profile: active spring profile (optional)
- label: usually
master
but can be any git tag, commit ID or branch name. - see Spring Cloud Config and Locating Remote Configuration Resources
- Uses Spring Cloud Bus, RabbitMQ and Spring Cloud Config Monitor to expose an
/monitor
endpoint which can be registered as a GitHub WebHook. Every time the configuration changes in GitHub, GitHub sends an event to the/monitor
endpoint. The controller behind the/monitor
endpoint fires a refresh event via the Spring Cloud Bus (using RabbitMQ as the signalling layer), BUT: only to the service instances that are affected by the change in GitHub (based on Eureka service registry). Services refresh automatically with changes in the configurations being pushed to GitHub! - Exposes
http://localhost:1111/actuator/bus-refresh
endpoint, to refresh all services on the bus at once. See also:http://localhost:1111/actuator/bus-env
where you could post key-value pairs to add to every service's environment. See also addressing of individual service instance. - Use http://smee.io to forward WebHook events to localhost.
You can see the configurations the server provides by opening its endpoint in a browser.
For example, http://localhost:1111/reservation-service/master
shows the configurations the reservation-service
sees. With the URL http://localhost:1111/application/master
you can see the configurations every application sees (the basic configurations).
Note that the reservation-service in this example sees an layered view of its own configurations mixed with the basic configurations!
Using http://localhost:1111/reservation-service/cloud/master
will show the configurations reservation-service
will see, if the cloud
profile is active in the service (e.g. by setting spring.profiles.active=cloud
in the reservation-service
's environment).
Update files, push to GitHub, then refresh services that need updated configs.
Actuator endpoints:
- For debugging:
/actuator/env
and/actuator/health
- For Refreshing:
/actuator/refresh
- POST only. Send empty POST request. Receive list of changed properties (delta) after refresh.
Note: Needs Rabbit MQ running!
This project was created with Spring Starter using the following dependencies:
- Eureka Server
- Config Client
- Zipkin Client
- Spring Boot Actuator
- Currently does not use configs from config-server but brings its own.
- Startup is independent from config-server
This project was created with Spring Starter using the following dependencies:
- Spring Web
- Spring for RabbitMQ (adds
spring-boot-starter-amqp
, andspring-cloud-stream-binder-rabbit
for Spring Cloud Bus) - Cloud Bus (Adds
spring-cloud-bus
) - Config Client
- Zipkin Client
- Eureka Discovery Client
- Spring Boot Actuator
There is a greetings endpoint, that shows a greetings message that comes from the greetings-service.yml
configuration in the Configs Repository.
With Rabbit MQ running (./scripts/startRabbit.sh
) and a connection to Smee.io established (./scripts/connectToSmee.sh
), you can change the configs in the repo, and see how the message gets updated automatically (you need to refresh greetings endpoint).
This project was created with Spring Starter using the following dependencies:
- Spring Reactive Web
- Rest Repositories
- Cloud Bus (Adds
spring-cloud-bus
) - Spring for RabbitMQ (adds
spring-boot-starter-amqp
, andspring-cloud-stream-binder-rabbit
for Spring Cloud Bus) - Spring Data JPA
- H2 Database
- Config Client
- Zipkin Client
- Eureka Discovery Client
- Spring Boot Actuator
- RSocket
- Lombok
Note that the service URL (http://localhost:2222/reservations?page=1&size=2&sort=reservationName,asc
) contains parameters for sorting and paging - all out of the box with Spring Data.
There is also a "search by name" endpoint available. E.g. http://localhost:2222/reservations/search/by-name?reservationName=Carl
will return only the reservations whose name is "Carl".
The service provides its REST endpoints via WebFlux (i.e. in a reactive way).
It also provides RSocket endpoints (see com.equalities.cloud.reservation.service.rsocket.RSocketEndpoints
) which are called by Reservation Service Client via the Service Gateway.
An RSocket endpoint to create reservations is exposed at route create-reservation
, and incoming requests (including a reservation name) will trigger the persistence of a new Reservation
object into an in-memory H2 database.
Spring Data JPARepository
is used for persistence, which is a blocking API. The code shows, how that blocking code can be turned into a (reactive) Mono
and wrapped inside a transaction.
Access in Browser Access via Postman (HTTP POST)
This project was created with Spring Starter using the following dependencies:
- Spring Reactive Web
- Cloud Bus (Adds
spring-cloud-bus
) - Spring for RabbitMQ (adds
spring-boot-starter-amqp
, andspring-cloud-stream-binder-rabbit
for Spring Cloud Bus) - Config Client
- Zipkin Client
- Eureka Discovery Client
- Spring Boot Actuator
- RSocket
- Lombok
Reservation service client provides Web endpoints (see WebEndpoints
) as well as RSocket endpoints (see RSocketEndpoints
).
The RSocket endpoint is currently not used, but could be called by a browser using rsocket-js
to communicate RSocket all the way from the frontend to the backend.
Reservation service client exposes a Web endpoint to retrieve a stream (Flux
) of health status messages. This shows how easy it is with WebFlux to create long-living HTTP connections and stream back data from a service via HTTP.
❗️DEPRECATION WARNING: Spring Cloud RSocket has been archived. What is described below is no longer officially available.
You can checkout the tag working-spring-cloud-rsocket
of this repository to see a working version (however with ancient Spring Boot and Spring Cloud versions).
Another endpoint is exposed to create reservations via HTTP PUSH
requests. The HTTP request is translated into an RSocket request, to call Reservation Service's RSocket endpoint and tell it to persist the reservation.
Commnunication happens via the Service Gateway which acts as an RSocket broker that both Reservation Service and Reservation Service Client connect to.
To try this out, proceed as follows:
start ZipKin (./scripts/startZipkin.sh
)start RabbitMQ (./scripts/startRabbit.sh
)startservice-registry
startconfig-service
startservice-gateway
startreservation-service
startreservation-service-client
send aPOST
request tohttp.//localhost:9999/reservation/create/<any name you like>
with an empty body.check that reservation was persisted by openingreservation-service
's endpointhttp://localhost:2222/reservations
and confirm that your name is there.
This project was created with Spring Starter using the following dependencies:
- Gateway
- Spring Boot Actuator
- Eureka Discovery Client
- Config Client
- Cloud Bus (Adds
spring-cloud-bus
) - Spring for RabbitMQ (adds
spring-boot-starter-amqp
, andspring-cloud-stream-binder-rabbit
for Spring Cloud Bus) - Zipkin Client
- Lombok
❗️DEPRECATION WARNING: Spring Cloud RSocket has been archived. What is described below is no longer officially available.
You can checkout the tag working-spring-cloud-rsocket
of this repository to see a working version (however with ancient Spring Boot and Spring Cloud versions).
And we manually added the RSocket gateway broker, which at the time of writing was in technical preview stage and not yet available via Spring starter.io:
<!-- No longer officially available -->
<!--
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gateway-rsocket-broker</artifactId>
</dependency>
-->
This project was created with Spring Starter using the following dependencies:
- Eureka Discovery Client
- Zipkin Client
- Spring Boot Starter Web
- Spring Boot Actuator
Additionally references WebJars to provide static UI content.
Usage: http://localhost:8777/lookup/<serviceName>
e.g. http://localhost:8777/lookup/config-server
. The output will be the information that is returned by Eureka.
- Protocol: RSocket | FAQ | Motivation | Github Repos
- Gateway: Spring Cloud Gateway
- Configs: Spring Cloud Config Server in combination with Git | Spring Cloud Bus
- Testing: Spring Cloud Contract
- Development: Spring Cloud CLI
- Tracing: Spring Cloud Sleuth / Zipkin | Tutorial | Baeldung Tutorial | Video
- Pipelines: Cloud Pipelines | Why the migration
- Data Access: Spring Data
- REST Docs: Spring REST Docs
- Secure Password Storage: Spring Vault | Vault | Vault Docker Image
When you are developing with Spring, you will usually want to use the released versions. However, there may be times in which you will need to switch to a newer milestone, e.g. in case of errors in a release or if you are asked to try out a new fix the Spring teams have introduced.
Generally, the following version patterns are usually encountered with Spring / Spring Boot:
- major.minor.patch.RELEASE
- major.minor.patch.SRx (with x=[1..N))
- major.minor.patch.Mx (with x=[1..N))
- major.minor.patch.RCx (with x=[1..N))
- major.minor.patch.BUILD-SNAPSHOT
The version suffixes mean the following:
- RELEASE - the (first) release and production-ready version of an artifact, e.g.
2.1.18.RELEASE
- SRx - one of potentially multiple service releases, i.e. newer versions of a released artifact, e.g. containing critical patches. Example:
2.1.18.SR2
- Mx - one of potentially many milestone releases, usually relevant if you already want to take a peek at the next version the Spring team is working on. E.g.
2.2.0.M6
- RCx - one of potentially multiple release candidates. These are usually newer than any milestone, and constitute one of potentially multiple milestones that are considered for final release.
- BUILD-SNAPSHOT - the (usually) latest snapshot versions of an artifact. Note, that we have experienced some release candidate versions being more up to date than the BUILD-SNAPSHOTs!
The general rule of thumb is:
- If you intend to stay on the safe release path, prefer service release (
SRx
) versions over release (RELEASE
) versions. And pick the one with the highest number, e.g.SR4
rather thanSR3
. - If you intend to peek into the next version coming, prefer release candidate (
RCx
) versions over milestone (Mx
) versions. And pick the one with the highest number, e.g.RC2
overRC1
overM6
.
Spring and Spring Boot usually use numbers for versions. For Spring Cloud, usually, no major.minor.patch versions are used, but names - e.g. those of British towns - in alphabetically increasing order.
For example, at the time of writing, the latest release of Spring Cloud is the Greenwhich
release, with Hoxton
milestones available as the next release is being prepared.
Predecessors of Greenwhich
are Angel
, Brighton
, Camden
, Dalston
, Edgware
, and Finchley
- you get the idea.
For Spring cloud the same version suffixes apply as stated above.
If you intend to use milestone or snapshot versions, you will have to add the following repository configurations to your Maven pom.xml
for the dependencies to be resolved properly:
For Milestones:
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</pluginRepository>
</pluginRepositories>
For SNAPSHOTs:
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
</pluginRepository>
</pluginRepositories>
The milestone repository links given above will contain also releases and service releases. Thus, you will also be able to resolve .RELEASE
versions while pointing to the milestones repository.
In case you only want to see the milestones and release candidates you can use the following URLs instead:
- For Milestones: https://repo.spring.io/libs-milestone-local
- For Snapshots: https://repo.spring.io/libs-snapshot-local
❗️Note: In case you are working from behind a Maven mirror (e.g. Sonatype Nexus) that does not contain Spring milestones and snapshots, you will need to make sure (in you Maven settings.xml
) that Maven by-passes the mirror when it tries to resolve the milestone or snapshot Spring dependencies.
Spring Cloud
- Beginner's guide to Spring Cloud | Github Repo
- Building Micro-Services with Spring Cloud (great video) | GitHub Repository
- Spring Tips: Spring Cloud Gateway | Living on the Edge: Spring Cloud Gateway (Interesting approach to exposing the Gateway as a Service (broker)!)
- Spring Boot CLI Installation
- Spring Cloud Bus | Baeldung Tutorial
RSocket
- Distributed Reactive Streams with RSocket, Reactor, and Spring (great video)
- RSocket and Spring Cloud Gateway Video | Presentation | Older Presentation | Sample | Older Sample
- RSocket Support in Spring 5.2 Video | Documentation (the basis for Spring Boot RSocket support)
- RSocket Support in Spring Boot 2.2
- RSocket Support in Spring Security Video | Documentation | Sample
- Netifi | Docs | Netifi Broker vs. Spring Cloud Gateway | Youtube Channel | Motivation | Spring Demo Repo
- Aeron Protocol | Blog Post
- RSocket CLI (great for debugging and running RSocket servers easily. See also RSocket Support in Spring 5.2 Video for usage)
Spring Boot RSocket Blog Series (Excellent!)
- Getting Started With RSocket Spring Boot: Server
- Getting Started with RSocket Spring Boot: Client
- Getting Started with RSocket Spring Boot: Fire And Forget
- Getting Started with RSocket Spring Boot: Request Stream
- Getting Started with RSocket Spring Boot: Channels
- Getting Started with RSocket Spring Boot: Servers Calling Clients
- Getting Started with RSocket Spring Boot: Testing Spring Boot Responders
- Getting Started with RSocket Spring Boot: Spring Security
Reactive Programming
- Understanding Reactive Types
- Reactive Streams
- Project Reactor
- RxJava
- 101 Reactive Gems
- Notes on Reactive Programming (Part 1) - The Reactive Landscape | Notes on Reactive Programming (Part 2) - Writing Some Code
- Reactive Databases
- Reactive Feign Client | Samples
Distributed Tracing & Metrics