用CBrother代替redis做PHP缓存

用CBrother脚本代替redis做PHP缓存


PHP的短板就是无法进行缓存,所有要保存的内容都要写进文件里,之前一直用readis做缓存,但是readis对于PHP来说也是每次建立链接获取数据,而且在数据灵活性比较大的时候,readis用起来总是很麻烦。
我一直想如果php可以提供一种常驻内存进程,自己提供http接口来做数据缓存就好了,身边的同事我建议我去学java,或者python,但是java太庞大,python的语法还适应不了,最后我找到了一种叫CBrother的脚本,它的语法和js非常类似,我几乎没怎么看教程就直接上手了。

1.安装Cbrother

从官网下载最新的包,绿色的免安装,我是在windows上跑的,做缓存需要大内存,我用的64位的。http://www.cbrother.net
在这里插入图片描述
是个zip压缩包,我解压的D盘在这里插入图片描述
具体目录可以去官网看文档,文档全是中文,里面有介绍,我就不多说了。
然后我在D盘创建一个自己的工作目录D:\cachetest,建议不要建到cbrother目录里,这样官方有新版本了直接覆盖就好了,不用挪代码目录。
从官网下载http://www.cbrother.net/down/cbrother.xml,这个是Notepad++的代码变色配置,导入后用Notepad++打开.cb后缀的脚本就会变色了

2.创建CBrother脚本

在这里插入图片描述
创建一个cache.cb的空文件,开始敲代码

import CBHttp.code	//导入Http扩展
import lib/mysqlpool	//导入官方提供的一个mysql链接池

function main(parm)//这个是主函数,程序启动的入口
{
	InitCatch();//初始化数据库,把数据库里的数据都加载进内存
	
	var httpServer = new HttpServer();
	httpServer.setThreadCount(50);
	httpServer.setOutTime(5);
	httpServer.addAction("query.cb",new QueryAction());	//添加一个接口响应,QueryAction我写到下面了
	httpServer.startServer(); //启动服务默认监听8000端口
	
	OpenSaveTime();	//开启一个定时器,定时回写数据
	
	while(1)  //这里我是看官方例子才知道的,主线程不能退出
	{
		Sleep(1000);
	}
}

下面来看下数据库初始化,我这里是建立了一张测试表说明问题,实际应用是多张表的数据组合
在这里插入图片描述

在这里插入图片描述

var g_mysqlpool = null;			//全局变量表示mysql连接池
var g_TestTable = new Map();	//存储表格的map
var g_Lock = new Lock();		//因为是多线程的,所有访问数据要加锁

//先定义一个跟表格相关的类,方便在内存里查询
class TestTableRow
{
	var _id;
	var _type;
	var _auth = new Array();
}

function InitCatch()
{
	g_mysqlpool = new MySQLPool(100,"127.0.0.1",3306,"root","root","test");//创建连接池,这个类的源码在cbrother的lib文件夹里
	
	var mysql = g_mysqlpool.GetFreeMySqlConnect();	//获取一个闲暇链接
	if(mysql == null)
	{
		print "mysql connect err!!";
		return;
	}

	var res = mysql.query("select * from test");//查询数据
	if(!res)
	{
		print "mysql query err!!";
		g_mysqlpool.ReleaseSqlConnect(mysql);//查询出错了要把链接还回去
		return;
	}
	
	//依次获取数据保存在内存中
	while(mysql.next())
	{
		var newRow = new TestTableRow();
		
		newRow._id = mysql.getInt(0);
		newRow._type = mysql.getString(1);
		var auth = mysql.getString(2);	
		newRow._auth = strsplit(auth,",");//这一列按逗号拆开
		
		g_TestTable.add(newRow._id,newRow);//添加进全局的map,初始化阶段是单线程的,所以不用加锁
	}
	
	g_mysqlpool.ReleaseSqlConnect(mysql);//还回去
}

这样我们就把表的数据插入到全局变量g_TestTable中了,后面可以直接访问了,再看看http接口的响应

class QueryAction
{
	function DoAction(request,respon)//听做java的同事说这个接口跟servlet很相似,官方说这个接口是被多线程调用的
	{
		var id = request.getParmInt("id");//获取参数
		var json = new Json();//创建一个json
		
		g_Lock.lock();//加锁
		
		var idRow = g_TestTable.get(id);//查询出来后放进json里
		if(idRow != null)
		{
			json.add("id",idRow._id);
			json.add("type",idRow._type);
			var jsonarray = json.addArray("auth");
			for(var i = 0 ; i < idRow._auth.size() ; i++)
			{
				jsonarray.push(idRow._auth[i]);
			}
		}
		
		g_Lock.unlock();//解锁
		
		respon.write(json.toJsonString());		
		respon.flush();//把数据返回
	}
}

再开看看回写数据的定时器

var g_LastTime = time();	//上次保存时间
var g_thread;	//定时器线程
function SaveTime()
{
	if(time() - g_LastTime > 3600)//相差一个小时了回写数据
	{
		g_LastTime = time();
		g_Lock.lock();
		
		g_TestTable.begin();
		do
		{
			var key = g_TestTable.getKey();
			var idRow = g_TestTable.getValue();
			var auth = "";
			for(var i = 0 ; i < idRow._auth.size() ; i++)		   
			{
				if(i != 0)
				{
					auth += ",";
				}
				auth += idRow._auth[i];
			}

			var sql = "update test set type=" + idRow._type + "," + "auth='" + auth + "' where id=" + idRow._id;
			var mysql = g_mysqlpool.GetFreeMySqlConnect();
			if(mysql != null)
			{
				print sql;
				mysql.upDate(sql);
				g_mysqlpool.ReleaseSqlConnect(mysql);
			}			
		   
		} while(g_TestTable.next());			
		
		g_Lock.unlock();
	}
}

function OpenSaveTime()
{
	g_LastTime = time();	//保存时间先赋值为当前
	
	g_thread = new Thread();	//创建线程
	g_thread.addTimer(1000,SaveTime);//添加一个1秒执行一次的心跳
	g_thread.start();	//开启线程
}

大功告成,我们在浏览器访问http://127.0.0.1:8000/query.cb?id=1
在这里插入图片描述
访问http://127.0.0.1:8000/query.cb?id=2
在这里插入图片描述
访问http://127.0.0.1:8000/query.cb?id=3
在这里插入图片描述
之后你就可以在PHP中调用这些接口了,你还可以根据自己的需求增加一些增删改查的接口,很多逻辑可以在CBrother端直接完成,返回结果,比以前用readis方便多了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值