LinuxIO模型概述
前言
一个socket进程进行一次read可以分成两个阶段,等待数据是否准备好,以及数据从内核copy到用户空间。 我们举个例子,肚子饿了要去小吃街吃拉面,在我们正式开始吃面之前需要1.先等拉面师傅做好面,2.然后把做好的面放到我们的桌子上。
一个socket进程进行一次read可以分成两个阶段,等待数据是否准备好,以及数据从内核copy到用户空间。 我们举个例子,肚子饿了要去小吃街吃拉面,在我们正式开始吃面之前需要1.先等拉面师傅做好面,2.然后把做好的面放到我们的桌子上。
参考了pssh的代码,实现了下面一个小的框架,用于实现并发处理涉及到的IO返回的标准输出和错误输出。IOMap里面保存了所有可读句柄对应的call函数。一旦select返回就read返回然后相应的处理,直接看代码吧。
分布式系统的运行是很复杂的,因为涉及到了网络通信还有节点失效等不可控的情况。下面介绍在最传统的master-workers模型,主要可以会遇到什么问题,传统方法是怎么解决以及怎么用zookeeper解决。
集群当中最重要的是Master,所以一般都会设置一台Master的Backup。
Backup会定期向Master获取Meta信息并且检测Master的存活性,一旦Master挂了,Backup立马启动,接替Master的工作自己成为Master,分布式的情况多种多样,因为涉及到了网络通信的抖动,针对下面的情况:
先看看这个
#!/bin/bash function a() { while read var do echo $var done < 1.txt echo $var } a
在ganglia安装好,呈现web的过程中。
RRDs directory '/var/lib/ganglia/rrds' is not readable
解决方案: 1.chown nobody:nobody -R RRDs /var/lib/ganglia 2.chmod 777 -R /var/lib/ganglia 3.vim /etc/php.ini safe_mode = Off 依次执行上面的,就能解决。
原因:ganglia web使用graph.php来生成rrd图,调用的函数为passthru,而默认的php.ini限制了passthru的执行。 解决方案: vim /etc/php.ini disable_functions = exec,passthru,popen,proc_open 把这个函数去了就行。
比如所有pdf文件都用skim打开,选中文件command+i,然后在跳出来的信息里修改打开文件程序,应用到同类型即可。
写日志模块的时候处理sql语句用了子进程,结果子进程比父进程预先退出了,导致生成了一大堆的僵尸进程。原因我猜想就应该是子进程退出的时候给父进程发送信号,等待父进程进行资源回收。可是父进程没有对该信号做相应的处理导致子进程一直等待,变成了僵尸进程。所以要做的就是在父进程生成子进程之前设置下对于子进程信号的处理,可以忽略。
import signal signal.signal(signal.SIGCHLD,signal.SIG_IGN)
转载请注明出处:http://www.firefoxbug.com/?p=2064
前文描述了Nginx核心模块的加载,对于Nginx模块的加载是根据配置文件读取从而递归加载的。本文以HTTP框架为例,解释Nginx的HTTP模块加载以及下面的子模块如何加载注册。
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;
转载请注明出处:http://www.firefoxbug.com/?p=2030
前文说了Nginx里万物皆模块,今天描述下模块的加载,因为模块的加载是一个递归的过程,所以比较难以理解。
装载请注明出处:http://www.firefoxbug.com/?p=1985
在前面一篇文章 http://www.firefoxbug.com/?p=1861 已经介绍如何把站点缓存分域名存放。相比之前的purge一个个URL刷新,按照域名存放对于站点Cache一键刷新是很方便的。本文会介绍如何通过开发一个Nginx三方模块,一键刷新某个域名站点下缓存。 注意:在使用下面模块之前必须根据前文,站点Cache已经按照目录存储,目录在 /home/cache/下。比如 www.firefoxbug.net 的 Cache 是 /home/cache/www.firefoxbug.net/ ,通过模块能一键清除此目录cache。
针对CDN加速是否对SEO有影响,百度的说法是:
只要对用户友好的,只要对用户有益的。百度都欢迎。
但是技术上是否真的严格做到这一点。不知道。
所以,不用管什么cdn,做好用户体验才是王道。
因为CDN是基于缓存的,所以在使用CDN之后,
第一,CDN对SEO没有影响;
第二,Alexa的流量不代表真实的流量。
对页面访问量不会有坏的影响,你说的访问量大幅下降,
首先,咋们要弄清楚的是CDN与爬虫抓取的原理,
第一:爬虫为什么只抓取网站的一级页面?2级、
第二:网站用了CDN与没有用CDN的对比,
第三:SEO营销,最为注重的就是内容被爬虫快速抓取,
1、使网站访问速度变快
这个是显而易见的。使用了CDN之后,网站的打开速度都很快。
2、收录有问题
当然这个方面是猜测,
1、回源机制
因为CDN服务器定期要发送请求同步更新源服务器上的文件内容。
Linux读写锁比mutex有更高的适用性,可以多个线程同时占用读模式的读写锁,但是只能一个线程占用写模式的读写锁;
1,当读写锁是写加锁状态<时, 在这个锁被解锁之前, 所有试图对这个锁加锁的线程都会被阻塞.
2,当读写锁在读加锁状态时, 所有试图以读模式对它进行加锁的线程都可以得到访问权,但是以写模式对它进行枷锁的线程将阻塞;
3,当读写锁在读模式锁状态时, 如果有另外线程试图以写模式加锁,读写锁通常会阻塞随后的读模式锁请求, 这样可以避免读模式锁长期占用, 而等待的写模式锁请求长期阻塞;
这种锁适用对数据结构进行读的次数比写的次数多的情况下,因为可以进行读锁共享。
日志格式 22/Dec/2012:01:52:30
字符串转化成 unix 时间戳
time.mktime(time.strptime("22/Dec/2012:01:01:01",'%d/%b/%Y:%H:%M:%S')) 1356109261.0
unix 时间戳转化成字符串
x = time.localtime(1356109261.0) time.strftime('%d/%b/%Y:%H:%M:%S',x) '22/Dec/2012:01:01:01'
%a 英文星期简写
%A 英文星期的完全
%b 英文月份的简写
%B 英文月份的完全
%c 显示本地日期时间
%d 日期,取1-31
%H 小时, 0-23
%I 小时, 0-12
%m 月, 01 -12
%M 分钟,1-59
%j 年中当天的天数
%w 显示今天是星期几
%W 第几周
%x 当天日期
%X 本地的当天时间
%y 年份 00-99间
%Y 年份的完整拼写
Nginx作为后起之秀,Lua又号称是最快的脚本,大连回来之后想去看看Nginx+Lua,大概搭建了,但是不怎么会用。下面是搭建的过程,我采用了Openresty,这样方便点。
yum install openssl-devel readline-devel pcre-devel git clone http://luajit.org/git/luajit-2.0.git cd luajit-2.0/ make && make install export LUAJIT_LIB=/usr/local/lib export LUAJIT_INC=/usr/local/include/luajit-2.0 wget http://openresty.org/download/ngx_openresty-1.2.7.8.tar.gz tar -zxvf ngx_openresty-1.2.7.8.tar.gz cd ngx_openresty-1.2.7.8 ./configure --with-luajit gmake && gmake install PATH=/usr/local/openresty/nginx/sbin:$PATH export PATH
之前和杰哥聊天过程中发现了ganglia这个开源的项目,发现还是比较给力的.
* gmond 是一个守护进程,他运行在每一个需要监测的节点上,收集监测统计,发送和接受在同一个组播或单播通道上的统计信息
*如果他是一个发送者(mute=no)他会收集基本指标,比如系统负载(load_one),CPU利用率。他同时也会发送用户通过添加C/Python模块来自定义的指标。
*如果他是一个接收者(deaf=no)他会聚合所有从别的主机上发来的指标,并把它们都保存在内存缓冲区中。
* gmetad 也是一个守护进程,他定期检查gmonds,从那里拉取数据,并将他们的指标存储在RRD存储引擎中。他可以查询多个集群并聚合指标。他也被用于生成用户界面的web前端。
* ganglia-web 顾名思义,他应该安装在有gmetad运行的机器上,以便读取RRD文件。
集群是主机和度量数据的逻辑分组,比如数据库服务器,网页服务器,生产,测试,QA等,他们都是完全分开的,你需要为每个集群运行单独的gmond实例。
一般来说每个集群需要一个接收的gmond,每个网站需要一个gmetad。
我之前在项目中遇到一个很奇怪的问题,对于inotify监视一个文件的时候,发现有些时候inotify有些时候会
“失效”。后来我就没办法,去监视文件所在的目录。看下面的,
[code]
#!/bin/bash
src=/tmp/test/test.txt # directory to monitor
/usr/local/bin/inotifywait -rmq -e modify $src | while read event
do
echo "hello"
done
[/code]
奇怪的现象就是如果我 mv test.txt /tmp/test/test.txt 的时候,发现 inotify 竟然没有触发,但是我无意中
发现 cp test.txt /tmp/test/test.txt 的时候,强制覆盖了,发现 inotity 就触发了。我这两天上OS的时候,突
然间想到了原因。可能是 inode 节点的问题,看下面
内核模块可以用insmod来动态加载,用rmmod来动态卸载.与应用层编程的不同在于,内核模块需要一个
初始化函数和一个清理函数,在向内核加载模块的时候调用初始化函数,卸载模块的时候调用清理函数.与
传统把函数编译进内核相比,通过模块的形式大大提高了开发的效率.
下面是内核版本的Hello World,先看代码
线程互斥锁的设置就是为了多线程之间临界资源更好的共享,加了锁的资源就不能被其他的线程访问,除非
等到占用锁的线程释放该锁。
互斥锁的操作主要包括互斥锁初始化、上锁、判断上锁、解锁、摧毁互斥锁。分别由以下几个函数实现