Springy Store is a conceptual simple μServices-based project using the latest cutting-edge technologies, to demonstrate how the Store services are created to be a cloud-native and 12-factor app agnostic. Those μServices are developed based on Spring Boot & Cloud framework that implements cloud-native intuitive, design patterns, and best practices.
Springy Store μServices
重要说明:本项目的新里程碑是将整个系统迁移到 Kubernetes 上运行,敬请关注。
简介
- 本项目开发了一套小型的基于 Spring Boot 和 Cloud 的微服务项目,实现了云原生理念、响应式编程、事件驱动、微服务设计模式以及编码最佳实践。
- 该项目遵循 CloudNative 建议和 十二因素应用 方法论来构建 软件即服务应用,以展示微服务应如何开发和部署。
- 本项目采用前沿技术,如 Docker、Kubernetes、用于日志和监控的 Elasticsearch Stack、Java SE 15、MySQL 和 MongoDB 数据库,所有组件的开发都考虑了 TDD,涵盖集成测试和性能测试等诸多方面。
- 本项目将分阶段开发,所有阶段步骤都记录在 Springy Store μServices 项目的 维基页面 中。
快速开始
系统组件结构
首先让我们说明系统结构,以了解其组件:
Springy Store μService --> Parent folder.
|- config --> All system configuration files
|- docs --> All docs and diagrams.
|- store-base
|- store-build-chassis --> Super Parent POM, contains all build information
|- store-cloud-chassis --> Cloud services Parent POM, inherit from build contains all cloud libraries
|- store-service-chassis --> Parent POM, inherits from cloud contains all microservices common libraries
|-store-cloud-infra
|- authorization-server --> Authorization server
|- edge-server --> API Gateway server
|- eureka-server --> Service discovery server
|- config-server --> Centralized Configuration server
|-store-common
|- store-api --> API Endpoint and services definitions for all microservices
|- store-utils --> Common utilities shared between all components
|-store-services
|- product-service --> Product Microservice
|- recommendation-service --> Recommendation Microservice
|- review-service --> Review Microservice
|- store-service --> Store Microservice
|- docker-compose.yml --> contains all services landscape with RabbitMQ
|- docker-compose-kafka.yml --> contains all services landscape with more instances working with Kafka with partitions
|- docker-compose-partitions.yml --> contains all services landscape with more instances working with RabbitMQ with partitions
|- run-em-all.sh --> Run all microservices in separate mode.
|- setup.sh --> Install all shared POMs and shared libraries.
|- stop-em-all.sh --> Stop all services runs in standalone mode.
|- test-em-all.sh --> This will start all docker compose landscape and test them, then shutdown docker compose containers with test finishes (use switch start stop)
现在,既然我们已经了解了不同的系统组件,那么就让我们开始吧。
系统边界 - 微服务全景

所需软件
以下是初始所需的软件:
-
Maven:Apache Maven 是一款软件项目管理和理解工具,可从 https://maven.apache.org/download.cgi 下载。
-
Git:可从 https://git-scm.com/downloads 下载并安装。
-
Java 15 EA:可从 https://jdk.java.net/15/ 下载并安装。
-
curl:这款用于测试基于 HTTP 的 API 的命令行工具可从 https://curl.haxx.se/download.html 下载并安装。
-
jq:这款命令行 JSON 处理器可从 https://stedolan.github.io/jq/download/ 下载并安装。
-
Spring Boot Initializer:此 Initializer 可生成仅包含快速启动所需内容的 spring boot 项目!从 https://start.spring.io/ 开始。
-
Docker Desktop:在桌面端容器化应用程序的最快方式,可从 https://www.docker.com/products/docker-desktop 下载。
对于后续的每个阶段,我将列出新需要的软件。
请按照每个软件网站链接上的安装指南进行操作,并通过命令行检查软件版本,以确认所有软件均已正确安装。
使用 IDE
我建议您使用支持 Spring Boot 应用程序开发的 IDE(如 Spring Tool Suite 或 IntelliJ IDEA Ultimate Edition)来处理 Java 代码。这样您就可以使用 Spring Boot 仪表板运行服务、运行每个微服务的测试用例等等。
您只需启动 IDE -> 打开或导入父文件夹 springy-store-microservices,一切就都准备就绪了。
玩转 Springy Store 项目
克隆项目
首先要做的是打开 git bash 命令行,然后只需按以下方式将项目克隆到您喜欢的任何位置:
> git clone https://github.com/mohamed-taman/Springy-Store-Microservices.git
独立构建与测试
要为项目中的每个服务和共享模块构建并运行测试用例,我们需要执行以下步骤:
第一步:构建并安装共享依赖项
此操作仅在首次构建时、共享模块和 POM 发生新更改或版本更新时执行。
若要构建并安装 store-build-chassis、store-utils、store-api、store-services-chassis 和 store-cloud-chassis 库,请从根文件夹 springy-store-microservices 运行以下命令:
mohamed.taman@DTLNV8 ~/springy-store-microservices
λ ./setup.sh
现在你应该期待这样的输出:
Installing all Springy store core shared modules & Parent POMs
...............................................................
1- Installing [Parent Build Chassis] module...
Done successfully.
2- Installing [Parent Cloud Chassis] module...
Done successfully.
3- Installing shared [Services Utilities] module...
Done successfully.
4- Installing shared [Services APIs] module...
Done successfully.
5- Installing [Services Parent Chassis] module...
Done successfully.
Woohoo, building & installing all project modules are finished successfully.
The project is ready for the next step. :)
第二步:构建和测试微服务
现在是时候构建我们的4 个微服务并通过运行以下命令单独运行每个服务的集成测试了:
mohamed.taman@DTLNV8 ~/springy-store-microservices
λ ./mvnw clean verify -Ddockerfile.skip
每个微服务的所有构建命令和测试套件都应成功运行,最终输出应如下所示:
---------------< com.siriusxi.ms.store:store-aggregator >---------------
[INFO] Building Springy Store Aggregator 1.0-SNAPSHOT [13/13]
[INFO] --------------------------------[ pom ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ store-aggregator ---
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary for Springy Store Aggregator 1.0-SNAPSHOT:
[INFO]
[INFO] Springy Store Build Chassis ........................ SUCCESS [ 0.228 s]
[INFO] Springy Store Cloud Chassis ........................ SUCCESS [ 1.257 s]
[INFO] Store APIs ......................................... SUCCESS [ 4.279 s]
[INFO] Store Utils ........................................ SUCCESS [ 1.809 s]
[INFO] Springy Store Chassis .............................. SUCCESS [ 0.857 s]
[INFO] Product Service .................................... SUCCESS [ 13.079 s]
[INFO] Review Service ..................................... SUCCESS [ 9.332 s]
[INFO] Recommendation Service ............................. SUCCESS [ 8.463 s]
[INFO] Store Service ...................................... SUCCESS [ 8.927 s]
[INFO] Eureka Discovery Server ............................ SUCCESS [ 6.536 s]
[INFO] Edge Server ........................................ SUCCESS [ 32.108 s]
[INFO] Authorization Server ............................... SUCCESS [ 1.616 s]
[INFO] Configuration Server ............................... SUCCESS [ 1.216 s]
[INFO] Springy Store Aggregator ........................... SUCCESS [ 0.100 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 57.663 s
[INFO] Finished at: 2020-05-08T03:38:34+02:00
[INFO] ------------------------------------------------------------------------
全部运行
使用不带分区的 RabbitMQ
现在是运行我们所有响应式微服务的时候了,只需运行以下 docker-compose 命令即可,操作非常简单:
mohamed.taman@DTLNV8 ~/springy-store-microservices
λ docker-compose -p ssm up -d
所有服务、数据库和消息服务将以分离模式(选项 -d)并行运行,命令输出将在控制台打印以下内容:
Creating network "ssm_default" with the default driver
Creating ssm_eureka_1 ... done
Creating ssm_config-server_1 ... done
Creating ssm_gateway_1 ... done
Creating ssm_auth-server_1 ... done
Creating ssm_mysql_1 ... done
Creating ssm_mongodb_1 ... done
Creating ssm_rabbitmq_1 ... done
Creating ssm_zipkin_1 ... done
Creating ssm_store_1 ... done
Creating ssm_review_1 ... done
Creating ssm_product_1 ... done
Creating ssm_recommendation_1 ... done
访问商店 API
您可以通过以下 URL 的 Swagger 界面手动测试 Store Service API:https://localhost:8443/swagger-ui.html。
访问服务发现服务器(Eureka)
如果您想访问 Eureka 服务发现,请访问此 URL http://localhosts:8443/eureka/web,以查看其中注册的所有服务。
请注意,它是通过 API Gateway 访问的,并且受到保护。因此,浏览器会要求您输入 username:mt 和 password:p,将它们输入对话框即可访问。这种安全类型是 基本表单安全。
API Gateway 和 Store Service 均充当 资源服务器。要了解如何以安全方式调用商店 API,您可以查看 test-em-all.sh 脚本,了解我如何使用 OAuth2 安全性更改服务的调用方式。
访问 RabbitMQ
在浏览器中访问此 URL http://localhost:5672/,使用 username: guest 和 password: guest 登录,您可以查看所有 主题、死信队列(DLQs)、分区 和消息负载。
- 若要运行每个服务的两个实例,并使用 每个主题具有两个分区的 RabbitMQ,请使用以下
docker-compose命令:mohamed.taman@DTLNV8 ~/springy-store-microservices λ docker-compose -p ssm -f docker-compose-partitions.yml up -d - 若要使用 每个主题具有两个分区的 Kafka 和 Zookeeper,请运行以下命令:
mohamed.taman@DTLNV8 ~/springy-store-microservices λ docker-compose -p ssm -f docker-compose-kafka.yml up -d
检查所有服务健康状态
当您使用 Docker Compose 启动所有微服务后,可以通过 Store front Service 检查所有核心服务的健康状态。
mohamed.taman@DTLNV8 ~/springy-store-microservices
λ curl -k https://localhost:8443/actuator/health -s | jq .components."\"Core Microservices\""
这将产生以下响应:
{
"status": "UP",
"components": {
"Authorization Server": {
"status": "UP"
},
"Product Service": {
"status": "UP"
},
"Recommendation Service": {
"status": "UP"
},
"Review Service": {
"status": "UP"
},
"Store Service": {
"status": "UP"
}
}
}
全面测试
现在是时候将所有应用功能作为一个整体进行测试了。为此,只需运行以下自动化测试脚本:
mohamed.taman@DTLNV8 ~/springy-store-microservices
λ ./test-em-all.sh start
您可以将
stop开关与start配合使用,这将
- 启动 docker,
- 运行测试,
- 停止 docker 实例。
结果将如下所示:
Starting 'Springy Store μServices' for [Blackbox] testing...
Start Tests: Tue, May 31, 2020 2:09:36 AM
HOST=localhost
PORT=8443
Restarting the test environment...
$ docker-compose -p ssm down --remove-orphans
$ docker-compose -p ssm up -d
Wait for: curl -k https://localhost:8443/actuator/health... , retry #1 , retry #2, {"status":"UP"} DONE, continues...
Test OK (HTTP Code: 200)
...
Test OK (actual value: 1)
Test OK (actual value: 3)
Test OK (actual value: 3)
Test OK (HTTP Code: 404, {"httpStatus":"NOT_FOUND","message":"No product found for productId: 13","path":"/store/api/v1/products/13","time":"2020-04-12@12:34:25.144+0000"})
...
Test OK (actual value: 3)
Test OK (actual value: 0)
Test OK (HTTP Code: 422, {"httpStatus":"UNPROCESSABLE_ENTITY","message":"Invalid productId: -1","path":"/store/api/v1/products/-1","time":"2020-04-12@12:34:26.243+0000"})
Test OK (actual value: "Invalid productId: -1")
Test OK (HTTP Code: 400, {"timestamp":"2020-04-12T12:34:26.471+00:00","path":"/store/api/v1/products/invalidProductId","status":400,"error":"Bad Request","message":"Type mismatch.","requestId":"044dcdf2-13"})
Test OK (actual value: "Type mismatch.")
Test OK (HTTP Code: 401, )
Test OK (HTTP Code: 200)
Test OK (HTTP Code: 403, )
Start Circuit Breaker tests!
Test OK (actual value: CLOSED)
Test OK (HTTP Code: 500, {"timestamp":"2020-05-26T00:09:48.784+00:00","path":"/store/api/v1/products/2","status":500,"error":"Internal Server Error","message":"Did not observe any item or terminal signal within 2000ms in 'onErrorResume' (and no fallback has been configured)","requestId":"4aa9f5e8-119"})
...
Test OK (actual value: Did not observe any item or terminal signal within 2000ms)
Test OK (HTTP Code: 200)
Test OK (actual value: Fallback product2)
Test OK (HTTP Code: 200)
Test OK (actual value: Fallback product2)
Test OK (HTTP Code: 404, {"httpStatus":"NOT_FOUND","message":"Product Id: 14 not found in fallback cache!","path":"/store/api/v1/products/14","timestamp":"2020-05-26@00:09:53.998+0000"})
...
Test OK (actual value: product name C)
Test OK (actual value: CLOSED)
Test OK (actual value: CLOSED_TO_OPEN)
Test OK (actual value: OPEN_TO_HALF_OPEN)
Test OK (actual value: HALF_OPEN_TO_CLOSED)
End, all tests OK: Tue, May 31, 2020 2:10:09 AM
使用 Zipkin 跟踪服务
现在,您可以通过以下链接,在 Zipkin UI 中跟踪微服务之间的交互:
http://localhost:9411/zipkin/

结束流程
最后,为了结束整个流程,我们需要手动逐个关闭微服务——哈哈,开个玩笑,只需运行以下命令即可一次性关闭所有服务:
mohamed.taman@DTLNV8 ~/springy-store-microservices
λ docker-compose -p ssm down --remove-orphans
你应该会看到如下输出:
Stopping ssm_recommendation_1 ... done
Stopping ssm_product_1 ... done
Stopping ssm_review_1 ... done
Stopping ssm_mongodb_1 ... done
Stopping ssm_store_1 ... done
Stopping ssm_auth-server_1 ... done
Stopping ssm_mysql_1 ... done
Stopping ssm_rabbitmq_1 ... done
Stopping ssm_eureka_1 ... done
Stopping ssm_gateway_1 ... done
Stopping ssm_config-server_1 ... done
Stopping ssm_zipkin_1 ... done
Removing ssm_recommendation_1 ... done
Removing ssm_product_1 ... done
Removing ssm_review_1 ... done
Removing ssm_mongodb_1 ... done
Removing ssm_store_1 ... done
Removing ssm_auth-server_1 ... done
Removing ssm_mysql_1 ... done
Removing ssm_rabbitmq_1 ... done
Removing ssm_eureka_1 ... done
Removing ssm_gateway_1 ... done
Removing ssm_config-server_1 ... done
Removing ssm_zipkin_1 ... done
Removing network ssm_default
结尾
最后,希望您能喜欢这个应用并觉得它有用,就像我在开发它时的感受一样。
如果您想对其进行增强,请:
- 提交 PR,
- 提供 反馈,
- 添加 新的建议,并且
- 最后,给它点个 🌟。
祝您编码愉快…… 🙂
许可证
Copyright (C) 2017-2020 Mohamed Taman,根据 MIT 许可证授权。
项目介绍
Springy Store is a conceptual simple μServices-based project using the latest cutting-edge technologies, to demonstrate how the Store services are created to be a cloud-native and 12-factor app agnostic. Those μServices are developed based on Spring Boot & Cloud framework that implements cloud-native intuitive, design patterns, and best practices.