diff --git a/sentinel-dashboard/src/main/webapp/resources/app/scripts/app.js b/sentinel-dashboard/src/main/webapp/resources/app/scripts/app.js index 430079fb..c4cdcb65 100755 --- a/sentinel-dashboard/src/main/webapp/resources/app/scripts/app.js +++ b/sentinel-dashboard/src/main/webapp/resources/app/scripts/app.js @@ -66,22 +66,38 @@ angular } }) - .state('dashboard.flow', { - templateUrl: 'app/views/flow.html', - url: '/flow/:app', - controller: 'FlowCtl', + .state('dashboard.flowV1', { + templateUrl: 'app/views/flow_old.html', + url: '/v1/flow/:app', + controller: 'FlowControllerV1', resolve: { loadMyFiles: ['$ocLazyLoad', function ($ocLazyLoad) { return $ocLazyLoad.load({ name: 'sentinelDashboardApp', files: [ - 'app/scripts/controllers/flow.js', + 'app/scripts/controllers/flow_old.js', ] }); }] } }) + .state('dashboard.flow', { + templateUrl: 'app/views/flow.html', + url: '/flow/:app', + controller: 'FlowController', + resolve: { + loadMyFiles: ['$ocLazyLoad', function ($ocLazyLoad) { + return $ocLazyLoad.load({ + name: 'sentinelDashboardApp', + files: [ + 'app/scripts/controllers/flow.js', + ] + }); + }] + } + }) + .state('dashboard.paramFlow', { templateUrl: 'app/views/param_flow.html', url: '/paramFlow/:app', @@ -98,6 +114,22 @@ angular } }) + .state('dashboard.clusterAll', { + templateUrl: 'app/views/cluster.html', + url: '/cluster/:app', + controller: 'SentinelClusterController', + resolve: { + loadMyFiles: ['$ocLazyLoad', function ($ocLazyLoad) { + return $ocLazyLoad.load({ + name: 'sentinelDashboardApp', + files: [ + 'app/scripts/controllers/cluster.js', + ] + }); + }] + } + }) + .state('dashboard.authority', { templateUrl: 'app/views/authority.html', url: '/authority/:app', diff --git a/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/cluster.js b/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/cluster.js new file mode 100644 index 00000000..2e6505c6 --- /dev/null +++ b/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/cluster.js @@ -0,0 +1,237 @@ +var app = angular.module('sentinelDashboardApp'); + +app.controller('SentinelClusterController', ['$scope', '$stateParams', 'ngDialog', + 'MachineService', 'ClusterStateService', + function ($scope, $stateParams, ngDialog, MachineService, ClusterStateService) { + $scope.app = $stateParams.app; + const UNSUPPORTED_CODE = 4041; + + const CLUSTER_MODE_CLIENT = 0; + const CLUSTER_MODE_SERVER = 1; + + $scope.macsInputConfig = { + searchField: ['text', 'value'], + persist: true, + create: false, + maxItems: 1, + render: { + item: function (data, escape) { + return '
' + escape(data.text) + '
'; + } + }, + onChange: function (value, oldValue) { + $scope.macInputModel = value; + } + }; + + function convertSetToString(set) { + if (set === undefined) { + return ''; + } + let s = ''; + for (let i = 0; i < set.length; i++) { + s = s + set[i]; + if (i < set.length - 1) { + s = s + ','; + } + } + return s; + } + + function convertStrToNamespaceSet(str) { + if (str === undefined || str == '') { + return []; + } + let arr = []; + let spliced = str.split(','); + spliced.forEach((v) => { + arr.push(v.trim()); + }); + return arr; + } + + function fetchMachineClusterState() { + if (!$scope.macInputModel) { + return; + } + let mac = $scope.macInputModel.split(':'); + ClusterStateService.fetchClusterUniversalState($scope.app, mac[0], mac[1]).success(function (data) { + if (data.code == 0 && data.data) { + $scope.loadError = undefined; + $scope.stateVO = data.data; + $scope.stateVO.currentMode = $scope.stateVO.stateInfo.mode; + if ($scope.stateVO.server && $scope.stateVO.server.namespaceSet) { + $scope.stateVO.server.namespaceSetStr = convertSetToString($scope.stateVO.server.namespaceSet); + } + } else { + $scope.stateVO = {}; + if (data.code === UNSUPPORTED_CODE) { + $scope.loadError = {message: '机器 ' + mac[0] + ':' + mac[1] + ' 的 Sentinel 客户端版本不支持集群限流,请升级至 1.4.0 以上版本并引入相关依赖。'} + } else { + $scope.loadError = {message: data.msg}; + } + } + }).error((data, header, config, status) => { + $scope.loadError = {message: '未知错误'}; + }); + } + + fetchMachineClusterState(); + + function checkValidClientConfig(stateVO) { + if (!stateVO.client || !stateVO.client.clientConfig) { + alert('不合法的配置'); + return false; + } + let config = stateVO.client.clientConfig; + if (!config.serverHost || config.serverHost.trim() == '') { + alert('请输入有效的 Token Server IP'); + return false; + } + if (config.serverPort === undefined || config.serverPort <= 0 || config.serverPort > 65535) { + alert('请输入有效的 Token Server 端口'); + return false; + } + if (config.requestTimeout === undefined || config.requestTimeout <= 0) { + alert('请输入有效的请求超时时长'); + return false; + } + return true; + } + + function sendClusterClientRequest(stateVO) { + if (!checkValidClientConfig(stateVO)) { + return; + } + if (!$scope.macInputModel) { + return; + } + let mac = $scope.macInputModel.split(':'); + let request = { + app: $scope.app, + ip: mac[0], + port: mac[1], + }; + request.mode = CLUSTER_MODE_CLIENT; + request.clientConfig = stateVO.client.clientConfig; + ClusterStateService.modifyClusterConfig(request).success(function (data) { + if (data.code == 0 && data.data) { + alert('修改集群限流客户端配置成功'); + window.location.reload(); + } else { + if (data.code === UNSUPPORTED_CODE) { + alert('机器 ' + mac[0] + ':' + mac[1] + ' 的 Sentinel 客户端版本不支持集群限流客户端,请升级至 1.4.0 以上版本并引入相关依赖。'); + } else { + alert('修改失败:' + data.msg); + } + } + }).error((data, header, config, status) => { + alert('未知错误'); + }); + } + + function checkValidServerConfig(stateVO) { + if (!stateVO.server || !stateVO.server.transport) { + alert('不合法的配置'); + return false; + } + if (stateVO.server.namespaceSetStr === undefined || stateVO.server.namespaceSetStr == '') { + alert('请输入有效的命名空间集合(多个 namespace 以 , 分隔)'); + return false; + } + let transportConfig = stateVO.server.transport; + if (transportConfig.port === undefined || transportConfig.port <= 0 || transportConfig.port > 65535) { + alert('请输入有效的 Token Server 端口'); + return false; + } + // if (transportConfig.idleSeconds === undefined || transportConfig.idleSeconds <= 0) { + // alert('请输入有效的连接清理时长 (idleSeconds)'); + // return false; + // } + return true; + } + + function sendClusterServerRequest(stateVO) { + if (!checkValidServerConfig(stateVO)) { + return; + } + if (!$scope.macInputModel) { + return; + } + let mac = $scope.macInputModel.split(':'); + let request = { + app: $scope.app, + ip: mac[0], + port: mac[1], + }; + request.mode = CLUSTER_MODE_SERVER; + request.flowConfig = stateVO.server.flow; + request.transportConfig = stateVO.server.transport; + request.namespaceSet = convertStrToNamespaceSet(stateVO.server.namespaceSetStr); + ClusterStateService.modifyClusterConfig(request).success(function (data) { + if (data.code == 0 && data.data) { + alert('修改集群限流服务端配置成功'); + window.location.reload(); + } else { + if (data.code === UNSUPPORTED_CODE) { + alert('机器 ' + mac[0] + ':' + mac[1] + ' 的 Sentinel 客户端版本不支持集群限流服务端,请升级至 1.4.0 以上版本并引入相关依赖。'); + } else { + alert('修改失败:' + data.msg); + } + } + }).error((data, header, config, status) => { + alert('未知错误'); + }); + } + + + $scope.saveConfig = () => { + let ok = confirm('是否确定修改集群限流配置?'); + if (!ok) { + return; + } + let mode = $scope.stateVO.stateInfo.mode; + if (mode != 1 && mode != 0) { + alert('未知的集群限流模式'); + return; + } + if (mode == 0) { + sendClusterClientRequest($scope.stateVO); + } else { + sendClusterServerRequest($scope.stateVO); + } + }; + + function queryAppMachines() { + MachineService.getAppMachines($scope.app).success( + function (data) { + if (data.code == 0) { + // $scope.machines = data.data; + if (data.data) { + $scope.machines = []; + $scope.macsInputOptions = []; + data.data.forEach(function (item) { + if (item.health) { + $scope.macsInputOptions.push({ + text: item.ip + ':' + item.port, + value: item.ip + ':' + item.port + }); + } + }); + } + if ($scope.macsInputOptions.length > 0) { + $scope.macInputModel = $scope.macsInputOptions[0].value; + } + } else { + $scope.macsInputOptions = []; + } + } + ); + }; + $scope.$watch('macInputModel', function () { + if ($scope.macInputModel) { + fetchMachineClusterState(); + } + }); + queryAppMachines(); + }]); diff --git a/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/flow.js b/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/flow.js index 1c8a2fea..fb49cfbe 100755 --- a/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/flow.js +++ b/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/flow.js @@ -1,6 +1,6 @@ var app = angular.module('sentinelDashboardApp'); -app.controller('FlowCtl', ['$scope', '$stateParams', 'FlowService', 'ngDialog', +app.controller('FlowController', ['$scope', '$stateParams', 'FlowServiceV2', 'ngDialog', 'MachineService', function ($scope, $stateParams, FlowService, ngDialog, MachineService) { @@ -72,7 +72,11 @@ app.controller('FlowCtl', ['$scope', '$stateParams', 'FlowService', 'ngDialog', app: $scope.app, ip: mac[0], port: mac[1], - limitApp: 'default' + limitApp: 'default', + clusterMode: false, + clusterConfig: { + thresholdType: 0 + } }; $scope.flowRuleDialog = { title: '新增流控规则', diff --git a/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/flow_old.js b/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/flow_old.js new file mode 100755 index 00000000..658c9d0c --- /dev/null +++ b/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/flow_old.js @@ -0,0 +1,203 @@ +var app = angular.module('sentinelDashboardApp'); + +app.controller('FlowControllerV1', ['$scope', '$stateParams', 'FlowServiceV1', 'ngDialog', + 'MachineService', + function ($scope, $stateParams, FlowService, ngDialog, + MachineService) { + $scope.app = $stateParams.app; + + $scope.rulesPageConfig = { + pageSize: 10, + currentPageIndex: 1, + totalPage: 1, + totalCount: 0, + }; + $scope.macsInputConfig = { + searchField: ['text', 'value'], + persist: true, + create: false, + maxItems: 1, + render: { + item: function (data, escape) { + return '
' + escape(data.text) + '
'; + } + }, + onChange: function (value, oldValue) { + $scope.macInputModel = value; + } + }; + + getMachineRules(); + function getMachineRules() { + if (!$scope.macInputModel) { + return; + } + var mac = $scope.macInputModel.split(':'); + FlowService.queryMachineRules($scope.app, mac[0], mac[1]).success( + function (data) { + if (data.code == 0 && data.data) { + $scope.rules = data.data; + $scope.rulesPageConfig.totalCount = $scope.rules.length; + } else { + $scope.rules = []; + $scope.rulesPageConfig.totalCount = 0; + } + }); + }; + $scope.getMachineRules = getMachineRules; + + var flowRuleDialog; + $scope.editRule = function (rule) { + $scope.currentRule = rule; + $scope.flowRuleDialog = { + title: '编辑流控规则', + type: 'edit', + confirmBtnText: '保存', + showAdvanceButton: rule.controlBehavior == 0 && rule.strategy == 0 + }; + flowRuleDialog = ngDialog.open({ + template: '/app/views/dialog/flow-rule-dialog.html', + width: 680, + overlay: true, + scope: $scope + }); + }; + + $scope.addNewRule = function () { + var mac = $scope.macInputModel.split(':'); + $scope.currentRule = { + grade: 1, + strategy: 0, + controlBehavior: 0, + app: $scope.app, + ip: mac[0], + port: mac[1], + limitApp: 'default' + }; + $scope.flowRuleDialog = { + title: '新增流控规则', + type: 'add', + confirmBtnText: '新增', + showAdvanceButton: true, + }; + flowRuleDialog = ngDialog.open({ + template: '/app/views/dialog/flow-rule-dialog.html', + width: 680, + overlay: true, + scope: $scope + }); + }; + + $scope.saveRule = function () { + if (!FlowService.checkRuleValid($scope.currentRule)) { + return; + } + if ($scope.flowRuleDialog.type === 'add') { + addNewRule($scope.currentRule); + } else if ($scope.flowRuleDialog.type === 'edit') { + saveRule($scope.currentRule, true); + } + }; + + var confirmDialog; + $scope.deleteRule = function (rule) { + $scope.currentRule = rule; + $scope.confirmDialog = { + title: '删除流控规则', + type: 'delete_rule', + attentionTitle: '请确认是否删除如下流控规则', + attention: '资源名: ' + rule.resource + ', 流控应用: ' + rule.limitApp + + ', 阈值类型: ' + (rule.grade == 0 ? '线程数' : 'QPS') + ', 阈值: ' + rule.count, + confirmBtnText: '删除', + }; + confirmDialog = ngDialog.open({ + template: '/app/views/dialog/confirm-dialog.html', + scope: $scope, + overlay: true + }); + }; + + $scope.confirm = function () { + if ($scope.confirmDialog.type === 'delete_rule') { + deleteRule($scope.currentRule); + } else { + console.error('error'); + } + }; + + function deleteRule(rule) { + FlowService.deleteRule(rule).success(function (data) { + if (data.code == 0) { + getMachineRules(); + confirmDialog.close(); + } else { + alert('失败!'); + } + }); + }; + + function addNewRule(rule) { + FlowService.newRule(rule).success(function (data) { + if (data.code == 0) { + getMachineRules(); + flowRuleDialog.close(); + } else { + alert('失败!'); + } + }); + }; + + $scope.onOpenAdvanceClick = function () { + $scope.flowRuleDialog.showAdvanceButton = false; + }; + $scope.onCloseAdvanceClick = function () { + $scope.flowRuleDialog.showAdvanceButton = true; + }; + + function saveRule(rule, edit) { + FlowService.saveRule(rule).success(function (data) { + if (data.code == 0) { + getMachineRules(); + if (edit) { + flowRuleDialog.close(); + } else { + confirmDialog.close(); + } + } else { + alert('失败!'); + } + }); + } + queryAppMachines(); + function queryAppMachines() { + MachineService.getAppMachines($scope.app).success( + function (data) { + if (data.code == 0) { + // $scope.machines = data.data; + if (data.data) { + $scope.machines = []; + $scope.macsInputOptions = []; + data.data.forEach(function (item) { + if (item.health) { + $scope.macsInputOptions.push({ + text: item.ip + ':' + item.port, + value: item.ip + ':' + item.port + }); + } + }); + } + if ($scope.macsInputOptions.length > 0) { + $scope.macInputModel = $scope.macsInputOptions[0].value; + } + } else { + $scope.macsInputOptions = []; + } + } + ); + }; + $scope.$watch('macInputModel', function () { + if ($scope.macInputModel) { + getMachineRules(); + } + }); + }]); diff --git a/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/identity.js b/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/identity.js index e8b3a0d7..0c740234 100755 --- a/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/identity.js +++ b/sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/identity.js @@ -1,7 +1,7 @@ var app = angular.module('sentinelDashboardApp'); app.controller('IdentityCtl', ['$scope', '$stateParams', 'IdentityService', - 'ngDialog', 'FlowService', 'DegradeService', 'AuthorityRuleService', 'ParamFlowService', 'MachineService', + 'ngDialog', 'FlowServiceV2', 'DegradeService', 'AuthorityRuleService', 'ParamFlowService', 'MachineService', '$interval', '$location', '$timeout', function ($scope, $stateParams, IdentityService, ngDialog, FlowService, DegradeService, AuthorityRuleService, ParamFlowService, MachineService, $interval, $location, $timeout) { diff --git a/sentinel-dashboard/src/main/webapp/resources/app/scripts/directives/sidebar/sidebar.html b/sentinel-dashboard/src/main/webapp/resources/app/scripts/directives/sidebar/sidebar.html index 2dac7349..fd435ed2 100755 --- a/sentinel-dashboard/src/main/webapp/resources/app/scripts/directives/sidebar/sidebar.html +++ b/sentinel-dashboard/src/main/webapp/resources/app/scripts/directives/sidebar/sidebar.html @@ -33,9 +33,13 @@
  • - +   流控规则
  • + + + +
  •   降级规则 @@ -52,6 +56,10 @@   授权规则
  • +
  • + +   集群限流 +
  •   机器列表 diff --git a/sentinel-dashboard/src/main/webapp/resources/app/scripts/services/cluster_state_service.js b/sentinel-dashboard/src/main/webapp/resources/app/scripts/services/cluster_state_service.js new file mode 100644 index 00000000..4d5facd0 --- /dev/null +++ b/sentinel-dashboard/src/main/webapp/resources/app/scripts/services/cluster_state_service.js @@ -0,0 +1,28 @@ +/** + * Parameter flow control service. + * + * @author Eric Zhao + */ +angular.module('sentinelDashboardApp').service('ClusterStateService', ['$http', function ($http) { + + this.fetchClusterUniversalState = function(app, ip, port) { + var param = { + app: app, + ip: ip, + port: port + }; + return $http({ + url: '/cluster/state', + params: param, + method: 'GET' + }); + }; + + this.modifyClusterConfig = function(config) { + return $http({ + url: '/cluster/config/modify', + data: config, + method: 'POST' + }); + }; +}]); diff --git a/sentinel-dashboard/src/main/webapp/resources/app/scripts/services/flowservice.js b/sentinel-dashboard/src/main/webapp/resources/app/scripts/services/flow_service_v1.js similarity index 91% rename from sentinel-dashboard/src/main/webapp/resources/app/scripts/services/flowservice.js rename to sentinel-dashboard/src/main/webapp/resources/app/scripts/services/flow_service_v1.js index b089fe29..02e5796d 100755 --- a/sentinel-dashboard/src/main/webapp/resources/app/scripts/services/flowservice.js +++ b/sentinel-dashboard/src/main/webapp/resources/app/scripts/services/flow_service_v1.js @@ -1,6 +1,6 @@ var app = angular.module('sentinelDashboardApp'); -app.service('FlowService', ['$http', function ($http) { +app.service('FlowServiceV1', ['$http', function ($http) { this.queryMachineRules = function (app, ip, port) { var param = { app: app, @@ -8,7 +8,7 @@ app.service('FlowService', ['$http', function ($http) { port: port }; return $http({ - url: 'flow/rules.json', + url: '/v1/flow/rules', params: param, method: 'GET' }); @@ -31,9 +31,9 @@ app.service('FlowService', ['$http', function ($http) { }; return $http({ - url: '/flow/new.json', - params: param, - method: 'GET' + url: '/v1/flow/rule', + data: rule, + method: 'POST' }); }; @@ -52,9 +52,9 @@ app.service('FlowService', ['$http', function ($http) { }; return $http({ - url: '/flow/save.json', + url: '/v1/flow/save.json', params: param, - method: 'GET' + method: 'PUT' }); }; @@ -65,9 +65,9 @@ app.service('FlowService', ['$http', function ($http) { }; return $http({ - url: '/flow/delete.json', + url: '/v1/flow/delete.json', params: param, - method: 'GET' + method: 'DELETE' }); }; diff --git a/sentinel-dashboard/src/main/webapp/resources/app/scripts/services/flow_service_v2.js b/sentinel-dashboard/src/main/webapp/resources/app/scripts/services/flow_service_v2.js new file mode 100755 index 00000000..37ae69a4 --- /dev/null +++ b/sentinel-dashboard/src/main/webapp/resources/app/scripts/services/flow_service_v2.js @@ -0,0 +1,85 @@ +var app = angular.module('sentinelDashboardApp'); + +app.service('FlowServiceV2', ['$http', function ($http) { + this.queryMachineRules = function (app, ip, port) { + var param = { + app: app, + ip: ip, + port: port + }; + return $http({ + url: '/v2/flow/rules', + params: param, + method: 'GET' + }); + }; + + this.newRule = function (rule) { + return $http({ + url: '/v2/flow/rule', + data: rule, + method: 'POST' + }); + }; + + this.saveRule = function (rule) { + return $http({ + url: '/v2/flow/rule/' + rule.id, + data: rule, + method: 'PUT' + }); + }; + + this.deleteRule = function (rule) { + return $http({ + url: '/v2/flow/rule/' + rule.id, + method: 'DELETE' + }); + }; + + function notNumberAtLeastZero(num) { + return num === undefined || num === '' || isNaN(num) || num < 0; + } + + function notNumberGreaterThanZero(num) { + return num === undefined || num === '' || isNaN(num) || num <= 0; + } + + this.checkRuleValid = function (rule) { + if (rule.resource === undefined || rule.resource === '') { + alert('资源名称不能为空'); + return false; + } + if (rule.count === undefined || rule.count < 0) { + alert('限流阈值必须大于等于 0'); + return false; + } + if (rule.strategy === undefined || rule.strategy < 0) { + alert('无效的流控模式'); + return false; + } + if (rule.strategy == 1 || rule.strategy == 2) { + if (rule.refResource === undefined || rule.refResource == '') { + alert('请填写关联资源或入口'); + return false; + } + } + if (rule.controlBehavior === undefined || rule.controlBehavior < 0) { + alert('无效的流控整形方式'); + return false; + } + if (rule.controlBehavior == 1 && notNumberGreaterThanZero(rule.warmUpPeriodSec)) { + alert('预热时长必须大于 0'); + return false; + } + if (rule.controlBehavior == 2 && notNumberGreaterThanZero(rule.maxQueueingTimeMs)) { + alert('排队超时时间必须大于 0'); + return false; + } + if (rule.clusterMode && (rule.clusterConfig === undefined || rule.clusterConfig.thresholdType === undefined)) { + alert('集群限流配置不正确'); + return false; + } + return true; + }; +}]); diff --git a/sentinel-dashboard/src/main/webapp/resources/app/views/cluster.html b/sentinel-dashboard/src/main/webapp/resources/app/views/cluster.html new file mode 100755 index 00000000..a02c7a61 --- /dev/null +++ b/sentinel-dashboard/src/main/webapp/resources/app/views/cluster.html @@ -0,0 +1,96 @@ + +
    +
    + {{app}} +
    +
    + +
    +
    +
    +
    +
    +
    + 集群限流 + + +
    + +
    +
    + + +
    +
    +
    +
    +
    +

    {{loadError.message}}

    +
    +
    +
    +
    +
    + + +
    + +
    +
    + +

    Client

    +

    Server

    +

    未开启

    +
    +
    + +
    +
    +  Client   +  Server +
    +
    +
    +
    + +
    + +
    +
    +
    +
    +
    +

    该机器未引入 Sentinel 集群限流客户端或服务端的相关依赖,请引入相关依赖。

    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    + +
    +
    + +
    +
    + +
    + +
    + +
    + +
    + +
    + diff --git a/sentinel-dashboard/src/main/webapp/resources/app/views/cluster/client.html b/sentinel-dashboard/src/main/webapp/resources/app/views/cluster/client.html new file mode 100644 index 00000000..db05aec0 --- /dev/null +++ b/sentinel-dashboard/src/main/webapp/resources/app/views/cluster/client.html @@ -0,0 +1,22 @@ +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    +
    \ No newline at end of file diff --git a/sentinel-dashboard/src/main/webapp/resources/app/views/cluster/server.html b/sentinel-dashboard/src/main/webapp/resources/app/views/cluster/server.html new file mode 100644 index 00000000..cebf857c --- /dev/null +++ b/sentinel-dashboard/src/main/webapp/resources/app/views/cluster/server.html @@ -0,0 +1,16 @@ +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    +
    \ No newline at end of file diff --git a/sentinel-dashboard/src/main/webapp/resources/app/views/dialog/flow-rule-dialog.html b/sentinel-dashboard/src/main/webapp/resources/app/views/dialog/flow-rule-dialog.html index 6ade264a..52ea78c8 100755 --- a/sentinel-dashboard/src/main/webapp/resources/app/views/dialog/flow-rule-dialog.html +++ b/sentinel-dashboard/src/main/webapp/resources/app/views/dialog/flow-rule-dialog.html @@ -30,9 +30,39 @@  线程数 - -
    - +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    + +
    +
    + +
    +
    +  单机均摊   +  Global +
    +
    diff --git a/sentinel-dashboard/src/main/webapp/resources/app/views/flow.html b/sentinel-dashboard/src/main/webapp/resources/app/views/flow.html index a349c9aa..bdec617b 100755 --- a/sentinel-dashboard/src/main/webapp/resources/app/views/flow.html +++ b/sentinel-dashboard/src/main/webapp/resources/app/views/flow.html @@ -3,8 +3,11 @@ {{app}}
    - + + + 回到旧版(单机)
    @@ -16,13 +19,7 @@
    流控规则 - - -
    - -
    @@ -36,21 +33,21 @@ 流控应用 - + 流控模式 - + 阈值类型 - + 单机阈值 - + + 是否集群 + + 流控效果 - - - 操作 @@ -67,15 +64,20 @@ 链路 - {{rule.grade==0 ? '线程数' : 'QPS'}} + {{rule.grade == 0 ? '线程数' : 'QPS'}} {{rule.count}} + + + + 快速失败 Warm Up 排队等待 + 预热排队 diff --git a/sentinel-dashboard/src/main/webapp/resources/app/views/flow_old.html b/sentinel-dashboard/src/main/webapp/resources/app/views/flow_old.html new file mode 100755 index 00000000..480e1c8b --- /dev/null +++ b/sentinel-dashboard/src/main/webapp/resources/app/views/flow_old.html @@ -0,0 +1,113 @@ +
    +
    + {{app}} +
    +
    + + + 回到新版 +
    +
    + +
    + +
    +
    +
    +
    +
    + 流控规则 + + + +
    + +
    +
    + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + 资源名 + + 流控应用 + + 流控模式 + + 阈值类型 + + 单机阈值 + + 流控效果 + + 操作 +
    {{rule.resource}}{{rule.limitApp }} + 直接 + 关联 + 链路 + + {{rule.grade==0 ? '线程数' : 'QPS'}} + + {{rule.count}} + + 快速失败 + Warm Up + 排队等待 + + + +
    +
    + + + +
    + +
    + +
    + +
    + diff --git a/sentinel-dashboard/src/main/webapp/resources/dist/js/app.js b/sentinel-dashboard/src/main/webapp/resources/dist/js/app.js index b6f17231..063515aa 100755 --- a/sentinel-dashboard/src/main/webapp/resources/dist/js/app.js +++ b/sentinel-dashboard/src/main/webapp/resources/dist/js/app.js @@ -1 +1 @@ -"use strict";var app;angular.module("sentinelDashboardApp",["oc.lazyLoad","ui.router","ui.bootstrap","angular-loading-bar","ngDialog","ui.bootstrap.datetimepicker","ui-notification","rzTable","angular-clipboard","selectize","angularUtils.directives.dirPagination"]).config(["$stateProvider","$urlRouterProvider","$ocLazyLoadProvider",function(e,r,t){t.config({debug:!1,events:!0}),r.otherwise("/dashboard/home"),e.state("dashboard",{url:"/dashboard",templateUrl:"app/views/dashboard/main.html",resolve:{loadMyDirectives:["$ocLazyLoad",function(e){return e.load({name:"sentinelDashboardApp",files:["app/scripts/directives/header/header.js","app/scripts/directives/sidebar/sidebar.js","app/scripts/directives/sidebar/sidebar-search/sidebar-search.js"]})}]}}).state("dashboard.home",{url:"/home",templateUrl:"app/views/dashboard/home.html",resolve:{loadMyFiles:["$ocLazyLoad",function(e){return e.load({name:"sentinelDashboardApp",files:["app/scripts/controllers/main.js"]})}]}}).state("dashboard.flow",{templateUrl:"app/views/flow.html",url:"/flow/:app",controller:"FlowCtl",resolve:{loadMyFiles:["$ocLazyLoad",function(e){return e.load({name:"sentinelDashboardApp",files:["app/scripts/controllers/flow.js"]})}]}}).state("dashboard.paramFlow",{templateUrl:"app/views/param_flow.html",url:"/paramFlow/:app",controller:"ParamFlowController",resolve:{loadMyFiles:["$ocLazyLoad",function(e){return e.load({name:"sentinelDashboardApp",files:["app/scripts/controllers/param_flow.js"]})}]}}).state("dashboard.authority",{templateUrl:"app/views/authority.html",url:"/authority/:app",controller:"AuthorityRuleController",resolve:{loadMyFiles:["$ocLazyLoad",function(e){return e.load({name:"sentinelDashboardApp",files:["app/scripts/controllers/authority.js"]})}]}}).state("dashboard.degrade",{templateUrl:"app/views/degrade.html",url:"/degrade/:app",controller:"DegradeCtl",resolve:{loadMyFiles:["$ocLazyLoad",function(e){return e.load({name:"sentinelDashboardApp",files:["app/scripts/controllers/degrade.js"]})}]}}).state("dashboard.system",{templateUrl:"app/views/system.html",url:"/system/:app",controller:"SystemCtl",resolve:{loadMyFiles:["$ocLazyLoad",function(e){return e.load({name:"sentinelDashboardApp",files:["app/scripts/controllers/system.js"]})}]}}).state("dashboard.machine",{templateUrl:"app/views/machine.html",url:"/app/:app",controller:"MachineCtl",resolve:{loadMyFiles:["$ocLazyLoad",function(e){return e.load({name:"sentinelDashboardApp",files:["app/scripts/controllers/machine.js"]})}]}}).state("dashboard.identity",{templateUrl:"app/views/identity.html",url:"/identity/:app",controller:"IdentityCtl",resolve:{loadMyFiles:["$ocLazyLoad",function(e){return e.load({name:"sentinelDashboardApp",files:["app/scripts/controllers/identity.js"]})}]}}).state("dashboard.metric",{templateUrl:"app/views/metric.html",url:"/metric/:app",controller:"MetricCtl",resolve:{loadMyFiles:["$ocLazyLoad",function(e){return e.load({name:"sentinelDashboardApp",files:["app/scripts/controllers/metric.js"]})}]}})}]),(app=angular.module("sentinelDashboardApp")).filter("range",[function(){return function(e,r){if(isNaN(r)||r<=0)return[];e=[];for(var t=1;t<=r;t++)e.push(t);return e}}]),(app=angular.module("sentinelDashboardApp")).service("AppService",["$http",function(e){this.getApps=function(){return e({url:"app/briefinfos.json",method:"GET"})}}]),(app=angular.module("sentinelDashboardApp")).service("FlowService",["$http",function(a){function r(e){return void 0===e||""===e||isNaN(e)||e<=0}this.queryMachineRules=function(e,r,t){return a({url:"flow/rules.json",params:{app:e,ip:r,port:t},method:"GET"})},this.newRule=function(e){var r={resource:e.resource,limitApp:e.limitApp,grade:e.grade,count:e.count,strategy:e.strategy,refResource:e.refResource,controlBehavior:e.controlBehavior,warmUpPeriodSec:e.warmUpPeriodSec,maxQueueingTimeMs:e.maxQueueingTimeMs,app:e.app,ip:e.ip,port:e.port};return a({url:"/flow/new.json",params:r,method:"GET"})},this.saveRule=function(e){var r={id:e.id,resource:e.resource,limitApp:e.limitApp,grade:e.grade,count:e.count,strategy:e.strategy,refResource:e.refResource,controlBehavior:e.controlBehavior,warmUpPeriodSec:e.warmUpPeriodSec,maxQueueingTimeMs:e.maxQueueingTimeMs};return a({url:"/flow/save.json",params:r,method:"GET"})},this.deleteRule=function(e){var r={id:e.id,app:e.app};return a({url:"/flow/delete.json",params:r,method:"GET"})},this.checkRuleValid=function(e){return void 0===e.resource||""===e.resource?(alert("资源名称不能为空"),!1):void 0===e.count||e.count<0?(alert("限流阈值必须大于等于 0"),!1):void 0===e.strategy||e.strategy<0?(alert("无效的流控模式"),!1):1!=e.strategy&&2!=e.strategy||void 0!==e.refResource&&""!=e.refResource?void 0===e.controlBehavior||e.controlBehavior<0?(alert("无效的流控整形方式"),!1):1==e.controlBehavior&&r(e.warmUpPeriodSec)?(alert("预热时长必须大于 0"),!1):2!=e.controlBehavior||!r(e.maxQueueingTimeMs)||(alert("排队超时时间必须大于 0"),!1):(alert("请填写关联资源或入口"),!1)}}]),(app=angular.module("sentinelDashboardApp")).service("DegradeService",["$http",function(a){this.queryMachineRules=function(e,r,t){return a({url:"degrade/rules.json",params:{app:e,ip:r,port:t},method:"GET"})},this.newRule=function(e){var r={id:e.id,resource:e.resource,limitApp:e.limitApp,count:e.count,timeWindow:e.timeWindow,grade:e.grade,app:e.app,ip:e.ip,port:e.port};return a({url:"/degrade/new.json",params:r,method:"GET"})},this.saveRule=function(e){var r={id:e.id,resource:e.resource,limitApp:e.limitApp,grade:e.grade,count:e.count,timeWindow:e.timeWindow};return a({url:"/degrade/save.json",params:r,method:"GET"})},this.deleteRule=function(e){var r={id:e.id,app:e.app};return a({url:"/degrade/delete.json",params:r,method:"GET"})},this.checkRuleValid=function(e){return void 0===e.resource||""===e.resource?(alert("资源名称不能为空"),!1):void 0===e.grade||e.grade<0?(alert("未知的降级策略"),!1):void 0===e.count||""===e.count||e.count<0?(alert("降级阈值不能为空或小于 0"),!1):void 0===e.timeWindow||""===e.timeWindow||e.timeWindow<=0?(alert("降级时间窗口必须大于 0"),!1):!(1==e.grade&&1