pull/109/head
Mr Chen 7 years ago
parent 480f240edf
commit 7ef22d011a
  1. 1
      .gitignore
  2. 6
      class/core/plugin_api.py
  3. 4
      plugins/memcached/index.html
  4. 90
      plugins/memcached/index.py
  5. 10
      plugins/memcached/init.d/memcached.tpl
  6. 194
      plugins/memcached/js/mem.js

1
.gitignore vendored

@ -112,3 +112,4 @@ data/json/index.json
*.zip
data/*.db
data/control.conf
plugins/memcached/init.d/memcached

@ -490,10 +490,10 @@ class plugin_api:
else:
py_cmd = py + ' ' + func + ' ' + version + ' ' + args
# print path
# print os.path.exists(path)
if not os.path.exists(path):
return ('', '')
data = public.execShell(py_cmd)
print py_cmd
print os.path.exists(py_cmd)
return (data[0].strip(), data[1].strip())

@ -4,7 +4,7 @@
<p class="bgw" onclick="pluginService('memcached');">服务</p>
<p onclick="pluginConfig('memcached');">配置修改</p>
<p onclick="redisConfig();">切换版本</p>
<p onclick="redisStatus();">负载状态</p>
<p onclick="memcachedStatus();">负载状态</p>
<p onclick="redisStatus();">性能调整</p>
</div>
<div class="bt-w-con pd15">
@ -15,5 +15,5 @@
</div>
<script type="text/javascript">
pluginService('memcached');
// $.getScript( "/plugins/file?name=memcached&f=js/mem.js");
$.getScript( "/plugins/file?name=memcached&f=js/mem.js");
</script>

@ -17,60 +17,88 @@ def status():
return 'start'
def initDreplace():
file_tpl = os.getcwd() + '/plugins/memcached/init.d/memcached.tpl'
file_bin = getConf()
if os.path.exists(file_bin):
return file_bin
content = public.readFile(file_tpl)
service_path = os.path.dirname(os.getcwd())
content = content.replace('{$PATH}', service_path)
public.writeFile(file_bin, content)
public.execShell('chmod +x ' + file_bin)
return file_bin
def start():
path = os.path.dirname(os.getcwd())
cmd = path + "/memcached/bin/memcached"
cmd = cmd + " " + path + "/memcached/memcached.conf"
data = public.execShell(cmd)
if data[0] == '':
file = initDreplace()
data = public.execShell(file + ' start')
if data[1] == '':
return 'ok'
return 'fail'
def stop():
data = public.execShell(
"ps -ef|grep memcached |grep -v grep |grep -v python |awk '{print $2}' | xargs kill -9")
if data[0] == '':
file = initDreplace()
data = public.execShell(file + ' stop')
if data[1] == '':
return 'ok'
return 'fail'
def restart():
return 'ok'
file = initDreplace()
data = public.execShell(file + ' reload')
if data[1] == '':
return 'ok'
return 'fail'
def reload():
return 'ok'
file = initDreplace()
data = public.execShell(file + ' reload')
if data[1] == '':
return 'ok'
return 'fail'
def runInfo():
path = os.path.dirname(os.getcwd())
cmd = path + "/redis/bin/redis-cli info"
data = public.execShell(cmd)[0]
res = [
'tcp_port',
'uptime_in_days', # 已运行天数
'connected_clients', # 连接的客户端数量
'used_memory', # Redis已分配的内存总量
'used_memory_rss', # Redis占用的系统内存总量
'used_memory_peak', # Redis所用内存的高峰值
'mem_fragmentation_ratio', # 内存碎片比率
'total_connections_received', # 运行以来连接过的客户端的总数量
'total_commands_processed', # 运行以来执行过的命令的总数量
'instantaneous_ops_per_sec', # 服务器每秒钟执行的命令数量
'keyspace_hits', # 查找数据库键成功的次数
'keyspace_misses', # 查找数据库键失败的次数
'latest_fork_usec' # 最近一次 fork() 操作耗费的毫秒数
]
data = data.split("\n")
# 获取memcached状态
import telnetlib
import re
tn = telnetlib.Telnet('127.0.0.1', 11211)
tn.write(b"stats\n")
tn.write(b"quit\n")
data = tn.read_all()
if type(data) == bytes:
data = data.decode('utf-8')
data = data.replace('STAT', '').replace('END', '').split("\n")
result = {}
res = ['cmd_get', 'get_hits', 'get_misses', 'limit_maxbytes', 'curr_items', 'bytes',
'evictions', 'limit_maxbytes', 'bytes_written', 'bytes_read', 'curr_connections']
for d in data:
if len(d) < 3:
continue
t = d.strip().split(':')
t = d.split()
if not t[0] in res:
continue
result[t[0]] = t[1]
result[t[0]] = int(t[1])
result['hit'] = 1
if result['get_hits'] > 0 and result['cmd_get'] > 0:
result['hit'] = float(result['get_hits']) / \
float(result['cmd_get']) * 100
conf = public.readFile(getConf())
result['bind'] = re.search('IP=(.+)', conf).groups()[0]
result['port'] = int(re.search('PORT=(\d+)', conf).groups()[0])
result['maxconn'] = int(re.search('MAXCONN=(\d+)', conf).groups()[0])
result['cachesize'] = int(
re.search('CACHESIZE=(\d+)', conf).groups()[0])
return public.getJson(result)

@ -29,28 +29,26 @@ prog="memcached"
start () {
echo -n $"Starting $prog: "
{$PATH}/memcached/bin/memcached -d -l $IP -p $PORT -u $USER -m $CACHESIZE -c $MAXCONN -P /var/run/memcached.pid $OPTIONS
{$PATH}/memcached/bin/memcached -d -l $IP -p $PORT -u $USER -m $CACHESIZE -c $MAXCONN -P {$PATH}/memcached/memcached.pid $OPTIONS
if [ "$?" != 0 ] ; then
echo " failed"
exit 1
else
touch /var/lock/subsys/memcached
echo " done"
fi
}
stop () {
echo -n $"Stopping $prog: "
if [ ! -e /var/run/$prog.pid ]; then
if [ ! -e {$PATH}/memcached/$prog.pid ]; then
echo -n $"$prog is not running."
exit 1
fi
kill `cat /var/run/memcached.pid`
kill `cat {$PATH}/memcached/memcached.pid`
if [ "$?" != 0 ] ; then
echo " failed"
exit 1
else
rm -f /var/lock/subsys/memcached
rm -f /var/run/memcached.pid
rm -f {$PATH}/memcached/memcached.pid
echo " done"
fi
}

@ -1,188 +1,16 @@
function redisOp(a, b) {
var c = "name=" + a + "&func=" + b;
var d = "";
switch(b) {
case "stop":
d = '停止';
break;
case "start":
d = '启动';
break;
case "restart":
d = '重启';
break;
case "reload":
d = '重载';
break
}
layer.confirm( '您真的要{1}{2}服务吗?'.replace('{1}', d).replace('{2}', a), {icon:3,closeBtn: 2}, function() {
var e = layer.msg('正在{1}{2}服务,请稍候...'.replace('{1}', d).replace('{2}', a), {icon: 16,time: 0});
$.post("/plugins/run", c, function(g) {
layer.close(e);
var f = g.data == 'ok' ? '{1}服务已{2}'.replace('{1}', a).replace('{2}', d):'{1}服务{2}失败!'.replace('{1}', a).replace('{2}', d);
layer.msg(f, {icon: g.data == 'ok' ? 1 : 2});
if(b != "reload" && g.data == 'ok') {
if (b == 'start') {
setRedisService('redis', true);
} else if (b=='stop'){
setRedisService('redis', false);
} else {
}
}
if(g.data != 'ok') {
layer.msg(g.data, {icon: 2,time: 0,shade: 0.3,shadeClose: true});
}
},'json').error(function() {
layer.close(e);
layer.msg('操作成功!', {icon: 1});
});
})
}
//服务
function setRedisService(name, status){
var serviceCon ='<p class="status">当前状态:<span>'+(status ? '开启' : '关闭' )+
'</span><span style="color: '+
(status?'#20a53a;':'red;')+
' margin-left: 3px;" class="glyphicon ' + (status?'glyphicon glyphicon-play':'glyphicon-pause')+'"></span></p><div class="sfm-opt">\
<button class="btn btn-default btn-sm" onclick="redisOp(\''+name+'\',\''+(status?'stop':'start')+'\')">'+(status?'停止':'启动')+'</button>\
<button class="btn btn-default btn-sm" onclick="redisOp(\''+name+'\',\'restart\')">重启</button>\
<button class="btn btn-default btn-sm" onclick="redisOp(\''+name+'\',\'reload\')">重载配置</button>\
</div>';
$(".soft-man-con").html(serviceCon);
}
//服务
function redisService(){
$.post('/plugins/run', {name:'redis', func:'status'}, function(data) {
console.log(data);
if(!data.status){
layer.msg(data.msg,{icon:0,time:3000,shade: [0.3, '#000']});
return;
}
if (data.data == 'start'){
setRedisService('redis', true);
} else {
setRedisService('redis', false);
}
},'json');
}
redisService();
//配置修改 --- start
function redisConfig(type){
var con = '<p style="color: #666; margin-bottom: 7px">提示Ctrl+F 搜索关键字Ctrl+G 查找下一个Ctrl+S 保存Ctrl+Shift+R 查找替换!</p><textarea class="bt-input-text" style="height: 320px; line-height:18px;" id="textBody"></textarea>\
<button id="OnlineEditFileBtn" class="btn btn-success btn-sm" style="margin-top:10px;">保存</button>\
<ul class="help-info-text c7 ptb15">\
<li>此处为redis主配置文件,若您不了解配置规则,请勿随意修改</li>\
</ul>';
$(".soft-man-con").html(con);
var loadT = layer.msg('配置文件路径获取中...',{icon:16,time:0,shade: [0.3, '#000']});
$.post('/plugins/run', {name:'redis', func:'conf'},function (data) {
layer.close(loadT);
var loadT2 = layer.msg('文件内容获取中...',{icon:16,time:0,shade: [0.3, '#000']});
var fileName = data.data;
$.post('/files/get_body', 'path=' + fileName, function(rdata) {
layer.close(loadT2);
if (!rdata.status){
layer.msg(rdata.msg,{icon:0,time:2000,shade: [0.3, '#000']});
return;
}
$("#textBody").empty().text(rdata.data.data);
$(".CodeMirror").remove();
var editor = CodeMirror.fromTextArea(document.getElementById("textBody"), {
extraKeys: {
"Ctrl-Space": "autocomplete",
"Ctrl-F": "findPersistent",
"Ctrl-H": "replaceAll",
"Ctrl-S": function() {
redisConfSafe(fileName);
}
},
lineNumbers: true,
matchBrackets:true,
});
editor.focus();
$(".CodeMirror-scroll").css({"height":"300px","margin":0,"padding":0});
$("#OnlineEditFileBtn").click(function(){
$("#textBody").text(editor.getValue());
redisConfSafe(fileName);
});
},'json');
},'json');
}
//配置保存
function redisConfSafe(fileName) {
var data = encodeURIComponent($("#textBody").val());
var encoding = 'utf-8';
var loadT = layer.msg('保存中...', {
icon: 16,
time: 0
});
$.post('/files/save_body', 'data=' + data + '&path=' + fileName + '&encoding=' + encoding, function(rdata) {
layer.close(loadT);
layer.msg(rdata.msg, {
icon: rdata.status ? 1 : 2
});
},'json');
}
//配置修改 --- end
//redis负载状态 start
function redisStatus() {
//memcached负载状态
function memcachedStatus() {
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
$.post('/plugins/run', {name:'redis', func:'run_info'}, function(data) {
layer.close(loadT);
$.post('/plugins/run', {name:'memcached', func:'run_info'}, function(data) {
if (!data.status){
layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']});
showMsg(data.msg, function(){}, null,13000);
return;
}
var rdata = $.parseJSON(data.data);
hit = (parseInt(rdata.keyspace_hits) / (parseInt(rdata.keyspace_hits) + parseInt(rdata.keyspace_misses)) * 100).toFixed(2);
var Con = '<div class="divtable">\
<table class="table table-hover table-bordered" style="width: 490px;">\
<thead><th>字段</th><th></th><th></th></thead>\
<tbody>\
<tr><th>uptime_in_days</th><td>' + rdata.uptime_in_days + '</td><td></td></tr>\
<tr><th>tcp_port</th><td>' + rdata.tcp_port + '</td><td></td></tr>\
<tr><th>connected_clients</th><td>' + rdata.connected_clients + '</td><td></td></tr>\
<tr><th>used_memory_rss</th><td>' + ToSize(rdata.used_memory_rss) + '</td><td>Redis</td></tr>\
<tr><th>used_memory</th><td>' + ToSize(rdata.used_memory) + '</td><td>Redis</td></tr>\
<tr><th>used_memory_peak</th><td>' + ToSize(rdata.used_memory_peak) + '</td><td>Redis</td></tr>\
<tr><th>mem_fragmentation_ratio</th><td>' + rdata.mem_fragmentation_ratio + '%</td><td></td></tr>\
<tr><th>total_connections_received</th><td>' + rdata.total_connections_received + '</td><td></td></tr>\
<tr><th>total_commands_processed</th><td>' + rdata.total_commands_processed + '</td><td></td></tr>\
<tr><th>instantaneous_ops_per_sec</th><td>' + rdata.instantaneous_ops_per_sec + '</td><td></td></tr>\
<tr><th>keyspace_hits</th><td>' + rdata.keyspace_hits + '</td><td></td></tr>\
<tr><th>keyspace_misses</th><td>' + rdata.keyspace_misses + '</td><td></td></tr>\
<tr><th>hit</th><td>' + hit + '%</td><td></td></tr>\
<tr><th>latest_fork_usec</th><td>' + rdata.latest_fork_usec + '</td><td> fork() </td></tr>\
<tbody>\
</table></div>'
$(".soft-man-con").html(Con);
},'json');
}
//redis负载状态 end
//memcached负载状态
function MemcachedStatus() {
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
$.get('/ajax?action=GetMemcachedStatus', function(rdata) {
layer.close(loadT);
var rdata = $.parseJSON(data.data);
var Con = '<div class="divtable">\
<table class="table table-hover table-bordered" style="width: 490px;">\
<thead><th>字段</th><th></th><th></th></thead>\
@ -198,17 +26,17 @@ function MemcachedStatus() {
<tr><th>hit</th><td>' + rdata.hit.toFixed(2) + '%</td><td>GET</td></tr>\
<tr><th>curr_items</th><td>' + rdata.curr_items + '</td><td></td></tr>\
<tr><th>evictions</th><td>' + rdata.evictions + '</td><td></td></tr>\
<tr><th>bytes</th><td>' + ToSize(rdata.bytes) + '</td><td>使</td></tr>\
<tr><th>bytes_read</th><td>' + ToSize(rdata.bytes_read) + '</td><td></td></tr>\
<tr><th>bytes_written</th><td>' + ToSize(rdata.bytes_written) + '</td><td></td></tr>\
<tr><th>bytes</th><td>' + toSize(rdata.bytes) + '</td><td>使</td></tr>\
<tr><th>bytes_read</th><td>' + toSize(rdata.bytes_read) + '</td><td></td></tr>\
<tr><th>bytes_written</th><td>' + toSize(rdata.bytes_written) + '</td><td></td></tr>\
<tbody>\
</table></div>'
$(".soft-man-con").html(Con);
});
},'json');
}
//memcached性能调整
function MemcachedCache() {
function memcachedCache() {
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
$.get('/ajax?action=GetMemcachedStatus', function(rdata) {
layer.close(loadT);
@ -224,7 +52,7 @@ function MemcachedCache() {
}
//memcached提交配置
function SetMemcachedConf() {
function setMemcachedConf() {
var data = {
ip: $("input[name='membind']").val(),
port: $("input[name='memport']").val(),

Loading…
Cancel
Save