2013年9月

僵尸进程处理

写日志模块的时候处理sql语句用了子进程,结果子进程比父进程预先退出了,导致生成了一大堆的僵尸进程。原因我猜想就应该是子进程退出的时候给父进程发送信号,等待父进程进行资源回收。可是父进程没有对该信号做相应的处理导致子进程一直等待,变成了僵尸进程。所以要做的就是在父进程生成子进程之前设置下对于子进程信号的处理,可以忽略。

import signal
signal.signal(signal.SIGCHLD,signal.SIG_IGN)

其实现在比较新的内核版本的话可以用wait就解决了。

Nginx Cache中$request_filename

对于Nginx的$request_filename变量指的就是请求的资源路径。在原先OpenCDN节点端配置里面是这样的。

location ~ .*\.(png|html|htm|ico|jpg|jpeg|bmp|gif|js|css)$ {
        ## 忽略浏览器的缓存
        proxy_ignore_headers Cache-Control;
        proxy_ignore_headers Expires;

        proxy_cache cache_one;
        proxy_cache_valid 200 304 1h;

        proxy_cache_key $host$uri$is_args$args;
        expires 1h;
        ## 此处为host锁定,可定制有无
        proxy_set_header        Host    $host;

        add_header OpenCDN-Cache "$upstream_cache_status";

       if (!-f $request_filename) {
                proxy_pass http://ocdn_www.firefoxbug.net;
                break;
        }
}

- 阅读剩余部分 -

Nginx缓存详细配置

Nginx的proxy_cache是有大讲究的。

用proxy_cache来指定cache的名字空间,proxy_cache_path来指定cache的属性。
proxy_cache_path /home/cache levels=1:2 keys_zone=cache_one:200m inactive=1d max_size=10g;
cache的路径是/home/cache,levels是2级目录(名字分别为一个字符和两个字符),名字是cache_one,分配的内存空间是200M,有效期是1天,最大可以存取的磁盘大小是10G,一旦满了就会被移除。

- 阅读剩余部分 -

Nginx和Apache区别

转载请注明出处:http://www.firefoxbug.com/?p=1932

Nginx的高并发得益于其采用了epoll模型,与传统的服务器程序架构不同,epoll是linux内核2.6以后才出现的。下面通过比较Apache和Nginx工作原理来比较。

传统Apache都是多进程或者多线程来工作,假设是多进程工作(prefork),apache会先生成几个进程,类似进程池的工作原理,只不过这里的进程池会随着请求数目的增加而增加。对于每一个连接,apache都是在一个进程内处理完毕。具体是 recv(),以及根据 URI 去进行磁盘I/O来寻找文件,还有 send()都是阻塞的。其实说白了都是 apche 对于套接字的I/O,读或者写,但是读或者写都是阻塞的,阻塞意味着进程就得挂起进入sleep状态,那么一旦连接数很多,Apache必然要生成更多的进程来响应请求,一旦进程多了,CPU对于进程的切换就频繁了,很耗资源和时间,所以就导致apache性能下了,说白了就是处理不过来这么多进程了。其实仔细想想,如果对于进程每个请求都没有阻塞,那么肯定效率会提高很多。

- 阅读剩余部分 -

Python Mysql 连接断开错误代码2006

我本地用Python连接Mysql,可能是由于写得太多,导致Mysql出现2006错误,出现MySQL server has gone away,应该就是Mysql断开的连接。后来发现只要加Mysql的ping功能就行。

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
		self.conn = MySQLdb.connect(host=self.host,user=self.user,passwd=self.password,db=self.db_name, charset=self.charset,cursorclass=MySQLdb.cursors.DictCursor)
                self.conn.ping(True)
	def insert_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
			print "%s"%(str(e))
			self.cur.close()
			return False

	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
			print "%s"%(str(e))
			self.cur.close()
			return False

	def query_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
			print "%s"%(str(e))
			self.cur.close()
			return False

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

Nginx源码分析核心模块加载

装载请注明出处:http://www.firefoxbug.com/?p=2053

之前一篇Nginx源码分析模块加载大概描述了Nginx官方定义的6个核心模块,本文再详细介绍这几类模块的加载。这些核心模块都属于宏NGX_CORE_MODULE,对应的模块上下文配置结构体是 ngx_core_module_t。

typedef struct {
    ngx_str_t             name;                                         //模块名,即ngx_core_module_ctx结构体对象的
    void               *(*create_conf)(ngx_cycle_t *cycle);             //解析配置项,nginx框架会调用create_conf方法
    char               *(*init_conf)(ngx_cycle_t *cycle, void *conf);   //解析配置项完成后,nginx框架会调用init_conf方法
} ngx_core_module_t;

NGX_CORE_MODULE这6类核心模块都用ngx_core_module_t接口定义上下文。

- 阅读剩余部分 -

Nginx代理被墙域名

转载请注明出处:http://www.firefoxbug.com/?p=2042

今天一用户想用OpenCDN使用被墙域名,所谓被墙域名和未备案域名还是有区别的。域名被墙,是指被中国的GFW防火墙屏蔽,使用域名访问时,出现连接重置的情况。我猜想就是GFW把HTTP的URL和Host字段进行过滤,所以某个域名的包都被deny了,但是可以通过Nginx反向代理来解决这个问题。下面大概说明下

www.ooxx.com是被墙域名
源站IP是192.168.1.1(国外)
反代NginxIP是192.168.2.1(国内)

- 阅读剩余部分 -

Nginx源码分析模块指令加载

上文写到了Nginx配置文件读取以及解析,本文介绍模块的指令加载。还是以前文的nginx_move_domain_cache为例

server {
        listen 80;
        server_name www.firefoxbug.net;
        gzip on;
 
        location /mv_cache{
                mv_cache;
        }
        ....
}

上面有一模块mv_cache,这个模块里面的指令是mv_cache,参数是0个。再比如server_name也是一个指令,参数是一个"www.firefoxbug.net"。调用前文的ngx_conf_parse读取配置文件,然后调用handler函数进行解析,对于普通的处理(普通指令),会调用ngx_conf_handler,这里再回顾下模块的指令数组定义结构

- 阅读剩余部分 -