@arkxos/arkos-app-gateway-manage 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/README.md +36 -0
  2. package/ark_dist/ark-meta.json +75 -0
  3. package/ark_dist/ark_userChunk_1.js +5 -0
  4. package/ark_dist/ark_userChunk_2.js +49 -0
  5. package/ark_dist/css/views/views-CreateGateway.41b2bde6.css +297 -0
  6. package/ark_dist/favicon.ico +0 -0
  7. package/ark_dist/img/404.png +0 -0
  8. package/ark_dist/img/auth_banner.jpg +0 -0
  9. package/ark_dist/img/avatar.jpg +0 -0
  10. package/ark_dist/img/avatar2.gif +0 -0
  11. package/ark_dist/img/avatar3.gif +0 -0
  12. package/ark_dist/img/loginbg.svg +1 -0
  13. package/ark_dist/img/logo-r.png +0 -0
  14. package/ark_dist/img/logo.png +0 -0
  15. package/ark_dist/img/no-widgets.svg +57 -0
  16. package/ark_dist/img/tasks-example.png +0 -0
  17. package/ark_dist/img/ver.svg +236 -0
  18. package/ark_dist/index.html +132 -0
  19. package/ark_dist/js/app.e014b7a5.js +1 -0
  20. package/ark_dist/js/views/views-CreateGateway.7db295a9.js +3 -0
  21. package/ark_dist/js/views/views-CreateGateway.7db295a9.js.LICENSE.txt +1 -0
  22. package/ark_dist/js/views/views-CreateGateway.7db295a9.js.map +1 -0
  23. package/ark_proxy/entry.js +30 -0
  24. package/ark_proxy_es/entry.js +18 -0
  25. package/package.json +156 -0
  26. package/scripts/check.js +13 -0
  27. package/scripts/meta.js +21 -0
  28. package/scripts/prepublishOnly.js +28 -0
  29. package/src/api/apidoc_api.js +35 -0
  30. package/src/api/authority.js +161 -0
  31. package/src/api/balanced_api.js +101 -0
  32. package/src/api/client_api.js +68 -0
  33. package/src/api/count_api.js +62 -0
  34. package/src/api/gateway-manage/client_api.js +68 -0
  35. package/src/api/gateway-manage/open_client.js +188 -0
  36. package/src/api/gateway_api.js +81 -0
  37. package/src/api/global_function.js +278 -0
  38. package/src/api/global_variable.js +35 -0
  39. package/src/api/groovyscript_api.js +130 -0
  40. package/src/api/ip_api.js +47 -0
  41. package/src/api/monitor_api.js +24 -0
  42. package/src/api/regserver_api.js +224 -0
  43. package/src/api/request.js +107 -0
  44. package/src/assets/font_1930435_u2cpsigmd9d.js +38 -0
  45. package/src/assets/font_ma6wg7gw3td/demo.css +539 -0
  46. package/src/assets/font_ma6wg7gw3td/demo_index.html +674 -0
  47. package/src/assets/font_ma6wg7gw3td/iconfont.css +105 -0
  48. package/src/assets/font_ma6wg7gw3td/iconfont.eot +0 -0
  49. package/src/assets/font_ma6wg7gw3td/iconfont.js +1 -0
  50. package/src/assets/font_ma6wg7gw3td/iconfont.json +163 -0
  51. package/src/assets/font_ma6wg7gw3td/iconfont.svg +92 -0
  52. package/src/assets/font_ma6wg7gw3td/iconfont.ttf +0 -0
  53. package/src/assets/font_ma6wg7gw3td/iconfont.woff +0 -0
  54. package/src/assets/font_ma6wg7gw3td/iconfont.woff2 +0 -0
  55. package/src/assets/logo.png +0 -0
  56. package/src/assets/particles.json +110 -0
  57. package/src/auto-imports.d.ts +307 -0
  58. package/src/component/BoxCard.vue +156 -0
  59. package/src/component/ClientInfo.vue +82 -0
  60. package/src/component/GroovyScriptTable.vue +74 -0
  61. package/src/component/PanThumb/index.vue +149 -0
  62. package/src/component/RouteAccessChart.vue +85 -0
  63. package/src/component/RouteInfo.vue +146 -0
  64. package/src/component/RouteRequestCount.vue +126 -0
  65. package/src/component/TextHoverEffect/Mallki.vue +120 -0
  66. package/src/configs/subApp.ts +9 -0
  67. package/src/entrance/libProperties.ts +30 -0
  68. package/src/entrance/libTypes.ts +27 -0
  69. package/src/main.ts +13 -0
  70. package/src/plugins/index.ts +11 -0
  71. package/src/router/constantRoutes.js +155 -0
  72. package/src/router/loadComponent.js +29 -0
  73. package/src/views/AddClientGateway.vue +253 -0
  74. package/src/views/AddGatewayClient.vue +360 -0
  75. package/src/views/AddGroovyScript.vue +337 -0
  76. package/src/views/ApiCount.vue +291 -0
  77. package/src/views/ApiDoc.vue +293 -0
  78. package/src/views/ApiMonitor.vue +292 -0
  79. package/src/views/ClientList.vue +217 -0
  80. package/src/views/CreateBalanced.vue +341 -0
  81. package/src/views/CreateClient.vue +171 -0
  82. package/src/views/CreateGateway.vue +836 -0
  83. package/src/views/GatewayList.vue +322 -0
  84. package/src/views/GatewayTopology.vue +245 -0
  85. package/src/views/IpList.vue +218 -0
  86. package/src/views/LoadBalanced.vue +389 -0
  87. package/src/views/Main.vue +98 -0
@@ -0,0 +1,836 @@
1
+ <template>
2
+ <div class="greateGateway">
3
+ <el-row>
4
+ <el-col>
5
+ <el-card class="box-card">
6
+ <template #header>
7
+ <div class="clear-box">
8
+ <div lass="clear-l">
9
+ <span style="font-weight: 500;">网关路由》服务配置</span>
10
+ <el-popover trigger="click" placement="bottom" width="500">
11
+ <div style="font-size: 10pt;">
12
+ <span>配置说明:</span><br/>
13
+ <span>1.服务URL,支持http、https、server-id(lb://xxx)模式转发。</span><br/>
14
+ <span>2.断言Path,请根据实际API调用路径设置,不含服务host和port,可添加自定义前缀。</span><br/>
15
+ <span>3.过滤StripPrefix根据值,截取断言Path多节斜杠后内容,拼接到服务URL上。</span><br/>
16
+ <span>4.重定向RewritePath,会将原始请求Path指向新的Path路径,但网关路由地址不变,如:/foo/abc指向/abc。</span><br/>
17
+ <span>5.断言Header,会查找原始请求Header头部信息,获取匹配项。</span><br/>
18
+ <span>6.示例:</span><br/>
19
+ <span>&nbsp;&nbsp;a.服务URL示例:http://server:port、http://server.com、lb://xxx ,支持但不推荐:http://server:port/api.do。</span><br/>
20
+ <span>&nbsp;&nbsp;b.断言Path示例:/route/producer/** 或 /producer/api。</span><br/>
21
+ <span>&nbsp;&nbsp;c.断言Host示例:**.my.com 或 my.com 、127.0.0.1:8771。</span><br/>
22
+ <span>&nbsp;&nbsp;d.断言RemoteAddr示例:192.168.1.1 或 192.168.1.1/100。</span><br/>
23
+ <span>&nbsp;&nbsp;e.重定向RewritePath示例:/foo/(?&lt;segment&gt;.*),/$\{segment},需满足java正则表达示或参见官方。</span><br/>
24
+ <span>&nbsp;&nbsp;f.断言Header示例:Header=X-Request-Id, \d+,其中\d+表示正则匹配的任意值,需满足java正则表达示或参见官方。</span><br/>
25
+ <span>7.如配置多个断言项,则gateway网关采用断言组合匹配方式(and关系)转发到符合的路由服务中。</span>
26
+ </div>
27
+ <template #reference>
28
+ <el-button style="padding: 3px 0; " icon="el-icon-questionFilledFilled" type="text" title="说明"></el-button>
29
+ </template>
30
+ </el-popover>
31
+ </div>
32
+ <div class="clear-r">
33
+ <el-button icon="el-icon-delete" size="mini" type="warning" @click="resetForm"> 清 空 </el-button>
34
+ <el-button icon="el-icon-tickets" size="mini" type="success" @click="submit"> 发 布 </el-button>
35
+ </div>
36
+ </div>
37
+
38
+ </template>
39
+
40
+
41
+ <el-row>
42
+ <el-col :span="24">
43
+ <div style="float: left;">
44
+ <el-input placeholder="示例:project-method" v-model="form.id" style="width: 343px;" :disabled="idDisabled">
45
+ <template #prepend>RouteId</template>
46
+ </el-input>
47
+ </div>
48
+ <div style="float: left; margin-left: 10px;">
49
+ <el-input placeholder="示例:CRM" v-model="form.systemCode" style="width: 343px;">
50
+ <template #prepend>系统代号</template>
51
+ </el-input>
52
+ </div>
53
+ <div style="float: left; margin-left: 10px;">
54
+ <el-input placeholder="示例:CRM-用户信息获取网关" v-model="form.name" style="width: 343px;">
55
+ <template #prepend>名称</template>
56
+ </el-input>
57
+ </div>
58
+ <div style="float: left; margin-left: 10px;">
59
+ <el-popover placement="bottom" width="170" trigger="click">
60
+ <el-radio v-model="form.status" label="0">启用</el-radio>
61
+ <el-radio v-model="form.status" label="1">禁用</el-radio>
62
+ <template #reference>
63
+ <el-button>服务状态:{{form.status === '0'?'启用':'禁用'}}<el-icon><CaretBottom /></el-icon></el-button>
64
+ </template>
65
+ </el-popover>
66
+ </div>
67
+ <div style="float: left; margin-left: 10px;">
68
+ <el-popover placement="bottom" trigger="click" width="420">
69
+ <el-radio-group v-model="form.groupCode" size="mini" @change="handleSelectedGroup">
70
+ <el-radio-button v-for="item in groupOptions" :key="item.value" :label="item.value">{{item.label}}</el-radio-button>
71
+ </el-radio-group>
72
+ <template #reference>
73
+ <el-button>分组:{{groupName}}<el-icon><CaretBottom /></el-icon></el-button>
74
+ </template>
75
+ </el-popover>
76
+ </div>
77
+ </el-col>
78
+ </el-row>
79
+
80
+ <el-row style="margin-top: 20px;">
81
+ <el-col :span="24">
82
+ <div style="float: left;">
83
+ <el-input placeholder="请输入网关服务URL,示例:http://server:port、http://server.com、lb://xxx" v-model="form.uri" class="input-with-select" style="width: 696px;">
84
+ <template #prepend>
85
+ <el-select v-model="form.method" placeholder="请选择" style="width: 90px;">
86
+ <el-option v-for="item in methodOptions" :key="item.value" :label="item.label" :value="item.value"/>
87
+ </el-select>
88
+ </template>
89
+
90
+ </el-input>
91
+ </div>
92
+ <div style="float: left; margin-left: 10px;">
93
+ <el-popover placement="bottom" width="550" trigger="click">
94
+ <el-input placeholder="示例:Path=/route/producer/** 或 /producer/api" v-model="form.path" style="width: 500px;">
95
+ <template #prepend>Path=</template>
96
+ </el-input>
97
+ <template #reference>
98
+ <el-button>断言Path={{form.path}}<el-icon><CaretBottom /></el-icon></el-button>
99
+ </template>
100
+ </el-popover>
101
+ </div>
102
+ <div style="float: left; margin-left: 10px;">
103
+ <el-popover placement="bottom" width="550" trigger="click">
104
+ <el-input placeholder="示例:Header=X-Request-Id, \d+" v-model="form.header">
105
+ <template #prepend>Header=</template>
106
+ </el-input>
107
+ <template #reference>
108
+ <el-button>断言Header={{form.header}}<el-icon><CaretBottom /></el-icon></el-button>
109
+ </template>
110
+ </el-popover>
111
+ </div>
112
+ <div style="float: left; margin-left: 10px;">
113
+ <el-popover placement="bottom" width="300" trigger="click">
114
+ <el-input placeholder="示例:StripPrefix=1" v-model="form.stripPrefix">
115
+ <template #prepend>StripPrefix=</template>
116
+ </el-input>
117
+ <template #reference>
118
+ <el-button>过滤StripPrefix={{form.stripPrefix}}<el-icon><CaretBottom /></el-icon></el-button>
119
+ </template>
120
+ </el-popover>
121
+ </div>
122
+ </el-col>
123
+ </el-row>
124
+
125
+ <el-row style="margin-top: 20px;">
126
+ <el-col :span="24">
127
+ <div style="float: left;">
128
+ <el-popover placement="bottom" width="400" trigger="click">
129
+ <el-input placeholder="示例:Host=**.my.com,my.com" v-model="form.host" >
130
+ <template #prepend>Host=</template>
131
+ </el-input>
132
+ <template #reference>
133
+ <el-button>断言Host={{form.host}}<el-icon><CaretBottom /></el-icon></el-button>
134
+ </template>
135
+ </el-popover>
136
+ </div>
137
+ <div style="float: left; margin-left: 10px;">
138
+ <el-popover placement="bottom" width="400" trigger="click">
139
+ <el-input placeholder="示例:RemoteAddr=192.168.1.1/100" v-model="form.remoteAddr" >
140
+ <template #prepend>RemoteAddr=</template>
141
+ </el-input>
142
+ <template #reference>
143
+ <el-button>断言RemoteAddr={{form.remoteAddr}}<el-icon><CaretBottom /></el-icon></el-button>
144
+ </template>
145
+ </el-popover>
146
+ </div>
147
+ <div style="float: left; margin-left: 10px;">
148
+ <el-popover placement="bottom" width="450" trigger="click">
149
+ <el-input placeholder="示例:RequestParameter=version,v01" v-model="form.requestParameter" >
150
+ <template #prepend>RequestParameter=</template>
151
+ </el-input>
152
+ <template #reference>
153
+ <el-button>参数RequestParameter={{form.requestParameter}}<el-icon><CaretBottom /></el-icon></el-button>
154
+ </template>
155
+ </el-popover>
156
+ </div>
157
+ <div style="float: left; margin-left: 10px;">
158
+ <el-popover placement="bottom" width="500" trigger="click">
159
+ <el-input placeholder="示例:RewritePath=/foo/(?<segment>.*), /$\{segment}" v-model="form.rewritePath">
160
+ <template #prepend>RewritePath=</template>
161
+ </el-input>
162
+ <template #reference>
163
+ <el-button>重写路径RewritePath={{form.rewritePath}}<el-icon><CaretBottom /></el-icon></el-button>
164
+ </template>
165
+ </el-popover>
166
+ </div>
167
+ </el-col>
168
+ </el-row>
169
+
170
+ </el-card>
171
+ </el-col>
172
+ </el-row>
173
+
174
+ <el-row :gutter="20" style="margin-top: 20px;">
175
+ <el-col :span="6">
176
+ <el-card class="box-card">
177
+ <template #header>
178
+ <div class="clearfix">
179
+ <span>Sentinel熔断器</span>
180
+ <el-popover trigger="click" placement="bottom">
181
+ <div style="font-size: 10pt;">
182
+ <span>配置说明:</span><br/>
183
+ <span>1.对调用链路中不稳定的资源进行熔断降级也是保障高可用的重要措施之一。</span><br/>
184
+ <span>2.熔断策略:支持慢调用比例/异常比例/异常数策略(默认慢调用比例)。</span><br/>
185
+ <span>3.熔断时长:单位为秒(s)。</span><br/>
186
+ <span>4.触发数量:熔断触发的最小请求数,请求数小于该值时即使异常比率超出阈值也不会熔断(默认5)。</span><br/>
187
+ <span>5.统计时长:统计时长(单位为 ms),如 60*1000 代表分钟级(1000 ms)。</span><br/>
188
+ <span>6.慢请求比例:慢调用比例阈值,仅慢调用比例模式有效。</span><br/>
189
+ <span>7.参见官方文档:https://sentinelguard.io/zh-cn/docs/circuit-breaking.html</span><br/>
190
+ </div>
191
+ <template #reference>
192
+ <el-button style="float: right; padding: 3px 0; " icon="el-icon-questionFilled" type="text" title="说明">说明</el-button>
193
+ </template>
194
+ </el-popover>
195
+ </div>
196
+ </template>
197
+ <div>
198
+ <el-row :gutter="24">
199
+ <el-col :span="5">
200
+ <span class="text item" style="line-height: 38px;">熔断策略</span>
201
+ </el-col>
202
+ <el-col :span="19">
203
+ <el-radio-group v-model="form.degradeRule.grade" size="small">
204
+ <el-radio-button v-for="item in degradeRuleGradeOptions" :key="item.value" :label="item.value">{{item.label}}</el-radio-button>
205
+ </el-radio-group>
206
+ </el-col>
207
+ </el-row>
208
+ </div>
209
+ <el-collapse accordion style="margin-top: 10px;">
210
+ <el-collapse-item>
211
+ <template #title>
212
+ 熔断配置&nbsp;&nbsp;<i v-show="degradeRule.checked" class="header-icon el-icon-success" style="color: #34bfa3; font-size: 12pt;"></i>
213
+ </template>
214
+ <div><el-checkbox v-model="degradeRule.checked">启用</el-checkbox></div>
215
+ <div>基于网关服务访问状态与阈值判断服务的可用性,当服务在指定时间内达到指定错误的次数或比例后,暂停路由服务访问。</div>
216
+ <div style="margin-top: 10px;">
217
+ <el-input size="small" placeholder="不同策略阈值,如:慢请求>=3000,异常比例0.6/异常数60" v-model="form.degradeRule.count" title="不同策略阈值,如:慢请求>=3000,异常比例0.6/异常数60">
218
+ <template #prepend>计算阈值</template>
219
+ </el-input>
220
+ </div>
221
+ <div style="margin-top: 10px;">
222
+ <el-input size="small" placeholder="单位:毫秒,如:在3000ms内错误的次数或比例" v-model="form.degradeRule.statIntervalMs" title="单位:毫秒,如:在3000ms内错误的次数或比例">
223
+ <template #prepend>统计时长</template>
224
+ </el-input>
225
+ </div>
226
+ <div style="margin-top: 10px;">
227
+ <el-input size="small" placeholder="触发熔断后的降级时长,单位:秒" v-model="form.degradeRule.timeWindow" title="触发熔断后的降级时长,单位:秒">
228
+ <template #prepend>熔断时长</template>
229
+ </el-input>
230
+ </div>
231
+ <div style="margin-top: 10px;">
232
+ <el-input size="small" placeholder="触发熔断最少请求数量,低于该值不触发" v-model="form.degradeRule.minRequestAmount" title="触发熔断最少请求数量,低于该值不触发">
233
+ <template #prepend>触发数量</template>
234
+ </el-input>
235
+ </div>
236
+ <!-- <div style="margin-top: 10px;">
237
+ <el-input size="small" placeholder="触发fallbackcmd提示内容,如:system is error" v-model="form.fallbackMsg">
238
+ <template #prepend>提示内容</template>
239
+ </el-input>
240
+ </div> -->
241
+ <div style="margin-top: 10px;">
242
+ <el-input size="small" placeholder="慢请求比例策略必配" v-model="form.degradeRule.slowRatioThreshold" title="慢请求比例策略必配">
243
+ <template #prepend>慢请求比例</template>
244
+ </el-input>
245
+ </div>
246
+ </el-collapse-item>
247
+ </el-collapse>
248
+ </el-card>
249
+
250
+ <el-card class="box-card" style="margin-top: 20px;">
251
+ <template #header>
252
+ <div class="clearfix">
253
+ <span>监控器</span>
254
+ <el-popover trigger="click" placement="bottom">
255
+ <div style="font-size: 10pt;">
256
+ <span>配置说明:</span><br/>
257
+ <span>1.只向网关服务发起http请求,只有服务host和port,不含请求路径和参数。</span><br/>
258
+ <span>2.未超时则认为服务存活,不考虑服务有效性。</span><br/>
259
+ <span>3.心跳检测请求Header中带<span style="font-weight: bold;">Keepalive:flying-fish-gateway</span>,服务可做特殊性响应。</span><br/>
260
+ <span>4.心跳检测服务URL示例:http://server:port、http://server.com、lb://xxx 。</span><br/>
261
+ <span>5.网关服务无客户端请求后,每30秒触发一次心跳检测。</span><br/>
262
+ <span>6.告警重试设置为禁用后,心跳检测失败后,将不再继续检测,并且网关将会拒绝所有客户端请求,直到网关服务状态为:启用。</span>
263
+ </div>
264
+ <template #reference>
265
+ <el-button style="float: right; padding: 3px 0; " icon="el-icon-questionFilled" type="text" title="说明">说明</el-button>
266
+ </template>
267
+ </el-popover>
268
+ </div>
269
+ </template>
270
+
271
+ <el-collapse accordion>
272
+ <el-collapse-item>
273
+ <template #title>
274
+ 监控告警&nbsp;&nbsp;<i v-show="monitor.checked" class="header-icon el-icon-success" style="color: #34bfa3; font-size: 12pt;"></i>
275
+ </template>
276
+ <div><el-checkbox v-model="monitor.checked">启用</el-checkbox></div>
277
+ <div>基于网关服务心跳检测,当网关服务正常运行中,没有客户端请求后,开始每30秒一次心跳检测。</div>
278
+ <div style="margin-top: 10px;">
279
+ <el-popover placement="bottom" width="170" trigger="click">
280
+ <el-radio v-model="form.monitor.recover" label="0">启用</el-radio>
281
+ <el-radio v-model="form.monitor.recover" label="1">禁用</el-radio>
282
+ <template #reference>
283
+ <el-button>告警重试:{{form.monitor.recover === '0'?'启用':'禁用'}}<el-icon><CaretBottom /></el-icon></el-button>
284
+ </template>
285
+ </el-popover>
286
+ <el-popover placement="bottom" width="460" trigger="click">
287
+ <el-radio-group v-model="form.monitor.frequency" size="mini" @change="handleSelectedMonitorFrequency">
288
+ <el-radio-button v-for="item in monitorOptions" :key="item.value" :label="item.value">{{item.label}}</el-radio-button>
289
+ </el-radio-group>
290
+ <template #reference>
291
+ <el-button>告警通知频率:{{monitorFrequencyName}}<el-icon><CaretBottom /></el-icon></el-button>
292
+ </template>
293
+ </el-popover>
294
+ </div>
295
+ <div style="margin-top: 10px;">
296
+ <el-input size="small" placeholder="示例:user1@qq.com,user2@qq.com" v-model="form.monitor.emails" maxlength="200" show-word-limit>
297
+ <template #prepend>通知邮箱</template>
298
+ </el-input>
299
+ </div>
300
+ <div style="margin-top: 10px;">
301
+ <el-input size="small" placeholder="示例:XXX网关服务发生告警,请及时处理" v-model="form.monitor.topic" maxlength="200" show-word-limit>
302
+ <template #prepend>告警提示</template>
303
+ </el-input>
304
+ </div>
305
+ </el-collapse-item>
306
+ </el-collapse>
307
+ </el-card>
308
+
309
+ </el-col>
310
+
311
+ <el-col :span="6">
312
+ <el-card class="box-card">
313
+ <template #header>
314
+ <div class="clearfix">
315
+ <span>过滤器</span>
316
+ <el-popover trigger="click" placement="bottom">
317
+ <div style="font-size: 10pt;">
318
+ <span>配置说明:</span><br/>
319
+ <span>1.IP过滤需要配置本网关路由的注册客户端,非注册客户端IP不可访问。</span><br/>
320
+ <span>2.IP名单管理中的禁止通行的IP不可访问本网关路由。</span><br/>
321
+ <span>3.TOKEN过滤目前只对请求Header中带<span style="font-weight: bold;">TOKEN</span>做非空验证,暂无其它响应。</span><br/>
322
+ <span>4.ID过滤对请求Header中带<span style="font-weight: bold;">CLIENTID</span>做较验,非注册客户端ID不可访问。</span><br/>
323
+ </div>
324
+ <template #reference>
325
+ <el-button style="float: right; padding: 3px 0; " icon="el-icon-questionFilled" type="text" title="说明">说明</el-button>
326
+ </template>
327
+ </el-popover>
328
+ </div>
329
+ </template>
330
+
331
+ <el-collapse accordion>
332
+ <el-collapse-item>
333
+ <template #title>
334
+ IP过滤&nbsp;&nbsp;<i v-show="filter.ipChecked" class="header-icon el-icon-success" style="color: #34bfa3; font-size: 12pt;"></i>
335
+ </template>
336
+ <div><el-checkbox v-model="filter.ipChecked">启用</el-checkbox></div>
337
+ <div>基于IP进行拦截,只有客户端管理中添加对本网关服务连接权限的指定IP才能访问本路由地址。</div>
338
+ </el-collapse-item>
339
+ <el-collapse-item>
340
+ <template #title>
341
+ TOKEN过滤&nbsp;&nbsp;<i v-show="filter.tokenChecked" class="header-icon el-icon-success" style="color: #34bfa3; font-size: 12pt;"></i>
342
+ </template>
343
+ <div><el-checkbox v-model="filter.tokenChecked">启用</el-checkbox></div>
344
+ <div>基于TOKEN进行拦截,只有符合指定TOKEN才能访问本路由地址。</div>
345
+ </el-collapse-item>
346
+ <el-collapse-item>
347
+ <template #title>
348
+ ID过滤&nbsp;&nbsp;<i v-show="filter.idChecked" class="header-icon el-icon-success" style="color: #34bfa3; font-size: 12pt;"></i>
349
+ </template>
350
+ <div><el-checkbox v-model="filter.idChecked">启用</el-checkbox></div>
351
+ <div>基于ID进行拦截,只有客户端管理中添加对本网关服务连接权限的指定ID才能访问本路由地址。</div>
352
+ </el-collapse-item>
353
+ </el-collapse>
354
+ </el-card>
355
+
356
+ <el-card class="box-card" style="margin-top: 20px;">
357
+ <template #header>
358
+ <div class="clearfix">
359
+ <span>缓存策略</span>
360
+ <el-popover trigger="click" placement="bottom">
361
+ <div style="font-size: 10pt;">
362
+ <span>配置说明:</span><br/>
363
+ <span>1.基于Redis缓存路由服务端响应结果到网关,减少后端服务并发压力。</span><br/>
364
+ <span>2.适用于非高频更新数据请求(如:配置、字典等)。高频更新数据或实时数据请求不适用,会严重影响Gateway网关服务Redis资源平衡。</span><br/>
365
+ <span>3.基于请求参数和body值组合,计算其md5值为缓存key并缓存路由服务响应结果,之后每次相同传参请求不再路由到后端服务,直接取网关未过期缓存结果;</span><br/>
366
+ <span>4.同一个路由服务不能超过100个不同请求参数缓存结果,否则缓存失效将直接路由到后端服务。</span><br/>
367
+ <span>5.缓存过期后,则下一次请求重新获取并缓存路由服务响应结果;</span><br/>
368
+ <span>6.最大缓存时间为7天,缓存单位为秒(s),即:7 * 24 * 60 * 60 = 604800 。</span><br/>
369
+
370
+ </div>
371
+ <template #reference>
372
+ <el-button style="float: right; padding: 3px 0; " icon="el-icon-questionFilled" type="text" title="说明">说明</el-button>
373
+ </template>
374
+ </el-popover>
375
+ </div>
376
+ </template>
377
+
378
+ <el-collapse accordion>
379
+ <el-collapse-item>
380
+ <template #title>
381
+ 数据缓存&nbsp;&nbsp;<i v-show="cacheResult.checked" class="header-icon el-icon-success" style="color: #34bfa3; font-size: 12pt;"></i>
382
+ </template>
383
+ <div><el-checkbox v-model="cacheResult.checked">启用</el-checkbox></div>
384
+ <div>基于Redis缓存本网关路由后的响应结果,只对response状态为200的响应进行缓存。主要适用于非高频更新数据请求,如:系统配置,字典数据,常量数据等。最大缓存时间为7天=缓存单位为604800秒。</div>
385
+ <div style="margin-top: 10px;">
386
+ <el-input size="small" placeholder="响应结果缓存过期时长(秒)" v-model="form.cacheTtl">
387
+ <template #prepend>最大缓存时间(秒/s)</template>
388
+ </el-input>
389
+ </div>
390
+ </el-collapse-item>
391
+ </el-collapse>
392
+ </el-card>
393
+
394
+ </el-col>
395
+
396
+
397
+ <el-col :span="6">
398
+ <el-card class="box-card">
399
+ <template #header>
400
+ <div class="clearfix">
401
+ <span>Sentinel限流器</span>
402
+ <el-popover trigger="click" placement="bottom">
403
+ <div style="font-size: 10pt;">
404
+ <span>配置说明:</span><br/>
405
+ <span>1.线程数限流用于保护业务线程数不被耗尽。</span><br/>
406
+ <span>2.流量控制主要有两种统计类型,一种是统计线程数,另外一种则是统计 QPS。</span><br/>
407
+ <span>3.参见官方文档:https://sentinelguard.io/zh-cn/docs/flow-control.html</span><br/>
408
+ </div>
409
+ <template #reference>
410
+ <el-button style="float: right; padding: 3px 0; " icon="el-icon-questionFilled" type="text" title="说明">说明</el-button>
411
+ </template>
412
+ </el-popover>
413
+ </div>
414
+ </template>
415
+
416
+ <div>
417
+ <el-row :gutter="24">
418
+ <el-col :span="5">
419
+ <span class="text item" style="line-height: 38px;">每秒流量</span>
420
+ </el-col>
421
+ <el-col :span="19">
422
+ <el-input-number size="small" v-model="form.flowRule.count" :step="1" :min="0" :max="10000" style="width: 60%;"/>
423
+ </el-col>
424
+ </el-row>
425
+
426
+ <el-row :gutter="24">
427
+ <el-col :span="5">
428
+ <span class="text item" style="line-height: 38px;">限流模式</span>
429
+ </el-col>
430
+ <el-col :span="19">
431
+ <el-radio-group v-model="form.flowRule.grade" size="small">
432
+ <el-radio-button v-for="item in flowRuleGradeOptions" :key="item.value" :label="item.value">{{item.label}}</el-radio-button>
433
+ </el-radio-group>
434
+ </el-col>
435
+ </el-row>
436
+ </div>
437
+ <el-collapse accordion style="margin-top: 10px;">
438
+ <el-collapse-item>
439
+ <template #title>
440
+ 直接拒绝&nbsp;&nbsp;<i v-show="flowRule.defaultChecked" class="header-icon el-icon-success" style="color: #34bfa3; font-size: 12pt;"></i>
441
+ </template>
442
+ <div><el-checkbox v-model="flowRule.defaultChecked" @change="handleFlowRuleChecked('default')">启用</el-checkbox></div>
443
+ <div>该方式是默认的流量控制方式,当QPS超过任意规则的阈值后,新的请求就会被立即拒绝,拒绝方式为抛出FlowException。</div>
444
+ </el-collapse-item>
445
+ <el-collapse-item title="URI限流">
446
+ <template #title>
447
+ 冷启动&nbsp;&nbsp;<i v-show="flowRule.warmUpChecked" class="header-icon el-icon-success" style="color: #34bfa3; font-size: 12pt;"></i>
448
+ </template>
449
+ <div><el-checkbox v-model="flowRule.warmUpChecked" @change="handleFlowRuleChecked('warmUp')">启用</el-checkbox></div>
450
+ <div>该方式主要用于系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮的情况。</div>
451
+ </el-collapse-item>
452
+ <el-collapse-item>
453
+ <template #title>
454
+ 匀速器&nbsp;&nbsp;<i v-show="flowRule.rateLimiterChecked" class="header-icon el-icon-success" style="color: #34bfa3; font-size: 12pt;"></i>
455
+ </template>
456
+ <div><el-checkbox v-model="flowRule.rateLimiterChecked" @change="handleFlowRuleChecked('rateLimiter')">启用</el-checkbox></div>
457
+ <div>该方式严格控制了请求通过的间隔时间,也即是让请求以均匀的速度通过,对应的是漏桶算法。主要用于处理间隔性突发的流量,例如消息队列。</div>
458
+ <div style="margin-top: 10px;">
459
+ <el-input size="small" placeholder="多余的请求在队列中等待时间(ms)" v-model="form.flowRule.maxQueueingTimeMs">
460
+ <template #prepend>最大等待时间</template>
461
+ </el-input>
462
+ </div>
463
+ </el-collapse-item>
464
+ </el-collapse>
465
+ </el-card>
466
+
467
+ </el-col>
468
+
469
+ <el-col :span="6">
470
+ <el-card class="box-card">
471
+ <template #header>
472
+ <div class="clearfix">
473
+ <span>鉴权器</span>
474
+ <el-button style="float: right; padding: 3px 0; " icon="el-icon-questionFilled" type="text">说明</el-button>
475
+ </div>
476
+ </template>
477
+
478
+ <el-collapse accordion>
479
+ <el-collapse-item>
480
+ <template #title>
481
+ HEADER验证&nbsp;&nbsp;<i v-show="access.headerChecked" class="header-icon el-icon-success" style="color: #34bfa3; font-size: 12pt;"></i>
482
+ </template>
483
+ <div><el-checkbox v-model="access.headerChecked">启用</el-checkbox></div>
484
+ <div>获取客户端请求中的所带的HEADER头部信息,验证指定键值,不符合验证规则,则直接拒决请求。</div>
485
+ <div style="margin-top: 10px;">
486
+ <el-input size="small" placeholder="示例:Accept-Language: zh-CN,zh;q=0.9" v-model="form.accessHeader">
487
+ <template #prepend>HEADER</template>
488
+ </el-input>
489
+ </div>
490
+ </el-collapse-item>
491
+ <el-collapse-item>
492
+ <template #title>
493
+ IP验证&nbsp;&nbsp;<i v-show="access.ipChecked" class="header-icon el-icon-success" style="color: #34bfa3; font-size: 12pt;"></i>
494
+ </template>
495
+ <div><el-checkbox v-model="access.ipChecked">启用</el-checkbox></div>
496
+ <div>如果启用IP过滤,则会先执行IP过滤后,再执行本IP验证,不符合验证规则,则直接拒决请求。通常用于临时性IP过滤。</div>
497
+ <div style="margin-top: 10px;">
498
+ <el-input size="small" placeholder="示例:192.168.1.100,92.168.1.*" v-model="form.accessIp">
499
+ <template #prepend>IP</template>
500
+ </el-input>
501
+ </div>
502
+ </el-collapse-item>
503
+ <el-collapse-item>
504
+ <template #title>
505
+ 参数验证&nbsp;&nbsp;<i v-show="access.parameterChecked" class="header-icon el-icon-success" style="color: #34bfa3; font-size: 12pt;"></i>
506
+ </template>
507
+ <div><el-checkbox v-model="access.parameterChecked">启用</el-checkbox></div>
508
+ <div>获取URL请求串中的所带的参数,验证指定参数值,不符合验证规则,则直接拒决请求。</div>
509
+ <div style="margin-top: 10px;">
510
+ <el-input size="small" placeholder="示例:token=uuid" v-model="form.accessParameter">
511
+ <template #prepend>请求参数</template>
512
+ </el-input>
513
+ </div>
514
+ </el-collapse-item>
515
+ <el-collapse-item>
516
+ <template #title>
517
+ 时间验证&nbsp;&nbsp;<i v-show="access.timeChecked" class="header-icon el-icon-success" style="color: #34bfa3; font-size: 12pt;"></i>
518
+ </template>
519
+ <div><el-checkbox v-model="access.timeChecked">启用</el-checkbox></div>
520
+ <div>只允许指定时间段内进行访问,不符合验证规则,则直接拒决请求。</div>
521
+ <div style="margin-top: 10px;">
522
+ <el-input size="small" placeholder="示例:08:00:00,20:00:00" v-model="form.accessTime">
523
+ <template #prepend>时间</template>
524
+ </el-input>
525
+ </div>
526
+ </el-collapse-item>
527
+ <el-collapse-item title="Cookie验证">
528
+ <template #title>
529
+ Cookie验证&nbsp;&nbsp;<i v-show="access.cookieChecked" class="header-icon el-icon-success" style="color: #34bfa3; font-size: 12pt;"></i>
530
+ </template>
531
+ <div><el-checkbox v-model="access.cookieChecked">启用</el-checkbox></div>
532
+ <div>获取客户端请求所带的cookie信息,验证指定cookie参数值,不符合验证规则,则直接拒决请求。</div>
533
+ <div style="margin-top: 10px;">
534
+ <el-input size="small" placeholder="示例:name=value" v-model="form.accessCookie">
535
+ <template #prepend>Cookie</template>
536
+ </el-input>
537
+ </div>
538
+ </el-collapse-item>
539
+ </el-collapse>
540
+ </el-card>
541
+ </el-col>
542
+ </el-row>
543
+ </div>
544
+ </template>
545
+
546
+ <script setup>
547
+ import { CaretBottom } from '@element-plus/icons-vue'
548
+ </script>
549
+
550
+ <script>
551
+ // import gatewayJson from '../api/json/gateway.json'
552
+ import {addRoute,updateRoute} from '../api/gateway_api.js'
553
+
554
+ export default {
555
+ data() {
556
+ return {
557
+ model3:'',
558
+ form:{
559
+ id:'',
560
+ systemCode:'',
561
+ name:'',
562
+ stripPrefix:'',
563
+ status:'1',
564
+ uri:'',
565
+ method:'',
566
+ path:'',
567
+ host:'',
568
+ remoteAddr:'',
569
+ header:'',
570
+ rewritePath:'',
571
+ requestParameter:'',
572
+ accessHeader:'',
573
+ accessIp:'',
574
+ accessParameter:'',
575
+ accessTime:'',
576
+ accessCookie:'',
577
+ fallbackMsg:'',
578
+ fallbackTimeout:0,
579
+ replenishRate:20,
580
+ burstCapacity:100,
581
+ groupCode:'',
582
+ monitor:{
583
+ recover: '0',
584
+ frequency: '30m',
585
+ emails: '',
586
+ topic: ''
587
+ },
588
+ flowRule:{
589
+ grade: 1,
590
+ count: 10.0,
591
+ limitApp: 'default',
592
+ strategy: 0,
593
+ controlBehavior: 0,
594
+ maxQueueingTimeMs: 500
595
+ },
596
+ degradeRule:{
597
+ grade: 0,
598
+ count: 0.0,
599
+ timeWindow: 3000,
600
+ minRequestAmount: 5,
601
+ statIntervalMs: 1000,
602
+ slowRatioThreshold: 1
603
+ },
604
+ cacheTtl: 0
605
+ },
606
+ filter:{
607
+ ipChecked: false,
608
+ tokenChecked: false,
609
+ idChecked: false
610
+ },
611
+ access:{
612
+ headerChecked: false,
613
+ ipChecked: false,
614
+ parameterChecked: false,
615
+ timeChecked: false,
616
+ cookieChecked: false
617
+ },
618
+ monitor: {
619
+ checked: false
620
+ },
621
+ degradeRule:{
622
+ checked: false
623
+ },
624
+ flowRule:{
625
+ defaultChecked: false,
626
+ warmUpChecked: false,
627
+ rateLimiterChecked: false
628
+ },
629
+ handleType: 'add',
630
+ idDisabled: false,
631
+ methodOptions: [
632
+ {value: null, label: 'ALL'},
633
+ {value: 'POST',label: 'POST'},
634
+ {value: 'GET',label: 'GET'},
635
+ {value: 'PUT',label: 'PUT'},
636
+ {value: 'DELETE',label: 'DELETE'}
637
+ ],
638
+ monitorFrequencyName: '',
639
+ monitorOptions: [
640
+ {value: '30m',label: '30分钟一次'},
641
+ {value: '1h', label: '1小时一次'},
642
+ {value: '5h',label: '5小时一次'},
643
+ {value: '12h',label: '12小时一次'},
644
+ {value: '24h',label: '24小时一次'}
645
+ ],
646
+ degradeRuleGradeOptions: [
647
+ {value: 0,label: '慢调用比例'},
648
+ {value: 1, label: '异常比例'},
649
+ {value: 2,label: '异常数量'}
650
+ ],
651
+ flowRuleGradeOptions: [
652
+ {value: 0,label: '---- 线程数 ---'},
653
+ {value: 1, label: '---- QPS ---'}
654
+ ],
655
+ maxTime: 60,
656
+ groupName:'',
657
+ groupOptions: this.GLOBAL_VAR.groups,
658
+ cacheResult: {
659
+ checked: false
660
+ }
661
+ }
662
+ },
663
+ created: function() {
664
+ //在组件创建完毕后加载
665
+ let query = this.$route.query;
666
+ if (query){
667
+ this.handleType = query.handleType;
668
+ if (this.handleType === 'edit'){
669
+ let route = query.route;
670
+ console.log('route', route);
671
+ this.init(route);
672
+ }
673
+ }
674
+ },
675
+ mounted: function() {
676
+ },
677
+ beforeDestroy: function() {
678
+ },
679
+ methods:{
680
+ init(route) {
681
+ if (route && route.form){
682
+ let monitor = route.form.monitor ? route.form.monitor : this.form.monitor;
683
+ let flowRule = route.form.flowRule ? route.form.flowRule : this.form.flowRule;
684
+ let degradeRule = route.form.degradeRule ? route.form.degradeRule : this.form.degradeRule;
685
+ console.log('flowRule', flowRule)
686
+ this.form = route.form;
687
+ this.filter = route.filter;
688
+ this.access = route.access;
689
+ this.monitor = route.monitor;
690
+ this.flowRule = route.flowRule;
691
+ this.degradeRule = route.degradeRule;
692
+ this.form.monitor = monitor;
693
+ this.form.flowRule = flowRule;
694
+ this.form.degradeRule = degradeRule;
695
+ this.cacheResult = route.cacheResult;
696
+ console.log('this.form', this.form);
697
+ this.idDisabled = true;
698
+
699
+ // if (this.form.monitor == undefined){
700
+ // this.form.monitor = {
701
+ // checked: false,
702
+ // recover: '0',
703
+ // frequency: '30m',
704
+ // emails: '',
705
+ // topic: ''
706
+ // };
707
+ // }
708
+
709
+ this.handleSelectedGroup(this.form.groupCode);
710
+ this.handleSelectedMonitorFrequency(this.form.monitor? this.form.monitor.frequency: null);
711
+ }
712
+ },
713
+ goBack() {
714
+ this.$router.push({path:'/gatewayList',query:{}});
715
+ },
716
+ handleFlowRuleChecked(type){//Sentinel限流器,三选一
717
+ this.flowRule.defaultChecked = (this.flowRule.defaultChecked && type === 'default')?true:false;
718
+ this.flowRule.warmUpChecked = (this.flowRule.warmUpChecked && type === 'warmUp')?true:false;
719
+ this.flowRule.rateLimiterChecked = (this.flowRule.rateLimiterChecked && type === 'rateLimiter')?true:false;
720
+ this.form.flowRule.controlBehavior = type === 'warmUp' ? 1 : (type === 'rateLimiter' ? 2 : 0);
721
+ },
722
+ handleSelectedGroup(val){
723
+ let size = this.groupOptions.length;
724
+ for (var i=0;i <size; i++){
725
+ if (this.groupOptions[i].value === val){
726
+ this.groupName = this.groupOptions[i].label;
727
+ break;
728
+ }
729
+ }
730
+ },
731
+ handleSelectedMonitorFrequency(val){
732
+ if (val){
733
+ let size = this.monitorOptions.length;
734
+ for (var i=0;i <size; i++){
735
+ if (this.monitorOptions[i].value === val){
736
+ this.monitorFrequencyName = this.monitorOptions[i].label;
737
+ break;
738
+ }
739
+ }
740
+ }
741
+ },
742
+ submit(){
743
+ let data = {
744
+ form: this.form,
745
+ filter: this.filter,
746
+ // hystrix:this.hystrix,
747
+ // limiter:this.limiter,
748
+ access: this.access,
749
+ monitor: this.monitor,
750
+ flowRule: this.flowRule,
751
+ degradeRule: this.degradeRule,
752
+ cacheResult: this.cacheResult
753
+ };
754
+ let _this = this;
755
+ if (this.handleType === 'edit'){
756
+ updateRoute(data).then(function(result){
757
+ console.log(result);
758
+ _this.GLOBAL_FUN.successMsg();
759
+ });
760
+ } else {
761
+ addRoute(data).then(function(result){
762
+ _this.GLOBAL_FUN.successMsg();
763
+ });
764
+ }
765
+ },
766
+ resetForm() {
767
+ this.form = {
768
+ id: this.handleType === 'edit'?this.form.id:null,
769
+ systemCode:null,
770
+ name:null,
771
+ stripPrefix:'',
772
+ status:'1',
773
+ uri:null,
774
+ method:null,
775
+ path:null,
776
+ host:null,
777
+ remoteAddr:null,
778
+ header:null,
779
+ rewritePath:null,
780
+ requestParameter:null,
781
+ accessHeader:null,
782
+ accessIp:null,
783
+ accessParameter:null,
784
+ accessTime:'',
785
+ accessCookie:null,
786
+ fallbackMsg:null,
787
+ fallbackTimeout:0,
788
+ replenishRate:20,
789
+ burstCapacity:100,
790
+ cacheTtl: 0,
791
+ monitor: {},
792
+ degradeRule: {},
793
+ flowRule: {}
794
+ }
795
+ this.filter={};
796
+ this.access={};
797
+ this.monitor={};
798
+ this.degradeRule={};
799
+ this.flowRule={};
800
+ this.cacheResult={};
801
+ }
802
+ }
803
+ }
804
+ </script>
805
+
806
+ <style lang="scss" scoped>
807
+ .greateGateway {
808
+ padding: 20px;
809
+ }
810
+
811
+ .clearfix,
812
+ .clear-box {
813
+ width: 100%;
814
+ display: flex;
815
+ justify-content: space-between;
816
+ align-items: center;
817
+
818
+ .clear-l,
819
+ .clear-r {
820
+ display: flex;
821
+ align-items: center;
822
+ }
823
+ }
824
+
825
+ .text {
826
+ font-size: 14px;
827
+ white-space: nowrap;
828
+ }
829
+ .item {
830
+ margin-bottom: 18px;
831
+ }
832
+ div {
833
+ font-weight: 500;
834
+ text-align: left;
835
+ }
836
+ </style>