Skip to content

Commit 7bbc45b

Browse files
authored
Merge pull request #549 from tapdata/feat/TAP-11095-aggregate-node
Feat/tap 11095 aggregate node
2 parents d75a9cc + 9c02d90 commit 7bbc45b

18 files changed

Lines changed: 3066 additions & 624 deletions

File tree

Lines changed: 392 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,392 @@
1+
# 任务仪表盘 API
2+
3+
## 状态
4+
5+
- 接口地址:`GET /api/task/dashboard`
6+
- 控制器映射:[TaskController.java](/Users/shihuangzhu/IdeaProjects/tapdata_v3/new_tapdata/manager/tm/src/main/java/com/tapdata/tm/task/controller/TaskController.java#L1102)
7+
- 服务组装:[TaskDashboardService.java](/Users/shihuangzhu/IdeaProjects/tapdata_v3/new_tapdata/manager/tm/src/main/java/com/tapdata/tm/task/service/dashboard/TaskDashboardService.java)
8+
- 响应 DTO:[TaskDashboardVo.java](/Users/shihuangzhu/IdeaProjects/tapdata_v3/new_tapdata/manager/tm-api/src/main/java/com/tapdata/tm/task/vo/TaskDashboardVo.java)
9+
10+
## 实际请求结果
11+
12+
```bash
13+
curl "http://localhost:5173/api/task/dashboard?access_token=<ACCESS_TOKEN>"
14+
```
15+
16+
响应示例:
17+
18+
```json
19+
{
20+
"reqId": "e6af6b69-7739-45a7-8b40-536037a5d4ce",
21+
"ts": 1775644914982,
22+
"code": "ok",
23+
"data": {
24+
"query": {
25+
"type": "minute",
26+
"step": 5,
27+
"dashboardType": "all",
28+
"top": 5,
29+
"startAt": 1775644614,
30+
"endAt": 1775644914
31+
},
32+
"summary": {
33+
"activeTasks": {
34+
"total": 33,
35+
"running": 6,
36+
"error": 0,
37+
"maxLag": 3648,
38+
"minLag": 1939
39+
},
40+
"totalThroughput": {
41+
"current": 3044.2182436487296,
42+
"peak": 3204.425445089018,
43+
"dataRate": 2873831.6276055207,
44+
"changeRate": 0.0
45+
},
46+
"connectedDbs": {
47+
"total": 261,
48+
"items": [
49+
{
50+
"id": "6719c1b948930c6f211e8232",
51+
"name": "ttt_184",
52+
"tableCount": 5000
53+
},
54+
{
55+
"id": "67ada55bd938d0648b2b0844",
56+
"name": "sybase_190 - COM_DB",
57+
"tableCount": 492
58+
},
59+
{
60+
"id": "667e738da9a7f83f49923fde",
61+
"name": "qa_oracle_11g_single_1718086209358_4120",
62+
"tableCount": 477
63+
}
64+
]
65+
},
66+
"apiRequests": {
67+
"total": 0,
68+
"failed": 0,
69+
"errorRate": 0.0,
70+
"avgTime": 0.0
71+
}
72+
},
73+
"trends": {
74+
"throughput": {
75+
"ts": [1775644610, 1775644615, "...(每5秒一个数据点,共61个)...", 1775644910],
76+
"values": [0.0, 3069.82, "...(与ts对齐的吞吐量值)...", 3044.22]
77+
},
78+
"apiRequests": {
79+
"ts": [],
80+
"values": []
81+
}
82+
},
83+
"tops": {
84+
"topLaggingTasks": [
85+
{
86+
"taskId": "69d5fed7c8747bdd01439e93",
87+
"taskName": "任务 21 - Copy - Copy",
88+
"latency": 3648,
89+
"throughput": 1.2
90+
},
91+
{
92+
"taskId": "69d5fdf1c8747bdd014396e2",
93+
"taskName": "任务 21",
94+
"latency": 2725,
95+
"throughput": 1.0002000400080016
96+
},
97+
{
98+
"taskId": "69d5fe60c8747bdd01439aa6",
99+
"taskName": "任务 21 - Copy",
100+
"latency": 2297,
101+
"throughput": 1.0
102+
},
103+
{
104+
"taskId": "69d60c7567d5e06cc9e263f3",
105+
"taskName": "任务 21 - dummy - Copy - Copy",
106+
"latency": 1953,
107+
"throughput": 1140.2280456091219
108+
},
109+
{
110+
"taskId": "69d60a3867d5e06cc9e2527d",
111+
"taskName": "任务 21 - dummy - Copy",
112+
"latency": 1944,
113+
"throughput": 950.8
114+
}
115+
],
116+
"topThroughputTasks": [
117+
{
118+
"taskId": "69d60c7567d5e06cc9e263f3",
119+
"taskName": "任务 21 - dummy - Copy - Copy",
120+
"latency": 1953,
121+
"throughput": 1140.2280456091219
122+
},
123+
{
124+
"taskId": "69d60a3867d5e06cc9e2527d",
125+
"taskName": "任务 21 - dummy - Copy",
126+
"latency": 1944,
127+
"throughput": 950.8
128+
},
129+
{
130+
"taskId": "69d5ff83369dd7d1c8d45d6f",
131+
"taskName": "任务 21 - dummy",
132+
"latency": 1939,
133+
"throughput": 949.9899979996
134+
},
135+
{
136+
"taskId": "69d5fed7c8747bdd01439e93",
137+
"taskName": "任务 21 - Copy - Copy",
138+
"latency": 3648,
139+
"throughput": 1.2
140+
},
141+
{
142+
"taskId": "69d5fdf1c8747bdd014396e2",
143+
"taskName": "任务 21",
144+
"latency": 2725,
145+
"throughput": 1.0002000400080016
146+
}
147+
]
148+
}
149+
}
150+
}
151+
```
152+
153+
> **说明**`trends.throughput` 中的 `ts``values` 数组实际包含 61 个数据点(每 5 秒一个),此处为简洁起见进行了省略。
154+
155+
## 请求
156+
157+
### 请求方法
158+
159+
`GET`
160+
161+
### 请求路径
162+
163+
`/api/task/dashboard`
164+
165+
### 查询参数
166+
167+
| 参数名 | 类型 | 是否必填 | 允许值 | 默认值 | 描述 |
168+
| --- | --- | --- | --- | --- | --- |
169+
| `access_token` | `string` | 在 token-query 模式下必填 | 任意有效的用户访问令牌 || 通过查询字符串传递的认证令牌。 |
170+
| `type` | `string` || `minute``hours``days` | `minute` | 时间窗口类型。 |
171+
| `step` | `number` || `minute` 对应 `5``hours` 对应 `1``days` 对应 `1` | `5` | 时间窗口步长。无效组合将回退到默认窗口。 |
172+
| `dashboardType` | `string` || `all``summary``activeTasks``totalThroughput``connectedDbs``apiRequests``trends``tops` | `all` | 控制填充哪个仪表盘板块。 |
173+
| `top` | `number` || `5``10``20` | `5` | `tops` 排行榜大小。无效值将回退为 `5`|
174+
175+
### 有效时间窗口
176+
177+
| 请求参数 | 实际范围 |
178+
| --- | --- |
179+
| `type=minute&step=5` | 最近 5 分钟 |
180+
| `type=hours&step=1` | 最近 1 小时 |
181+
| `type=days&step=1` | 最近 24 小时 |
182+
| 任何无效组合 | 最近 5 分钟 |
183+
184+
### 请求示例
185+
186+
```bash
187+
curl "http://localhost:5173/api/task/dashboard?access_token=<ACCESS_TOKEN>"
188+
```
189+
190+
```bash
191+
curl "http://localhost:5173/api/task/dashboard?access_token=<ACCESS_TOKEN>&type=hours&step=1"
192+
```
193+
194+
```bash
195+
curl "http://localhost:5173/api/task/dashboard?access_token=<ACCESS_TOKEN>&dashboardType=apiRequests&type=minute&step=5"
196+
```
197+
198+
```bash
199+
curl "http://localhost:5173/api/task/dashboard?access_token=<ACCESS_TOKEN>&dashboardType=tops&top=10&type=days&step=1"
200+
```
201+
202+
Apifox 风格请求:
203+
204+
```bash
205+
curl --location --request GET 'http://localhost:5173/api/task/dashboard?access_token=<ACCESS_TOKEN>&dashboardType=tops&type=hours&step=1' \
206+
--header 'User-Agent: Apifox/1.0.0 (https://apifox.com)' \
207+
--header 'Accept: */*' \
208+
--header 'Host: localhost:5173' \
209+
--header 'Connection: keep-alive'
210+
```
211+
212+
## 响应包装器
213+
214+
该接口返回标准包装器 [ResponseMessage.java](/Users/shihuangzhu/IdeaProjects/tapdata_v3/new_tapdata/manager/tm-api/src/main/java/com/tapdata/tm/base/dto/ResponseMessage.java)
215+
216+
```json
217+
{
218+
"reqId": "string",
219+
"ts": 0,
220+
"code": "ok",
221+
"message": null,
222+
"stack": null,
223+
"data": {}
224+
}
225+
```
226+
227+
`data``TaskDashboardVo`
228+
229+
## 响应结构
230+
231+
```json
232+
{
233+
"query": {
234+
"type": "minute",
235+
"step": 5,
236+
"dashboardType": "all",
237+
"top": 5,
238+
"startAt": 0,
239+
"endAt": 0
240+
},
241+
"summary": {
242+
"activeTasks": {
243+
"total": 0,
244+
"running": 0,
245+
"error": 0,
246+
"maxLag": 0,
247+
"minLag": 0
248+
},
249+
"totalThroughput": {
250+
"current": 0.0,
251+
"peak": 0.0,
252+
"dataRate": 0.0,
253+
"changeRate": 0.0
254+
},
255+
"connectedDbs": {
256+
"total": 0,
257+
"items": [
258+
{
259+
"id": "string",
260+
"name": "string",
261+
"tableCount": 0
262+
}
263+
]
264+
},
265+
"apiRequests": {
266+
"total": 0,
267+
"failed": 0,
268+
"errorRate": 0.0,
269+
"avgTime": 0.0
270+
}
271+
},
272+
"trends": {
273+
"throughput": {
274+
"ts": [0],
275+
"values": [0.0]
276+
},
277+
"apiRequests": {
278+
"ts": [0],
279+
"values": [0.0]
280+
}
281+
},
282+
"tops": {
283+
"topLaggingTasks": [
284+
{
285+
"taskId": "string",
286+
"taskName": "string",
287+
"latency": 0,
288+
"throughput": 0.0
289+
}
290+
],
291+
"topThroughputTasks": [
292+
{
293+
"taskId": "string",
294+
"taskName": "string",
295+
"latency": 0,
296+
"throughput": 0.0
297+
}
298+
]
299+
}
300+
}
301+
```
302+
303+
## 字段语义
304+
305+
### query
306+
307+
| 字段 | 类型 | 描述 |
308+
| --- | --- | --- |
309+
| `type` | `string` | 后端实际使用的标准化时间类型。 |
310+
| `step` | `number` | 后端实际使用的标准化步长。 |
311+
| `dashboardType` | `string` | 标准化的仪表盘板块选择器。 |
312+
| `top` | `number` | 标准化的排行榜大小。 |
313+
| `startAt` | `number` | 窗口起始时间,Unix 秒级时间戳。 |
314+
| `endAt` | `number` | 窗口结束时间,Unix 秒级时间戳。 |
315+
316+
### summary.activeTasks
317+
318+
| 字段 | 类型 | 描述 |
319+
| --- | --- | --- |
320+
| `total` | `number` | 可见的迁移/同步任务总数。 |
321+
| `running` | `number` | 运行中的任务数。 |
322+
| `error` | `number` | 处于 `error``schedule_failed` 状态的任务数。 |
323+
| `maxLag` | `number` | 最大任务延迟(毫秒)。 |
324+
| `minLag` | `number` | 最小任务延迟(毫秒)。 |
325+
326+
### summary.totalThroughput
327+
328+
| 字段 | 类型 | 描述 |
329+
| --- | --- | --- |
330+
| `current` | `number` | 当前窗口内最新的吞吐量数据点。 |
331+
| `peak` | `number` | 当前窗口内的峰值吞吐量。 |
332+
| `dataRate` | `number` | 最新的输出数据量吞吐量数据点。 |
333+
| `changeRate` | `number` | 从第一个数据点到最后一个数据点的变化百分比。 |
334+
335+
### summary.connectedDbs
336+
337+
| 字段 | 类型 | 描述 |
338+
| --- | --- | --- |
339+
| `total` | `number` | 可见的数据源连接总数。 |
340+
| `items` | `array` |`tableCount 降序, name 升序` 排列的前 3 个连接。 |
341+
342+
### summary.apiRequests
343+
344+
| 字段 | 类型 | 描述 |
345+
| --- | --- | --- |
346+
| `total` | `number` | 所选窗口内的 API 请求总数。 |
347+
| `failed` | `number` | 失败的 API 请求数。 |
348+
| `errorRate` | `number` | API 监控服务返回的错误率百分比/值。 |
349+
| `avgTime` | `number` | 平均响应时间。 |
350+
351+
### trends
352+
353+
| 字段 | 类型 | 描述 |
354+
| --- | --- | --- |
355+
| `throughput.ts` | `array<number>` | Unix 秒级时间戳数组。 |
356+
| `throughput.values` | `array<number>` |`ts` 对齐的吞吐量值。 |
357+
| `apiRequests.ts` | `array<number>` | Unix 秒级时间戳数组。 |
358+
| `apiRequests.values` | `array<number>` |`ts` 对齐的请求速率值。 |
359+
360+
### tops
361+
362+
| 字段 | 类型 | 描述 |
363+
| --- | --- | --- |
364+
| `topLaggingTasks` | `array` |`latency 降序`,其次 `throughput 降序` 排列。 |
365+
| `topThroughputTasks` | `array` |`throughput 降序`,其次 `latency 降序` 排列。 |
366+
367+
## dashboardType 行为
368+
369+
| `dashboardType` | 填充的板块 |
370+
| --- | --- |
371+
| `all` | `summary``trends``tops` |
372+
| `summary` |`summary` |
373+
| `activeTasks` |`summary.activeTasks` |
374+
| `totalThroughput` |`summary.totalThroughput` |
375+
| `connectedDbs` |`summary.connectedDbs` |
376+
| `apiRequests` | `summary.apiRequests``trends.apiRequests` |
377+
| `trends` | `trends.throughput``trends.apiRequests` |
378+
| `tops` |`tops` |
379+
380+
未请求的板块会以空值或零值返回,因为响应 DTO 在选择性填充之前已完成全部初始化。
381+
382+
## 注意事项
383+
384+
- `access_token` 需使用真实的用户令牌。调用前请将 `<ACCESS_TOKEN>` 替换为实际值。
385+
- `connectedDbs.items` 有意限制为最多 3 条记录。
386+
- `top` 仅影响 `tops` 下的排行榜数组。
387+
- 该接口为用户级作用域,因为控制器/服务流程中使用了当前登录用户。
388+
- 如需获取实际响应示例,请先启动本地 Web/后端服务,然后重新执行:
389+
390+
```bash
391+
curl -i http://localhost:3000/api/task/dashboard
392+
```

0 commit comments

Comments
 (0)