分类 Linux 下的文章

OpenCDN2.0安装

部署说明

为网站加速,建立私有的CDN节点群,每部署一个CDN节点只需5分钟,无节点数量上限!参考 http://ocdn.me/ 安装需求 OpenCDN的Beta版目前在CentOS5.x - CentOS6.x 下测试通过。内存大小:不低于512M内存。安装前确保主机的80端口不被占用。 注意事项
  • OpenCDN2.0版目前提供了CDN集中管控中心,无需再独立部署管控端,只需部署多个CDN节点,从集中管控中心添加节点即可。
  • 如果节点机房所在地80端口因白名单等原因无法直接通信,请确保节点的 9242 端口放开(IPtables等防火墙),用以CDN管控端的通信。

- 阅读剩余部分 -

crontable shell 脚本

对于要添加单独一项的crontable,可以使用

echo “*/1 * * * *  /home/test.sh” | crontab -

但是之前要是已经有crontab的job就会覆盖了,所以要继续添加一项可以采用下面的方法。

crontab -l > mycron
echo "*/1 * * * *  /home/test.sh"
crontab mycron
rm mycron

Linux下I/O模型介绍

阻塞I/O


阻塞 I/O 模型是最原始的模型,进程一旦执行某个函数调用,进程就进入休眠状态(Sleeping)。比如平时FIFO管道的 read,还有基于TCP的流socket的 read 调用,进程一旦进行系统函数的调用,会从用户态切入内核态,内核会进行系统调用 read ,这时候如果对应的流(管道,socket都算)还没准备写入数据,那么 read 函数就会阻塞,从而导致进程挂起。直到数据来了,内核才会把数据拷贝从内核的缓冲区到进程用户的缓冲区。这时候 read 函数才能返回,进程才能向下走,继续下面的处理。整个过程是串行的,必须一步一步来。

- 阅读剩余部分 -

Python socket tcp

Server

#!/usr/bin/python

'''
	tcp socket server
'''

import sys
import socket

HOST = ''  
PORT = 9243
DATA_BUFFER = 4096

# create a TCP socket
try :
	s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
	print 'Socket created'
except socket.error, msg :
	print 'Failed to create socket. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
	sys.exit()

# Bind socket to local host and port
try:
	s.bind((HOST, PORT))
except socket.error , msg:
	print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
	sys.exit()

s.listen(5)			# allow 5 simultaneous

while True:
	# wait for next client to connect
	connection, address = s.accept()		# connection is a new socket
	while True:
		data = connection.recv(DATA_BUFFER) # receive up to 1K bytes
		if data:
			print data
		else:
			break
	connection.close()						# close socket

Client


#!/usr/bin/python

'''
	tcp socket client
'''

import socket  
  
address = ('223.4.238.138', 9243) 
# create a TCP socket
try :
	s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
	print 'Socket created'
except socket.error, msg :
	print 'Failed to create socket. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
	sys.exit()	

# create a TCP socket
try :
	s.connect(address)
	print 'Connect successfully'
except socket.error, msg :
	print 'Failed to Connect . Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
	sys.exit()

s.send('hello world')  

s.close()  

Python Mysql类

Python支持Mysql的库

# yum -y install  MySQL-python

import MySQLdb

mysql_instance = "";
class MySQLHelper:
	def __init__(self,host,user,password,db_name,charset="utf8"):
		self.host = host
		self.user = user
		self.password = password
		self.db_name = db_name
		self.charset = charset
		try:
			self.conn = MySQLdb.connect(host=self.host,user=self.user,passwd=self.password,db=self.db_name, charset=self.charset)
		except:
			print("Mysql Connect Error ")
			sys.exit(0)

	def update_sql_cmd(self,sql_cmd):
		self.cur = self.conn.cursor()
		try :
			self.cur.execute(sql_cmd)
			self.conn.commit()
			self.cur.close()
			return True
		except Exception, e:
			print "[MYSQL ERROR] : %s"%sql_cmd
			self.cur.close()
			return False

	def run_sql_cmd(self,sql_cmd):
		try :
			self.cur = self.conn.cursor()
			self.cur.execute(sql_cmd)
			res = self.cur.fetchall()
			self.cur.close()
			return res
		except Exception, e:
			print "[MYSQL ERROR] : %s"%sql_cmd
			self.cur.close()
			return False

	def close(self):
		self.conn.close()

def mysql_init():
	'''connect to mysql database opencdn'''
	try:
		global mysql_instance
		mysql_instance = MySQLHelper(mysql_host,mysql_username,mysql_password,mysql_dbname)
	except Exception, e:
		print("Mysql Error %d: %s" % (e.args[0], e.args[1]))
		sys.exit(1)

update_sql_cmd()可以对mysql进行插入操作
run_sql_cmd()可以对mysql查询操作并且返回二元组

python进程池

python自2.6开始提供了多进程模块multiprocessing,进程池使用multiprocessing.pool,pool的构造如下:

```
multiprocessing.Pool([processes[, initializer[, initargs[, maxtasksperchild]]]])
```

* processes: 表示pool中进程的数目,默认地为当前CPU的核数。
* initializer: 表示新进程的初始化函数。
* initargs: 表示新进程的初始化函数的参数。
* maxtasksperchild: 表示每个进程执行task的最大数目

```
apply_async(func[, args[, kwds[, callback]]])
```

主进程循环运行过程中不等待apply_async的返回结果,在主进程结束后,即使子进程还未返回整个程序也会退出。虽然 apply_async是非阻塞的,但其返回结果的get方法却是阻塞的,如使用result.get()会阻塞主进程。
如果我们对返回结果不感兴趣, 那么可以在主进程中使用pool.close与pool.join来防止主进程退出。注意join方法一定要在close或terminate之后调用。

```
#!/usr/bin/python
# -*- coding: UTF-8 -*-

import os
import multiprocessing
import time

def func(msg):
print msg,os.getpid()
time.sleep(1)
return "done" + msg

if __name__ == "__main__":
pool = multiprocessing.Pool(processes=12)
result = []
for i in xrange(10):
msg = "hello %d" %(i)
result.append(pool.apply_async(func, (msg, )))
pool.close()
pool.join()
print "wait"
for res in result:
print res.get()
print "Sub-process done.";
```

python HTTP请求包

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import urllib2
import socket

def send(url,host,body=""):
	socket.setdefaulttimeout(2)
	request = urllib2.Request(url,body)
	request.add_header('User-Agent', 'Firefox')
	request.add_header('Cache-Control', 'no-cache')
	request.add_header('Accept-Charset', 'ISO-8859-1,utf-8;q=0.7,*;q=0.7')
	request.add_header('Referer', "http://www.firefoxbug.com/")
	request.add_header('Keep-Alive',60)
	request.add_header('Connection', 'keep-alive')
	request.add_header('Host',host)
	try:
		response = urllib2.urlopen(request)
		code = response.code
		msg = response.msg
		print "status code %d"%code
		print "message : %s"%msg

		headers = response.headers
		print "\n\n%s"%headers

		data = response.read()
		print "data\n%s"%data
	except Exception,e:
		raise e

send("http://223.4.238.138","www.firefoxbug.net")

是否发送Post包可以通过Body字段是否为空来指定。

socket.setdefaulttimeout()来指定请求超时时间。

日志可视化分析

玩了两个开源的日志可视化分析软件,一个是logstalgia,另一个是maptail

maptail 安装


[code]
# install node
yum install gcc-c++ openssl-devel
wget http://nodejs.org/dist/v0.6.8/node-v0.6.8.tar.gz
tar -xvf node-v0.6.8.tar.gz
cd node-v0.6.8
./configure
make
make install

# install npm
curl https://npmjs.org/install.sh | sh

# install maptail
npm install maptail –g

# usage
# maptail -h 0.0.0.0 -p 8080 nginx_access.log

访问 http://ip:8080

[/code]

- 阅读剩余部分 -

Nginx Cache按域名存放

From http://blog.meiu.cn/nginx-proxy_cache.html

在Nginx或者Tengine默认的cache都是按照一定的hash算法出来的,如果需要擦除某个域名下的全站cache,用purge只能通过遍历所有的url在实现,效率肯定是很低的。那么如果把cache按照域名存放那么清空起来就很快了。

修改 src/http/ngx_http_file_cache.c

在文件头声明函数部分加

- 阅读剩余部分 -

Linux 读写锁

Linux读写锁比mutex有更高的适用性,可以多个线程同时占用读模式的读写锁,但是只能一个线程占用写模式的读写锁;

1,当读写锁是写加锁状态<时, 在这个锁被解锁之前, 所有试图对这个锁加锁的线程都会被阻塞.

2,当读写锁在读加锁状态时, 所有试图以读模式对它进行加锁的线程都可以得到访问权,但是以写模式对它进行枷锁的线程将阻塞;

3,当读写锁在读模式锁状态时, 如果有另外线程试图以写模式加锁,读写锁通常会阻塞随后的读模式锁请求, 这样可以避免读模式锁长期占用, 而等待的写模式锁请求长期阻塞;

这种锁适用对数据结构进行读的次数比写的次数多的情况下,因为可以进行读锁共享。

- 阅读剩余部分 -

python线程池

线程池的概念简单理解就是很多线程的列表,一般线程池和任务队列相结合。一个任务队列是FIFO的,主线程负责所有进程的管理,生成一个子线程(一个子进程或者线程池)对队列进行任务输入,任务的输出端可以是线程池。由主线程进行调度,根据线程ID分配任务。

- 阅读剩余部分 -

Nginx cache 命中率

location  / {
    proxy_redirect          off;
    proxy_set_header        Host            $host;
    proxy_set_header        X-Real-IP       $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_connect_timeout   180;
    proxy_send_timeout      180;
    proxy_read_timeout      180;
    proxy_buffer_size       128k;
    proxy_buffers           4 128k;
    proxy_busy_buffers_size 128k;
    proxy_temp_file_write_size 128k;
    proxy_cache cache;
    proxy_cache_valid 200 304 1h;
    proxy_cache_valid 404 1m;
    proxy_cache_key $uri$is_args$args;
    add_header  Nginx-Cache "$upstream_cache_status";
    proxy_pass http://backend;
}

- 阅读剩余部分 -

Nginx 全站缓存

location / {
        proxy_cache cache_one;
        proxy_cache_valid  200 304 1d; #Cache for 1Days
        proxy_cache_key $host$uri$is_args$args;
        proxy_redirect      off;
        proxy_pass          http://1.1.1.1;
        proxy_set_header Host   $host;
        proxy_set_header    X-Real-IP       $remote_addr;
        proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_ignore_headers Cache-Control;
        proxy_hide_header Cache-Control;
        proxy_ignore_headers Expires;
        proxy_hide_header Expires;
        proxy_hide_header Set-Cookie;
        proxy_ignore_headers Set-Cookie;
}

- 阅读剩余部分 -

base64编码

By firefoxbug

shell base64编码


[root@firefoxbug] str="hello world"

[root@firefoxbug] echo -n "$str" | base64

aGVsbG8gd29ybGQ=

[root@firefoxbug] echo "$str" | base64 注意要加 -n ,不然会有换行,编码就有问题了。

aGVsbG8gd29ybGQK

shell base64解码


-d :decode

[root@firefoxbug]  echo -n "$str" | base64 | base64 -d

hello world

python base64编码


[code]
#!/usr/bin/python
#-*-coding:utf-8-*-

import base64
sour_str = "hello world"
print base64.encodestring(sour_str)
[/code]

python base64解码


[code]
#!/usr/bin/python
#-*-coding:utf-8-*-

import base64
sour_str = "hello world"
decode_str = base64.encodestring(sour_str)
print base64.decodestring(decode_str)
[/code]

shell字符串操作

By firefoxbug
string="abcABC123ABCabc"
字符串长度:

echo ${#string}			#15
echo `expr length $string`	#15

索引


用法:expr index $string $substring

expr index $string "ABC"	#4

提取子串


用法:${string:position}

echo ${string:3}		#ABC123ABCabc

提取指定长度子串
用法:${string:position:length}

echo ${string:3:3}		#ABC

从末尾提取子串
用法:
${string: -length}注意有空格
${string:(-length)}

echo ${string:(-3)}		#abc

子串剔除

从左边开始截吊第一个匹配的$substring
用法:${string#*substring}

echo ${string#*abc}		#ABC123ABCabc
substr="abc";echo ${string#*$substr}	##ABC123ABCabc

从左边开始截吊最后一个匹配的$substring
[php]
echo ${string##*abc} #
[/php]

从右边开始截吊第一个匹配的$substring
用法:${string%substring*}

echo ${string%abc*}		#abcABC123ABC

从右边开始截吊最后一个匹配的$substring

echo ${string%%abc*}		#

子串替换


用$replacement来替换第一个匹配的$substring
用法:${string/substring/replacement}

echo ${string/ABC/XYZ}		#abcXYZ123ABCabc

用$replacement来替换全部匹配的$substring
用法:${string//substring/replacement}

echo ${string//ABC/XYZ}		#abcXYZ123XYZabc

如果$substring匹配$string的开头部分,那么就用$replacement来替换
用法:${string/#substring/replacement}

echo ${string/#abc/xyz}		#xyzABC123ABCabc

如果$substring匹配$string的结尾部分,那么就用$replacement来替换
用法:${string/%substring/replacement}

echo ${string/%abc/xyz}		#abcABC123ABCxyz

fedora install xmind

[php]
wget http://www.xmind.net/xmind/downloads/xmind-linux-3.3.1.201212250029_i386.deb
ar -x xmind-linux-3.3.1.201212250029_i386.deb
tar xvf data.tar.gz
cp -r usr/local/xmind/ /opt/
cp usr/share/mime/packages/xmind.xml /usr/share/mime/packages/
cp usr/share/applications/xmind.desktop /usr/share/applications/
tar -zxvf control.tar.gz
chmod 755 postinst
./postinst
sed -i 's:/usr/local:/opt:g' /usr/share/applications/xmind.desktop
[/php]

Shell 操作fifo

看下面的命令

[root@firefoxbug firefoxbug]# mkfifo /tmp/test.fifo
[root@firefoxbug firefoxbug]# echo "hello" > /tmp/test.fifo

注意:这时候第二条命令就卡住了,阻塞了,原因就是没有读端,只有读端做好读的准备,写端才能写入

(这里默认都是阻塞管道)

[root@firefoxbug firefoxbug]# read a < /tmp/test.fifo

这时候再 echo 就可以成功写入了,读端也可以成功读取。

- 阅读剩余部分 -