MemcachedUI-一款基于.NET MVC编写的Memcached监控软件
一、起源
服务器上使用了Memcached做缓存加速,但是想查看Memcached状态的时候都只能telnet 127.0.0.1 11211 这样来查看,甚是累人,就想能不能做一款web端的软件,方便在PC and 手机上查看,所以就有了这一款软件(属于闲暇时光写的,如有不对,请指正)
二、安装Memcached And 新建Web项目
安装教程略过,因为网上有许多教程,如有不懂请留言问我吧,我电脑上安装了4个Memcached作为测试用
新建一个MVC的项目(其他也行,随自己),并在Nuget上搜索安装包Memcached.ClientLibrary
三、主要代码演示与讲解
首先,我们新建一个类MemcachedHelper
,代码如下
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using Memcached.ClientLibrary;
using Newtonsoft.Json;
namespace MemcachedUI.Web.Models
{
public class MemcachedHelper
{
private MemcachedClient _mc;
public MemcachedHelper(string[] servers)
{
//初始化池
SockIOPool pool = SockIOPool.GetInstance();
pool.SetServers(servers);
pool.InitConnections = 3;
pool.MinConnections = 3;
pool.MaxConnections = 5;
pool.SocketConnectTimeout = 1000;
pool.SocketTimeout = 3000;
pool.MaintenanceSleep = 30;
pool.Failover = true;
pool.Nagle = false;
pool.Initialize();
_mc = new MemcachedClient { EnableCompression = false };
}
/// <summary>获取Memcached的状态
///
/// </summary>
/// <returns></returns>
public Hashtable Stats()
{
return _mc.Stats();
}
/// <summary>获取设置的服务器集群
///
/// </summary>
/// <returns></returns>
public static ServersModel GetServerList()
{
StreamReader sr = System.IO.File.OpenText(System.Web.HttpContext.Current.Server.MapPath("~/Config/Servers.json"));
StringBuilder jsonArrayTextTmp = new StringBuilder();
string input;
while ((input = sr.ReadLine()) != null)
{
jsonArrayTextTmp.Append(input);
}
sr.Close();
ServersModel model = JsonConvert.DeserializeObject<ServersModel>(jsonArrayTextTmp.ToString());
return model;
}
}
}
Memcached的列表放在/Config/Servers.json文件中,这里是我本地的4个Memcached实例
{
"Data": [
{
"ServerName": "本地服务器-1",
"Address": "127.0.0.1:11211"
},
{
"ServerName": "本地服务器-2",
"Address": "127.0.0.1:11212"
},
{
"ServerName": "本地服务器-3",
"Address": "127.0.0.1:11213"
},
{
"ServerName": "本地服务器-4",
"Address": "127.0.0.1:11214"
}
]
}
HomeController主要为展示页面
public ActionResult Index()
{
var model = MemcachedHelper.GetServerList();
string[] servers = model.Data.Select(t => t.Address).ToArray();
ViewBag.ht = new MemcachedHelper(servers).Stats();
ViewBag.ServerList = model;
return View();
}
public ActionResult Node(string server)
{
ViewBag.ht = new MemcachedHelper(new string[] { server }).Stats();
return View();
}
首页集群页面代码如下
@{
ViewBag.Title = "集群视图";
}
@using System.Collections;
@using MemcachedUI.Web.Models
<div class="row">
@{
ServersModel model = ViewBag.ServerList;
Hashtable ht = (Hashtable)ViewBag.ht;
foreach (DictionaryEntry de in ht)
{
Hashtable info = (Hashtable)de.Value;
string servsername = de.Key.ToString();
foreach (var datum in model.Data)
{
if (datum.Address == de.Key.ToString())
{
servsername = datum.ServerName;
continue;
}
}
<div class="col-md-3">
<div class="panel panel-primary">
<div class="panel-heading" onclick="">
@Html.Raw(servsername) 概况
</div>
<div class="panel-body">
<div class="container-fluid">
<div><label>服务器进程ID</label>:@Html.Raw(info["pid"].ToString())</div>
<div><label>服务器运行时间</label>:@Html.Raw(info["uptime"].ToString())</div>
<div><label>服务器当前的UNIX 时间</label>:@Html.Raw(info["time"].ToString())</div>
<div><label>版本号</label>:@Html.Raw(info["version"].ToString())</div>
<div><label>服务器操作系统位数</label>:@Html.Raw(info["pointer_size"].ToString())</div>
<div><label>当前连接数</label>:@Html.Raw(info["curr_connections"].ToString())</div>
<div><label>总连接数</label>:@Html.Raw(info["total_connections"].ToString())</div>
<div><label>获取请求数量</label>:@Html.Raw(info["cmd_get"].ToString())</div>
<div><label>存储请求数量</label>:@Html.Raw(info["cmd_set"].ToString())</div>
<div><label>flush请求的数量</label>:@Html.Raw(info["cmd_flush"].ToString())</div>
<div><label>获取成功的总次数</label>:@Html.Raw(info["get_hits"].ToString())</div>
<div><label>获取失败的总次数</label>:@Html.Raw(info["get_misses"].ToString())</div>
<div><label>删除失败次数</label>:@Html.Raw(info["delete_misses"].ToString())</div>
<div><label>删除命中次数</label>:@Html.Raw(info["delete_hits"].ToString())</div>
<div><label>递增失败次数</label>:@Html.Raw(info["incr_misses"].ToString())</div>
<div><label>递增命中次数</label>:@Html.Raw(info["incr_hits"].ToString())</div>
<div><label>递减命中次数</label>:@Html.Raw(info["decr_misses"].ToString())</div>
<div><label>递减失败次数</label>:@Html.Raw(info["decr_hits"].ToString())</div>
<div><label>Cas 原子设置操作失败次数</label>:@Html.Raw(info["cas_misses"].ToString())</div>
<div><label>Cas 命中次数</label>:@Html.Raw(info["cas_hits"].ToString())</div>
<div><label>Cas 操作找到key, 但是版本过期,没有设置成功</label>:@Html.Raw(info["cas_badval"].ToString())</div>
<div><label>认证次数(包括成功和失败)</label>:@Html.Raw(info["auth_cmds"].ToString())</div>
<div><label>认证失败次数</label>:@Html.Raw(info["auth_errors"].ToString())</div>
<div><label>总共获取的数据量</label>:@Html.Raw(info["bytes_read"].ToString())</div>
<div><label>总写入数量数</label>:@Html.Raw(info["bytes_written"].ToString())</div>
<div><label>总允许写入的数据量</label>:@Html.Raw(info["limit_maxbytes"].ToString())</div>
<div><label>允许的总连接数</label>:@Html.Raw(info["accepting_conns"].ToString())</div>
<div><label>监听失败的次数</label>:@Html.Raw(info["listen_disabled_num"].ToString())</div>
<div><label>需要的工作线程数</label>:@Html.Raw(info["threads"].ToString())</div>
<div><label>conn_yields</label>:@Html.Raw(info["conn_yields"].ToString())</div>
<div><label>已用缓存空间</label>:@Html.Raw(info["bytes"].ToString())</div>
<div><label>当前缓存item数量</label>:@Html.Raw(info["curr_items"].ToString())</div>
<div><label>总的存储缓存item数量</label>:@Html.Raw(info["total_items"].ToString())</div>
<div><label>通过删除item释放内存的次数</label>:@Html.Raw(info["evictions"].ToString())</div>
</div>
</div>
</div>
</div>
}
}
</div>
运行截图
四、后语
本文只是简单的将各个属性代表的意思给读取出来,大家可以根据自己的要求修改,如添加命中率等
闲暇时间写的,如有不对,请指正,谢谢