ABP VNext + Tye:本地微服务编排与调试 🚀
📚 目录
- [ABP VNext + Tye:本地微服务编排与调试 🚀](#ABP VNext + Tye:本地微服务编排与调试 🚀)
-
- [TL;DR ✨](#TL;DR ✨)
- [一、环境与依赖 🛠️](#一、环境与依赖 🛠️)
- [二、核心配置详解 🚀](#二、核心配置详解 🚀)
-
- [1. 主配置 `tye.yaml`](#1. 主配置
tye.yaml
)
- [1. 主配置 `tye.yaml`](#1. 主配置
- [三、多环境文件 🌱🌳](#三、多环境文件 🌱🌳)
- [四、依赖容器定义 🐳](#四、依赖容器定义 🐳)
- [五、ABP VNext 集成 🔌](#五、ABP VNext 集成 🔌)
-
- [1. NuGet 包](#1. NuGet 包)
- [2. `appsettings.json`](#2.
appsettings.json
) - [3. 分布式缓存 & 锁 🔒](#3. 分布式缓存 & 锁 🔒)
- [4. RabbitMQ & CAP 🐰](#4. RabbitMQ & CAP 🐰)
- [5. 全链路追踪 🕵️](#5. 全链路追踪 🕵️)
- [六、一键启动 & 验证 ⚡](#六、一键启动 & 验证 ⚡)
- [七、流程图 📊](#七、流程图 📊)
-
- [1. 配置加载与启动](#1. 配置加载与启动)
- [2. 服务依赖关系](#2. 服务依赖关系)
- [八、断点调试 🎯](#八、断点调试 🎯)
-
- [VS Code Attach](#VS Code Attach)
- 调试序列图
- [九、进阶与安全 🛠️🔒](#九、进阶与安全 🛠️🔒)
TL;DR ✨
- 🚀 一键编排 :ABP VNext 微服务 + SQL Server、Redis、RabbitMQ、Jaeger,
tye run --env ...
即可全量本地启动 - 💪 高可用 & 性能 :双保险健康检查、资源
requests/limits
、多副本、死信队列与自动重试 - 🔍 全链路可观测:HTTP/gRPC/EF Core Trace → Jaeger UI → Tye Dashboard
一、环境与依赖 🛠️
-
必备工具
-
.NET 6+ SDK
-
ABP VNext 6.x(
Volo.Abp.*
系列) -
Microsoft Tye CLI
bashdotnet tool install -g Microsoft.Tye --version "0.12.0-alpha.*"
-
Docker Desktop(含 SQL Server、Redis、RabbitMQ、Jaeger 镜像)
-
-
容器镜像
- SQL Server 2022:
mcr.microsoft.com/mssql/server:2022-latest
- Redis 7:
redis:7
- RabbitMQ 3-management:
rabbitmq:3-management
- Jaeger All-in-One:
jaegertracing/all-in-one:1.49
- SQL Server 2022:
-
项目结构
abp-tye-demo/ ├─ services/ │ ├─ IdentityService/ │ ├─ OrderService/ │ └─ ProductService/ ├─ tye.yaml ├─ tye.development.yaml ├─ tye.production.yaml ├─ docker-compose.override.yml └─ README.md
二、核心配置详解 🚀
1. 主配置 tye.yaml
yaml
name: abp-tye-demo
secrets:
- name: Jwt__Key
services:
# ------ 外部依赖 ------
- name: sql
dockerCompose:
file: docker-compose.override.yml
- name: redis
dockerCompose:
file: docker-compose.override.yml
- name: rabbitmq
dockerCompose:
file: docker-compose.override.yml
- name: jaeger
dockerCompose:
file: docker-compose.override.yml
# ------ ABP 微服务 ------
- name: identity
project: services/IdentityService/IdentityService.csproj
bindings:
- port: 5001
env:
ConnectionStrings__Default: "Server=sql;User Id=sa;Password=Your_password123;"
Redis__Configuration: "redis:6379"
RabbitMQ__HostName: "rabbitmq"
RabbitMQ__User: "tye"
RabbitMQ__Pass: "tyePass123"
Jaeger__AgentHost: "jaeger"
Jaeger__AgentPort: "6831"
Jwt__Key: "Jwt__Key"
- name: order
project: services/OrderService/OrderService.csproj
bindings:
- port: 5002
env:
ConnectionStrings__Default: "Server=sql;User Id=sa;Password=Your_password123;"
Redis__Configuration: "redis:6379"
RabbitMQ__HostName: "rabbitmq"
RabbitMQ__User: "tye"
RabbitMQ__Pass: "tyePass123"
Jaeger__AgentHost: "jaeger"
Jaeger__AgentPort: "6831"
- name: product
project: services/ProductService/ProductService.csproj
bindings:
- port: 5003
env:
ConnectionStrings__Default: "Server=sql;User Id=sa;Password=Your_password123;"
Redis__Configuration: "redis:6379"
RabbitMQ__HostName: "rabbitmq"
RabbitMQ__User: "tye"
RabbitMQ__Pass: "tyePass123"
Jaeger__AgentHost: "jaeger"
Jaeger__AgentPort: "6831"
- 多环境自动合并 :
tye run --env development|production
会加载对应文件 - Secrets :通过
tye secret set Jwt__Key ...
注入 - RabbitMQ 用户 :
guest
仅限本地,容器间需自定义用户
三、多环境文件 🌱🌳
tye.development.yaml
yaml
services:
- name: identity
replicas: 1
- name: order
replicas: 1
- name: product
replicas: 1
tye.production.yaml
yaml
services:
- name: identity
replicas: 2
resources:
requests:
cpu: "0.25"
memory: "256Mi"
limits:
cpu: "0.5"
memory: "512Mi"
- name: order
replicas: 2
resources:
requests:
cpu: "0.25"
memory: "256Mi"
limits:
cpu: "0.5"
memory: "512Mi"
- name: product
replicas: 2
resources:
requests:
cpu: "0.25"
memory: "256Mi"
limits:
cpu: "0.5"
memory: "512Mi"
四、依赖容器定义 🐳
yaml
version: '3.4'
services:
sql:
image: mcr.microsoft.com/mssql/server:2022-latest
environment:
SA_PASSWORD: "Your_password123"
ACCEPT_EULA: "Y"
ports:
- "1433:1433"
volumes:
- ./mssql-data:/var/opt/mssql
healthcheck:
test: ["CMD", "sh", "-c", "if nc -z localhost 1433; then exit 0; else exit 1; fi"]
interval: 10s
retries: 5
redis:
image: redis:7
ports:
- "6379:6379"
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
retries: 5
rabbitmq:
image: rabbitmq:3-management
environment:
RABBITMQ_DEFAULT_USER: "tye"
RABBITMQ_DEFAULT_PASS: "tyePass123"
ports:
- "5672:5672" # AMQP
- "15672:15672" # Management UI
healthcheck:
test: ["CMD", "rabbitmq-diagnostics", "ping"]
interval: 10s
retries: 5
jaeger:
image: jaegertracing/all-in-one:1.49
ports:
- "16686:16686" # Jaeger UI
- "6831:6831/udp" # Trace 数据
- 数据持久化:SQL Server volume
- 网络说明 :Linux 可选
network: host
五、ABP VNext 集成 🔌
1. NuGet 包
xml
<PackageReference Include="Volo.Abp.AspNetCore" Version="6.*" />
<PackageReference Include="Volo.Abp.DistributedLocking.Redis" Version="6.*" />
<PackageReference Include="Volo.Abp.EventBus.CAP" Version="6.*" />
2. appsettings.json
jsonc
{
"ConnectionStrings": {
"Default": "Server=sql;User Id=sa;Password=Your_password123;"
},
"Redis": {
"Configuration": "redis:6379"
},
"RabbitMQ": {
"HostName": "rabbitmq",
"Port": 5672,
"User": "tye",
"Pass": "tyePass123"
},
"Jaeger": {
"AgentHost": "jaeger",
"AgentPort": 6831
},
"Jwt": {
"Key": ""
}
}
3. 分布式缓存 & 锁 🔒
csharp
builder.Services
.AddStackExchangeRedisCache(options =>
{
options.Configuration = builder.Configuration["Redis:Configuration"];
})
.AddAbpDistributedLock(sp =>
sp.AddRedisLock(builder.Configuration["Redis:Configuration"]));
4. RabbitMQ & CAP 🐰
csharp
builder.Services.AddCap(options =>
{
options.UseRabbitMQ(cfg =>
{
cfg.HostName = builder.Configuration["RabbitMQ:HostName"];
cfg.Port = int.Parse(builder.Configuration["RabbitMQ:Port"]);
cfg.UserName = builder.Configuration["RabbitMQ:User"];
cfg.Password = builder.Configuration["RabbitMQ:Pass"];
});
options.UseDashboard();
options.FailedRetryCount = 5;
});
// 事件订阅示例
public class OrderCreatedConsumer : ICapSubscribe
{
[CapSubscribe("order.created")]
public Task Handle(OrderCreatedEvent evt) => /*...*/;
}
5. 全链路追踪 🕵️
csharp
builder.Services.AddOpenTelemetryTracing(tp =>
{
tp.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddGrpcClientInstrumentation()
.AddEntityFrameworkCoreInstrumentation()
.AddJaegerExporter(opts =>
{
opts.AgentHost = builder.Configuration["Jaeger:AgentHost"];
opts.AgentPort = int.Parse(builder.Configuration["Jaeger:AgentPort"]);
});
});
六、一键启动 & 验证 ⚡
bash
# 注入 Secret
tye secret set Jwt__Key --value "YourSuperSecretKey"
# 启动服务
tye run --env production --watch
-
验证副本 & 资源 :
tye describe
-
访问监控
功能 地址 Tye Dashboard http://localhost:8000 RabbitMQ UI http://localhost:15672 Jaeger UI http://localhost:16686
七、流程图 📊
1. 配置加载与启动
合并配置 环境变量 自动加载 tye.production.yaml 合并到 tye.yaml tye run --env production Tye Runtime 启动 服务列表 sql, redis, rabbitmq, jaeger identity, order, product
2. 服务依赖关系
Services Containers Trace Trace Trace Metrics & Logs Metrics & Logs Metrics & Logs IdentityService
5001 OrderService
5002 ProductService
5003 SQL Server
1433 Redis
6379 RabbitMQ
5672 Jaeger
6831/UDP Tye Dashboard
八、断点调试 🎯
VS Code Attach
jsonc
{
"version": "0.2.0",
"configurations": [
{
"name": "Attach to Tye IdentityService",
"type": "coreclr",
"request": "attach",
"processName": "dotnet",
"justMyCode": false
}
]
}
调试序列图
开发者 Tye Runtime VS Code IdentityService tye run --watch Attach Debugger Attach to process Breakpoint Hit 开发者 Tye Runtime VS Code IdentityService
Tip :遇到 IIS Express 冲突,切换至 "Project" 启动或在
launchSettings.json
指定--urls http://*:5001
。
九、进阶与安全 🛠️🔒
-
自定义 Dockerfile
yaml- name: custom-service container: dockerFile: services/Custom/Dockerfile image: myorg/custom:latest
-
公网隧道
bashtye proxy identity --bind 5001
⚠️ 仅限测试,生产请结合 API Gateway/认证。
-
网络模式
- Linux 可选
network: host
- 跨宿主机访问时可自定义 Docker 网络
- Linux 可选