Skip to content

Commit 29a999d

Browse files
committed
init
1 parent d5f6d76 commit 29a999d

File tree

99 files changed

+5268
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

99 files changed

+5268
-0
lines changed

.env

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
TAG=1.0

.gitignore

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
target/
2+
!.mvn/wrapper/maven-wrapper.jar
3+
!**/src/main/**/target/
4+
!**/src/test/**/target/
5+
6+
### IntelliJ IDEA ###
7+
.idea/modules.xml
8+
.idea/jarRepositories.xml
9+
.idea/compiler.xml
10+
.idea/libraries/
11+
*.iws
12+
*.iml
13+
*.ipr
14+
15+
### Eclipse ###
16+
.apt_generated
17+
.classpath
18+
.factorypath
19+
.project
20+
.settings
21+
.springBeans
22+
.sts4-cache
23+
24+
### NetBeans ###
25+
/nbproject/private/
26+
/nbbuild/
27+
/dist/
28+
/nbdist/
29+
/.nb-gradle/
30+
build/
31+
!**/src/main/**/build/
32+
!**/src/test/**/build/
33+
34+
### VS Code ###
35+
.vscode/
36+
37+
### Mac OS ###
38+
.DS_Store
39+
**/logs/
40+
/docker/nacos/
41+
/.idea/

README.md

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
[![](https://img.shields.io/badge/release-v1.0-lightgray.svg)](https://github.com/ReionChan/programmatic-microservice-arch/) [![](https://img.shields.io/badge/license-Apache--2.0-orange.svg)](https://github.com/ReionChan/programmatic-microservice-arch/blob/main/LICENSE) [![](https://img.shields.io/badge/Author-ReionChan-cyan.svg)](https://reionchan.github.io/)
2+
3+
# 基于『Spring Cloud』编程式、非云原生的骨架
4+
5+
> **子曰:欣聞關注,樂見散佈!**&emsp;&emsp; <a href="https://github.com/ReionChan/programmatic-microservice-arch/stargazers"><img src="https://img.shields.io/github/stars/ReionChan/programmatic-microservice-arch?style=social&label=Star" title="关注" alt="关注" height="18" /></a>&emsp;<a href="https://github.com/ReionChan/programmatic-microservice-arch/network/members"><img src="https://img.shields.io/github/stars/ReionChan/programmatic-microservice-arch?style=social&label=Fork" title="关注" alt="关注" height="18" /></a>
6+
7+
## 为什么强调非原生?
8+
9+
&emsp;&emsp;这是个容器化、云端化的后微服务时代。
10+
11+
&emsp;&emsp;若从分布式微服务技术与解决方案演进角度来看,**后微服务时代**主张 “***向应用代码隐藏分布式架构复杂度、让分布式架构得以成为一种可普遍推广的普适架构风格***[^1] 的技术流派,可称为 “仙术” 派。
12+
13+
&emsp;&emsp;而采用**足够灵活的编程式**微服务解决方案,是软硬件能够提供**透明化的不可变基础设施**出现之前的过渡方案,这个时期也被称作**微服务时代**,而采用编程式提供微服务的技术流派,不妨称作 “体术” 派。之所以在 “体术” 派的项目中着重强调其非 “仙术” 派,是为了增强对比性来观察体会架构迭代中的原由。
14+
15+
## 项目架构
16+
17+
![](https://raw.githubusercontent.com/ReionChan/PhotoRepo/master/arch/programmatic-microservice-arch%20Private.png)
18+
19+
## 项目运行
20+
21+
### dev 模式
22+
23+
```sh
24+
# 容器启动必要依赖中间件: Nacos、Jaeger、OpenTelemetry Collector
25+
docker compose up -d --build
26+
27+
# 然后在 IDE 运行模块,推荐顺序:
28+
# 认证授权中心
29+
arch-iam
30+
# 用户模块
31+
arch-users
32+
# 测试应用
33+
arch-app
34+
# API 网关
35+
arch-gateway
36+
```
37+
38+
### test 模式
39+
40+
```sh
41+
# 采用 test 配置 Docker Compose 方式启动所有模块
42+
docker compose --profile test up -d --build
43+
```
44+
45+
## 使用技术栈
46+
47+
* 服务注册与发现
48+
* Alibaba Nacos
49+
* 负载均衡
50+
* Spring Cloud Loadbalancer
51+
* 服务容错
52+
* Spring Cloud Circuitbreak
53+
* Resilience4J
54+
* RPC
55+
* Spring Cloud OpenFeign
56+
* 认证授权
57+
* Spring Security OAuth2 Server
58+
* Spring Security OAuth2 Client
59+
* Spring Security OAuth2 Resource
60+
* 可观测性
61+
* Micrometer (统一埋点 API)
62+
* OpenTelemetry Java Agent (统一采集方式)
63+
* OpenTelemetry Collector (统一 OTLP 协议收集,隔离不同监控提供商)
64+
* 指标数据观测,包括不限于:Prometheus、Grafana、
65+
* 追踪数据观测,包括不限于:Jaeger、Zipkin、Tempo
66+
* 日志数据观测,包括不限于:ELK、Loki
67+
68+
## 云原生基础设施可替代
69+
70+
| | 基于 Spring Cloud 编程式 | 基于 K8S 云原生基础设施 |
71+
| -------- | ------------------------------------------------------------ | ----------------------- |
72+
| 弹性伸缩 | —— | Autoscaling |
73+
| 服务发现 | Spring Cloud Alibaba Nacos / Netflix Eureka | KubeDNS / CoreDNS |
74+
| 配置中心 | Spring Cloud Config Alibaba Nacos / Azure App Configuratioin | ConfigMap / Secret |
75+
| 服务网关 | Spring Cloud Gateway | Ingress Controller |
76+
| 负载均衡 | Spring Cloud Loadbalancer | Load Balancer |
77+
| 服务安全 | Spring Security OAuth2 | RBAC API |
78+
| 监控追踪 | Micrometer Tracing | Metrics API / Dashboard |
79+
| 熔断降级 | Spring Cloud Circuit Breaker with Resilience4J / Spring Retry | Istio Envoy |
80+
81+
[^1]: [凤凰架构 - 从微服务到云原生](https://icyfenix.cn/immutable-infrastructure/msa-to-cn.html)

arch-business/.gitignore

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
target/
2+
!.mvn/wrapper/maven-wrapper.jar
3+
!**/src/main/**/target/
4+
!**/src/test/**/target/
5+
6+
### IntelliJ IDEA ###
7+
.idea/modules.xml
8+
.idea/jarRepositories.xml
9+
.idea/compiler.xml
10+
.idea/libraries/
11+
*.iws
12+
*.iml
13+
*.ipr
14+
15+
### Eclipse ###
16+
.apt_generated
17+
.classpath
18+
.factorypath
19+
.project
20+
.settings
21+
.springBeans
22+
.sts4-cache
23+
24+
### NetBeans ###
25+
/nbproject/private/
26+
/nbbuild/
27+
/dist/
28+
/nbdist/
29+
/.nb-gradle/
30+
build/
31+
!**/src/main/**/build/
32+
!**/src/test/**/build/
33+
34+
### VS Code ###
35+
.vscode/
36+
37+
### Mac OS ###
38+
.DS_Store

arch-business/arch-app/.gitignore

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
target/
2+
!.mvn/wrapper/maven-wrapper.jar
3+
!**/src/main/**/target/
4+
!**/src/test/**/target/
5+
6+
### IntelliJ IDEA ###
7+
.idea/modules.xml
8+
.idea/jarRepositories.xml
9+
.idea/compiler.xml
10+
.idea/libraries/
11+
*.iws
12+
*.iml
13+
*.ipr
14+
15+
### Eclipse ###
16+
.apt_generated
17+
.classpath
18+
.factorypath
19+
.project
20+
.settings
21+
.springBeans
22+
.sts4-cache
23+
24+
### NetBeans ###
25+
/nbproject/private/
26+
/nbbuild/
27+
/dist/
28+
/nbdist/
29+
/.nb-gradle/
30+
build/
31+
!**/src/main/**/build/
32+
!**/src/test/**/build/
33+
34+
### VS Code ###
35+
.vscode/
36+
37+
### Mac OS ###
38+
.DS_Store

arch-business/arch-app/pom.xml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
<parent>
7+
<groupId>io.github.reionchan</groupId>
8+
<artifactId>arch-parent</artifactId>
9+
<version>1.0</version>
10+
<relativePath>../../pom.xml</relativePath>
11+
</parent>
12+
13+
<artifactId>arch-app</artifactId>
14+
<version>1.0</version>
15+
<packaging>jar</packaging>
16+
<description>测试项目 app</description>
17+
18+
<dependencies>
19+
<dependency>
20+
<groupId>io.github.reionchan</groupId>
21+
<artifactId>arch-core</artifactId>
22+
</dependency>
23+
<dependency>
24+
<groupId>org.springframework.boot</groupId>
25+
<artifactId>spring-boot-starter-web</artifactId>
26+
</dependency>
27+
</dependencies>
28+
29+
<build>
30+
<plugins>
31+
<!-- Maven Plugin for Spring Boot Fat Jar -->
32+
<plugin>
33+
<groupId>org.springframework.boot</groupId>
34+
<artifactId>spring-boot-maven-plugin</artifactId>
35+
<executions>
36+
<execution>
37+
<goals>
38+
<goal>repackage</goal>
39+
</goals>
40+
</execution>
41+
</executions>
42+
</plugin>
43+
</plugins>
44+
</build>
45+
46+
</project>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package io.github.reionchan;
2+
3+
import org.springframework.boot.SpringApplication;
4+
import org.springframework.boot.autoconfigure.SpringBootApplication;
5+
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
6+
7+
/**
8+
* @author Reion
9+
* @date 2024-06-01
10+
**/
11+
@SpringBootApplication
12+
@EnableMethodSecurity
13+
public class AppBootstrap {
14+
public static void main(String[] args) {
15+
SpringApplication.run(AppBootstrap.class, args);
16+
}
17+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package io.github.reionchan.controller;
2+
3+
import io.github.reionchan.AppBootstrap;
4+
import io.github.reionchan.dto.R;
5+
import io.opentelemetry.api.OpenTelemetry;
6+
import io.opentelemetry.api.common.AttributeKey;
7+
import io.opentelemetry.api.common.Attributes;
8+
import io.opentelemetry.api.metrics.LongHistogram;
9+
import io.opentelemetry.api.metrics.Meter;
10+
import io.opentelemetry.api.trace.Span;
11+
import io.opentelemetry.api.trace.Tracer;
12+
import io.opentelemetry.context.Scope;
13+
import io.swagger.v3.oas.annotations.Operation;
14+
import io.swagger.v3.oas.annotations.media.Content;
15+
import io.swagger.v3.oas.annotations.tags.Tag;
16+
import lombok.extern.slf4j.Slf4j;
17+
import org.springframework.beans.factory.annotation.Autowired;
18+
import org.springframework.http.MediaType;
19+
import org.springframework.security.access.prepost.PreAuthorize;
20+
import org.springframework.web.bind.annotation.GetMapping;
21+
import org.springframework.web.bind.annotation.RestController;
22+
23+
import java.util.Random;
24+
25+
import static io.github.reionchan.consts.Role.ADMIN;
26+
import static io.github.reionchan.consts.Role.USER;
27+
28+
/**
29+
* @author Reion
30+
* @date 2024-06-01
31+
**/
32+
@Slf4j
33+
@RestController
34+
@Tag(name = "PingController", description = "测试服务请求端点")
35+
public class PingController {
36+
37+
private final AttributeKey<String> ATTR_METHOD = AttributeKey.stringKey("method");
38+
39+
private final Random random = new Random();
40+
private final Tracer tracer;
41+
private final LongHistogram doWorkHistogram;
42+
43+
@Autowired
44+
public PingController(OpenTelemetry openTelemetry) {
45+
tracer = openTelemetry.getTracer(AppBootstrap.class.getName());
46+
Meter meter = openTelemetry.getMeter(AppBootstrap.class.getName());
47+
doWorkHistogram = meter.histogramBuilder("do-work").ofLongs().build();
48+
}
49+
50+
@GetMapping("/ping")
51+
@PreAuthorize("hasAnyRole('" + USER + "','" + ADMIN + "')")
52+
@Operation(summary = "ping 方法", description = "测试接口",
53+
requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(
54+
description = "R 传输对象",
55+
content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE))
56+
)
57+
public R<String> ping() throws InterruptedException {
58+
int sleepTime = random.nextInt(200);
59+
doWork(sleepTime);
60+
doWorkHistogram.record(sleepTime, Attributes.of(ATTR_METHOD, "ping"));
61+
return R.success("pong");
62+
}
63+
64+
private void doWork(int sleepTime) throws InterruptedException {
65+
Span span = tracer.spanBuilder("doWork").startSpan();
66+
try (Scope ignored = span.makeCurrent()) {
67+
Thread.sleep(sleepTime);
68+
log.info("A sample log message!");
69+
} finally {
70+
span.end();
71+
}
72+
}
73+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
server:
2+
port: 8080
3+
4+
spring:
5+
application:
6+
name: arch-app
7+
8+
profiles:
9+
default: dev
10+
11+
---
12+
# 开发环境配置
13+
spring:
14+
config:
15+
activate:
16+
# 仅在 dev 环境激活本配置
17+
on-profile: dev
18+
# 仅启用本地配置
19+
import:
20+
- classpath:application_common_dev.yml
21+
- classpath:application_dev.yml
22+
23+
---
24+
# 测试环境
25+
spring:
26+
config:
27+
activate:
28+
on-profile: test
29+
import:
30+
- nacos:${spring.application.name:arch-app}?refresh=true&group=DEFAULT_GROUP
31+
32+
---
33+
# 生产环境
34+
spring:
35+
config:
36+
activate:
37+
on-profile: prod
38+
import:
39+
- nacos:${spring.application.name:arch-app}?refresh=true&group=DEFAULT_GROUP

0 commit comments

Comments
 (0)