LNAMP|LAMP|PHP团队(多人)开发环境搭建配置教程

    经常听到团队的小伙伴说:这个版本的扩展真难找,在本地运行正常的代码,上线之后却运行异常…诸如此类的问题大多是因为系统差异、扩展缺失、版本差异引起的。要解决此类问题搭建一个和线上一致的多人开发环境即可解决。
    思路:搭建一台本地开发服务器,开发服务器和线上服务器环境保持一致,用samba服务映射到本地电脑磁盘,团队中所有人的开发代码都存储在开发机上,所有人的代码都是在开发机器上运行;团队成员无需再单独搭建开发环境,只需要挂载远程目录到本地磁盘,加上DNS解析,开发机上apache根据域名绑定对应的目录即可。
搭建过程:
1.一台PC主机,U盘安装CentOS5.11;
2.安装lamp或lnamp或lnmp环境,网上有很多关于LNAMP或LAMP组合安装的教程(我写过的另一篇博文,有需要的请移步->:LAMP安装手记(CentOS6.4+Apache-2.2.22+Mysql-5.1.63+PHP-5.2.17+phpmyadmin-3.4.10.2+ZendDebug),安装过程不再赘述,本文主要讲如何配置多人开发环境。
3.配置步骤
修改防火墙规则
vi /etc/sysconfig/iptables
添加如下规则
#samba
-A RH-Firewall-1-INPUT -p tcp -m tcp --dport 137 -j ACCEPT
-A RH-Firewall-1-INPUT -p tcp -m tcp --dport 138 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 139 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 445 -j ACCEPT
service iptables restart
4.安装samba
yum install samba system-config-samba samba-client samba-common
编辑samba配置文件
vi /etc/samba/smb.conf
[homes]
        comment = Home Directories
        browseable = no
        writable = yes
        create mode = 0755
        force create mode = 0755
        directory mode = 0755
        force directory mode = 0755
;       valid users = %S
;       valid users = MYDOMAIN\%S
[share]
        workgroup = www
        netbios name = www
        path = /home/share
        browseable = yes
        writeable = yes

service smb restart
[home]目录是每个samba账号对应的个人目录,就是/home下的个人目录,这里也就是每个账号对应的挂载目录;
[share]是共享目录。

简单介绍一下这几个参数的含义:

  • create mode – 这个配置定义新创建文件的属性。Samba在新建文件时,会把dos文件的权限映射成对应的unix权限,在映射后所得的权限,会与这个参数所定义的值进行与操作。然后再和下面的force create mode进行或操作,这样就得到最终linux下的文件权限。
  • force create mode – 见上面的描述。相当于此参数所设置的权限位一定会出现在文件属性中。
  • directory mode – 这个配置与create mode参数类似,只是它是应用在新创建的目录上。Samba在新建目录时,会把dos–>linux映射后的文件属性,与此参数所定义的值相与,再和force directory mode相或,然后按这个值去设置目录属性。
  • force directory mode – 见上面的描述。相当于此参数中所设置的权限位一定会出现在目录的属性中。

说明一点,上面的create mode和create mask参数是同义词,用哪个都可以;而directory mode和directory mask参数是相同的。

创建账号:
useradd zhangsan   
passwd zhangsan
chmod -R 0755 /home/zhangsan
smbpasswd -a zhangsan                         创建samba账号
service smb reload

测试samba 快捷键 windows(开始键)+R 在弹出的框中输入 \\samba服务器地址  然后回车 输入账号密码 如下图所示即为搭建配置成功

映射磁盘驱动器:

映射成功。

5.配置apache

编辑apache配置文件httpd.conf 添加
vi httpd.conf
Include /usr/local/apache/conf/vhost/*.conf
在/usr/local/apache/conf/vhost目录中添加配置文件
vi test.data.house.sina.com.cn.conf 
添加如下内容
<VirtualHost *:88>
        ServerName test.house.sina.com.cn
        #ServerAlias localhost
        DocumentRoot /home/yangyi/test.house.sina.com.cn
        DirectoryIndex index.php index.html index.htm
        <Directory /home/yangyi/test.house.sina.com.cn>
                Options +Includes -Indexes
                AllowOverride All
                Order Deny,Allow
                Allow from All
                php_admin_value open_basedir /home/yangyi/test.house.sina.com.cn:/tmp:/proc
        </Directory>
</VirtualHost>
重启apache
service httpd restart
本地添加DNS解析
192.168.1.110 test.house.sina.com.cn

在映射目录创建文件夹 添加测试文件 如下所示:

test_web_service

搭建配置成功!

参考:

快速配置 Samba 将 Linux 目录映射为 Windows 驱动器,用于跨平台编程

CentOS6.3 Samba安装配置、多用户、加域

Centos搭建Samba

设置Samba服务器中新建文件/目录的权限

附可能遇到的问题及解决办法:

<1>.httpd: Could not reliably determine the server’s fully qualified domain name

    http://blog.csdn.net/aidenliu/article/details/6589040

<2>.防火墙配置

    http://bbs.51cto.com/thread-830123-1.html

<3>.PHP 配置文件中open_basedir选项作用

    http://www.jb51.net/article/19231.htm

<4>.phpnow:open_basedir restriction in effect;file is not within the allowed path

    http://blog.sina.com.cn/s/blog_6328fd3a0100rh5y.html

<5>.PHP 错误日志报告等级

    http://www.cnblogs.com/lost-1987/articles/2982380.html

<6>.PHP Fatal error: require_once(): Failed opening required 

    https://bbs.archlinux.org/viewtopic.php?id=57877 (参考这个解决了问题)

    http://superuser.com/questions/590208/phpmyadmin-symlinks-error-after-ubuntu-upgrade

    http://kb.odin.com/en/6065

未经授权请勿转载:怡然之乐 – FineYi

我们这一代人的困惑–关于梦想、努力与时间价值

    于宙在TEDx上的演讲,关于梦想、努力与时间价值的思考,以下是演讲全文:
 
    很荣幸能够参加本次TEDx大会,非常感谢东北财经大学TED团队和华臣影城为我们提供这样一个交流的机会。
  
    我是大连人,高中就读于大连市二十四中。因为当时学习十分不努力,所以高中毕业之后选择了出国留学,这其实是很多本科出国留学的人不能说的秘密,辗转了几个学校,最终毕业于美国印第安纳大学凯利商学院,主修投资和金融衍生品。上学的时候迷恋炒股,学习依旧散漫,没能成为一个“放弃了华尔街的高薪工作毅然回国”海归精英,真的颇为遗憾,因为实在没有什么华尔街的公司愿意要我。碰巧的是,毕业前两年股市和外汇的行情比较好,赚到了一点点资本,于是我决定回国做点生意。现在在大连从事餐饮行业,目前拥有万达广场的不出二品,大都会,福佳新天地,奥林匹克广场的莉蒂娅城堡4家芝士蛋糕店,青泥洼桥2路车站,长春路百盛,和即将开业的罗斯福地下的乔东家脆皮火烧三家火烧店。
 
    大学毕业之后第一次面对这么多人做演讲,坦率地说,非常的紧张。虽然年轻的时候我曾经畅想过很多次,功成名就之后能像我曾经的那些偶像一样和年轻的朋友们分享一下我是如何从一无所有走上人生巅峰的经验,然后语重心长的告诉大家,人活着不能像一根草而是要像一棵树,能走到金字塔顶端的只有雄鹰和蜗牛两种动物,我的成功你也可以复制等等。可是过了26岁之后我忽然意识到一个严肃的问题,就是自己的一生未必会取得很大的成就啊,所以当TEDx DUFE团队找到我说没关系即便你只是一个开小吃店的,我们也愿意为你提供这样一个和很多人交流思想的机会时,我的心情是多么地激动。因为公司还没上市,所以小草大树,雄鹰蜗牛,睡地板捡易拉罐这样的故事还不到说的时候。今天,只想和大家分享几个困扰了我和我身边的一些朋友十几年的问题,和在经历了一些变故和挫折后,我对这些问题的看法。
 
    努力奋斗真的能实现梦想吗?
 
    大家现在可以想象一下汪峰老师坐在转椅上,深情的望着你对你说,“你的梦想是什么?”周星驰老师的那句“做人如果没有梦想,和咸鱼有什么区别?”据说也激励了几代人。梦想这个东西是如此的重要,简直就是人生的一盏明灯。成功的人们成功的原因各不相同,但他们都不会忘记告诉你,无论到什么时候,都不曾忘记梦想,是他们成功的首要原因。以至于我们这一代人对于人生意义的最通常的理解,就在于坚持梦想并最终实现它。可很少有人愿意面对的一件事情是,大部分人的梦想永远,没错,永远都实现不了。
 
    你没听错,大部分人的梦想永远都实现不了。
 
    先和大家分享一个我之前的梦想。上大学的时候我热衷于各式各样的赌博游戏,是学校旁边赌场的常客。我赌徒生涯的起点源于赌场里最基本游戏轮盘赌,轮盘上1到36个数字和两个0,赔率是1赔36。1到36分为红黑两色,押注红黑的赔率是1赔1。作为一个合格的接受过九年义务教育的人都知道,每一次轮盘开始转动的那一刻,都是一次纯粹的独立随机事件。但是赌博这件事情的魅力就在于,当你真正身处赌场,看到已经连续4次开出红色的时候,几乎所有人都会想把筹码压在黑色的那一面。而我当时的梦想,就是破译这其中的奥秘。我最初的策略非常简单,当连续三次开出奇数,就押注偶数,连续三次红色,就押注黑色。难以置信的事情发生了,在我严格的执行这个策略的情况下,前几次去赌场不但全身而退,每次都还赚了不少,以至于我产生了一种幻觉,也许游戏是有规律可循的,我已经看到了人生巅峰就在不远处向我招手。当然最终的结尾你们一定想到了,在经历过连续18个偶数,连续开出21次黑色后,我把之前赚到的钱都乖乖地还给了赌场。
 
    后来我知道,我那个愚蠢的梦想叫做赌徒谬论,就不具体展开讲了。但它对我意义深刻,我终于明白了在纯粹的随机事件面前,一切规律都是无谓的。
 
    生活中的事情有极个别和轮盘赌一样,属于纯粹的随机事件,比如双色球。可是几乎每一个中了双色球的人都会告诉你啊,他们花了多少精力去钻研往期号码,研究历史规律,付出了多少辛勤的努力最终获得了成功。实际上,即使是纯粹由随机性主导的事情,只要参与的人的基数足够大,小概率事件总会发生。有趣的是,几乎所有在随机事件中的受益者,都会把这完全由运气决定的结果归功于自己的努力上。不仅仅是参与者本身,旁观者也会这么认为。再比如,中国好声音的冠军嘛。
 
    我们生活中遇到的所有事情基本可以分为三类,第一类纯粹由随机性决定,比如布朗运动和轮盘赌博,第二类纯粹由能力决定,比如英语六级考试,110米栏之类。第三类,也是我们最常遇到的,由能力和随机性共同决定,比如创业,投资,恋爱或是梦想。
 
    我对励志大师们总告诉年轻人要不惜一切代价追逐梦想感到深深厌倦的原因就在于,大多数人的梦想虽然不是纯粹的双色球,但也绝对是由随机性主导的。在强大的随机性面前,付出再多辛勤的汗水,就好比夜以继日蹲在轮盘赌旁边渴望参透其中规律。前面说到中国好声音的冠军,张碧晨的那一句you are my destiny,听得我也是醉了。但毕竟那一刻,中国又有多少唱歌唱的和她一样好甚至更好的姑娘,如果真把成为好声音冠军作为一生的梦想,一生中都得在痛苦中度过。我个人很喜欢黄渤,但绝对不会用黄渤作为例子去激励一个我这种长相差的年轻人不惜一切代价去追逐演员梦,注意是不惜一切代价。因为无论是唱歌还是演戏,再多的努力也只能让你变得很优秀,它们并不存在可以量化的评判标准,想成为万众瞩目明星,随机性的重要程度都远远大于实力。
 
    我想,一个人在年轻的时候,做的每一件事情,能清楚的区分其中随机性所占的比例并能心平气和的接受它,在我看来就是最宝贵的财富。
    那么在你的梦想中,运气又扮演了多重要的角色呢?当你深深的感知到这件事情的随机性也许不会青睐与你,是否还愿意坚持下去呢?对我而言,梦想永远是值得执着追求的,但我可以无比心平气和的接受,它就是永远无法实现。
 
    既然连梦都实现不了,还有什么事情值得努力呢?
 
    去年这个时候,我发过一条微博。
 
    这些年我一直提醒自己一件事情,千万不要自己感动自己。大部分人看似的努力,不过是愚蠢导致的。什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了,如果这些东西也值得夸耀,那么富士康流水线上任何一个人都比你努力多了。人难免天生有自怜的情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。
 
    这段话在网上的疯传,是我始料不及的。更出乎我意料之外的是,我在评论中看到了相当一部分的骂声,还有人认真的给我写下了相当深刻的话,“你在拥有自己的光亮时不要吹熄别人的蜡烛,你不能因为你自己的不喜欢就否定别人。”很莫名其妙是吧,即使你刚刚听完我上一段关于随机性的看法,你也会知道,我从来都不觉得努力是一件无所谓的事情。恰恰相反,我一直相信,在能力没达到一定程度之前,你连面对随机性的资格都没有啊。张碧晨能拿好声音冠军自然离不开运气,但换成杨幂,评委不但不会转身可能直接撒腿就跑了。
 
     可现在问题来了,那究竟什么才算是有价值的努力?这可以从我那条微博说起。去年这个时候我和朋友在琢磨去大庆做点服装生意,决定去考察几个商场。我当时住在北京,因为之前晚上和朋友在外面玩的比较尽兴回到家里已经比较晚了,担心睡觉睡过头会错过航班,那晚上就直接在沙发上靠了一晚。那是我第一次去哈尔滨,十一月份已经很冷了,衣服拿的不足,下了飞机冻得头疼。又因为没有提前订票,到了哈尔滨之后才买的火车票,发现就只剩站票了。于是,当我一晚上没睡,冻得头晕眼花,又在绿皮火车上站了两个多小时之后,抵达大庆的那一瞬间我觉得自己实在是太不容易了,将来必须要写进回忆录里面。可是,回头仔细一想,这些所谓的“努力”对我最终把那个服装生意做好,没有半毛钱关系。更何况,如果我前一天晚上能早点上床睡觉,多准备点衣服,提前在网上把火车票订好,完全可以舒舒服服的达到同样的目的。‍我的那次经历像是自己二十多年生活中很多事情的缩影,沉溺在对结果没有直接帮助只是因为自己遭受了一些痛苦的行为中,误以为那就是努力。
 
    当我终于意识到我并不是唯一曾经把无意义的消耗当作努力的时候,忽然发现,原来生活中我觉得很努力的人,也许没那么勤奋,如果在正确的方向上坚持行动,超过他们也并不困难。
 
    因为我们这一代人对于勤奋和努力的理解,几乎清一色的来自于学校,更精确的说,在前二十多年的生活中,我们眼中最努力的人,就是那些最能拼命看书和做题的人。实际上,这种理解是极其片面而幼稚的,因为看书和做题本身,都是为了一个极其鲜明的目的而存在的,就是通过考试。这种勤奋的付出极其纯粹,更多的复习时间,更高的复习强度,一般而言,都可以直接的提高考试的分数,它们之间的联系鲜明而直接,每个人都看的懂。‍
 
    但生活的美妙之处却在于,很多事情在我们没做到一定程度之前,是完全没法理解的。
 
    这就好比学英语,十几年漫长的岁月里我都在幻想,要通过多么复杂的流程,多么精密的设计,多么全面的涉及和多么不可思议的努力,终于有那么一天,或许就我就能因为前期的那些无懈可击的学习,说一口比较流利的英语,像说中文一样,可以边说边想,而不是说每一句话之前设计它的句式时态词汇然后在心里复述几遍再看上去流利的背诵出来。谁不是这么设想的呢?可惜,它不仅从来没有实现,并且让我看不到有任何实现的趋势,对于每一个设立目标的人来说,没有比这更痛苦的感受。
 
    但是在去了美国两年左右的时间之后,我忽然发现自己可以已经毫无障碍的说一口流利的英语了。这并非我采用了什么新的学习方法,而是因为去了印第安纳之后身边中国人很少,在没有选择的情况下,只能被迫用英语去交流和表达,在这个过程中我并没有认真想过自己每天进步了多少,也没有阶段性的检验学习效果,只是不停的去听和说,因为没有选择嘛。直到两年多后的忽然有一天我才意识到,咦,自己好像真的已经可以了。但是我确实无法总结出来是如何一步一步做到的,只是那两年的时间,我一直都在很不情愿地用英语去生活嘛。
 
    一个人能获得的最可贵的能力,都和掌握一门语言一样,你所付出的努力不是能够获得即时回馈的,甚至在很长的一段时间内没有任何收获,直到积累到了一定的阶段后,忽然爆发出惊人的力量,连你自己都不清楚这一切是如何发生的。比如锻炼身体,读书写作,或者是做生意。当你经历了足够的量变终于引起质变时拥有的技能,大部分人是终身难以企及的,不是因为他们太笨,恰恰相反,因为他们都太聪明了。
 
    触发人类行动的最基本原理被称为反射,我们是需要即时回馈的物种。所以绝大多数人对于世界的理解度是线性的,但更多情况下,事物却是以漫长的潜伏震荡后爆发突破的形式发展的。我现在时常觉得,人在少年时期更容易掌握语言,乐器,美术这些成年后很难学的技艺,并非那小时候就是天资聪颖,而是小孩子很少会一个星期质疑一次自己收获了多少,都是闷头一练就是好几年,直到学会了才知道哦自己已经会了。只有聪明的成年人,才相信1本书读懂易经,10句话揭秘马云的成功之道,30天成为吉他高手的故事。
    简而言之,现实生活中,付出和结果之间往往没有那么立竿见影。在离开学校之后,当我们遇到的很多事情不再像做题和考试之间联系的那么紧密的时候,很多人的付出都是浅尝辄止的。而最可贵的努力,是选择一个正确的方向,那些无法立即获得回报的事情,依然能付出十年如一日的专注和热情,最终的结果也许不足以让你独孤求败,但足以出类拔萃.
 
    人这一生中是否有一个节点,过了之后一切都会好起来?
 
    前面说了这么多,谈论的都与目标和实现目标有关。仔细想想,我们的一生好像都是在实现目标中挣扎着度过的。上初中的时候,老师告诉你,中考的淘汰率是最高的,只要闯过去,上了高中一切就好了。但上了高中的时候发现不是那么回事嘛,高中老师又说了啊,考上大学就进了天堂。于是你考上了大学,依然空虚迷茫各种草样年华,父母老师又告诉你,找到工作就好了。工作之后发现烦恼和忧虑依然都在,女朋友给你看马云的故事,告诉你等你事业有成就好了……
 
    你发现了吗,其实人这一辈子的每一个阶段都有新的痛苦和顾虑,周而复始,生生不息。绝对不会因为你考上大学,事业有成,迎娶了女神就从此happily ever after。但每一个阶段也有每一个阶段的快乐,无法替代。生活不是安徒生童话也不是好莱坞电影,从出生的那一刻起直到生命的尽头,都不存在什么节点,过去了之后一切幸福美满无忧无虑。
 
    每一段岁月都有它存在的价值,没有高低贵贱之分,都不应该被辜负。而我能想到的人这一生能做的最愚蠢的事情,就是把全部人生的希望都孤注一掷到未来的某个节点上,而忽略了生活本身应有的乐趣。哪怕你以后真正实现了那个执念中的目标,才会发现它远远没你想的那么美好。
 
    年轻的时候和哥们在操场上打篮球喝可乐的快乐,是以后高尔夫会球所品里红酒替代不了的。尤其男生,千万不要总想着等将来老子有钱了如何如何,且不说你以后很可能不会太有钱,而且相信我,就是有钱了也真的不能怎么样。生命就在每天的生活里,一切执念都是虚妄,和身边的人愉快相处,认真安排好每一天的活动,用心去感受每一天的心境,就是生活的意义本身。这其实是我今天最想分享给你们的事情。

 

修改tomcat中JVM非堆内存默认配置解决内存溢出

 

系统CentOS6.4下yum安装了tomcat6和jdk1.6,安装配置过程如下:
tomcat中部署两个项目A、B,同时部署时报内存溢出错误,系统CPU负载飙升,而单独部署A、B 和 只部署多个A或者只部署多个B项目系统运行正常。
查看日志报错:OutOfMemoryError: PermGen space….   
查询资料得知:是非堆溢出(永久保存区域溢出)
这种错误常见在web服务器对JSP进行pre compile的时候。如果你的WEB APP下都用了大量的第三方jar, 其大小超过了jvm默认的大小(4M)那么就会产生此错误信息了。如果web app用了大量的第三方jar或者应用有太多的class文件而恰好MaxPermSize设置较小,超出了也会导致这块内存的占用过多造成溢出,或者tomcat热部署时侯不会清理前面加载的环境,只会将context更改为新部署的,非堆存的内容就会越来越多。
解决办法:修改JVM非堆内存默认大小
网上提供的方法是:
修改tomcat是bin目录下的catalina.sh文件中的配置,但是yum安装的tomcat此文件的内容为空,将配置项 JAVA_OPTS=” -XX:PermSize=512M -XX:MaxPermSize=1024m” 加进 catalina.sh文件,重启tomcat,无效。
搜索JAVA_OPTS字符串找到tomcat的配置文件位置
find  /etc  |xargs grep “JAVA_OPTS”
[root@AY14070314494954704eZ tomcat6]# find /etc |xargs grep "JAVA_OPTS" 
/etc/tomcat6/tomcat6.conf:#JAVA_OPTS="-Xminf0.1 -Xmaxf0.3" 
/etc/tomcat6/tomcat6.conf:# Use JAVA_OPTS to set java.library.path for libtcnative.so 
/etc/tomcat6/tomcat6.conf:#JAVA_OPTS="-Djava.library.path=/usr/lib" 
/etc/tomcat6/tomcat6.conf:JAVA_OPTS="${JAVA_OPTS} -Djavax.sql.DataSource.Factory=org.apache.commons.dbcp.BasicDataSourceFactory"
在/etc/tomcat6/tomcat6.conf文件中加入
JAVA_OPTS=" -XX:PermSize=512M -XX:MaxPermSize=1024m"
重启tomcat 项目运行正常。
PS:具体设置大小可以根据物理内存和项目实际运行需求进行调整。
yum安装tomcat的默认路径:/usr/share/tomcat6/
其它相关路径如下:(供参考)
clipboard

…………………………………………………………………………………………..

Tomcat中JAVA JVM内存溢出及合理配置

Tomcat本身不能直接在计算机上运行,需要依赖于硬件基础之上的操作系统和一个Java虚拟机。Tomcat的内存溢出本质就是JVM内存溢出,所以在本文开始时,应该先对Java JVM有关内存方面的知识进行详细介绍。

一、Java JVM内存介绍

JVM管理两种类型的内存,堆和非堆。按照官方的说法:“Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配。堆是在 Java 虚拟机启动时创建的。”“在JVM中堆之外的内存称为非堆内存(Non-heap memory)”。简单来说堆就是Java代码可及的内存,是留给开发人员使用的;非堆就是JVM留给自己用的,所以方法区、JVM内部处理或优化所需的内存(如JIT编译后的代码缓存)、每个类结构(如运行时常数池、字段和方法数据)以及方法和构造方法的代码都在非堆内存中,它和堆不同,运行期内GC不会释放其空间。

(1). 堆内存分配
JVM初始分配的内存由-Xms指定,默认是物理内存的1/64;JVM最大分配的内存由-Xmx指 定,默认是物理内存的1/4。默认空余堆内存小于 40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制。因此服务器一般设置-Xms、 -Xmx相等以避免在每次GC 后调整堆的大小。可以利用JVM提供的-Xmn -Xms -Xmx等选项可进行堆内存设置,一般的要将-Xms和-Xmx选项设置为相同,而-Xmn为1/4的-Xmx值,建议堆的最大值设置为可用内存的最大值的80%。

初始化堆的大小是JVM在启动时向系统申请的内存的大小。一般而言,这个参数不重要。但是有的应用程序在大负载的情况下会急剧地占用更多的内存,此时这个参数就是显得非常重要,如果JVM启动时设置使用的内存比较小而在这种情况下有许多对象进行初始化,JVM就必须重复地增加内存来满足使用。由于这种原因,我们一般把-Xms和-Xmx设为一样大,而堆的最大值受限于系统使用的物理内存。一般使用数据量较大的应用程序会使用持久对象,内存使用有可能迅速地增长。当应用程序需要的内存超出堆的最大值时JVM就会提示内存溢出,并且导致应用服务崩溃。所以,如果Xms超过了Xmx值,或者堆最大值和非堆最大值的总和超过了物理内存或者操作系统的最大限制都会引起服务器启动不起来。

(2). 非堆内存分配
也叫永久保存的区域,用于存放Class和Meta信息,Class在被Load的时候被放入该区域。它和存放类实例(Instance)的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理。JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。 GC不会对PermGen space进行清理,所以如果你的APP会LOAD很多CLASS的话,就很可能出现PermGen space错误。

(3). JVM内存限制(最大值)
首先JVM内存限制于实际的最大物理内存(废话!,呵呵),假设物理内存无限大的话,JVM内存的最大值跟操作系统有很大的关系。简单的说就32位处理器虽然可控内存空间有4GB,但是具体的操作系统会给一个限制,这个限制一般是2GB-3GB(一般来说Windows系统下为1.5G-2G,Linux系统 下为2G-3G),而64bit以上的处理器就不会有限制了。

二、三种内存溢出异常介绍

1. OutOfMemoryError: Java heap space  堆溢出

内存溢出主要存在问题就是出现在这个情况中。当在JVM中如果98%的时间是用于GC且可用的 Heap size 不足2%的时候将抛出此异常信息。

 2. OutOfMemoryError: PermGen space   非堆溢出(永久保存区域溢出)

这种错误常见在web服务器对JSP进行pre compile的时候。如果你的WEB APP下都用了大量的第三方jar, 其大小超过了jvm默认的大小(4M)那么就会产生此错误信息了。如果web app用了大量的第三方jar或者应用有太多的class文件而恰好MaxPermSize设置较小,超出了也会导致这块内存的占用过多造成溢出,或者tomcat热部署时侯不会清理前面加载的环境,只会将context更改为新部署的,非堆存的内容就会越来越多。

3. OutOfMemoryError: unable to create new native thread.   无法创建新的线程

这种现象比较少见,也比较奇怪,主要是和jvm与系统内存的比例有关。这种怪事是因为JVM已经被系统分配了大量的内存(比如1.5G),并且它至少要占用可用内存的一半。

三、Java JVM内存配置

1. JVM内存分配设置的参数有四个

-Xmx    Java Heap最大值,默认值为物理内存的1/4;

-Xms    Java Heap初始值,Server端JVM最好将-Xms和-Xmx设为相同值,开发测试机JVM可以保留默认值;

-Xmn    Java Heap Young区大小,不熟悉最好保留默认值;

-Xss      每个线程的Stack大小,不熟悉最好保留默认值;

-XX:PermSize:设定内存的永久保存区域;

-XX:MaxPermSize:设定最大内存的永久保存区域;

-XX:PermSize:设定内存的永久保存区域;

-XX:NewSize:设置JVM堆的‘新生代’的默认大小;

-XX:MaxNewSize:设置JVM堆的‘新生代’的最大大小;

2. 如何设置JVM的内存分配

(1)当在命令提示符下启动并使用JVM时(只对当前运行的类Test生效):

java -Xmx128m -Xms64m -Xmn32m -Xss16m Test

(2)当在集成开发环境下(如eclipse)启动并使用JVM时:

a. 在eclipse根目录下打开eclipse.ini,默认内容为(这里设置的是运行当前开发工具的JVM内存分配):  -vmargs -Xms40m -Xmx256m -vmargs表示以下为虚拟机设置参数,可修改其中的参数值,也可添加-Xmn,-Xss,另外,eclipse.ini内还可以设置非   堆内存,如:-XX:PermSize=56m,-XX:MaxPermSize=128m。

b. 打开eclipse-窗口-首选项-Java-已安装的JRE(对在当前开发环境中运行的java程序皆生效)  编辑当前使用的JRE,在缺省VM参数中输入:-Xmx128m -Xms64m -Xmn32m –Xss16m。

c. 打开eclipse-运行-运行-Java应用程序(只对所设置的java类生效)  选定需设置内存分配的类-自变量,在VM自变量中输入:-Xmx128m -Xms64m -Xmn32m -Xss16m  注:如果在同一开发环境中同时进行了b和c设置,则b设置生效,c设置无效,如:  开发环境的设置为:-Xmx256m,而类Test的设置为:-Xmx128m -Xms64m,则运行Test时生效的设置为:  -Xmx256m -Xms64m。

(3)当在服务器环境下(如Tomcat)启动并使用JVM时(对当前服务器环境下所以Java程序生效):

a. 设置环境变量:  变量名:CATALINA_OPTS  变量值:-Xmx128m -Xms64m -Xmn32m -Xss16m。

b. 打开Tomcat根目录下的bin文件夹,编辑catalina.bat,将其中的%CATALINA_OPTS%(共有四处)替换为:-Xmx128m -Xms64m -Xmn32m -Xss16m。

c. 若没有catalina.bat,只有tomcat.exe,tomcat6w.exe;则可以在启动tomcat6w.exe 后 右键配置–Java–java option 下面输入:

-Xmx256m –Xms64m

也可以找到注册表HKEY_LOCAL_MACHINE\SOFTWARE\Apache Software Foundation\TomcatService Manager\Tomcat6\Parameters\JavaOptions原值为 -Dcatalina.home=”C:\ApacheGroup\Tomcat 6.0″ -Djava.endorsed.dirs=”C:\ApacheGroup\Tomcat 6.0\common\endorsed” -Xrs 加入  -Xms300m  -Xmx350m  (我的是加入-Xmx350m,tomcat才能启动,加入-Xms300m  -Xmx350m反而tomcat都不能启动)重起tomcat服务,设置生效。

3. 查看JVM内存信息

Runtime.getRuntime().maxMemory(); //最大可用内存,对应-Xmx 

Runtime.getRuntime().freeMemory(); //当前JVM空闲内存 

Runtime.getRuntime().totalMemory(); //当前JVM占用的内存总数,其值相当于当前JVM已使用的内存及freeMemory()的总和 

关于maxMemory(),freeMemory()和totalMemory():maxMemory()为JVM的最大可用内存,可通过-Xmx设置,默认值为物理内存的1/4,设置不能高于计算机物理内存;  totalMemory()为当前JVM占用的内存总数,其值相当于当前JVM已使用的内存及freeMemory()的总和,会随着JVM使用内存的增加而增加;  freeMemory()为当前JVM空闲内存,因为JVM只有在需要内存时才占用物理内存使用,所以freeMemory()的值一般情况下都很小,而JVM实际可用内存并不等于freeMemory(),而应该等于maxMemory()-totalMemory()+freeMemory()。

4. 实例,以下给出1G内存环境下java jvm 的参数设置参考

JAVA_OPTS=”-server -Xms800m -Xmx800m -XX:PermSize=64M -XX:MaxNewSize=256m -XX:MaxPermSize=128m -Djava.awt.headless=true “

大型的web工程,用tomcat默认分配的内存空间无法启动,如果不是在myeclipse中启动tomcat可以对tomcat这样设置:

TOMCAT_HOME\bin\catalina.bat 中添加这样一句话:

set JAVA_OPTS= -Xmx1024M -Xms512M -XX:MaxPermSize=256m

如果要在myeclipse中启动,上述的修改就不起作用了,可如下设置:

Myeclipse->preferences->myeclipse->servers->tomcat->tomcat×.×->JDK面板中的

Optional Java VM arguments中添加:-Xmx1024M -Xms512M -XX:MaxPermSize=256m

对于单独的.class,可以用下面的方法对Test运行时的jvm内存进行设置。 java -Xms64m -Xmx256m Test -Xms是设置内存初始化的大小 -Xmx是设置最大能够使用内存的大小。

四、JVM内存配置与GC

需要考虑的是Java提供的垃圾回收机制。JVM的堆大小决定了JVM花费在收集垃圾上的时间和频度。收集垃圾可以接受的速度与应用有关,应该通过分析实际的垃圾收集的时间和频率来调整。如果堆的大小很大,那么完全垃圾收集就会很慢,但是频度会降低。如果你把堆的大小和内存的需要一致,完全收集就很快,但是会更加频繁。调整堆大小的的目的是最小化垃圾收集的时间,以在特定的时间内最大化处理客户的请求。在基准测试的时候,为保证最好的性能,要把堆的大小设大,保证垃圾收集不在整个基准测试的过程中出现。如果系统花费很多的时间收集垃圾,请减小堆大小。一次完全的垃圾收集应该不超过 3-5 秒。如果垃圾收集成为瓶颈,那么需要指定堆的大小,检查垃圾收集的详细输出,研究垃圾收集参数对性能的影响。一般说来,你应该使用物理内存的 80% 作为堆大小。当增加处理器时,记得增加内存,因为分配可以并行进行,而垃圾收集不是并行的。

Java Heap分为3个区:

1.Young 2.Old 3.Permanent。Young保存刚实例化的对象。当该区被填满时,GC会将对象移到Old区。Permanent区则负责保存反射对象,本文不讨论该区。

JVM有2个GC线程:
第一个线程负责回收Heap的Young区;
第二个线程在Heap不足时,遍历Heap,将Young 区升级为Older区,Older区的大小等于-Xmx减去-Xmn,不能将-Xms的值设的过大,因为第二个线程被迫运行会降低JVM的性能。

为什么一些程序频繁发生GC?有如下原因:
1. 程序内调用了System.gc()或Runtime.gc()。
2. 一些中间件软件调用自己的GC方法,此时需要设置参数禁止这些GC。
3. Java的Heap太小,一般默认的Heap值都很小。
4. 频繁实例化对象,Release对象 此时尽量保存并重用对象,例如使用StringBuffer()和String()。

如果你发现每次GC后,Heap的剩余空间会是总空间的50%,这表示你的Heap处于健康状态许多Server端的Java程序每次GC后最好能有65%的剩余空间。

经验之谈:
1.Server端JVM最好将-Xms和-Xmx设为相同值。为了优化GC,最好让-Xmn值约等于-Xmx的1/3。
2.一个GUI程序最好是每10到20秒间运行一次GC,每次在半秒之内完成。

注意:
1.增加Heap的大小虽然会降低GC的频率,但也增加了每次GC的时间。并且GC运行时,所有的用户线程将暂停,也就是GC期间,Java应用程序不做任何工作。
2.Heap大小并不决定进程的内存使用量。进程的内存使用量要大于-Xmx定义的值,因为Java为其他任务分配内存,例如每个线程的Stack等。

参考:
http://blog.csdn.net/ye1992/article/details/9344807
http://www.cnblogs.com/edwardlauxh/archive/2010/04/25/1918602.html
http://www.lirongzhen.cn/?p=1194
http://www.dgdxs.com/it/jishu/450.html

转载请注明出处:怡然之乐 – FineYi

Linux|CentOS+Nginx+Apache+MySQL+PHP+Tomcat的配置教程,完美支持PHP、JAVA

网上有很多关于LNAMP或LAMP组合安装的教程(我写过的另一篇博文,有需要的请移步->:LAMP安装手记(CentOS6.4+Apache-2.2.22+Mysql-5.1.63+PHP-5.2.17+phpmyadmin-3.4.10.2+ZendDebug),安装过程不再赘述,本文主要讲如何在LNAMP环境下安装JDK+Tomcat6使同一台服务器同时支持PHP和JAVA语言。
服务器系统和各软件版本如下所示:
[root@E ~]# uname -a 
Linux E.CentOS6.4 2.6.32-358.el6.x86_64 #1 SMP Fri Feb 22 00:31:26 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux 
[root@E ~]# /www/wdlinux/nginx/sbin/nginx -v 
nginx version: nginx/1.2.9 
[root@E ~]# /www/wdlinux/httpd-2.2.24/bin/httpd -v 
Server version: Apache/2.2.24 (Unix) 
Server built: Oct 30 2014 00:17:07 
[root@E ~]# rpm -qa |grep mysql 
mysql-libs-5.1.66-2.el6_3.x86_64 
[root@E ~]# /www/wdlinux/php/bin/php -v 
Cannot load Zend Extension Manager - it was built with configuration 1.2.0, whereas running engine is API220090626,NTS 
PHP 5.3.27 (cli) (built: Oct 30 2014 00:30:02) 
Copyright (c) 1997-2013 The PHP Group 
Zend Engine v2.3.0, Copyright (c) 1998-2013 Zend Technologies
1
开始安装jdk:
列出yum库可用的jdk安装包
[root@E ~]# yum -y list java* 
Loaded plugins: fastestmirror 
Loading mirror speeds from cached hostfile 
* base: mirror.bit.edu.cn 
* extras: mirror.bit.edu.cn 
* rpmforge: mirrors.neusoft.edu.cn 
* updates: mirrors.neusoft.edu.cn 
base | 3.7 kB 00:00 
extras | 3.3 kB 00:00 
rpmforge | 1.9 kB 00:00 
updates | 3.4 kB 00:00 
updates/primary_db | 171 kB 00:00 
Available Packages 
java-1.5.0-gcj.x86_64 1.5.0.0-29.1.el6 base 
java-1.5.0-gcj-devel.x86_64 1.5.0.0-29.1.el6 base 
java-1.5.0-gcj-javadoc.x86_64 1.5.0.0-29.1.el6 base 
java-1.5.0-gcj-src.x86_64 1.5.0.0-29.1.el6 base 
java-1.6.0-openjdk.x86_64 1:1.6.0.33-1.13.5.0.el6_6 updates 
java-1.6.0-openjdk-demo.x86_64 1:1.6.0.33-1.13.5.0.el6_6 updates 
java-1.6.0-openjdk-devel.x86_64 1:1.6.0.33-1.13.5.0.el6_6 updates 
java-1.6.0-openjdk-javadoc.x86_64 1:1.6.0.33-1.13.5.0.el6_6 updates 
java-1.6.0-openjdk-src.x86_64 1:1.6.0.33-1.13.5.0.el6_6 updates 
java-1.7.0-openjdk.x86_64 1:1.7.0.71-2.5.3.1.el6 updates 
java-1.7.0-openjdk-demo.x86_64 1:1.7.0.71-2.5.3.1.el6 updates 
java-1.7.0-openjdk-devel.x86_64 1:1.7.0.71-2.5.3.1.el6 updates 
java-1.7.0-openjdk-javadoc.noarch 1:1.7.0.71-2.5.3.1.el6 updates 
java-1.7.0-openjdk-src.x86_64 1:1.7.0.71-2.5.3.1.el6 updates 
java-1.8.0-openjdk.x86_64 1.8.0.25-1.b17.el6 updates 
java-1.8.0-openjdk-demo.x86_64 1.8.0.25-1.b17.el6 updates 
java-1.8.0-openjdk-devel.x86_64 1.8.0.25-1.b17.el6 updates 
java-1.8.0-openjdk-headless.x86_64 1.8.0.25-1.b17.el6 updates 
java-1.8.0-openjdk-javadoc.noarch 1.8.0.25-1.b17.el6 updates 
java-1.8.0-openjdk-src.x86_64 1.8.0.25-1.b17.el6 updates 
java_cup.x86_64 1:0.10k-5.el6 base 
java_cup-javadoc.x86_64 1:0.10k-5.el6 base 
java_cup-manual.x86_64 1:0.10k-5.el6 base 
javacc.x86_64 4.1-0.5.el6 base 
javacc-demo.x86_64 4.1-0.5.el6 base 
javacc-manual.x86_64 4.1-0.5.el6 base 
javassist.noarch 3.9.0-6.el6 base 
javassist-javadoc.noarch 3.9.0-6.el6 base
2
选择jdk1.6安装
[root@E ~]# yum -y install java-1.6.0-openjdk*
其它版本请自己修改对应的版本号安装
检测是否安装成功
[root@E ~]# java -version 
java version "1.6.0_33" 
OpenJDK Runtime Environment (IcedTea6 1.13.5) (rhel-1.13.5.0.el6_6-x86_64) 
OpenJDK 64-Bit Server VM (build 23.25-b01, mixed mode)
3
安装tomcat6
[root@E ~]# yum install tomcat6 tomcat6-webapps tomcat6-admin-webapps
安装成功 启动
[root@E ~]# service tomcat6 start
其它命令:service tomcat6 {start|stop|restart|condrestart|try-restart|reload|force-reload|status|version}
启动成功,访问测试:http://ip:8080
如下图所示即为安装成功:
5
 
配置nginx和tomcat,使其不加端口号,直接通过域名也能访问
首先增加解析,使域名指向到主机IP,本地可以直接改host实现
6
解析正常
不加8080端口访问
7
添加8080端口访问
8
接下来修改nginx和tomcat的配置使其不加端口号也能访问到tomcat的webservice
[root@E ~]# cd /www/wdlinux/nginx/conf/vhost/
[root@E ~]# vi myweb.com.conf
添加如下内容
server { 
listen 80;
server_name www.myweb.com myweb.com;
#root /www/web/master_myweb_com/public_html;
index index.html index.jsp index.htm;
error_page 400 /errpage/400.html;
error_page 403 /errpage/403.html;
error_page 404 /errpage/404.html;
error_page 405 /errpage/405.html;
location ~ \.jsp$ {
proxy_pass http://127.0.0.1:8080;
include naproxy.conf;
}
location / {
try_files $uri @tomcat;
}
location @tomcat {
proxy_pass http://127.0.0.1:8080;
include naproxy.conf;
    }
    access_log /www/web_logs/myweb_com_access.log wwwlogs;
    error_log /www/web_logs/myweb_com_error.log;
}
重新加载nginx配置文件或重启nginx
[root@E vhost]# service nginxd reload 
nginx: the configuration file /www/wdlinux/nginx/conf/nginx.conf syntax is ok 
nginx: configuration file /www/wdlinux/nginx/conf/nginx.conf test is successful
不加端口号访问测试:
9
至此nginx已经成功将来自myweb.com域名的请求代理到8080端口
如果需要配置多域名的话,还需要修改tomcat虚拟主机配置文件
默认配置文件路径:/etc/tomcat6/
默认项目路径:/var/lib/tomcat6/webapps/
tomcat默认指向/var/lib/tomcat6/webapps/ROOT目录
创建新项目目录,这里直接复制ROOT项目,进行修改
[root@E webapps]# pwd 
/var/lib/tomcat6/webapps
[root@E webapps]# chown -R root myweb.com
修改权限,使新项目权限和默认项目权限一致
[root@E webapps]# chgrp -R tomcat myweb.com
[root@E webapps]# ll 
总用量 24 
drwxrwxr-x 5 root tomcat 4096 10月 30 22:06 examples 
drwxrwxr-x 5 root tomcat 4096 10月 30 22:06 host-manager 
drwxrwxr-x 5 root tomcat 4096 10月 30 22:06 manager 
drwxr-xr-x 3 root tomcat 4096 10月 30 22:48 myweb.com 
drwxrwxr-x 3 root tomcat 4096 10月 30 22:06 ROOT 
drwxrwxr-x 5 root tomcat 4096 10月 30 22:06 sample
[root@E myweb.com]# cd myweb.com/
[root@E myweb.com]# rm -f index.html
[root@E myweb.com]# vi index.jsp
写入:WebService is Tomcat
不要忘记删除ROOT项目或者对它重命,否则新项目不生效
[root@E webapps]# mv ROOT/ ROOT.BAK


修改tomcat虚拟主机配置
[root@E myweb.com]# vi /etc/tomcat6/server.xml
在最下面<Host></Host>标签后面添加如下内容
<!--myweb.com host config--> 
<Host name="www.myweb.com" appBase="webapps" 
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">
<Context path="/" reloadable="true" docBase="myweb.com"/>
<Alias>myweb.com</Alias>
<!-- SingleSignOn valve, share authentication between web applications
Documentation at: /docs/config/valve.html -->
<!--
<Valve className="org.apache.catalina.authenticator.SingleSignOn" />
-->
<!-- Access log processes all example.
Documentation at: /docs/config/valve.html -->
<!--
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log." suffix=".txt" pattern="common" resolveHosts="false"/>
-->
</Host>
如下图所示
10
重启tomcat,测试http://myweb.com
[root@E myweb.com]# service tomcat6 restart
11
success!
转载请注明出处:怡然之乐 – FineYi

CentOS6.4 Linux 解决 Device eth0 does not seem to be present

用虚拟机vmware克隆CentOS系统,启动后网络出现问题,重启网络后报错
Device eth0 does not seem to be present,delaying initialization
e1
解决办法如下:
vi /etc/udev/rules.d/70-persistent-net.rules
找到eth1对应的 ATTR{address} 记下 对应的串,如下图所示:
e2
修改网卡配置:
vi /etc/sysconfig/network-scripts/ifcfg-eth0
修改
DEVICE=eth1
HWADDR=00:0C:29:4E:2D:93
如下图所示:
e3
重启网络
service network restart
e4
正常

转载请注明出处:怡然之乐 – FineYi

centos6.4下 Bugzilla的安装配置

Bugzilla是Mozilla公司提供的一款开源的免费Bug(错误或是缺陷)追踪系统,用来帮助你管理软件开发,建立完善的BUG跟踪体系。
安装环境:
OS:CentOS6.4 64bit
apache + mysql 加载perl模块
安装依赖包
yum install perl
yum&nbsp;install&nbsp;perl-CPAN
下载软件包:
wget http://ftp.mozilla.org/pub/mozilla.org/webtools/bugzilla-4.4.6.tar.gz
tar -zxvf bugzilla-4.4.6.tar.gz
cd bugzilla-4.4.6
检测:
./checksetup.pl --check-modules
很多没有安装的模块都列了出来,指南上说可以用下面的命令安装缺少的模块:
perl install-module.pl&nbsp;<modulename>
但是运行上条命令是给出了更加简便的方式: 安装所有环境依赖包
./install-module.pl --all
安装需要一段时间:
创建数据库,供bugzilla项目存储数据。
安装完成后 修改配置文件
vi localconfig 
clipboard-3

ps:数据库账号必须具有操作索引的权限,否则下一步安装过程会报错

然后执行安装:

 ./checksetup.pl

安装过程中需要输入管理员账号<邮箱>、真实姓名、密码

安装完成

配置虚拟主机:

vi /etc/httpd/conf.d/httpd-vhosts.conf

增加如下内容:

#bug.test.com 
<Directory /home/www/web/bugzilla> 
AddHandler cgi-. .cgi
Options +Indexes +ExecCGI
DirectoryIndex index.cgi index.html
AllowOverride Limit
AddHandler cgi-script .cgi
Options Indexes FollowSymLinks
AllowOverride FileInfo Options All
Order allow,deny
Allow from all
</Directory> 
<VirtualHost *:80> 
ServerAdmin admin@admin
DocumentRoot "/home/www/web/bugzilla"
ServerName bug.test.com
ErrorLog "/home/www/web/log/bug.test.com-error.log"
CustomLog "/home/www/web/log/bug.test.com-access.log" common
</VirtualHost>

clipboard-1

重启Apache

service httpd restart

增加解析:略

访问 bug.test.com

clipboard

安装过程中的报错
Software error:
The ./data/params file does not exist. You probably need to run checksetup.pl. at Bugzilla/Config.pm line 314.
Compilation failed in require at /home/www/web/bugzilla/index.cgi line 19.
BEGIN failed–compilation aborted at /home/www/web/bugzilla/index.cgi line 19.
For help, please send mail to the webmaster (admin@admin), giving this error message and the time and date of the error.
原因:配置文件未修改,安装失败。
转载请注明出处:怡然之乐 – FineYi

 

Blog list & Book list

Blog list
张晏的博客:
酷壳:
服务器运维与网站架构|Linux运维|X研究:
现代简明魔法-数据之美:
阮一峰的博客:
……
 
Book list
《C语言程序设计》- 谭浩强 
《黑客与画家》- Paul Graham (作者), 阮一峰 (译者)
《失控》- 凯文•凯利 (Kevin Kelly) 
……
 

Apache日志格式配置及查看方法

  Apache 日志格式配置及查看方法

  有时候我们需要根据需求去定制Apache默认日志的格式和内容,比如增加或减少日志所记录的信息、改变默认日志文件的格式等。本文介绍可以用日志记录的所有信息,以及如何设置Apache使其记录这些信息。

  一、定义日志格式

  很久以前,日志文件只有一种格式,这就是“公共格式”,许多人已经习惯于使用这种格式。随后出现了定制日志格式,而且看起来定制日志格式更很受欢迎,即使公共日志格式本身也重新用定制日志格式定义。本文介绍的就是如何随心所欲地定制日志文件的格式、如何让日志文件记录自己想要的信息。

  定制日志文件的格式涉及到两个指令,即LogFormat指令和CustomLog指令,默认httpd.conf文件提供了关于这两个指令的几个示例。

  LogFormat指令定义格式并为格式指定一个名字,以后我们就可以直接引用这个名字。CustomLog指令设置日志文件,并指明日志文件所用的格式(通常通过格式的名字)。

  LogFormat指令的功能是定义日志格式并为它指定一个名字。例如,在默认的httpd.conf文件中,我们可以找到下面这行代码:

  LogFormat “%h %l %u %t \”%r\” %>s %b” common该指令创建了一种名为“common”的日志格式,日志的格式在双引号包围的内容中指定。格式字符串中的每一个变量代表着一项特定的信息,这些信息按照格式串规定的次序写入到日志文件。

  Apache文档已经给出了所有可用于格式串的变量及其含义,下面是其译文:

  %…a: 远程IP地址

  %…A: 本地IP地址

  %…B: 已发送的字节数,不包含HTTP头

  %…b: CLF格式的已发送字节数量,不包含HTTP头。例如当没有发送数据时,写入‘-’而不是0。

  %…{FOOBAR}e: 环境变量FOOBAR的内容

  %…f: 文件名字

  %…h: 远程主机

  %…H 请求的协议

  %…{Foobar}i: Foobar的内容,发送给服务器的请求的标头行。

  %…l: 远程登录名字(来自identd,如提供的话)%…m 请求的方法

  %…{Foobar}n: 来自另外一个模块的注解“Foobar”的内容%…{Foobar}o: Foobar的内容,应答的标头行%…p: 服务器响应请求时使用的端口

  %…P: 响应请求的子进程ID。

  %…q 查询字符串(如果存在查询字符串,则包含“?”后面的部分;否则,它是一个空字符串。)%…r: 请求的第一行

  %…s: 状态。对于进行内部重定向的请求,这是指*原来*请求 的状态。如果用%…>s,则是指后来的请求。

  %…t: 以公共日志时间格式表示的时间(或称为标准英文格式)%…{format}t: 以指定格式format表示的时间%…T: 为响应请求而耗费的时间,以秒计

  %…u: 远程用户(来自auth;如果返回状态(%s)是401则可能是伪造的)%…U: 用户所请求的URL路径

  %…v: 响应请求的服务器的ServerName

  %…V: 依照UseCanonicalName设置得到的服务器名字在所有上面列出的变量中,“…”表示一个可选的条件。如果没有指定条件,则变量的值将以“-”取代。分析前面来自默认httpd.conf文件的 LogFormat指令示例,可以看出它创建了一种名为“common”的日志格式,其中包括:远程主机,远程登录名字,远程用户,请求时间,请求的第一行代码,请求状态,以及发送的字节数。

  有时候我们只想在日志中记录某些特定的、已定义的信息,这时就要用到“…”。如果在“%”和变量之间放入了一个或者多个HTTP状态代码,则只有当请 求返回的状态代码属于指定的状态代码之一时,变量所代表的内容才会被记录。例如,如果我们想要记录的是网站的所有无效链接,那么可以使用:

  LogFormat %404{Referer}i BrokenLinks

  反之,如果我们想要记录那些状态代码不等于指定值的请求,只需加入一个“!”符号即可:

  Apache日志:访问日志(一)

  想要知道什么人在什么时候浏览了网站的哪些内容吗?查看Apache的访问日志就可以知道。访问日志是Apache的标准日志,本文详细解释了访问日志的内容以及相关选项的配置。

  一、访问日志的格式

  Apache内建了记录服务器活动的功能,这就是它的日志功能。这个《Apache日志》系列文章介绍的就是Apache的访问日志、错误日志,以及如何分析日志数据,如何定制Apache日志,如何从日志数据生成统计报表等内容。

  如果Apache的安装方式是默认安装,服务器一运行就会有两个日志文件生成。这两个文件是access_log(在Windows上是 access.log)和error_log(在Windows上是error.log)。采用默认安装方式时,这些文件可以在/usr/local /apache/logs下找到;对于Windows系统,这些日志文件将保存在Apache安装目录的logs子目录。不同的包管理器会把日志文件放到 各种不同的位置,所以你可能需要找找其他的地方,或者通过配置文件查看这些日志文件配置到了什么地方。

  正如其名字所示,访问日志access_log记录了所有对Web服务器的访问活动。下面是访问日志中一个典型的记录:

  216.35.116.91 – – [19/Aug/2000:14:47:37 -0400] “GET / HTTP/1.0” 200 654这行内容由7项构成,上面的例子中有两项空白,但整行内容仍旧分成了7项。

  第一项信息是远程主机的地址,即它表明访问网站的究竟是谁。在上面的例子中,访问网站的主机是216.35.116.91。随便说一句,这个地址属于一台 名为si3001.inktomi.com的机器(要找出这个信息,可以使用nslookup工具查找DNS),inktomi.com是一家制作Web 搜索软件的公司。可以看出,仅仅从日志记录的第一项出发,我们就可以得到有关访问者的不少信息。

  默认情况下,第一项信息只是远程主机的IP地址,但我们可以要求Apache查出所有的主机名字,并在日志文件中用主机名字来替代IP地址。然而,这种做 法通常不值得推荐,因为它将极大地影响服务器记录日志的速度,从而也就减低了整个网站的效率。另外,有许多工具能够将日志文件中的IP地址转换成主机名 字,因此要求Apache记录主机名字替代IP地址是得不偿失的。

  然而,如果确实有必要让Apache找出远程主机的名字,那么我们可以使用如下指令:

  HostNameLookups on

  如果HostNameLookups设置成double而不是on,日志记录程序将对它找到的主机名字进行反向查找,验证该主机名字确实指向了原来出现的IP地址。默认情况下HostNameLookups设置为off。

  上例日志记录中的第二项是空白,用一个“-”占位符替代。实际上绝大多数时候这一项都是如此。这个位置用于记录浏览者的标识,这不只是浏览者的登录名字, 而是浏览者的email地址或者其他唯一标识符。这个信息由identd返回,或者直接由浏览器返回。很早的时候,那时Netscape 0.9还占据着统治地位,这个位置往往记录着浏览者的email地址。然而,由于有人用它来收集邮件地址和发送垃圾邮件,所以它未能保留多久,很久之前市 场上几乎所有的浏览器就取消了这项功能。因此,到了今天,我们在日志记录的第二项看到email地址的机会已经微乎其微了。

  日志记录的第三项也是空白。这个位置用于记录浏览者进行身份验证时提供的名字。当然,如果网站的某些内容要求用户进行身份验证,那么这项信息是不会空白的。但是,对于大多数网站来说,日志文件的大多数记录中这一项仍旧是空白的。

  日志记录的第四项是请求的时间。这个信息用方括号包围,而且采用所谓的“公共日志格式”或“标准英文格式”。因此,上例日志记录表示请求的时间是2000 年8月19日星期三14:47:37。时间信息最后的“-0400”表示服务器所处时区位于UTC之前的4小时。

  日志记录的第五项信息或许是整个日志记录中最有用的信息,它告诉我们服务器收到的是一个什么样的请求。该项信息的典型格式是“METHOD RESOURCE PROTOCOL”,即“方法 资源 协议”。

  在上例中,METHOD是GET,其他经常可能出现的METHOD还有POST和HEAD。此外还有不少可能出现的合法METHOD,但主要就是这三种。

  RESOURCE是指浏览者向服务器请求的文档,或URL。在这个例子中,浏览者请求的是“/”,即网站的主页或根。大多数情况下,“/”指向DocumentRoot目录的index.html文档,但根据服务器配置的不同它也可能指向其他文件。

  PROTOCOL通常是HTTP,后面再加上版本号。版本号或者是1.0,或者是1.1,但出现1.0的时候比较多。我们知道,HTTP协议是Web得以 工作的基础,HTTP/1.0是HTTP协议的早期版本,而1.1是最近的版本。当前大多数Web客户程序仍使用1.0版本的HTTP协议。

  日志记录的第六项信息是状态代码。它告诉我们请求是否成功,或者遇到了什么样的错误。大多数时候,这项值是200,它表示服务器已经成功地响应浏览器的请 求,一切正常。此处不准备给出状态代码的完整清单以及解释它们的含义,请参考相关资料了解这方面的信息。但一般地说,以2开头的状态代码表示成功,以3开 头的状态代码表示由于各种不同的原因用户请求被重定向到了其他位置,以4开头的状态代码表示客户端存在某种错误,以5开头的状态代码表示服务器遇到了某个 错误。

  日志记录的第七项表示发送给客户端的总字节数。它告诉我们传输是否被打断(即,该数值是否和文件的大小相同)。把日志记录中的这些值加起来就可以得知服务器在一天、一周或者一月内发送了多少数据。

  二、配置访问日志

  访问日志文件的位置实际上是一个配置选项。如果我们检查httpd.conf配置文件,可以看到该文件中有如下这行内容:

  CustomLog /usr/local/apache/logs/access_log common注意,对于版本较早的Apache服务器,这行内容可能略有不同。它使用的可能不是CustomLog指令,而是TransferLog指令。如果你的服务器属于这类情况,建议你尽可能地早日升级服务器。

  CustomLog指令指定了保存日志文件的具体位置以及日志的格式。至于如何定制日志文件的格式以及内容,我们将在这个《Apache日志》系列文章的 后面几篇讨论。上面这行指令指定的是common日志格式,自从有了Web服务器开始,common格式就是它的标准格式。由此我们也可以理解,虽然几乎 不再有任何客户程序向服务器提供用户的标识信息,但访问日志却还保留着第二项内容。

  CustomLog指令中的路径是日志文件的路径。注意,由于日志文件是由HTTP用户打开的(用User指令指定),因此必须注意这个路径要有安全保证,防止该文件被随意改写。

 转载请注明出处:怡然之乐 – FineYi