mirror of
https://gitee.com/durcframework/SOP.git
synced 2025-08-12 07:02:14 +08:00
限流管理
This commit is contained in:
@@ -47,11 +47,11 @@
|
|||||||
|
|
||||||
<div id="updateWin" class="x-win">
|
<div id="updateWin" class="x-win">
|
||||||
<form id="updateForm" class="layui-form" action="" lay-filter="updateWinFilter">
|
<form id="updateForm" class="layui-form" action="" lay-filter="updateWinFilter">
|
||||||
<input type="hidden" name="serviceId" />
|
<input type="hidden" name="serviceId">
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-form-label">id</label>
|
<label class="layui-form-label">id</label>
|
||||||
<div class="layui-input-block">
|
<div class="layui-input-block">
|
||||||
<input type="text" name="id" readonly="readonly" class="layui-input"/>
|
<input type="text" name="routeId" readonly="readonly" class="layui-input"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
@@ -64,19 +64,19 @@
|
|||||||
<div class="layui-form-item limit-type type1">
|
<div class="layui-form-item limit-type type1">
|
||||||
<label class="layui-form-label">每秒可处理请求数</label>
|
<label class="layui-form-label">每秒可处理请求数</label>
|
||||||
<div class="layui-input-block">
|
<div class="layui-input-block">
|
||||||
<input type="text" name="execCountPerSecond" lay-verify="required" class="layui-input"/>
|
<input type="text" name="execCountPerSecond" class="layui-input"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-form-item limit-type type1">
|
<div class="layui-form-item limit-type type1">
|
||||||
<label class="layui-form-label">错误码</label>
|
<label class="layui-form-label">错误码</label>
|
||||||
<div class="layui-input-block">
|
<div class="layui-input-block">
|
||||||
<input type="text" name="limitCode" lay-verify="required" class="layui-input"/>
|
<input type="text" name="limitCode" class="layui-input"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-form-item limit-type type1">
|
<div class="layui-form-item limit-type type1">
|
||||||
<label class="layui-form-label">错误信息</label>
|
<label class="layui-form-label">错误信息</label>
|
||||||
<div class="layui-input-block">
|
<div class="layui-input-block">
|
||||||
<input type="text" name="limitMsg" lay-verify="required" class="layui-input"/>
|
<input type="text" name="limitMsg" class="layui-input"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-form-item limit-type type2">
|
<div class="layui-form-item limit-type type2">
|
||||||
@@ -85,7 +85,13 @@
|
|||||||
<input type="text" name="tokenBucketCount" class="layui-input"/>
|
<input type="text" name="tokenBucketCount" class="layui-input"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">开启状态</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="radio" name="limitStatus" value="1" title="开启">
|
||||||
|
<input type="radio" name="limitStatus" value="0" title="关闭" checked="checked">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<div class="layui-input-block">
|
<div class="layui-input-block">
|
||||||
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="updateWinSubmitFilter">保存</button>
|
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="updateWinSubmitFilter">保存</button>
|
||||||
|
@@ -30,10 +30,14 @@ lib.importJs('../../assets/js/routerole.js')
|
|||||||
|
|
||||||
// 监听修改提交
|
// 监听修改提交
|
||||||
form.on('submit(updateWinSubmitFilter)', function(data) {
|
form.on('submit(updateWinSubmitFilter)', function(data) {
|
||||||
ApiUtil.post('route.update', data.field, function (resp) {
|
var formData = updateForm.getData();
|
||||||
|
if (!checkUpdateForm(formData)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ApiUtil.post('route.limit.update', formData, function (resp) {
|
||||||
layer.closeAll();
|
layer.closeAll();
|
||||||
limitTable.reload();
|
limitTable.reload();
|
||||||
})
|
});
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -46,6 +50,30 @@ lib.importJs('../../assets/js/routerole.js')
|
|||||||
loadLimitTable(this.innerHTML);
|
loadLimitTable(this.innerHTML);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function checkUpdateForm(formData) {
|
||||||
|
var type = formData.type;
|
||||||
|
if (type == 1) {
|
||||||
|
if (!/^[1-9]\d*$/.test(formData.execCountPerSecond)) {
|
||||||
|
layer.alert('每秒可处理请求数必须大于0')
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!formData.limitCode || formData.limitCode.length == 0) {
|
||||||
|
layer.alert('错误码不能为空')
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!formData.limitMsg || formData.limitMsg.length == 0) {
|
||||||
|
layer.alert('错误信息不能为空')
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (type == 2) {
|
||||||
|
if (!/^[1-9]\d*$/.test(formData.tokenBucketCount)) {
|
||||||
|
layer.alert('令牌桶容量必须大于0')
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function initServiceTab() {
|
function initServiceTab() {
|
||||||
ApiUtil.post('service.list', {}, function (resp) {
|
ApiUtil.post('service.list', {}, function (resp) {
|
||||||
@@ -98,7 +126,7 @@ lib.importJs('../../assets/js/routerole.js')
|
|||||||
, headers: {access_token: ApiUtil.getAccessToken()}
|
, headers: {access_token: ApiUtil.getAccessToken()}
|
||||||
, cellMinWidth: 80 //全局定义常规单元格的最小宽度,layui 2.2.1 新增
|
, cellMinWidth: 80 //全局定义常规单元格的最小宽度,layui 2.2.1 新增
|
||||||
, cols: [[
|
, cols: [[
|
||||||
{field: 'id', title: 'id(接口名+版本号)', width: 200}
|
{field: 'routeId', title: 'id(接口名+版本号)', width: 200}
|
||||||
, {
|
, {
|
||||||
field: 'type', title: '限流策略', width: 80, templet: function (row) {
|
field: 'type', title: '限流策略', width: 80, templet: function (row) {
|
||||||
return LIMIT_TYPE[row.type + ''];
|
return LIMIT_TYPE[row.type + ''];
|
||||||
@@ -106,14 +134,14 @@ lib.importJs('../../assets/js/routerole.js')
|
|||||||
}
|
}
|
||||||
, {
|
, {
|
||||||
field: 'info', title: '限流信息', width: 500, templet: function (row) {
|
field: 'info', title: '限流信息', width: 500, templet: function (row) {
|
||||||
if (row.limitStatus == 0) {
|
if (!row.hasRecord) {
|
||||||
return '--'
|
return '--'
|
||||||
}
|
}
|
||||||
var html = [];
|
var html = [];
|
||||||
if (row.type == 1) {
|
if (row.type == 1) {
|
||||||
html.push('每秒可处理请求数:' + row.execCountPerSecond);
|
html.push('每秒可处理请求数:' + row.execCountPerSecond);
|
||||||
html.push('错误码:' + row.limitCode);
|
html.push('subCode:' + row.limitCode);
|
||||||
html.push('错误信息:' + row.limitMsg);
|
html.push('subMsg:' + row.limitMsg);
|
||||||
} else if(row.type == 2) {
|
} else if(row.type == 2) {
|
||||||
html.push('令牌桶容量:' + row.tokenBucketCount);
|
html.push('令牌桶容量:' + row.tokenBucketCount);
|
||||||
}
|
}
|
||||||
@@ -149,7 +177,7 @@ lib.importJs('../../assets/js/routerole.js')
|
|||||||
layer.open({
|
layer.open({
|
||||||
type: 1
|
type: 1
|
||||||
,title: '修改限流' + smTitle
|
,title: '修改限流' + smTitle
|
||||||
,area: ['600px', '380px']
|
,area: ['600px', '460px']
|
||||||
,content: $('#updateWin') //这里content是一个DOM,注意:最好该元素要存放在body最外层,否则可能被其它的相对元素所影响
|
,content: $('#updateWin') //这里content是一个DOM,注意:最好该元素要存放在body最外层,否则可能被其它的相对元素所影响
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -18,6 +18,7 @@ import com.gitee.sop.adminserver.mapper.ConfigRouteLimitMapper;
|
|||||||
import com.gitee.sop.adminserver.service.RouteConfigService;
|
import com.gitee.sop.adminserver.service.RouteConfigService;
|
||||||
import com.gitee.sop.adminserver.service.RouteService;
|
import com.gitee.sop.adminserver.service.RouteService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang.BooleanUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
@@ -55,10 +56,12 @@ public class LimitApi {
|
|||||||
List<LimitVO> gatewayRouteDefinitions = routeDefinitionList
|
List<LimitVO> gatewayRouteDefinitions = routeDefinitionList
|
||||||
.stream()
|
.stream()
|
||||||
.map(gatewayRouteDefinition -> {
|
.map(gatewayRouteDefinition -> {
|
||||||
|
String routeId = gatewayRouteDefinition.getId();
|
||||||
LimitVO vo = new LimitVO();
|
LimitVO vo = new LimitVO();
|
||||||
CopyUtil.copyProperties(gatewayRouteDefinition, vo);
|
ConfigRouteLimit configRouteLimit = routeLimitMap.getOrDefault(routeId, getDefaultLimit());
|
||||||
ConfigRouteLimit configRouteLimit = routeLimitMap.getOrDefault(gatewayRouteDefinition.getId(), getDefaultLimit());
|
|
||||||
CopyUtil.copyPropertiesIgnoreNull(configRouteLimit, vo);
|
CopyUtil.copyPropertiesIgnoreNull(configRouteLimit, vo);
|
||||||
|
vo.setRouteId(routeId);
|
||||||
|
vo.setHasRecord(BooleanUtils.toInteger(configRouteLimit.getId() != null));
|
||||||
return vo;
|
return vo;
|
||||||
})
|
})
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
@@ -14,9 +14,13 @@ import javax.validation.constraints.NotNull;
|
|||||||
@Data
|
@Data
|
||||||
public class LimitParam {
|
public class LimitParam {
|
||||||
@ApiDocField(description = "routeId")
|
@ApiDocField(description = "routeId")
|
||||||
@NotBlank
|
@NotBlank(message = "routeId can not null")
|
||||||
private String routeId;
|
private String routeId;
|
||||||
|
|
||||||
|
@ApiDocField(description = "serviceId")
|
||||||
|
@NotBlank(message = "serviceId can not null")
|
||||||
|
private String serviceId;
|
||||||
|
|
||||||
/** 限流策略,1:漏桶策略,2:令牌桶策略, 数据库字段:type */
|
/** 限流策略,1:漏桶策略,2:令牌桶策略, 数据库字段:type */
|
||||||
@ApiDocField(description = "限流策略,1:漏桶策略,2:令牌桶策略")
|
@ApiDocField(description = "限流策略,1:漏桶策略,2:令牌桶策略")
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -40,6 +44,6 @@ public class LimitParam {
|
|||||||
|
|
||||||
/** 1:开启,0关闭, 数据库字段:limit_status */
|
/** 1:开启,0关闭, 数据库字段:limit_status */
|
||||||
@ApiDocField(description = "1:开启,0关闭")
|
@ApiDocField(description = "1:开启,0关闭")
|
||||||
@NotNull
|
@NotNull(message = "limitStatus不能为空")
|
||||||
private Byte limitStatus;
|
private Byte limitStatus;
|
||||||
}
|
}
|
||||||
|
@@ -10,8 +10,11 @@ import lombok.Data;
|
|||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
public class LimitVO {
|
public class LimitVO {
|
||||||
|
@ApiDocField(description = "是否存在记录")
|
||||||
|
private int hasRecord;
|
||||||
|
|
||||||
@ApiDocField(description = "路由id")
|
@ApiDocField(description = "路由id")
|
||||||
private String id;
|
private String routeId;
|
||||||
|
|
||||||
@ApiDocField(description = "serviceId")
|
@ApiDocField(description = "serviceId")
|
||||||
private String serviceId;
|
private String serviceId;
|
||||||
|
@@ -29,6 +29,9 @@ public class ConfigRouteLimit {
|
|||||||
/** 路由id, 数据库字段:route_id */
|
/** 路由id, 数据库字段:route_id */
|
||||||
private String routeId;
|
private String routeId;
|
||||||
|
|
||||||
|
/** serviceId, 数据库字段:service_id */
|
||||||
|
private String serviceId;
|
||||||
|
|
||||||
/** 限流策略,1:漏桶策略,2:令牌桶策略, 数据库字段:type */
|
/** 限流策略,1:漏桶策略,2:令牌桶策略, 数据库字段:type */
|
||||||
private Byte type;
|
private Byte type;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user