当我们确认某vip开放了端口p,但访问时好时坏,你们可能是应为vip后面的部分真实服务器到我们自己的机器没有回包路由,这时的检查办法可以如下:
for i in seq 1 100
;do nmap vip -p port | grep filtered; done
检查100次,应该可以遍历所有的真实服务器了,如果出现filtered; 则基本是有问题的
DevOps
当我们确认某vip开放了端口p,但访问时好时坏,你们可能是应为vip后面的部分真实服务器到我们自己的机器没有回包路由,这时的检查办法可以如下:
for i in seq 1 100
;do nmap vip -p port | grep filtered; done
检查100次,应该可以遍历所有的真实服务器了,如果出现filtered; 则基本是有问题的
我是经常使用nc来查看mc的状态的,突然有一天,我使用nc命令做set操作,发现总是失败;用telnet没有问题,至少应该不是memcached的问题,可能是nc的问题吧。
今天又遇到了这个问题,我使用tcpdump观察使用nc和使用telnet的差别,发现nc发送的回车为\n ,而telnet发送的回车符为\r\n,差异就这么多了,于是使用下列命令测试:
echo -e "set a 0 0 1\r\na\r\nquit\r\n"|nc host port
结果成功
echo -e "set a 0 0 1\na\nquit\n"|nc host port
结果失败
比较久可以知道问题是出现在回车符上了,至于memcached是怎么解释的,有时间在了解一下源码吧
PHP中有些设置是不能修改的,有些设置只能在指定的地方修改,有些设置在任何地方都能修改,原来不能到在哪里控制的,今晚就借着PHP手册到PHP源码里面一探究竟。
手册中提到:
常量 | 值 | 含义 |
---|---|---|
PHP_INI_USER | 1 | 配置选项可在用户的 PHP 脚本或 Windows 注册表中设置 |
PHP_INI_PERDIR | 2 | 配置选项可在 php.ini, .htaccess 或 httpd.conf 中设置 |
PHP_INI_SYSTEM | 4 | 配置选项可在 php.ini or httpd.conf 中设置 |
PHP_INI_ALL | 7 | 配置选项可在各处设置 |
根据这些常量查PHP的源码,发现配置选项在设置的时候都指定了这些常量属性的,要想知道某配置选项是否可以修改,在源码中 grep PHP_INI -R * | grep 该配置选项 就行了。
还了解了几个宏定义,如,初始化配置选项时总是先 PHP_INI_BEGIN() 然后PHP_INI_END() ,这里给出这两个宏的定义:
#define PHP_INI_BEGIN ZEND_INI_BEGIN
#define PHP_INI_END ZEND_INI_END
#define ZEND_INI_BEGIN() static zend_ini_entry ini_entries[] = {
#define ZEND_INI_END() { 0, 0, NULL, 0, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0, 0, NULL } };
所以,初始化配置选项就是按照一定的数据结构写到一个数组里。
对目录做md5,稍加修饰可以比较目录是否完全相同,摘自PHP手册
function MD5_DIR($dir)
{
if (!is_dir($dir))
{
return false;
}
$filemd5s = array();
$d = dir($dir);
while (false !== ($entry = $d->read()))
{
if ($entry != '.' && $entry != '..')
{
if (is_dir($dir.'/'.$entry))
{
$filemd5s[] = MD5_DIR($dir.'/'.$entry);
}
else
{
$filemd5s[] = md5_file($dir.'/'.$entry);
}
}
}
$d->close();
return md5(implode('', $filemd5s));
}
有一种需求:
PHP想完成很多件事情,但是不关心事情的最终结果,本来按理说是完全该用队列来实现的,但是没有发现一个比较合适的队列,于是就想通过一种别的办法来实现;
我想让PHP将需要处理的数据扔给本机的apache,不等待apache完成,直接断开连接,继续做别的事情,这样没有使用队列,但是达到了使用队列的效果。
因为PHP在apache中执行时,如果客户端断开了,则脚本就不再执行了(大概是这么个意思),当然这不是我想要的,又知道函数ignore_user_abort可以来控制,尽管知道是这么个意思,但是还是要测试一下才放心;
测试了一下ignore_user_abort和connection_status 都不像描述的那样。
在研究,另外,不写了
var loadScript = function(src,callback,cache){
var s=document.createElement("script");
s.type="text/javascript";
s[document.all?"onreadystatechange":"onload"] = function(){
if(document.all&&this.readyState!="loaded"&&this.readyState!="complete"){
return;
}
this[document.all?"onreadystatechange":"onload"]=null;
this.parentNode.removeChild(this);
if(callback != undefined) callback();
};
if(!cache) src += (/?/.test(src)?"&":"?") + "_=" + (new Date()).getTime();
s.src = src;
document.getElementsByTagName("head")[0].appendChild(s);
}
注意的问题:
1. Firefox下的onload事件是在正常加载完毕后出发的,如果是404或500等错误,则不会触发onload事件,这时回调函数就没时候执行了。
1. 对于已经运行着的memcached,如果要在里面存放其他的东西,需要注意这item的大小是否和原来存放的item的大小相当,如果不相当,同时memcached的内存已经开辟完了,则无法开辟新的空间给新的item使用,因为开辟出去的内存是不会自动回收的。
2. 尽量不要使用set来删除内容,使用set方法删除的item是不会优先使用的,只有内存都开辟完了才会使用,所以使用set来删除的话,内存开辟的很快的,你将不知道有多少内存是有效利用的
一般情况下我们都是用正则来处理一行字符串,如果要处理多行的字符串怎么办呢?
对于函数:
function a(){
…
}
是一个多行的字符串,要取函数名,怎么写?
方法一:
因为函数名肯定出现在第一行,所以可以通过: /^function +([^(]*)/)[1] 来获取
方法二:
将函数名前面的字符和后面的字符都替换掉:
.replace(/^function +/,"").replace(/\((.|\n)*/m,"");
注意不要写成:
.replace(/^function +/,"").replace(/\([.\n]*/m,"");
因为
1. dot 在 [] 里面是不能表示任意字符的
2. dot 也不包含回车
3. 注意m修改选项
一般情况下我们都用typeof来判断数据类型,但是javascript 中任何一个东西都是对象,如:
var a = new Array();
alert(typeof a); // object
var b = new Date();
alert(typeof b); // object
于是我们就只知道a b都是object,但是不知道这个对象究竟是什么名字,这时候constructor就可以帮助我了:
var a = new Array();
alert(a.constructor); // function Array(){..}
var b = new Date();
alert(b.constructor); // function Date(){..}
比object具体多了,但是表达方式不太友好,用正则替换一下就行了:
var a = new Array();
alert(a.constructor.toString().match(/^function ([^(]*)/)[1]); // Array
var b = new Date();
alert(b.constructor.toString().match(/^function ([^(]*)/)[1]); // Date
1. 最简单的方法
var obj = {};
obj.func1 = function(){alert("func1");};
2.
var Class = {
create: function() {
return function() { this.initialize.apply(this, arguments); }
}
}
// 这是prototype.js里面的类构造方法,使用方法是:
var myClass = Class.create();
// 这样就可以创建一个类了。
// 继续加入:
myClass.prototype = {
x : function () { return 1; },
y : function () { return 2; },
initialize : function () { alert(this.x() + this.y()); }
}
// 那么,你在实例化该类的时候:
var mclass = new myClass();
// 此时会弹出一个对话框,相当于:alert(1 + 2);
3. 定义函数的方式
var mycalss = function(){
// 这里写什么东西在new的时候都会执行,相当于构造函数了
this.method1 = function(){
//…
};
// 或者写一个方法然后调用
this.initailize = function(){…};
this.initailize();
// 或者: this.initailize.apply(this,arguments); 不知道和直接调用有多大差别
};
4.
var myclass = {
method1:function(){…},
method2:function(){…},
property1:"string"
};