每天屁颠屁颠的干着琐碎的事
每天和同志们吵着闹着
我们为一个到底谁创造了命名空间(namespace)而争吵不休
我们为了Python为什么推倒重来而面红耳赤
我们为了吃8块的外卖还是10块的而犹豫不决
我们拿着螺丝刀拆了好几个硬盘,盘片最后成了镜子
我错过,没人责备过我
我们都错过,另外一个人替他补上
8个人,是兄弟还是团队?
我们一起喝酒喝到凌晨
我们在最拮据的时候相互援助
我们因为社会原因而逝去的同事而抱头痛哭
我们因拓展而更深的了解彼此
我们相信每个人都是自己的老师
我相信他们都是我的老师
每天我都在开心着、开心着、开心着
每天我都有收获着、收获着、收获着
坚持着,是因为放不下,真的放不下
“薪酬不是第一位,这里给你一次创业的机会”
我信了,于是我坚持了
某一天,有人在QQ上说:再过几天你就9个月了,
而我们在一起加起来还没2个月。
我相信这个世界,我依然相信这个世界。
刚刚过去的一天,是我母亲的生日,她识字不多。
我,
一个当年背着板车拉着西瓜到处叫卖的被人戏称为“黑子”的家伙,这个板车上也曾经卖过甘蔗
一个当年一蛇皮袋一蛇皮袋将三千多斤稻谷从脱粒场扛到家里的家伙,每个来回就有两公里,那我不知道抗了多少个来回,那天晚上,我真的咳出血,很多很多
抗这些稻谷的过程中别人拿着罐头从我面前走过,问我要不要吃,我母亲说,不用了,我们家有西瓜,比这个东西好。那个人走后,我母亲对我说,听着,你的一切在你手上,别人的东西,再好也不要。那个夏天我虚岁16岁。
在别人鄙视的言语中上了最好的高中,然后在嘘声中成绩降到了谷底,再在嫉妒的目光中走进大学,在注视的眼神 中走到社会。
老横在他的博客中说:“因为没几个人相信,你的梦想 ,所有的事,都是你实现了,别人才接受而已”
这些年的经历证明了,老横是对的,真的很对,很对
生日快乐,妈妈,我不会让你失望的。
在绕了N个圈之后我终于找到了会场,看看时间12点48分,按照规定牛人要13点30开始演讲,到了这个时间,我发现只有51.com 的finalbsd同志到场了,主持会议的草上飞(唐川)说嘉宾正在路上,牛人的时间自然贵点,晚点到场也是应该的,于是我安慰了一下自己,牛人于14点左右差不多陆续来了。
FinalBSD同志的“群服务器负载均衡的开源解决方案”讲的很好,个人理解如下:
1、目前最好的负载均衡的硬件设备是F5和Netscaler,两者基本上属于同质品,所以两者是直接竞争者,不过后者可以将TCP的三次握手全部自己搞定,F5是转发到后端,因此Netscaler具有更高的抗DDOS特性。两者拥有太多的相似点,其中之一就是价格,中小互联网企业根本舍不得买,比如BlogBus。
2、F5、Netscaler都能工作在OSI模型的4~7层中。
3、开源软件解决负载均衡中,HaProxy和LVS相对比较优秀,LVS只能工作在4层中,HaProxy能工作在4~7层,并且提供web的状态查询,LVS可以基于命令行进行管理,HaProxy只能通过配置文件实现,HaProxy配置信息子节点可以继承,也可以重新定义,HaProxy能够实现高层应用,也意味着损失一些性能,当然加入实现同样的功能,和LVS差别不大,HaProxy可以很容易实现备份均衡器配置,加入一组负载均衡的机器倒掉之后,HaProxy会自动切换到备份的一组机器上,并且session等信息可以平滑过渡,好处是用户不需要重新登录、购物车不会因切换而被清空等
4、HaProxy实现了负载均衡的ALC控制,减轻后端的集群压力,但是我怀疑这台负载均衡机器的性能是否足够的好,不然会造成单点故障,当然,可以配置多台负载均衡机器
5、HaProxy比LVS更容易实现CDN加速,具体原因没听明白。
接着淘宝来的同志介绍了XEN实现的虚拟化技术,演讲者的名字我也忘了,改日补上。
1、虚拟化主要是指一分多或者多合一,之所以记住这句话,是我的概念中总是以为虚拟化是一分多,可能日常基础的例子都是这样。虚拟主机,VPS等等。
2、虚拟化能够实现快速拷贝环境,配置好一个环境可以复制任意多份运行,前提是物理机器足够的多和强大。
3、虚拟化软件中,Vmware和XEN效率最高,前者是商业软件,后者是免费开源产品。
4、虚拟化并没有在生产环境中得到大规模的应用,目前都是试验性质的,淘宝几乎所有的测试环境都构建于虚拟环境,但生产环境没有例子。
5、虚拟化可以共享存储,真实系统可以读取到虚拟主机中的任意文件,只要设置正确。
第三个是来自这次活动赞助商梭子鱼的经理的演讲,主要是推销梭子鱼的负载均衡设备,号称只有F5三分之一的价格,通过他滔滔不绝的演讲,让我了解(或者叫猜测)到梭子鱼网络均衡设备便宜的原因,实际上梭子鱼就是一个软件集成的厂商,将几个开源软件修改修改,然后丢进一台开起来很山寨的server中,就可以买到F5三分之一的价格,假如这个也叫便宜的话,我觉得F5应该再提价5倍。
第四位依然是51.com的工程师,讲Mysql的灾备体系。
1、灾备体系就是灾难备份体系,也就是在特别紧急情况下的数据恢复问题,比如911事件后,美国摩根斯坦利第二天就能正常运作,这就得意于他们的灾难备份和恢复体系。
2、灾难备份不仅要同地区备份,还要异地备份,最好能定期存入永久存储介质中。
3、备份中需要注意的几个问题是:备份一致性,备份存储,备份对正在运行的业务影响,备份策略等
4、假如11:00发出备份指令,12:00备份完成,如何保证备份时间中的数据一致性问题,主要解决方案如下
a、 使用从库(slave)进行备份,11:00时对从库加锁,然后进行备份,这样做的缺点是,需要增加架设从库的硬件成本,假如有300台主库(master),那么就需要300个从库,当然,可以通过一台机器启动多个从库来减少一部分成本,假如从库压力不大的话。切记要在从库备份前先flush table,不然很多数据还在内存中,无法被备份。
b、直接使用Mysqldump来备份,优点是不会增加太多成本,缺点是一旦启用dump那么数据库将加锁,业务就会被停止,尽管可能停止很短时间
c、使用snapshot(快照)进行备份,此种备份只适合使用InnoDB的存储引擎,因为在备份开始和结束这短时间中,数据库的所有改动操作全部保存在undo log中,备份完成后通过undo log的前滚来保证备份的一致性。
5、在99.9%的情况下Mysql的安全性是可以得到保证的,还有0.1%情况下是不可靠的,比如你正在执行一个删除操作,然后立刻按住CTRL + C中断删除,你会发现一个神奇的事情,你的数据被删了,bin log中却没有任何记录,也就是说,没法恢复了。
6、淘宝现在的所有后台操作只用十几个oracle就搞定了,可见oracle的性能。
7、oracle和Mysql的搭配能显出更高的效率,比如oracle只写,而用Mysql做同步的只读数据。
我感兴趣的内容总结如上,还有其他的演讲者内容就忽略了,抱歉~~
演讲的PPT估计过几天ChinaUnix会挂出来,隔几日再奉上。
CI自带的缓存系统确实很方便,但她存在一个很大的弊端,看缓存系统的源码:
CI把md5(index.php+uri_string)作为缓存文件名(没完全copy,详见libraries/output.php)
这个uri_string允许URI串夹杂垃圾信息,比如:
http://ci-site.com/index.php/index/index/1
http://ci-site.com/index.php/index/index/1/2
http://ci-site.com/index.php/index/index/1/2/3
上面三个请求,CI将生成3个不同的缓存文件
问题来了,假如攻击者写一个并发访问脚本:
每秒并发访问100次(任何adsl用户都有足够带宽发起攻击)
循环访问 index.php/index/index/1 至 index.php/index/index/10000000
那么服务器将生成一千万个首页垃圾缓存,在同一个目录里面!
假如你的网站首页html有10kb(一般来讲,10kb作为首页不算大)
这个缓存目录的尺寸将达到:10kb x 10,000,000 = 100GB
完成攻击所需时间:大约27小时
更重要的是CodeIgniter本身并没有提供更详细的缓存检测机制和缓存容量限制机制,加入你没有对cache目录进行磁盘配额限制的话,那么一轮并发高的缓存攻击将有可能将硬盘塞满,之后网站就会变得异常缓慢。而且更要命的是CodeIgniter本身没有缓存清除机制,只能干等着缓存过期或者手动清除,CodeIgniter最大的优势在于它的性能和学习曲线。
总觉得CodeIgniter本身就是一个半成品,没有缓存清除机制也就算了,还没有模块化缓存(即只缓存页面某个或者某几个部分)的的机制,CodeIgniter这么优秀的Framework在缓存方面算是做得很失败了,不过得益于它优秀的扩展性能,仍然有很多解决方法,况且任何Framework都不是完美的。
解决CodeIgniter大体上有四种方法
1)关闭缓存,我觉得这基本上算不得一种解决方法,因为这牺牲了网站的性能
2)架设缓存服务器,对于一般的中小型网站来说这也比较奢侈,且不说squid或者vanish的学习曲线有点长,也没与服务器设备。
3)增加严格的检测机制,这是一个非常可行的方案,比如对URI每个传入参数的类型进行严格的验证,在一个页面显示前进行详细的处理,比如ID为10000的记录数据库中根本不存在,那么使用show_404()方法输出404页面,这个页面并不会被缓存,假如没有增加这个验证,程序输出的页面将会被缓存,只是页面的某个区域的内容为空而已。比如显示文章的区域是空,侧边栏和头部都是从模板中继承过来了,仍然被缓存了。
4)使用其他cache类替代CodeIgniter的缓存类,比如APC
vmstat查看当前系统运行状态时,不能看出一段时间的趋势,我们常用的流量监控软件Cacti做的非常的棒,事实上也可以通过修改Cacti的脚本监控系统的大部分状态信息,如果你不经常用,只是想分析某段时间的vmstat,或许老外写的这个叫vmplot的脚本比较适合你,如果你没有X11的环境,会有一个这样的提示:set term png small ,因为终端不支持png显示。你有很大的可能会出现如下错误:
gnuplot: unable to open display ”
gnuplot: X11 aborted.
这是因为默认会使用X11环境来显示生成的png图片,事实上终端上是肯定做不到的,我就是这样错误的。如果你使用的是tcsh那么请执行下面语句:
setenv GNUTERM dumb
如果你使用的是bash,那么执行:
export GNUTERM=dumb
关于为什么要执行这样的语句,请看这个帖子肯定比我解释的清楚 ![]()
当然,说这么多,前提是你已经安装了GNUPlot,然后参考手册输出设备上调整你的显示模式,如果你比较讨厌像蝌蚪一样的英文,这里还有中文版本的手册,你可以根据里面的第六章的设备输出来调整显示状态。在执行这个脚本之前,当然要生成一个数据源,类似这样的:
vmstat 1 200 >vmstat.out
1表示间隔时间,200表示总次数,也就是每个1秒取一次样,一共两百次,然后输出的vmstat.out文件中,这个文件名是在脚本中指定的,如果你输出的名字不是这个,你需要修改一下脚本里面的名字。如果你不想改任何东西,那么也可下载我修改过的脚本,虽然显示丑了点,终端环境也就凑合着用吧 ![]()
附上效果图一张(只是分析一个参数的截图,实际上有7个类似的图):

上节我们介绍了mod_wsgi,下面我们讨论怎么在Linux发行版上安装他们。
如果你使用的是Linux操作系统,可以直接从源代码安装。
在Linux上安装可能会遇到的问题,详情请见“安装指导”,如果你喜欢专门为你的Linux发行版准备的包,下面给出详细列表。
Debian 包
可以再这里找到Debian包的详细信息:
http://packages.debian.org/unstable/python/libapache2-mod-wsgi
感谢Bernd Zeimet对这个版本的打包的与编译。
Fedora 包
可以在这里找到Fedora包的详细信息,URL是:
http://download.fedora.redhat.com/pub/epel/5/i386/repoview/mod_wsgi.html
Arch Linux 包
Arch Linux包的详细信息可以在下面链接找到:
http://aur.archlinux.org/packages.php?ID=13394
感谢Nicolas Steinmetz在这个发行版上的与编译与打包
SUSE Linux 包
关于SUSE包的详细信息请点击如下链接:
http://software.opensuse.org/search?q=mod_wsgi
重启Apache服务
当在Linux上使用与编译的Apache时,他们一般将Apache的启动和停止功能纳入服务进行管理。在这
种情况下’apachectl’脚本将不能正常,这需要使用操作系统的具体机制去启动、重启和停止Apache服务。
在这样的操作系统利用’apachectl’重启Apache服务可能会出现如下错误:
httpd (pid 22361?) not running
(98)Address already in use: make_sock: could not bind to address 0.0.0.0:80
no listening sockets available, shutting down
Unable to open logs
不同Linux的服务管理也可能不同,你应该先阅读与编译版Apache的文档或者操作系统本身的手册
还有一种方法是直接使用“init.d”脚本
/etc/init.d/apache2 stop
/etc/init.d/apache2 start
还有一种方法是使用中间管理脚本使用“init.d”脚本
invoke-rc.d apache2 reload
什么是mod_wsgi ?
mod_wsgi的目标是实现一个简单的Apache模块,支持任何Python WSGI的接口的Python应用程序的托管。该模块适用于高性能生产的WEB站点,同时也适用于自己维护站点的WEB 服务托管(虚拟主机环境–译者注)。
运行模式
用mod_wsgi来托管应用,有两个主要的模式可以使用,一种是“嵌入式”模式,Mod_wsgi与Mod_python运行方式相同,所有的python代码都将在apache 子进程中执行。因此当WSGI应用在此模式下运行可以与其他的Apache托管的模块PHP和Perl共享形同进程。
另一个在UNIX Apache 2.*环境下可选替代的daemon模式,这种模式运作的方式在类似的FastCGI / SCGI解决方案,即在不同的进程运行WSGI应用。与FastCGI / SCGI解决方案不同的是,当执行WSGI程序时不需要单独的基础结构(infrastructure),一切都是自动处理的mod_wsgi。
一切都是自动处理的mod_wsgi,影响正常使用的Apache模块的PHP , Perl或其他语言的Apache子进程服务的静态文件和主机应用程序使用大大减少。守护(daemon)进程可能需要时也可以作为一个独特的用户运行以确保WSGI应用程序之间不能互相干扰或获取信息。
服务性能
该mod_wsgi模块是用C代码直接对内部的Apache和Python应用程序接口编程。因此,服务WSGI应用与Apache它具有较低的内存开销和性能优于现有的WSGI适配器mod_python或替代的FastCGI / SCGI / CGI或代理的解决方案。
虽然嵌入式技术模式能够表现得更好, daemon模式通常是最安全的选择使用。这是因为要嵌入模式高性能需要调整apache MPM设置,默认设置偏向于服务静态媒体和PHP应用。如果Apache 的MPM设置未与服务的应用相对应,将会表现出糟糕的性能而不是更好的性能。
因此,除非你非常熟悉Aapache的配置,否则推荐使用daemon模式,总体而言,大型Python Web程序,通常你不能看出嵌入式(embedded mode)和守护模式(daemon mode)明显的差异,因为瓶颈在Python Web和数据库访问上。
支持的应用
mod_wsgi遵循WSGI接口规范,任何符合WSGI接口规范的Python Web框架或者应用都可以被支持。
我们所熟悉的主要的Python web框架或工具,包括CherryPy, Django, Karrigell, Pylons, TurboGears, web.py, Werkzeug 和Zope 运行良好,我们所熟知的主要的Python web应用包括MoinMoin, PyBlosxom 和 Trac 能够很好的运行。
系统要求
mod_wsgi软件包可以编译和使用任何的Apache 1.3 , 2.0或2.2 UNIX系统(包括Linux ) ,以及Windows操作系统。无论是Apache MPM的单线程“prefork” 或者多线程的“worker”只能在unix/linux系统中使用。daemon模式的mod_wsgi仅限于运行于UNIX/LINUX环境的Apache 2.0或2.2上,而且要求Apache的基本运行环境库已经编译并支持多线程。
需要Python 2.3以上版本并且已经编译支持多线程,如果你想尝试Python 3.0,需要从Subversion仓库中下载源代码编译 mod_wsgi。
使用入门
最新的版本,并建议mod_wsgi是2.3
确保您首先阅读“安装与配置”,指南为开发者提供了获得Mod_wsgi 最大产出指导,也可以提供问题调试的协助或者提出问题。
如果你不明白你的应用出了什么问题或者你觉得你发现了Mod_wsgi的问题,你可以在mod_wsgi群组论坛中提出问题
资助
开发开源软件往往被认为吃力不讨好的事情,如果您想展示你对实际上一直在帮助你的软件的赞赏,作为一种反馈,你可以将你成功或失败等要说明的任何问题张贴到用户组中,通过你的反馈,人们才可以知道软件是否正确的工作着,软件或者文档如何改进,以更好的满足你的需要,如果这些听起来非常辛苦,至少在考虑帮助我们提升声望排名。
还请注意,与一些论坛上的传闻相反,这个项目与Google没有任何关系,也没有接受Google(或其他公司)任何形式的资助,唯一与Google有关系的是,该项目托管在代码自由和公开的Google代码托管服务商。这个项目的所有开发花费的都是我个人时间,如果你发现他对你有益,并且希望以更具体的方式捐助,请为我的Amazon上的愿望列表买单或者通过PayPal捐助,如果是作为公司的一笔小的捐款,可以提供报表或者发票用于会计。
祝用得愉快
Graham Dumpleton
很多天没再研究Zend Framework了,趁着还有些闲时间,再次研究一下,Zend Framework学习笔记(一)中大概了解了一下Zend Framework的代码接口分布,《Zend Framework in Action》一书中给出的标准文件夹结构如下图:
个人觉得这个结构只适合很小的项目或者不太复杂的项目,因为zend Library是包含在项目里面与web_root同一级,假如我需要创建一个helloword_2的项目,那么不得不再复制一个同样的文件夹结构,Zend Library将会有两份,如果有十几个或者更多的这样的工程,那么Library将会有很多,Zend Framework是个很活跃的框架,没准哪天就升级了好几个版本,如果你需要升级或者打补丁,那么就会烦死。
当然在application下新建一个modules文件夹,将各个功能放在这里也是一个方法,但是你肯定不想一堆一点关联都没有的项目堆在一起,比如豆瓣的九点和群组,这两个几乎没有任何关联,当然实际应用中还有一个非常重要的用户模块。每个应用只做自己该做的事情,才会最大限度的独立很分散,无论是为了负载均衡进行多点发布还是代码维护都非常有用。而且所有的应用都通过一个入口(web_root中的index.php)和同一个分配器来处理,显然并发能力和容错能力都会下降,稍微有点差错,所有的应用都挂了。入口,分配器等属于全局的东西会影响所有应用,事实上可能很多东西对别的应用毫无用处,但是又有很多应用又需要,这时候就产生了浪费。
不过Zend Framework是个自由度很高的框架,可以自己定义一些东西,让Library从项目中独立出来,与项目目录平级,每个项目拥有自己的独立名称、web_root、入口和分配器,这样做可以为每个项目单独添加Vhost,升级内核(zend Library)也只要升级一个即可,有更高的自由度和松散度。所以我推荐如下的结构:
图中的test是一个项目名,请注意是项目名,不是功能名称,在application中你可以为这个项目建立很多modules,我在图中没有建立这样的文件夹,你可以建立test2,test3……项目,这些项目毫不相关,或者关联度很低,比如用户就得是一个独立的项目,其他的功能可能是一个或者几个独立的项目,事实上还有更好的目录结构,我是从神仙那里学过来的.在controllers文件夹中建立front, backend, amdin,三个文件夹,在view中也建立对应的文件夹,放在front中的内容不做任何限制,backend中需要登录,admin就不用说了,渲染views中对应文件夹的模板,全局进行权限控制,似乎神仙这样的结构不能提供精细访问权限,zend Framework提供了这样的精细权限控制。
如果你的代码要改成左图的结构,需要改动一些代码,首先是需要在入口文件中注册这些目录的位置代码如下:
define('APP_PATH', dirname( dirname ( __FILE__ ) ) ); define('LIB_PATH', dirname( APP_PATH ) . "/library"); date_default_timezone_set('Asia/Shanghai'); //directory setup and class loading set_include_path('.' . PATH_SEPARATOR . LIB_PATH . PATH_SEPARATOR . APP_PATH . '/application/models' . PATH_SEPARATOR . get_include_path()); include "Zend/Loader.php"; Zend_Loader::registerAutoload(); //set up controller $frontController = Zend_Controller_Front::getInstance(); $frontController->throwExceptions(true); $frontController->setControllerDirectory( APP_PATH . '/application/controllers'); Zend_layout::startMvc(array('layoutPath'=>; APP_PATH . '/application/layouts' ) ); //run $frontController->dispatch();
这么一堆代码中其实最主要的就是最开始两句,获取当前项目的磁盘路径和Library,然后告诉程序,在你的action文件你需要一个在渲染模板前告诉程序去哪里取得相应的模板文件,默认是在View/script/中,zend Framework在渲染模板前提供一个抽象方法 postDispatch,可以override之:
function postDispatch() { $this->view->addScriptPath(APP_PATH. '/application/views/'); }
需要改变的代码就这么两处,实际上还可以做得更好点,将这个postDispatch写入helper中,这样就不需要在每个action文件中重复这段代码了
Recent Comments