关注小众语言、AI技术,记录、分享技术点滴!

0%

在国内镜像下载二进制包

1
wget http://www.golangtc.com/static/go/go1.4.2.linux-amd64.tar.gz

直接解压到目标目录即可

1
tar -C /usr/local -zxvf go1.4.2.linux-amd64.tar.gz

把golang的bin目录加入全局环境变量

1
2
3
cat >> /etc/profile << EOF  
export PATH=$PATH:/usr/local/go/bin
EOF

让配置生效

1
source /etc/profile

检查下是否成功

1
go version

在当前用户目录下新建go目录作为项目目录

1
mkdir -p $HOME/go

用cat的方法在尾部增加配置配置golang的 GOROOT GOPATH

1
2
3
4
5
6
cat >> $HOME/.bash_profile << EOF  
export GOROOT=/usr/local/go
export GOPATH=$HOME/go
export GOBIN=$HOME/go/bin
export PATH=$PATH:$GOROOT/bin
EOF

让配置生效

1
source $HOME/.bash_profile

检查下go的env环境变量

1
go env

PIL是python理想的图片处理module,没安装该模块时会提示:ImportError: No module named Image,以下是PIL安装的依赖和步骤

我的环境:CentOS 6.5 / Python2.7

第一步:安装zlib png freetype ** jpeg**

安装zlib:http://zlib.net/zlib-1.2.8.tar.gz

1
2
3
4
5
$ tar -xvzf zlib-1.2.8.tar.gz
$ cd zlib-1.2.8
$ ./configure --prefix=/usr/local
$ make
$ make install

安装png:ftp://ftp.simplesystems.org/pub/libpng/png/src/libpng15/libpng-1.5.23.tar.gz (如果文件不存在就浏览 /src/目录查找一下最新版)

1
2
3
4
5
$ tar -xvzf libpng-1.5.23.tar.gz
$ cd libpng-1.5.23
$ ./configure --prefix=/usr/local
$ make
$ make install

安装freetype:http://nchc.dl.sourceforge.net/project/freetype/freetype2/2.4.7/freetype-2.4.7.tar.gz

1
2
3
4
5
$ tar -xvzf freetype-2.4.7.tar.gz
$ cd freetype-2.4.7/
$ ./configure --prefix=/usr/local
$ make
$ make install

安装jpeg:http://www.ijg.org/files/jpegsrc.v8c.tar.gz

1
2
3
4
5
$ tar -xvzf jpegsrc.v8c.tar.gz
$ cd jpeg-8c/
$ ./configure --prefix=/usr/local
$ make
$ make install

第二步:安装需要的 devel库(该步视情况可忽略)

1
2
3
4
$ yum install libjpeg8-dev
$ yum install libpng12-dev
$ yum install libfreetype6-dev
$ yum install zlib1g-dev

第三步:安装 PIL( Python Imaging Library

安装Image Library:http://effbot.org/downloads/Imaging-1.1.7.tar.gz

1
2
3
4
5
6
7
8
9
10
$ tar -xvzf Imaging-1.1.7.tar.gz
$ cd Imaging-1.1.7/

#修改setup.py文件
vi setup.py

#修改如下:
JPEG_ROOT = "/usr/local/lib"
ZLIB_ROOT = "/usr/local/lib"
FREETYPE_ROOT = "/usr/local/lib"

检查是否支持

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ python setup.py build_ext -i

running build_ext
--------------------------------------------------------------------
PIL 1.1.7 SETUP SUMMARY
--------------------------------------------------------------------
version 1.1.7
platform linux2 2.7.8 (default, Sep 5 2014, 10:24:17)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-4)]
--------------------------------------------------------------------
*** TKINTER support not available
--- JPEG support available
--- ZLIB (PNG/ZIP) support available
--- FREETYPE2 support available
*** LITTLECMS support not available
--------------------------------------------------------------------
To add a missing option, make sure you have the required
library, and set the corresponding ROOT variable in the
setup.py script.

To check the build, run the selftest.py script.

开始安装Image Library

1
2
$ python setup.py build
$ python setup.py install

Python代码验证

1
2
$ python selftest.py
*** The _imaging C module is not installed

ps:
运行python selftest.py提示The _imaging C module is not installed

解决方法,实际根据自己的python PIL路径设置

$ echo ‘/usr/local/lib/python2.7/site-packages/PIL’ >> /etc/ld.so.conf
$ ldconfig

重新python selftest.py,一路安装完成。

nvm与Python的virtualenv和Ruby的rvm类似。
NVM (Node Version Manager,Node多版本管理器)是一个通用的叫法,它目前有许多不同的实现。通常我们说的 nvm 是指 https://github.com/creationix/nvm 或者 https://github.com/visionmedia/n 。这两个工具都是使用shell编写的。

n

安装

如果已经安装了npm的话,可以直接执行命令进行安装n :

1
$ npm install -g n

或者是直接获取源代码安装:

1
2
3
$ git clone https://github.com/visionmedia/n.git
$ cd n
$ make install

使用

直接运行 n 命令查看所有已安装的版本。

1
$ n

运行命令 n 进行安装指定版本的node。 version 可以是 stable(最新稳定版)、latest(最新版)或者具体的版本数字。

1
2
3
4
$ n stable
install : v0.10.24
mkdir : /usr/local/n/versions/0.10.24
fetch : http://nodejs.org/dist/v0.10.24/node-v0.10.24-linux-x64.tar.gz

指定的版本将会安装在 /usr/local/n/versions 目录下。
运行命令 n rm 删除已安装指定版本的node。
运行命令 n use 选择使用指定版本的node。

nvm(推荐使用)

nvm全称Node Version Manager,它与n的实现方式不同,其是通过shell脚本实现的。

安装

安装方式有两种:

1
2
3
4
5
6
7
#增外使用
$ git clone https://github.com/creationix/nvm.git ~/.nvm
$ source ~/.nvm/nvm.sh

#墙内使用
$ curl -fsSL https://gitee.com/sdq/nvm/raw/master/install.sh | bash
$ source ~/.bashrc

或者

1
2
3
4
5
6
7
#增外使用
$ wget -qO- https://raw.githubusercontent.com/creationix/nvm/master/install.sh | sh
$ source ~/.bash_profile

#墙内使用
$ curl -fsSL https://gitee.com/sdq/nvm/raw/master/install.sh | bash
$ source ~/.bashrc

以上脚本会把nvm库clone到~/.nvm,然后会在~/.bash_profile, ~/.zshrc`~/.profile末尾添加source,安装完成之后,你可以用以下命令来安装node

使用

查看已安装的版本:

1
$ nvm ls

查看可以安装的版本:

1
$ nvm ls-remote

安装指定的版本:

1
$ nvm install <version>

指定的版本将会直接安装在 nvm 程序所在的目录下。

删除指定的版本:

1
$ nvm uninstall <version>

使用选定的版本:

1
$ nvm use <version>

Unlike PHP and other more traditional web applications, a Node.js server is just that–the server itself. Which means when we write a web application in Node.js, we’re creating a server application that is loaded into memory, and handles requests from there. If the source files change, the application does not, because it’s already been loaded into memory. In order to update the application with new code, the server has to be restarted.

This becomes a little challenging when the goal is to run a server cleanly with no downtime. If we reboot the Node server, we kill all existing connections, have a period of downtime, and then a fresh instance starts, ready to handle connections. That’s not going to fly in production.

There are ways to prevent this, though. Up, for example, acts as a intermediate between your application and the request, which allows changes to be gracefully reloaded. It’s nice, but a little heavier than I’d like, and doesn’t play nicely with Node clusters. Besides, I thought figuring out how to handle this myself would make a good learning experience.

Fortunately, the cluster module has a disconnect event, which allows us to gracefully end the worker process. It will stop handling new requests, and the process will exit once the current requests are finished. That’s perfect.

Here’s an example of what I cooked up. We’ll start with a separate app.js file; it’s important that the application code and clustering code be separate.

app.js

1
2
3
4
5
6
var http = require("http");
http.createServer(function(req,rep) {
rep.writeHead(200);
rep.write("Hello, world!");
rep.end();
}).listen(8080);

This is our application. It can do whatever we want, but I’m keeping it simple for my testing purposes.

Next, we need a master process to handle the clustering and worker respawns.

runner.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// fork as many times as we have CPUs
var numCPUs = require("os").cpus().length;

for (var i = 0; i < numCPUs; i++) {
cluster.fork();
}

// handle unwanted worker exits
cluster.on("exit", function(worker, code) {
if (code != 0) {
console.log("Worker crashed! Spawning a replacement.");
cluster.fork();
}
});

// I'm using the SIGUSR2 signal to listen for reload requests
// you could, instead, use file watcher logic, or anything else
process.on("SIGUSR2", function() {
console.log("SIGUSR2 received, reloading workers");

// delete the cached module, so we can reload the app
delete require.cache[require.resolve("./app")];

// only reload one worker at a time
// otherwise, we'll have a time when no request handlers are running
var i = 0;
var workers = Object.keys(cluster.workers);
var f = function() {
if (i == workers.length) return;
console.log("Killing " + workers[i]);
cluster.workers[workers[i]].disconnect();
cluster.workers[workers[i]].on("disconnect", function() {
console.log("Shutdown complete");
});
var newWorker = cluster.fork();
newWorker.on("listening", function() {
console.log("Replacement worker online.");
i++;
f();
});
}
f();
});

Make sense? I’ll break it down a little bit. We fork, per the cluster example. In all the non-master threads (the forked children), we load our separate application. Then, if the master process receives a SIGUSR2 signal, we delete the cache of our application module, retrieve a list of active worker ids, and disconnect them one by one. We do this to ensure that there is never a situation where we go below the threshold of optimal worker threads, or worse, reach a point where no workers are running. We then load a replacement worker, and repeat the process until all of the old workers have been told to disconnect.

It’s a little rough, but it works. To test it, I run the application server, and hit it with an apachebench with 100,000 requests at 1000 concurrency to check for failed requests.

Beautiful. I can now integrate this into my post-update git hook for use in deployment.

获得flv视频的缩略图和视频时间长度,php代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
function BigEndian2Int($byte_word, $signed = false) {
$int_value = 0;
$byte_wordlen = strlen($byte_word);
for ($i = 0; $i < $byte_wordlen; $i++) {
$int_value += ord($byte_word{$i}) * pow(256, ($byte_wordlen - 1 - $i));
}
if ($signed) {
$sign_mask_bit = 0x80 << (8 * ($byte_wordlen - 1));
if ($int_value & $sign_mask_bit) {
$int_value = 0 - ($int_value & ($sign_mask_bit - 1));
}
}
return $int_value;
}

//获得视频的数字时间
function getTime($name){
if(!file_exists($name)){
return;
}
$flv_data_length=filesize($name);
$fp = @fopen($name, 'rb');
$flv_header = fread($fp, 5);
fseek($fp, 5, SEEK_SET);
$frame_size_data_length =BigEndian2Int(fread($fp, 4));
$flv_header_frame_length = 9;
if ($frame_size_data_length > $flv_header_frame_length) {
fseek($fp, $frame_size_data_length - $flv_header_frame_length, SEEK_CUR);
}
$duration = 0;
while ((ftell($fp) + 1) < $flv_data_length) {
$this_tag_header = fread($fp, 16);
$data_length = BigEndian2Int(substr($this_tag_header, 5, 3));
$timestamp = BigEndian2Int(substr($this_tag_header, 8, 3));
$next_offset = ftell($fp) - 1 + $data_length;
if ($timestamp > $duration) {
$duration = $timestamp;
}
fseek($fp, $next_offset, SEEK_SET);
}
fclose($fp);
return $duration;
}
//转化为0:03:56的时间格式
function fn($time){
$num = $time;
$sec = intval($num/1000);
$h = intval($sec/3600);
$m = intval(($sec%3600)/60);
$s = intval(($sec%60));
$tm = $h.':'.$m.':'.$s;
return $tm;
}

$t = getTime("22.flv");//显示数字时间如236722
echo fn($t);//显示时间格式0:03:56

许式伟的《go语言编程》,有一个简单的例子,描述go协程和通信通道chan。挺优美的。如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[root@localhost test]$ cat sum.go
package main

import "fmt"

func sum(values []int, myChan chan int) {
sum := 0
for _, value := range values {
sum += value
}
myChan <- sum
}

func main() {
myChan := make(chan int, 2)

values := []int{1, 2, 3, 5, 5, 4}
go sum(values, myChan) //协程1
go sum(values[:3], myChan) //协程2

sum1, sum2 := <-myChan, <-myChan
fmt.Println("Result:", sum1, sum2, sum1+sum2)
}

结果:

1
2
[root@localhost test]$ go run sum.go
Result: 6 20 26

xp sp3系统,当安装SVN客户端时出现问题

当安装 TortoiseSVN 1.8** 版本的时候

出现“无法通过 windows installer 服务安装此安装程序包。您必须安装带有更新版本 Windows Installer 服务的 Windows Service Pack ”提示如何解决?

在网上搜集了好久,有好多人出现了同样的问题,所以记录下来

点击下载: http://www.microsoft.com/zh-cn/download/confirmation.aspx?id=8483

下载补丁 WindowsXP-KB942288-v3-x86.exe , 重启电脑就可以安装了

今天正式的去了理了下zmq这个传说是史上最快的消息队列,之前一直认为是个“服务”程序,是个类似于Socket的一系列接口,他跟Socket的区别是:普通的socket是端到端的(1:1的关系),而ZMQ却是可以N:M 的关系可以任意组合。上一段nodejs中使用zmq的官方例子

1、producer.js

1
2
3
4
5
6
7
8
9
10
11
var zmq = require('zmq')
, sock = zmq.socket('push');</code></code>

sock.bindSync('tcp://127.0.0.1:3000');
console.log('Producer bound to port 3000');

setInterval(function(){
console.log('sending work');
sock.send('some work');
}, 500);
`

2、worker.js

1
2
3
4
5
6
7
8
9
var zmq = require('zmq')
, sock = zmq.socket('pull');</code></code>

sock.connect('tcp://127.0.0.1:3000');
console.log('Worker connected to port 3000');

sock.on('message', function(msg){
console.log('work: %s', msg.toString());
});

这样worker就开始工作了,接收到producer发送的数据

一、所需软件包

1
2
wget https://launchpad.net/libmemcached/1.0/1.0.18/+download/libmemcached-1.0.18.tar.gz  
wget http://pecl.php.net/get/memcached-2.2.0.tgz

二、解压

1
2
tar xzf libmemcached-1.0.18.tar.gz  
tar xzf memcached-2.2.0.tgz

三、GCC升级

1
2
3
yum install gcc44 gcc44-c++ libstdc++44-devel  
export CC=/wp-content/bin/gcc44
export CXX=/wp-content/bin/g++44

提示:yum源更新命令yum update

四、libmemcached安装

1
2
./configure --prefix=/usr/local/libmemcached --with-memcached  
make && make install

五、memcached扩展安装

1
2
3
/usr/local/php/bin/phpize
./configure --with-php-config=/usr/local/php/bin/php-config --with-libmemcached-dir=/usr/local/libmemcached --enable-memcached-sasl
make && make install

安装完成

安装daemonize

1、安装git环境

1
yum install git -y

2、获取daemonize

1
git clone git://github.com/bmc/daemonize.git

3、安装daemonize

1
2
3
cd daemonize  
./configure
make && make install

4、查看是否安装

1
daemonize -v

通过daemonize执行golang守护进程
你需要打包你的golang程序为可执行文件(go build),并通过daemonize来执行它来实现守护进程,如:

1
daemonize -p /var/run/myapp.pid -l /var/lock/subsys/myapp -u nobody /path/to/myapp