Hot For Coding

Supervisor守护Python进程

使用Python socket + HTML5 WebSocket写一个Web聊天室,上线使用时经常进程经常挂掉,然后手动重启进程,大家重新进入聊天室继续聊。时间长了以后,发现这样不是没有根本解决办法,因为每天聊天室的进程可能会因为各种原因挂掉。

Supervisor

Supervisor的出现,结束了我这苦恼的问题,它可以帮你守护任何进程,守护的意思是如果你的进程死了,会重新帮你起服务,确保你的服务一直可用。当然如果它的进程也挂了就全都over了。实际情况是上线三个多月运行非常好,没有发现服务断过。

CentOS下安装Supervisor

...

READ ALL

用QUnit单元测试开发你的程序

关于单元测试

单元测试是保障程序按照预期逻辑执行的一种测试方式,现在也逐渐被应用到前端项目。我刚开始写JavaScript的时候每次测试都要启动浏览器调用一下需要测试的代码,甚至还需要模拟一些数据来达到效果,最后这些测试的代码片段会被删除。但是bug出现的时候不得不在页面中重新写测试代码,非常费时。

事实上单元测试已经非常的成熟,包括赫赫有名的YUI test,今天我们介绍jQuery团队开发的QUnit单元测试框架,目前jQuery的测试正是使用这个单元测试框架,如果感兴趣可以到github上看看jQuery的test内容

准备

QUnit框架实际上就是一个JavaScript文件还有一个css文件,从官网http://qunitjs.com/下载引用或者直接使用cdn镜像

...

READ ALL

lsof好用的Linux命令

lsof(list open files)是一个列出当前系统打开文件的工具,我通常使用它来查看网络端口占用,因为在Linux下所有事物都是以文件的形式存在。

root@node5:~# lsof | head -10
COMMAND     PID   TID       USER   FD      TYPE             DEVICE   SIZE/OFF       NODE NAME
systemd       1             root  cwd       DIR              254,0       4096          2 /
systemd       1             root  rtd       DIR              254,0       4096          2 /
systemd       1             root  txt       REG              254,0    1120992    2884146 /lib/systemd/systemd
systemd       1             root  mem       REG              254,0      19008    2883683 /lib/x86_64-linux-gnu/libuuid.so.1.3.0
systemd       1             root  mem       REG              254,0      18832    2883613 /lib/x86_64-linux-gnu/libattr.so.1.1.0
systemd       1             root  mem       REG              254,0      79936    2883655 /lib/x86_64-linux-gnu/libgpg-error.so.0.21.0
systemd       1             root  mem       REG              254,0     283464    2883666 /lib/x86_64-linux-gnu/libblkid.so.1.1.0
systemd       1             root  mem       REG              254,0      22944    2883621 /lib/x86_64-linux-gnu/libcap-ng.so.0.0.0
systemd       1             root  mem       REG              254,0      14640    2883595 /lib/x86_64-linux-gnu/libdl-2.24.so

...

READ ALL

Cannot locate header file MagickWand.h

今天编译安装PHP拓展imagick的时候,总是提示:

checking for MagickWand.h header file... configure: error: Cannot locate header file MagickWand.h

跳不过去,缺少头文件

configure: WARNING: You will need re2c 0.13.4 or later if you want to regenerate PHP parsers.
checking for gawk... gawk
checking whether to enable the imagick extension... yes, shared
checking whether to enable the imagick GraphicsMagick backend... no
checking ImageMagick MagickWand API configuration program... found in /usr/local/bin/MagickWand-config
checking if ImageMagick version is at least 6.2.4... found version 6.8.6 Q16 
checking for MagickWand.h header file... configure: error: Cannot locate header file MagickWand.h

...

READ ALL

jQuery Ajax 的同步与异步

默认jQuery所有的Ajax请求默认都是异步处理,即在回调函数里处理返回结果:

$.get('b.txt', function(data){
  console.log(data);
});

执行结果:

full

为了更清楚的知道异步处理特性,改写一下

console.log("开始请求!");
 
$.get('b.txt',function(data){
  console.log("请求结果!");
});
 
console.log("请求之后!");

...

READ ALL

JsDoc生成你的JavaScript文档

这是一个Java写的文档生成工具,注释风格要求跟Java的一样即可生成出注释文档,非常好用。直接到官网下载,网上一大堆教程都是JsDoc2版的,现在官网已经说了不再支持JsDoc2版,推荐使用JsDoc3版本。

Github: https://github.com/jsdoc3/jsdoc

下载后不用安装直接就能用,当然还是要先安装配置好JDK环境,不会的自行找资料。以Win平台做例子,下载过来后解压然后启动命令模式进入程序目录下执行jsdoc即可启动程序,可以直接jsdoc --help查看帮助文档,jsdoc3更直接方便的生成注释文档

...

READ ALL

Linux使用grep命令检索多个文件

Linux中grep是一个常用的搜索命令,今天介绍一下如何使用这个命令在多个文件里检索,用法很简单

grep <searching string> <pattern searching file>

如果我要检索当前所有md文件中的Hello关键字,可以这么用

$ grep Hello *.md
a.md:Hello World!
b.md:Hello, Jac
b.md:Hello, Jim

如果我们想知道是哪一行,可以加-nr属性

grep -nr Hello *.md
a.md:1:Hello World!
b.md:1:Hello, Jac
b.md:2:Hello, Jim

...

READ ALL

jQuery替换标签函数replaceWith()的使用

jQuery中,有一个强大的替换函数replaceWith(),使用非常简单,如:

// 把所有p标签替换为“##”
$('p').replaceWith('##');

利用这个replaceWith,我们可以把所有p标签替换为b标签,内容不变:

$('p').each(function(){
  $(this).replaceWith('<b>'+$(this).html()+'</b>');
});

如果你开发的是一个多语言的网站,甚至可以利用这个特性,比如,在你需要翻译的文字上加上i标签,然后遍历翻译替换。

...

READ ALL

JavaScript深度比较两个对象是否相等

在JavaScript中比较两个对象的成员是否相等有点麻烦,如果只是第一层比较,很容易,但子对象里的属性可能又是一个对象,所以只能递归。

代码:

// 去重
Array.prototype.unique = function () {
  this.sort();
  var re = [this[0]];
  for (var i = 1; i < this.length; i++) {
    if (this[i] !== re[re.length-1]) {
      re.push(this[i]);
    }
  }
  return re;
}

var objectDeepEqual = function(o1, o2) {
  if(typeof o1 != typeof o2){
    return false;
  }

  if(typeof o1.length != typeof o2.length ){
    return false;
  }

  var bool = true;

  var keyArr1 = [];
  var keyArr2 = [];
    
  for (var i in o1) {
    keyArr1.push(i);
  }

  for (var i in o2) {
    keyArr2.push(i);
  }

  if (keyArr1.length != keyArr2.length) {
    return false;
  }

  for(var i = 0, k = keyArr2.length; i < k; i++){
    keyArr1.push(keyArr2[i]);
  }

  var keyArr = keyArr1.unique();

  for(var i=0,k=keyArr.length;i<k;i++){
    if ((keyArr[i] in o1) && (keyArr[i] in o2)) {
      if (typeof o1[keyArr[i]] == 'object' && typeof o2[keyArr[i]] == 'object' ) {
        bool = objectDeepEqual(o1[keyArr[i]], o2[keyArr[i]]);
      } else if (o1[keyArr[i]] !== o2[keyArr[i]]){
        return false;
      }
    }else{
      return false;
    }
  }

  return bool;
};

...

READ ALL

看看这些程序是如何盗取站点数据的

翻了一下Nginx的log,发现这些傻逼天天使用程序不停的想要盗取我站点资料

14.114.23.72 - [23/Jul/2013:16:40:01] "HEAD /wwwroot.rar HTTP/1.1" 405 0 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)"
14.114.23.72 - [23/Jul/2013:16:40:01] "HEAD /wwwroot.zip HTTP/1.1" 405 0 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)"
14.114.23.72 - [23/Jul/2013:16:40:01] "HEAD /www.rar HTTP/1.1" 405 0 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)"
14.114.23.72 - [23/Jul/2013:16:40:02] "HEAD /www.zip HTTP/1.1" 405 0 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)"
14.114.23.72 - [23/Jul/2013:16:40:02] "HEAD /bbs.rar HTTP/1.1" 405 0 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)"
14.114.23.72 - [23/Jul/2013:16:40:02] "HEAD /bbs.zip HTTP/1.1" 405 0 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)"
14.114.23.72 - [23/Jul/2013:16:40:02] "HEAD /web.rar HTTP/1.1" 405 0 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)"
14.114.23.72 - [23/Jul/2013:16:40:02] "HEAD /web.zip HTTP/1.1" 405 0 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)"
14.114.23.72 - [23/Jul/2013:16:40:02] "HEAD /www.qttc.net.rar HTTP/1.1" 405 0 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)"
14.114.23.72 - [23/Jul/2013:16:40:02] "HEAD /www.qttc.net.zip HTTP/1.1" 405 0 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)"
14.114.23.72 - [23/Jul/2013:16:40:02] "HEAD /www_qttc_net.rar HTTP/1.1" 405 0 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)"
14.114.23.72 - [23/Jul/2013:16:40:02] "HEAD /www_qttc_net.zip HTTP/1.1" 405 0 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)"
14.114.23.72 - [23/Jul/2013:16:40:02] "HEAD /wwwqttcnet.rar HTTP/1.1" 405 0 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)"
14.114.23.72 - [23/Jul/2013:16:40:02] "HEAD /wwwqttcnet.zip HTTP/1.1" 405 0 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)"
14.114.23.72 - [23/Jul/2013:16:40:02] "HEAD /qttc.net.rar HTTP/1.1" 405 0 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)"
14.114.23.72 - [23/Jul/2013:16:40:03] "HEAD /qttc.net.zip HTTP/1.1" 405 0 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)"
14.114.23.72 - [23/Jul/2013:16:40:03] "HEAD /qttc.rar HTTP/1.1" 405 0 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)"
14.114.23.72 - [23/Jul/2013:16:40:03] "HEAD /qttc.zip HTTP/1.1" 405 0 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)"

...

READ ALL