redis.tmpl 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. {{template "header.tmpl" .}}
  2. <style type="text/css">
  3. #filterform{
  4. margin: 10px 0px;
  5. }
  6. #filterform .form-group{
  7. margin-right: 20px;
  8. }
  9. </style>
  10. </head>
  11. <body>
  12. {{template "navbar.tmpl" .}}
  13. <div class="container-fluid">
  14. <table class="table table-bordered" style="margin-bottom:0px;">
  15. <thead>
  16. <tr>
  17. <th colspan="16" class="text-center"><big>Redis服务列表</big>
  18. <span style="margin-left:10px;">
  19. <button class="btn btn-sm btn-warning" href="#" id="add_btn"><i class="glyphicon glyphicon-plus"></i> 点击这里添加</button>
  20. </span>
  21. </th>
  22. </tr>
  23. <tr>
  24. <th>ID</th>
  25. <th>服务地址</th>
  26. <th>备注名</th>
  27. <th>连接密码</th>
  28. <th>连接超时(秒)&nbsp;<a href="#" data-toggle="popover" data-trigger="focus" title="连接超时(单位:秒)" data-content="检测Redis状态时如果连接操作超过该值将会被认为Redis状态异常。" onclick="return false;">?</a></th>
  29. <th>最大失败次数&nbsp;<a href="#" data-toggle="popover" data-trigger="focus" title="最大失败次数" data-content="如果Redis状态检测失败连续失败次数达到该值将会触发报警。" onclick="return false;">?</a></th>
  30. <th>最小剩余内存&nbsp;<a href="#" data-toggle="popover" data-trigger="focus" title="最小剩余内存" data-content="Redis最小可用的内存空间值,低于该值将会触发自动扩容操作。" onclick="return false;">?</a></th>
  31. <th>最小剩余内存(%)&nbsp;<a href="#" data-toggle="popover" data-trigger="focus" title="最小剩余内存(百分比)" data-content="Redis最小可用的内存空间占比(已用值/分配值*100),低于该值将会触发自动扩容操作。" onclick="return false;">?</a></th>
  32. <th>最大内存使用&nbsp;<a href="#" data-toggle="popover" data-trigger="focus" title="最大内存使用" data-content="自动扩容的内存上限,Redis的内存使用达到该值将不再自动扩容。" onclick="return false;">?</a></th>
  33. <th>最大连接数&nbsp;<a href="#" data-toggle="popover" data-trigger="focus" title="最大连接数" data-content="Redis的最大并发连接数,达到该值将会触发报警。" onclick="return false;">?</a></th>
  34. <th>最大新增淘汰数&nbsp;<a href="#" data-toggle="popover" data-trigger="focus" title="最大新增淘汰数" data-content="上次检测之后增加的淘汰记录数上限,达到该值后将触发报警。" onclick="return false;">?</a></th>
  35. <th>最大QPS&nbsp;<a href="#" data-toggle="popover" data-trigger="focus" title="最大QPS" data-content="Redis的最大QPS值,达到该值将会触发报警。" onclick="return false;">?</a></th>
  36. <th>报警邮箱列表&nbsp;<a href="#" data-toggle="popover" data-trigger="focus" title="报警邮箱列表" data-content="接收报警邮件的邮箱地址列表,与邮件组合并后作为接收报警邮箱的邮箱列表。" onclick="return false;">?</a></th>
  37. <th>状态</th>
  38. <th>操作</th>
  39. </tr>
  40. </thead>
  41. <tbody id="list"></tbody>
  42. </table>
  43. </div>
  44. <script type="text/javascript">
  45. var $SESS = {{.Sess}};
  46. $(function(){
  47. //加载列表
  48. function redis_list() {
  49. var list = $('#list');
  50. list.empty();
  51. $.post('/syscfg/redis_list', {}, function(resp){
  52. if (resp && resp.errno == 0 && resp.data) {
  53. var html = '';
  54. for (var i=0; i<resp.data.length; i++) {
  55. var item = resp.data[i];
  56. html += '<tr>';
  57. html += '<td>' + item.Id + '</td>';
  58. html += '<td>' + item.Address + '</td>';
  59. html += '<td>' + (item.Remark == '' ? '<i class="text-muted">无</i>' : item.Remark) + '</td>';
  60. html += '<td>' + (item.Password == '' ? '<i class="text-muted">无</i>' : item.Password) + '</td>';
  61. html += '<td>' + item.MaxConnectWait + '</td>';
  62. html += '<td>' + item.MaxStatusFailed + '</td>';
  63. html += '<td>' + size2str(item.MinMemoryFree) + '</td>';
  64. html += '<td>' + (item.MinMemoryFreePC ? item.MinMemoryFreePC + '%' : '<i class="text-muted">无</i>') + '</td>';
  65. html += '<td>' + size2str(item.MaxMemoryUsage) + '</td>';
  66. html += '<td>' + numberFormat(item.MaxConnection) + '</td>';
  67. html += '<td>' + item.MaxEviIncreased + '</td>';
  68. html += '<td>' + numberFormat(item.MaxQPS) + '</td>';
  69. html += '<td>' + (item.MailList == '' ? '<i class="text-muted">无</i>' : item.MailList) + '</td>';
  70. html += '<td' + (item.Disabled ? ' class="text-danger"' : '') + '>' + (item.Disabled ? '禁用' : '正常') + '</td>';
  71. html += '<td>';
  72. html += ' <button class="btn btn-xs btn-primary" type="button" data-value="' + item.Id + '">编辑</button>&nbsp;';
  73. html += ' <button class="btn btn-xs btn-danger" type="button" data-value="' + item.Id + '">删除</button>';
  74. html += '</td>';
  75. html += '</tr>';
  76. }
  77. list.html(html);
  78. //修改
  79. $('.btn-primary', list).click(function(){
  80. var id = $(this).attr('data-value');
  81. $.get('/syscfg/redis_get', {'id': id}, function(resp){
  82. if (resp && resp.errno == 0) {
  83. redis_set(resp.data);
  84. }
  85. }, 'json');
  86. return false;
  87. });
  88. //删除
  89. $('.btn-danger', list).click(function(){
  90. var id = $(this).attr('data-value');
  91. $.alert({
  92. 'content': '确定要删除该记录吗?',
  93. 'btncancel': true,
  94. 'callback': function() {
  95. $.post('/syscfg/redis_del', {'id': id}, function(resp){
  96. if (resp && resp.errno == 0) {
  97. redis_list();
  98. } else {
  99. $.alert({'content': resp.error ? resp.error : '操作失败!'});
  100. }
  101. }, 'json');
  102. }
  103. });
  104. });
  105. }
  106. }, 'json');
  107. return false;
  108. }
  109. //添加或修改记录
  110. function redis_set(record){
  111. record = $.extend({
  112. 'Id': 0,
  113. 'Address': '',
  114. 'Remark': '',
  115. 'Password': '',
  116. 'MaxConnectWait': 5,
  117. 'MaxStatusFailed': 1,
  118. 'MinMemoryFree': 10*1024*1024,
  119. 'MinMemoryFreePC': 10,
  120. 'MaxMemoryUsage': 500*1024*1024,
  121. 'MaxConnection': 1024,
  122. 'MaxEviIncreased': 1,
  123. 'MaxQPS': 30000,
  124. 'MailList': '',
  125. 'Disabled': false
  126. }, record);
  127. var html = `<form class="form-horizontal">
  128. <div class="form-group id-group" style="display:none;">
  129. <label class="col-md-4 control-label">ID</label>
  130. <div class="col-md-8">
  131. <input type="text" class="form-control" name="Id" maxlength="20" value="${record.Id}" readonly="readonly" />
  132. </div>
  133. </div>
  134. <div class="form-group">
  135. <label class="col-md-4 control-label">服务地址(IP:端口)</label>
  136. <div class="col-md-8">
  137. <input type="text" class="form-control" name="Address" maxlength="20" value="${record.Address}" placeholder="IP或域名:端口" />
  138. </div>
  139. </div>
  140. <div class="form-group">
  141. <label class="col-md-4 control-label">备注名称</label>
  142. <div class="col-md-8">
  143. <input type="text" class="form-control" name="Remark" maxlength="20" value="${record.Remark}" placeholder="用于后台展示" />
  144. </div>
  145. </div>
  146. <div class="form-group">
  147. <label class="col-md-4 control-label">连接密码</label>
  148. <div class="col-md-8">
  149. <input type="text" class="form-control" name="Password" maxlength="20" value="${record.Password}" placeholder="未设置密码时留空" />
  150. </div>
  151. </div>
  152. <div class="form-group">
  153. <label class="col-md-4 control-label">连接超时时长(秒)</label>
  154. <div class="col-md-8">
  155. <div class="input-group" style="width:100px;">
  156. <input type="text" class="form-control" name="MaxConnectWait" maxlength="2" value="${record.MaxConnectWait}" />
  157. <div class="input-group-addon">秒</div>
  158. </div>
  159. <p class="help-block">连接等待时长超过该值将当作失败处理</p>
  160. </div>
  161. </div>
  162. <div class="form-group">
  163. <label class="col-md-4 control-label">最大状态检测失败次数</label>
  164. <div class="col-md-8">
  165. <div class="input-group" style="width:100px;">
  166. <input type="text" class="form-control" name="MaxStatusFailed" maxlength="2" value="${record.MaxStatusFailed}" />
  167. <div class="input-group-addon">次</div>
  168. </div>
  169. <p class="help-block">连续失败次数达到该值将会触发报警</p>
  170. </div>
  171. </div>
  172. <div class="form-group">
  173. <label class="col-md-4 control-label">最小可用内存空间</label>
  174. <div class="col-md-8">
  175. <div class="input-group" style="width:200px;">
  176. <input type="text" class="form-control" name="MinMemoryFree" maxlength="10" value="${record.MinMemoryFree}" />
  177. <div class="input-group-addon">字节</div>
  178. </div>
  179. <p class="help-block">低于该值将自动扩容,设置0跳过该检查项</p>
  180. </div>
  181. </div>
  182. <div class="form-group">
  183. <label class="col-md-4 control-label">最小可用内存空间占比</label>
  184. <div class="col-md-8">
  185. <div class="input-group" style="width:100px;">
  186. <input type="text" class="form-control" name="MinMemoryFreePC" maxlength="2" value="${record.MinMemoryFreePC}" />
  187. <div class="input-group-addon">%</div>
  188. </div>
  189. <p class="help-block">低于该值将自动扩容,设置0跳过该检查项</p>
  190. </div>
  191. </div>
  192. <div class="form-group">
  193. <label class="col-md-4 control-label">最大使用内存上限</label>
  194. <div class="col-md-8">
  195. <div class="input-group" style="width:200px;">
  196. <input type="text" class="form-control" name="MaxMemoryUsage" maxlength="10" value="${record.MaxMemoryUsage}" />
  197. <div class="input-group-addon">字节</div>
  198. </div>
  199. <p class="help-block">已用内存达到该值将不再自动扩容</p>
  200. </div>
  201. </div>
  202. <div class="form-group">
  203. <label class="col-md-4 control-label">最大客户端并发连接数</label>
  204. <div class="col-md-8">
  205. <div class="input-group" style="width:150px;">
  206. <input type="text" class="form-control" name="MaxConnection" maxlength="10" value="${record.MaxConnection}" />
  207. <div class="input-group-addon">个</div>
  208. </div>
  209. <p class="help-block">超过该值将会触发报警</p>
  210. </div>
  211. </div>
  212. <div class="form-group">
  213. <label class="col-md-4 control-label">最大新增淘汰记录数</label>
  214. <div class="col-md-8">
  215. <div class="input-group" style="width:100px;">
  216. <input type="text" class="form-control" name="MaxEviIncreased" maxlength="5" value="${record.MaxEviIncreased}" />
  217. <div class="input-group-addon">个</div>
  218. </div>
  219. <p class="help-block">超过该值将会触发报警</p>
  220. </div>
  221. </div>
  222. <div class="form-group">
  223. <label class="col-md-4 control-label">最大QPS上限值</label>
  224. <div class="col-md-8">
  225. <div class="input-group" style="width:150px;">
  226. <input type="text" class="form-control" name="MaxQPS" maxlength="10" value="${record.MaxQPS}" />
  227. <div class="input-group-addon">次/s</div>
  228. </div>
  229. <p class="help-block">超过该值将会触发报警</p>
  230. </div>
  231. </div>
  232. <div class="form-group">
  233. <label class="col-md-4 control-label">报警邮件接收邮箱列表<br />(多个之间使用“;”间隔)</label>
  234. <div class="col-md-8">
  235. <textarea class="form-control" name="MailList" rows="4" maxlength="1000">${record.MailList}</textarea>
  236. </div>
  237. </div>
  238. <div class="form-group">
  239. <label class="col-md-4 control-label">状态</label>
  240. <div class="col-md-8">
  241. <select class="form-control" name="Disabled" style="width:100px;">
  242. <option value="0">正常</option>
  243. <option value="1">禁用</option>
  244. </select>
  245. </div>
  246. </div>
  247. </form>`;
  248. $.alert({
  249. 'title': record.Id == 0 ? '添加新配置' : '修改配置',
  250. 'content': html,
  251. 'init': function(dlg) {
  252. var form = $('form', dlg).get(0);
  253. form.Disabled.value = record.Disabled ? '1' : '0';
  254. $(form.MinMemoryFree).change(function(){
  255. this.value = numberFormat(this.value);
  256. });
  257. $(form.MaxMemoryUsage).change(function(){
  258. this.value = numberFormat(this.value);
  259. });
  260. $(form.MinMemoryFree).change();
  261. $(form.MaxMemoryUsage).change();
  262. if (record.Id == 0) {
  263. $('.id-group', dlg).hide();
  264. } else {
  265. $('.id-group', dlg).show();
  266. }
  267. },
  268. 'callback': function(dlg){
  269. var form = $('form', dlg).get(0);
  270. form.MinMemoryFree.value = form.MinMemoryFree.value.replace(/,/g, '');
  271. form.MaxMemoryUsage.value = form.MaxMemoryUsage.value.replace(/,/g, '');
  272. if (form.Address.value == '') {
  273. $.alert({'content': '请填写Redis的服务地址!'});
  274. } else if (!/[0-9A-Za-z.\-]+:\d{3,5}$/.test(form.Address.value)) {
  275. $.alert({'content': 'Redis服务地址格式不正确!'});
  276. } else if (form.Remark.value == '') {
  277. $.alert({'content': '请填写备注名称!'});
  278. } else if (/\D/.test(form.MaxConnectWait.value)) {
  279. $.alert({'content': '请填写正确的连接超时时长!'});
  280. } else if (/\D/.test(form.MaxStatusFailed.value)) {
  281. $.alert({'content': '请填写正确的最大状态检测失败次数!'});
  282. } else if (/\D/.test(form.MinMemoryFree.value)) {
  283. $.alert({'content': '请填写正确的最小可用内存空间(字节)!'});
  284. } else if (/\D/.test(form.MinMemoryFreePC.value)) {
  285. $.alert({'content': '请填写正确的最小可用内存空间(百分比)!'});
  286. } else if (/\D/.test(form.MaxMemoryUsage.value)) {
  287. $.alert({'content': '请填写正确的最大使用内存上限!'});
  288. } else if (/\D/.test(form.MaxConnection.value)) {
  289. $.alert({'content': '请填写正确的最大客户端并发连接数!'});
  290. } else if (/\D/.test(form.MaxEviIncreased.value)) {
  291. $.alert({'content': '请填写正确的最大新增淘汰记录数!'});
  292. } else if (/\D/.test(form.MaxQPS.value)) {
  293. $.alert({'content': '请填写正确的最大QPS上限值!'});
  294. } else if (form.MailList.value == '') {
  295. $.alert({'content': '请填写报警邮件接收邮箱列表!'});
  296. } else {
  297. $.post('/syscfg/redis_set', $(form).serialize(), function(resp){
  298. if (resp && resp.errno == 0) {
  299. redis_list();
  300. } else {
  301. $.alert({'content': resp.error ? resp.error : '操作失败!'});
  302. }
  303. }, 'json');
  304. return true;
  305. }
  306. return false;
  307. },
  308. 'btncancel': true
  309. });
  310. return false;
  311. }
  312. redis_list(); //加载页面
  313. $('#add_btn').click(redis_set); //添加按钮
  314. $('[data-toggle="popover"]').popover(); //tips
  315. });
  316. </script>
  317. </body>
  318. </html>