微服务
微服务架构(Microservices Architecture)是一种将单个应用程序分解为多个独立部署的小服务的架构模式, 每个服务专注于特定的业务功能, 具有高内聚和松耦合的特点. 它允许各个服务独立开发, 部署和扩展, 支持灵活的技术选型, 提高系统的弹性和扩展性. 然而微服务架构也带来了系统复杂性增加, 运维成本高, 通信开销大和数据一致性保障难等挑战
Graphoenix 全面支持微服务架构, 提供服务注册, 网关, 熔断, 负载均衡, 事务补偿等全套的微服务解决方案. 系统通过不同的包名(Package Name)来区分模块, 每个模块可以独立提供服务, 通过 gRPC 等通讯协议构成微服务矩阵, 也可以与其他模块合并为单体架构提供服务
服务拆分
微服务的拆分是将一个单体应用分解为多个独立部署的小服务, 每个服务专注于特定业务功能. 通过领域驱动设计(DDD), 业务功能划分, 独立数据库, 独立部署和服务通信, 实现更好的隔离和独立性
例: 我们将快速开始中的订单系统拆分为订单(demo.gp.order), 用户(demo.gp.user), 评论(demo.gp.review)三个子系统
模块和服务
项目按照功能分为模块(package)和服务(app), 服务作为模块的载体, 按照不同的组合方式构建单体架构或微服务矩阵:
- app(package1 + package2 + package3) = monolithic
- app1(package1) + app2(package2) + app3(package3) = microservices
项目结构
|-- order-microservices
|-- build.gradle
|-- gradle.properties
|-- settings.gradle
|-- order-app 订单系统
| |-- build.gradle
| |-- src
| |-- main
| |-- java
| | |-- demo.gp.order
| | |-- App.java
| |-- resources
| |-- application.conf
|-- order-package 订单模块
| |-- build.gradle
| |-- src
| |-- main
| |-- java
| | |-- demo.gp.order
| | |-- package-info.java
| |-- resources
| |-- graphql
| |-- order.gql 定义订单相关类型
|-- review-app 评论系统
| |-- build.gradle
| |-- src
| |-- main
| |-- java
| | |-- demo.gp.review
| | |-- App.java
| |-- resources
| |-- application.conf
|-- review-package 评论模块
| |-- build.gradle
| |-- src
| |-- main
| |-- java
| | |-- demo.gp.review
| | |-- package-info.java
| |-- resources
| |-- graphql
| |-- review.gql 定义评论相关类型
|-- user-app 用户系统
| |-- build.gradle
| |-- src
| |-- main
| |-- java
| | |-- demo.gp.user
| | |-- App.java
| |-- resources
| |-- application.conf
|-- user-package 用户模块
|-- build.gradle
|-- src
|-- main
|-- java
| |-- demo.gp.user
| |-- package-info.java
|-- resources
|-- graphql
|-- user.gql 定义用户相关类型
- 用户模块中定义用户(User)和用户类型(UserType)
- 评论模块中定义评论(Review), 评论的评论人字段(user)引用用户模块的用户(User)
- 订单模块中定义订单(Order)和产品(Product), 订单的购买用户字段(user)引用用户模块的用户(User), 产品的评论列表字段(reviews)引用评论模块的评论(Review)
安装
protobuf 插件
模块之间默认使用 gRPC 进行通讯, 需要引用插件生成 protobuf 文件
user-package
build.gradle
buildscript {
repositories {
jcenter()
}
}
plugins {
id 'java'
id 'com.google.protobuf' version '0.9.1'
id "org.graphoenix" version "0.1.1"
}
classes {
dependsOn generateGraphQLSource
dependsOn generateProtobufV3
}
生成 DTO 和 protobuf
./gradlew :user-package:build
review-package
build.gradle
buildscript {
repositories {
jcenter()
}
}
plugins {
id 'java'
id 'com.google.protobuf' version '0.9.1'
id "org.graphoenix" version "0.1.1"
}
classes {
dependsOn generateGraphQLSource
dependsOn generateProtobufV3
}
生成 DTO 和 protobuf
./gradlew :review-package:build
order-package
build.gradle
buildscript {
repositories {
jcenter()
}
}
plugins {
id 'java'
id 'com.google.protobuf' version '0.9.1'
id "org.graphoenix" version "0.1.1"
}
classes.dependsOn {
generateGraphQLSource
generateProtobufV3
}
生成 DTO 和 protobuf
./gradlew :order-package:build
模块(package)依赖
安装和配置 gRPC, 引用其他模块
user-package
build.gradle
// gRPC 配置
protobuf {
protoc {
artifact = 'com.google.protobuf:protoc:3.21.7'
}
plugins {
grpc {
artifact = 'io.grpc:protoc-gen-grpc-java:1.52.1'
}
reactor {
artifact = 'com.salesforce.servicelibs:reactor-grpc:1.2.3'
}
}
generateProtoTasks {
all()*.plugins {
grpc {}
reactor {}
}
}
}
// gRPC 目录配置
sourceSets {
main {
java {
srcDirs 'build/generated/source/proto/main/java'
srcDirs 'build/generated/source/proto/main/grpc'
srcDirs 'build/generated/source/proto/main/reactor'
}
}
}
dependencies {
// gRPC 依赖
runtimeOnly 'io.grpc:grpc-netty-shaded:1.52.1'
implementation 'io.grpc:grpc-protobuf:1.52.1'
implementation 'io.grpc:grpc-stub:1.52.1'
implementation 'com.salesforce.servicelibs:reactor-grpc-stub:1.2.3'
compileOnly 'org.apache.tomcat:annotations-api:6.0.53' // necessary for Java 9+
// ...
}
review-package
build.gradle
// gRPC 配置
protobuf {
protoc {
artifact = 'com.google.protobuf:protoc:3.21.7'
}
plugins {
grpc {
artifact = 'io.grpc:protoc-gen-grpc-java:1.52.1'
}
reactor {
artifact = 'com.salesforce.servicelibs:reactor-grpc:1.2.3'
}
}
generateProtoTasks {
all()*.plugins {
grpc {}
reactor {}
}
}
}
// gRPC 目录配置
sourceSets {
main {
java {
srcDirs 'build/generated/source/proto/main/java'
srcDirs 'build/generated/source/proto/main/grpc'
srcDirs 'build/generated/source/proto/main/reactor'
}
}
}
dependencies {
// 引用 User 模块
implementation project(':user-package')
// gRPC 依赖
runtimeOnly 'io.grpc:grpc-netty-shaded:1.52.1'
implementation 'io.grpc:grpc-protobuf:1.52.1'
implementation 'io.grpc:grpc-stub:1.52.1'
implementation 'com.salesforce.servicelibs:reactor-grpc-stub:1.2.3'
compileOnly 'org.apache.tomcat:annotations-api:6.0.53' // necessary for Java 9+
// 引用 User 模块
annotationProcessor project(':user-package')
// 引用 User 模块
protobuf project(':user-package')
// ...
}
order-package
build.gradle
// gRPC 配置
protobuf {
protoc {
artifact = 'com.google.protobuf:protoc:3.21.7'
}
plugins {
grpc {
artifact = 'io.grpc:protoc-gen-grpc-java:1.52.1'
}
reactor {
artifact = 'com.salesforce.servicelibs:reactor-grpc:1.2.3'
}
}
generateProtoTasks {
all()*.plugins {
grpc {}
reactor {}
}
}
}
// gRPC 目录配置
sourceSets {
main {
java {
srcDirs 'build/generated/source/proto/main/java'
srcDirs 'build/generated/source/proto/main/grpc'
srcDirs 'build/generated/source/proto/main/reactor'
}
}
}
dependencies {
// 引用 User 模块
implementation project(':user-package')
// 引用 Review 模块
implementation project(':review-package')
// gRPC 依赖
runtimeOnly 'io.grpc:grpc-netty-shaded:1.52.1'
implementation 'io.grpc:grpc-protobuf:1.52.1'
implementation 'io.grpc:grpc-stub:1.52.1'
implementation 'com.salesforce.servicelibs:reactor-grpc-stub:1.2.3'
compileOnly 'org.apache.tomcat:annotations-api:6.0.53' // necessary for Java 9+
// 引用 User 模块
annotationProcessor project(':user-package')
// 引用 Review 模块
annotationProcessor project(':review-package')
// 引用 User 模块
protobuf project(':user-package')
// 引用 Review 模块
protobuf project(':review-package')
// ..
}
服务(app)依赖
引用模块, 安装服务依赖
user-app
build.gradle
dependencies {
// User 模块
implementation project(':user-package')
// Http 服务
implementation 'org.graphoenix:graphoenix-http-server:0.1.4'
// gRPC 服务
implementation 'org.graphoenix:graphoenix-grpc-server:0.1.4'
// User 模块
annotationProcessor project(':user-package')
// gRPC 服务
annotationProcessor 'org.graphoenix:graphoenix-grpc-server:0.1.4'
// ...
}
review-app
build.gradle
dependencies {
// User 模块
implementation project(':user-package')
// Review 模块
implementation project(':review-package')
// Http 服务
implementation 'org.graphoenix:graphoenix-http-server:0.1.4'
// gRPC 服务
implementation 'org.graphoenix:graphoenix-grpc-server:0.1.4'
// gRPC 客户端, 调用其他模块
implementation 'org.graphoenix:graphoenix-grpc-client:0.1.3'
// User 模块
annotationProcessor project(':user-package')
// Review 模块
annotationProcessor project(':review-package')
// gRPC 服务
annotationProcessor 'org.graphoenix:graphoenix-grpc-server:0.1.4'
// gRPC 客户端, 调用其他模块
annotationProcessor 'org.graphoenix:graphoenix-grpc-client:0.1.3'
// ...
}
order-app
build.gradle
dependencies {
// User 模块
implementation project(':user-package')
// Review 模块
implementation project(':review-package')
// Order 模块
implementation project(':order-package')
// Http 服务
implementation 'org.graphoenix:graphoenix-http-server:0.1.4'
// gRPC 服务
implementation 'org.graphoenix:graphoenix-grpc-server:0.1.4'
// gRPC 客户端, 调用其他模块
implementation 'org.graphoenix:graphoenix-grpc-client:0.1.3'
// User 模块
annotationProcessor project(':user-package')
// Review 模块
annotationProcessor project(':review-package')
// Order 模块
annotationProcessor project(':order-package')
// gRPC 服务
annotationProcessor 'org.graphoenix:graphoenix-grpc-server:0.1.4'
// gRPC 客户端, 调用其他模块
annotationProcessor 'org.graphoenix:graphoenix-grpc-client:0.1.3'
// ...
}
配置
配置数据库和服务
user-app/src/main/resources/application.conf
r2dbc {
driver = "mariadb"
database = "user"
user = "root"
password = "root"
}
http {
port = 8082 //Http 端口
}
grpc {
port = 50053 //gRPC 端口
}
review-app/src/main/resources/application.conf
r2dbc {
driver = "mariadb"
database = "review"
user = "root"
password = "root"
}
http {
port = 8081 //Http 端口
}
grpc {
port = 50052 //gRPC 端口
}
order-app/src/main/resources/application.conf
r2dbc {
driver = "mariadb"
database = "order"
user = "root"
password = "root"
}
http {
port = 8080 //Http 端口
}
grpc {
port = 50051 //gRPC 端口
}
配置模块地址
使用 package.members
配置每个模块的地址, 每个模块都可以提供多个服务作为冗余
review-app/src/main/resources/application.conf
package {
members: {"demo.gp.user": [{host: "127.0.0.1", port: 50053, protocol: "GRPC"}]}
}