分类目录归档:架构

关于系统重构的10点经验总结

Published / by 成成 / Leave a Comment

做我们的日常工作中系统重构都应该是最让人头疼的工作了,无论是错综复杂还是经意简单的系统在发展的过程中都会经历重构,而系统重构也是任何一个技术团队都无法回避的问题,在我服务的多家公司几乎每家公司都经历了一次甚至多次系统的重构,本文就我在多年的重构工作中总结出来的几点建议分享给各位朋友,希望能够给朋友们带来帮助。

1、重构确定并且聚焦目标

首先我相信我们大家都确信系统重构是会有巨大的成本投入的,业务可能需要暂缓、新系统引入的问题(BUG)带来业务的不稳定、研发人员以及配合人员的投入还有各种隐性成本等等,我们服务的是一家商业公司获取利润是最终目的,在投入具体成本做一个项目就肯定要获得收益的。重构的目标一定要能够获得更大的提升无论是业务流程还是系统性能或是其他方面,如果仅仅一个很小的改善完全没有如此的大费周章,权衡好成本是否能够获得良好的收益。

无论如何进行系统重构都是一次伤筋动骨的过程,是涅槃重生还是飞蛾扑火,完全取决我们项目执行的过程中是否明确了目标且一直聚焦于目标的实现,保持目标的聚集是能否取得良好结果的必要促销,如果我们仅仅确立了目标没有聚集于目标在多个非重要的节点投入较大资源必然会导致我们对目标的投入降低,工作中的原始资本投入都是8个小时,当然如果每个人都愿意乐于加班的话另外讨论,而我们的实际情况往往是8个小时都是不够用的,这就更加需要我们明确目标聚焦目标,把有限的资源投入到最重要的事情中,才能获得既定目标的良好结果。

2、重构要有可量化的指标

团队确认了重构的目标之后,下一步一定要将目标量化,确定好目标之后也就能够确认边界,围绕在边界内要将需要实现的事项一一罗列出来,并且尽可能对每个实现制定可以用数据清晰表现出来的指标,比如用户操作的响应时间缩短到100毫秒、单元测试的覆盖率达到80%、发现问题时长降低到30分钟以内等等,有了明确的数据指标我们才能评估最终是否获得了良好收益,这些目标必须要在重构团队,包括产品、研发、测试等等,甚至包括业务方在内达成一致,是团队的目标清晰明了,防止出现过度或是不达标是最终不能获得良好收益。

3、重构要有更好的质量

既然决定了要对系统进行一次重构,那么我们肯定要做到的就是要比之前做的更好,如果之前接口响应时间在100毫秒,而经过重构之后反而减低到了200毫秒以上那么岂不是很难看,大家辛苦付出的努力是不是也更加不值得。而进行重构往往是一件十分引人注目的事情,一个微小的问题反而容易在众人注目下变得非常严重的问题。为了减少引起不必要的麻烦,重构团队就更加要注重各个方面的问题,无论是系统性能、用户体验还是BUG数量等

4、重构之前要和业务方沟通

技术团队进行系统重构的工作的时候往往忽略掉了业务方,认为这是技术团队内部的事情,不需要知会业务方,这个想法是非常错误的,进行重构的目标就是为了改善改进业务流程,而不去和业务方提前沟通进行闭门造车,最后的结果很可能和进行重构的初衷背道而驰。进行系统重构首先我们必须了解现有系统的业务需求,是否有待改进的业务需求点,是否有新的业务诉求等这些需求往往会影响到我们重构的进度和目标,甚至出现南辕北撤的事情。
技术团队和业务方往往对待问题的出发角度不同,思考问题的方式也不同,在进行重构之前和业务方沟通获得业务方的支持,往往能够事半功倍。
例如,我的团队在进行一块业务系统重构的时候进入到了系统切换的试运行的阶段,由于拿出的方案给到业务方无法被业务方接受,业务方提出的解决方案我们还需要进行再次开放对整个项目进度影响了足足一个月时间之多。吸取教训的我们在进行下一个项目的时候提前和业务方进行了沟通,业务方从他们的角度给予了很多的意见和建议以及业务未来的发展方向的指引,我们发现这些建议和意见帮助我们更好理解业务的同时也大大的降低了我们工作量,减少了我们很多冗余的设计。

5、重构应该才用迭代的方式

参与过重构项目的朋友都知道,重构项目往往是个时间跨度很长的工作,少则一两个月多则一年半载都有,如果不将整个重构进行合理拆分,而是采用全部开发完成,再进行系统切换的方式会对整个重构引入很大的风险,首先长时间的时间跨度内业务会进行持续变更,其次团队面临长时间没有结果输出面临来自各个方面的压力还有系统问题持续累积,这种蒙头狂奔的方式往往造成了项目失败或是目标便宜,而采用迭代方式进行重构,可以以更小的颗粒度持续交付工作成果,交付-试用-反馈-调整,持续有交付,持续有反馈,持续调整能够保证团队的目标不会偏移,形成一个正向循环,保证最后的重构目标。

6、重构要清晰了解旧系统

知己知彼,百战不殆,系统重构是一个与旧系统对抗的过程,不对旧系统的弄的清清楚楚怎么能够比旧系统做的更好呢?其实了解现有系统是一个学习的过程,如果有旧系统的开发人员还在公司那么就事半功倍了,旧系统的开发同学帮忙给做次分享省去了我们重构团队很多的工作,比直接去读代码更能清晰明了的了解到旧系统的相关知识以及有哪些需求点和应该注意的问题等等,通过学习和了解旧系统设定目标基准值避免引入老旧问题也是避免重蹈覆辙的一个好办法。

7、重构要提前规划系统切换方案

不知道朋友有没有遇到过重构完系统发现如果进行新旧系统的切换是个难题,反正我是遇到过,由于没有提前做好规划和切换步骤导致最后临时抱佛脚,开始使用各种奇葩办法做系统切换,有的还需要增加额外工作量甚至各种办法的刷脸求人,总之这不是一个很好的体验。系统切换往往是在重构中被我们忽略的一个步骤,但是这是非常重要的一个环节,在做最初的计划就应该考虑到如何进行系统切换,一个设计好的切换方案也应该贯穿重构始终,避免因为切换方案引起服务不可用或是引入系统BUG。尤其是前期整个团队付出巨大努力取得了一定成果的时候在最后一步切换的时候出现问题对团队是个非常大的打击,也使得业务方对团队失去信心,带来很不必要的麻烦。

8、重构高度重视系统数据

一次系统重构大多数情况下会涉及到数据结构的修改,对数据结构进行修改必然引入很大的风险,尤其在一些老旧的业务系统重构精简业务去掉冗余数据的时候,往往需要将老数据的业务数据重新写入到新系统的数据库。重构的目标是为了比旧系统更好无论是性能还是业务方面,如果我们对数据的操作导致外部依赖旧系统的业务无法正常运行那将是影响SLA指标的问题还有,说到系统数据有些同学可能仅仅关注的是业务数据其实数据也包含了系统运行所产生的日志数据,无论新旧系统的日志数据都是很重要的,如果因为重构影响到数据的读取、处理、分析那么岂不是得不偿失的事情。

9、重构要才用成熟的技术选型

技术选型是重构工作的基石,选择一套成熟稳定的技术方案是重构项目完成的必要条件。有些时候我们引入最新版的数据库虽说会有性能提升但是也会引入一定的不稳定因素,之前我们团队在使用MongoDB的一个新版本的时候发现主从库的数据并不能很好的同步出现过丢失数据的情况,进入社区发现这个版本使用的用户很多都反馈了这个问题,这时候我们不得不选择了大多数人共同的一个选择降低了一个版本来解决问题,相信此类情况比比皆是。在不是很成熟的方案带来并不显著的性能提升反而还会引入不确定的风险的时候我们需要权衡利弊得失,重构更是要保证系统的稳定性。
技术方案能否有足够强大的支撑也是我们需要考虑的一个方面,现在我们团队面对的重构是从单体式架构往微服务转变,旧系统的版本构建在是PHP语言上,新的系统我们由两个选择继续选择用PHP进行重构或是才用公司统一的微服务框架,我们毫不犹豫的选择了使用公司统一的微服务,这样做有几个显而易见的好处。
1、和公司内部进行交互更加方便快捷;
2、可以直接获取成熟的经验;
3、基础服务有公司级的支持;
以上的好处显然对我们能否成功重构系统并且获得足够的帮助起到了显著的帮助,反而才用PHP进行微服务,公司内部并无成功经验可以借鉴,业内也并无太多可靠的方案可以进行选择。一个成熟可靠的的技术方案是我们能否更进一步的保障和基石。

10、重构更加关注重视团队成员

参与过重构的同学都知道重构工作是一项枯燥乏味的工作,往往周期长、复杂度、 难度大、牵扯广、优先级低而且很有可能是一件费力不讨好的工作,开发一个业 务方期待的新功能、新模块往往比一场翻天覆地的重构更能引起业务方的重视也 更容易获取良好结果与反馈,反而不需要承担大多的压力。而越是面对这样的情 况越是需要加大对团队的鼓励增强团队的信心,消除团队的疑虑困惑,给予团队 持续的鼓励,给整个团队注入正能量,让团队保持积极向上的团队氛围,即使面 对各种困难、问题,也始终对团队保持信心保持乐观,让大家轻松愉快的投入到 重构工作中,尽量不担负额外的压力。

以内内容均为工作中的总结反思,分享给大家希望以上的这些总结能够对大家有所帮助,文章所讲述的内容如有不足之处还望指出。

log4php日志框架的配置使用介绍

Published / by 成成 / Leave a Comment

随着系统和业务的复杂度提升我们会对日志进行各种分类处理如通过日志的级别分类或是对不同的业务的日志进行分类处理,即使面对以上的需要我们仍然需要有一个统一的日志格式,这样就需要我们有一个标准的日志模块来完成这些工作,然而我们也希望这个日志模块是性能优良且方便易用的。

Java有一个比较出名的日志组件log4j,PHP语言也有类似的日志框架,同样来自于Apache的log4php是一个多功能的为PHP使用的日志框架。和log4j类似,通过log4php我们也可以控制日志信息输送的目的地是控制台、文件、数据库甚至是套接口服务器、syslog守护进程等,同样我们也可以控制每一条日志的输出格式;通过定义日志信息的级别,我们能够更加有效细致地控制日志的生成过程。更加惊喜的是以上叙述的这些功能甚至不需要我们修改代码,而是通过一个配置文件来灵活地进行配置。

安装介绍

log4php提供了两种安装方式,一是通过直接下载源码包,Apache log4php – Download;二是通过PEAR渠道安装。

PEAR方式安装命令

pear channel-discover pear.apache.org/log4php
pear install log4php/Apache_log4php

目录结构

├───apidocs – API生成文档
└───src

├───assembly – Maven的配置
├───changes – 更新日志
├───examples – 各种用法示例
├───main
│       └───php – 主要源码
├───site – 网站源码
└───test – 单元测试

配置介绍

log4php支持XML、PHP以及Properties三种配置文件,我们今天主要通过Properties方式的配置文件来讲解,此种方式的配置较为全面。如果不在日志记录前调用Logger::configure()方法进行配置,log4php使用默认方式进行配置

日志输出方式

名称                                     介绍
LoggerAppenderConsole         控制台,标准输出或标准错误流。
LoggerAppenderEcho             控制台,通过PHP的echo方式输出
LoggerAppenderFile               文件
LoggerAppenderDailyFile        文件(通过日志生成新文件)
LoggerAppenderRollingFile     文件 (通过尺寸设置生成新的日志文件).
LoggerAppenderMail              通过电子邮件发送日志,整个日志在一个电子邮件发送。
LoggerAppenderMailEvent      通过电子邮件发送日志,每条日志通过单独的电子邮件发送。
LoggerAppenderMongoDB      MongoDB
LoggerAppenderNull              忽略所有的日志事件
LoggerAppenderPDO             数据库
LoggerAppenderPhp              通过使用PHP trigger_error()函数PHP用户级的消息
LoggerAppenderSocket          通过套接口输出日志
LoggerAppenderSyslog          syslog

日志内容输出格式方式

名称                                   介绍
LoggerLayoutHTML              输出到HTML表格中
LoggerLayoutPattern            灵活格式,通过一个字符串配置
LoggerLayoutSimple             简单格式,不可配置
LoggerLayoutSerialized         输出序列化对象
LoggerLayoutTTCC               包括时间,主题,类别和嵌套诊断上下文的 (不建议使用)
LoggerLayoutXml                 输出到XML文件

示例说明

示例一

配置示例

;定义输出方式名称default
log4php.appender.default = LoggerAppenderEcho
log4php.appender.default.layout = LoggerLayoutSimple

;定义一组新的输出方式名称为test
;日志输出方式设置
log4php.appender.test = LoggerAppenderDailyFile
;日志内容格式设置
log4php.appender.test.layout = LoggerLayoutPattern
;日志内容参数设置(日期 PID 日志级别 日志名称 日志文本 换行符)
log4php.appender.test.layout.ConversionPattern = “%d{Y-m-d H:i:s.u} [%t] %p %c: %m%n”
;日志文件名称配置
log4php.appender.test.datePattern = Ymd
;日志文件路径配置
log4php.appender.test.file = /var/log/daily_%s.log

;日志输出方式以及输入级别设置
log4php.rootLogger = DEBUG, default

如果设置为已下值,日志可同时使用default和test两个输出定义进行记录
log4php.rootLogger = DEBUG, default,test

代码示例

<?php

require_once dirname(__FILE__) . ‘/log4php/main/php/Logger.php’;
Logger::configure(dirname(__FILE__) . ‘/log4php.properties’);
$logger = Logger::getLogger(‘exception’);
$message = ‘hello world!’;
$logger->error(‘error,’ . $message);//会产生记录
$logger->info(‘info,’ . $message);//会产生记录
$logger->trace(‘trace,’ . $message);//不会产生记录,因为设置的日志级别DEBUG,只有高于等于DEBUG级别的日志才会记录

输出示例

2016-12-15 16:25:55.55 [121215] ERROR exception: error,hello world!
2016-12-15 16:25:55.55 [121215] INFO exception: info,hello world!

示例二

配置示例

;定义输出方式名称default
log4php.appender.default = LoggerAppenderEcho
log4php.appender.default.layout = LoggerLayoutSimple

;定义一组新的输出方式名称为test
;日志输出方式设置
log4php.appender.test = LoggerAppenderDailyFile
;日志内容格式设置
log4php.appender.test.layout = LoggerLayoutPattern
;日志内容参数设置(日期 PID 日志级别 日志名称 日志文本 换行符)
log4php.appender.test.layout.ConversionPattern = “%d{Y-m-d H:i:s.u} [%t] %p %c: %m%n”
;日志文件名称配置
log4php.appender.test.datePattern = Ymd
;日志文件路径配置
log4php.appender.test.file = /var/log/test_daily_%s.log
;日志输出方式以及输入级别设置
log4php.logger.test = INFO, test

;定义一组新的输出方式名称为pro
;日志输出方式设置
log4php.appender.pro = LoggerAppenderDailyFile
;日志内容格式设置
log4php.appender.pro.layout = LoggerLayoutPattern
;日志文内容式参数配(日期 PID 日志级别 日志名称 日志文本 换行符)
log4php.appender.test.layout.ConversionPattern = “%d{Y-m-d H:i:s.u} [%t] %p %c: %m%n”
;日志文件名称配置
log4php.appender.pro.datePattern = Ymd
;日志文件路径配置
log4php.appender.pro.file = /var/log/pro_daily_%s.log
;日志输出方式以及输入级别设置
log4php.logger.pro = INFO, pro

代码示例

<?php
require_once dirname(__FILE__) . ‘/log4php/main/php/Logger.php’;
Logger::configure(dirname(__FILE__) . ‘/log4php.properties’);

/*
* 使用名称为test的方式处理日志
*/
$logger = Logger::getLogger(‘test’);
$message = ‘hello world!’;
$logger->error($message);//会产生记录

/*
* 使用名称为pro的方式处理日志
*/
$logger = Logger::getLogger(‘pro’);
$message = ‘Hey, beautiful!’;
$logger->error($message);//会产生记录

输出示例

/var/log/test_daily_20161215.log文件

2016-12-15 16:25:55.55 [121215] ERROR test: hello world!

/var/log/pro_daily_20161215.log文件

2016-12-15 16:25:55.55 [121215] ERROR test: Hey, beautiful!

log4php的配置文件十分灵活和简单,以上的只是很简单的两个示例,还不能全面的展示出来log4php配置方面的简单易用以及灵活性,仍然希望这能够对大家有所帮助,log4php的官方提供了良好的文档以及十分丰富的API,几乎满足了我们对于日志模块需要的全部需求,大家也可以通过查阅相关文档调整配置做出自己需要的日志模块。

log4php文档地址:http://logging.apache.org/log4php/index.html

希望这篇文章对你有所帮助,如果没有任何帮助抱歉浪费了你的阅读时间但是我不负任何责任,如有不足支持还望指出

给开发工程师关于日志记录的建议

Published / by 成成 / Leave a Comment

摘要

对于工程师而言懂得记录合理正确的日志是件很艰巨的任务。日志是记录必要的信 息和数据,方便问题定位和追踪,给我们足够的依据解释和发现问题,以及帮我们清晰 反映出应用的运行状况,这或许能够决定一个工程师是升职还是被开除。记录日志也是 有一定原则或是技巧的,并不是把所有内容有加以记录就可以了,一是可能收到运维工 程师的抗议;二是记录过多内容反而不容易查找关键信息,说来我们的日志记录的简单 可依赖即可,简单可以依赖的关键性数据。

一.日志要分级

日志一定要分级。多个级别的日志等级TRACE、DEBUG、INFO、NOTICE、 WARNING、ERROR、FATAL等,不同级别的日志应当分类处理,在大型应用的海量 日志面前不分级的日志处理起来非常麻烦,我们必须要对日志进行分级分类处理,清楚的明白哪些级别的日志需要时刻关注,影响到了应用的正常运行,有些日志只是帮我们在记录应用的运行状态。

二.日志记录必要的信息即可

日志记录必要的信息即可,无意义的信息必须要排除在日志之外,开发工程师作为对程序最了解的人如果在记录含糊不清的日志只会增加我们查询关键信息的困难,且过多的内容记录也会招致运维工程师的反感和增加应用运行的成本,我们要明白当应用出现问题的时候日志是你唯一可以依赖的,请让保存记录最关键的信息。

三.日志要让其他人也能看懂

为什么要记录日志,是因为有一天我们要去读他,而读他日志的不一定是谁,有一定加密属性的日志读起来总会给我们带来很大困惑,请善待日志的读者,因为每个人都会是日志的读者。
1.排版整洁有序,格式统一规范。随笔式的日志看起来会很麻烦,给日志读者增加很多困难。
2.采用关键字来突出显示如:时间、操作名称等,让读者能够轻松通过关键字来精确定位日志内容。

四.关于程序中加入日志的方法

千万不要自己写个记录日志的方法!千万不要自己写个记录日志的方法!千万不要自己写个记录日志的方法!重要的事情说三遍,绝对不要这么做,即便是用打印输入或者是自己 写入到日志文件中,第一个这么做的朋友也会影响其他同事——首先,这会让你的代码不那么美;其次也会给你的运维工程师带来很大麻烦。每个人都自己写个日志会很容易造成日志 个格式不统一,这会给日志的收集分类带来很大麻烦,PHP有不少第三方的log类库弥补了上述缺陷,如log4php、plog、Analog等还有内置error_log、syslog函数功能强大且性能 极好,用Java开发也有很多选择,例如Log4j、SLF4J、和Logback等其他语言如Python、ruby也有相应的日志类库或是组件,请调用标准类库来完成日志记录。

五.日志要做到方便解析

日志记录下来一定要做到可以方便解析,因为有些时候需要做到报警或是数据提取,这 些功能往往是需要自动化实现的,如果没有一个方便解析的日志实现起来就增加了很多成本。如下,日志记录了时间、日志级别、脚本、IP地址,以及数据:
2015-12-15 12:00:00ERRORlist.php127.0.0.1PAGE=1&NUM=500 解析以上日志是不是需要正则表达式或是更麻烦的程序逻辑来处理?答案是肯定的,如果换一种方式,很可能需要很少的工作就能达到我想要的效果。如下:
2015-12-15 12:00:00||ERROR||list.php||127.0.0.1||{‘PAGE’:1,’NUM’:500} 这样解析起来awk -F‘||’就可以轻松解决了。

总结

希望这篇文章对您在开发过程中记录日志有所帮助,如果有什么遗漏之处还望见谅。看了这篇文章之后发掘没有任何帮助,抱歉我概不负责。

Ubuntu下安装GoAccess过程中对源代码编译时产生错误的处理方法

Published / by 成成 / Leave a Comment

前几日在VPS上面重新安装了下GoAccess,以前博主为图省事直接用的apt-get install goaccess进行的安装,没有对源代码进行编译安装,在Ubuntu下编译的时候不能通过报出了两个错误,博主于是发邮件给GoAccess官方需求解决方法,很快得到的回复。对了GoAccess官方邮件地址是goaccess(at)prosoftcorp.com,有问题可以直接给他们发邮件,很快就会得到答复!
我安装的时候产生的错误是这样的

gcc -g -Wall -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include   -lmenuw -lncursesw -lm  -o goaccess settings.o error.o commons.o goaccess.o parser.o ui.o util.o  -lglib-2.0 -lmenuw -lncursesw 
ui.o: In function `create_graphs':
/usr/local/goaccess/ui.c:300: undefined reference to `log10'
/usr/local/goaccess/ui.c:300: undefined reference to `floor'
ui.o: In function `data_by_total_hits':
/usr/local/goaccess/ui.c:390: undefined reference to `log10'
/usr/local/goaccess/ui.c:390: undefined reference to `floor'
collect2: ld returned 1 exit status
make[1]: *** [goaccess] Error 1
make[1]: Leaving directory `/usr/local/goaccess'
make: *** [all] Error 2

官方的给出的解决办法是
首先安装autoconf,如果没有安装的话

apt-get install autoconf

打开Makefile.am文件查看是否有如下两行的内容,没有则进行添加

AM_CFLAGS = -g -Wall @GLIB2_CFLAGS@
goaccess_LDADD = -lm

修改configure.ac文件

vi configure.ac

注释掉AM_INIT_AUTOMAKE,然后执行以下命令

autoheader
autoconf

再次修改configure.ac文件

vi configure.ac

将AM_INIT_AUTOMAKE注释去掉,然后执行以下命令

aclocal
automake -a
autoconf

再次进行编译顺利通过,GoAccess官方建议用git获取源代码

git clone git://goaccess.git.sourceforge.net/gitroot/goaccess/goaccess

我也是通过这种方式获取的源代码进行修改之后编译安装顺利通过

简述uWSGI+Nginx+Python 搭建过程

Published / by 成成 / 简述uWSGI+Nginx+Python 搭建过程有1条评论

由于服务器上面的Python和Nginx都已经安装完毕,咱们就直接叙述uWSGI的安装,对照各方面的测试数据uWsgi在性能方面相对其他方式还是比较不错的!他是一个快速的、纯C语言开发的、自维护的、对开发者或是系统管理员友好的应用程序服务器。

官方网址:http://projects.unbit.it/uwsgi/

文档地址:http://projects.unbit.it/uwsgi/wiki/Doc

准备

cd /usr/local
wget http://projects.unbit.it/downloads/uwsgi-1.0.2.1.tar.gz

安装

tar zxvf uwsgi-1.0.2.1.tar.gz
cd uwsgi-1.0.2.1/
python uwsgiconfig.py --build

配置

cp nginx/uwsgi_params /usr/local/nginx/conf/
vi /usr/local/nginx/conf/nginx.conf

编辑Nginx配置文件添加,uWSGI监听8000端口,这个原理跟PHP的fastcgi相同

    server {
        listen        80;
        server_name py.wuwangwo.net;

        location / {
            root  /data/htdocs/py.wuwangwo.net;
            include uwsgi_params;
            uwsgi_pass 127.0.0.1:8000;
        }

        access_log  /data1/logs/py.wuwangwo.net.access.log;
    }

重新启动Nginx

/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf -s reload

配置web站点

cd /data/htdocs/py.wuwangwo.net
vi uwsgi.xml

编辑uWSGI配置文件,他也同样支持.ini文件等的配置形式,个人习惯不同,具体可以参照官方示例:http://projects.unbit.it/uwsgi/wiki/Example


127.0.0.1:8000
myuwsgi

/data/htdocs/py.wuwangwo.net
2

编辑web.py文件

#!/usr/bin/env python

import os
import web

urls = ('/(.*)', 'hello')

app = web.application(urls, globals())

class hello:
    def GET(self, name):
        if not name:
            name = "World"
        return "Hello" + name + "!"

application = app.wsgifunc()

启动uWSGI,添加–daemonize参数以后台方式运行

/usr/local/uwsgi-1.0.2.1/uwsgi -x /data/htdocs/py.bukaopu.org/uwsgi.xml --daemonize /data/htdocs/py.wuwangwo.net/uwsgi.error.log

停止uWSGI

killall -9 uwsgi

MongoDB之no db response数据库没有响应

Published / by 成成 / MongoDB之no db response数据库没有响应有1条评论

今天查看PHP的error log有很多错误产生,有Fatal error也有Warning,本着错误的级别先开始处理Fatal error除了几条还被搜索机器人抓取的不在使用的页面产生这种错误外,发现了一个多行的Fatal error仔细查看下是:

[17-Jan-2012 11:16:19] PHP Fatal error:  Uncaught exception 'MongoCursorException' with message 'no db response' in XXXXX.php:194

乍一看是为捕获抛出的异常,异常的错误信息是’no db response’数据库没有响应,接下去查看代码:

省略...
$query = array('type' => 5);
$cursor = $collection->find($query);
foreach($cursor as $key => $val) {//出错的行
	省略...
}
省略...

变量$cursor为查询MongoDB的返回结果,但是抛出的异常是’MongoCursorException’异常信息是’no db response’,查看PHP手册解释是:This may not even be an error, for example, the database command “shutdown” returns no response. However, if you were expecting a response, this means the database didn’t give one.坑爹的PHP手册上来就说:This may not even be an error(这甚至有可能不会是一个错误),for example, the database command “shutdown” returns no response.(例如,数据库输入’shutdown’命令而没有获得相应)。
访遍Google、百度没有获得满意的答案,不过问题应该已经比较清晰出现在了MongoDB或是网络上面,于是继续想办法查找问题中,截止到博文发布还没有找到问题原因!

GoAccess,Apache/Nginx 日志统计分析软件

Published / by 成成 / GoAccess,Apache/Nginx 日志统计分析软件有2条评论

 

什么是GoAccess?

GoAccess是运行在Unix系统终端,开源、实时分析Apache日志(其实也能够分析Nginx日志)并且能够动态呈现的软件。它为系统管理员提供了一个快速、有价值的HTTP统计,动态的可视化的服务器报告。

它是做什么以及如何工作?

从本质上讲,GoAccess的工作方式是,它将解析众所周知的Apache访问日志文件 access log,GoAccess通过解析日志收集的数据,将会显示它的控制台或某个终端。收集到的信息或生成的报告将显示给在视觉、交互窗口的系统管理员用户。报告包括:

  • 综合统计
  • 访客排行榜
  • 请求文件排行榜
  • 请求的静态文件排行榜,如图片、JS文件、CSS文件等
  • 访问来源
  • 404页面
  • 访问者的操作系统
  • 访问者的浏览器
  • 浏览器和蜘蛛(搜索爬虫)
  • 主机,反向DNS,IP位置
  • HTTP状态码
  • 推介网站
  • 搜索关键词
  • 显示时不同的配色方案
  • 无限制日志文件的大小(决定了GoAccess的打开速度)

日志文件格式

GoAccess可以解析Apache的日志格式,通用日志格式(CLF)和组合日志格式(XLF/ ELF),包括虚拟主机. 它也能够解析Nginx日志. (如果你按照Apache日志的格式配置了Nginx日志)

GoAccess主页 http://goaccess.prosoftcorp.com/

安装方法

1、安装GoAccess需要一些系统支持库

Ncurses 提供字符终端处理库,包括面板和菜单
GLib C语言的函数库(大于2.0的版本)
GeoIP 通过IP,定位他的经纬度,国家/地区,省市,甚至街道等位置信息。(如果不需要这个不是必须的,配置时候去掉这个选项 –enable-geoip)

CentOS下yum安装

yum install ncurses-devel
yum install glib2-devel

Ubuntu下apt安装

apt-get install libglib2.0-dev
apt-get install libncursesw5-dev

2、安装GoAccess

CentOS下安装

wget http://sourceforge.net/projects/goaccess/files/0.4.2/goaccess-0.4.2.tar.gz
tar zxvf goaccess-0.4.2.tar.gz
cd goaccess-0.4.2
./configure --enable-utf8
make
make install

Ubuntu下安装

apt-get install goaccess

GoAccess使用介绍

启动参数介绍:

  • -b 流量消耗统计,如果想要提高解析速度,不要开启这个选项。缺省值为不开启此选项
  • -f 日志文件路径。
  • -s HTTP 状态码报告,为了能够更好的解析日志,选项被默认关闭。
  • -e 指定IP地址的访问统计。
  • -a 通过代理的请求统计。

菜单介绍

  • F1 帮助菜单
  • F5 刷新
  • q 退出当前口窗、菜单、或是当前查看的选项
  • o 打开当前的选项、菜单
  • c 改变窗口配色(目前只有两种 默认和绿色)
  • SHIFT + TAB 从当前选定模块向后切换
  • RIGHT 打开当前选中模块,查看详细信息
  • s 通过日期排序,只会在访问请求模块起作用
  • S 通过点击次数排序,只会在访问请求模块起作用
  • / 查看详细信息的窗口进行搜索
  • n 通过/进行查找后,查找下个匹配的内容的位置,如果没有则在窗口底部显示“search hit BOTTOM”
  • t 在查看详细信息窗口,移动指针到最顶部
  • b 在查看详细信息窗口,移动指针到最底部

使用实例

  • 最简单、快速的使用方式
goaccess -f /data1/logs/blog.wuwangwo.net/access.log
  • 产生完整、全面统计数据的使用方式
goaccess -f /data1/logs/blog.wuwangwo.net/access.log -a -s -b
  • 通过管道的方式将更多access log 通过GoAccess解析
zcat access.log.*.gz | goaccess

或者

zcat -f access.log* | goaccess
  • 另外一种通过管道使用GoAccess解析日志的方式
sed -n '/05\/Dec\/2010/,$ p' access.log | goaccess -s -b
  • 低优先级运行GoAccess的方式
nice -n 19 goaccess -f access.log -s -a -b
  • 如果你只把GoAccess安装到了一台服务器上
ssh user@server 'cat /var/log/apache2/access.log' | goaccess -s -a -b

注意事项

  1. 每一个详细信息窗口,只显示300条数据
  2. GoAccess 通过管道解析日志时将禁用实时解析的功能

总结

GoAceess 不是很大的一款软件却有着强大的功能即使软件可能还有些BUG,软件的更多介绍信息请查看GoAccess的官方网站«./GoAccess»,当前版本的官方手册页面 Man Page

勿忘我博客的搭建过程(Ubuntu下安装Nginx+PHP+MySQL)

Published / by 成成 / Leave a Comment

简述下此博客的搭建过程,现在的访问到的博客是第二次搭建了,第一次搭建完的时候出现了点问题,然后处理各种问题服务器被高的乱七八糟实在是不愿意再去解决自己搞出的问题了,直接重新刷新了系统,从头开始安装,由于经过了第一次的安装,第二个过程中就少了很多纠结很多问题
服务器:服务器采用的linode的VPS(日本东京机房)
不再多说直接简述服务器的搭建过程
软件准备:

wget http://nginx.org/download/nginx-1.1.10.tar.gz
wget http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.14.tar.gz
wget http://cdnetworks-kr-1.dl.sourceforge.net/project/mcrypt/MCrypt/2.6.8/mcrypt-2.6.8.tar.gz
wget http://cdnetworks-kr-1.dl.sourceforge.net/project/mcrypt/Libmcrypt/2.5.8/libmcrypt-2.5.8.tar.gz
wget http://cdnetworks-kr-1.dl.sourceforge.net/project/mhash/mhash/0.9.9.9/mhash-0.9.9.9.tar.gz
wget http://cdnetworks-kr-2.dl.sourceforge.net/project/pcre/pcre/8.20/pcre-8.20.tar.gz
wget http://jp.php.net/distributions/php-5.3.8.tar.gz
wget http://dev.mysql.com/get/Downloads/MySQL-5.5/mysql-5.5.19.tar.gz/from/http://ftp.jaist.ac.jp/pub/mysql/

操作系统采用的 Ubuntu 11.10 64bit(系统较为纯净要安装一些必要的工具软件)

apt-get install gcc g++ ssh automake cmake build-essential autoconf make re2c wget cron bzip2 rcconf flex vim bison m4 mawk cpp binutils libncurses5 unzip tar libncurses5 libncurses5-dev libtool libpcre3 libpcrecpp0 libssl-dev zlibc openssl libxml2-dev libltdl3-dev libpcre3 libpcrecpp0 libssl-dev zlibc openssl libxml2-dev libltdl3-dev libmcrypt-dev

编译安装PHP所需的支持库

tar zxvf libiconv-1.14.tar.gz
cd libiconv-1.14/
./configure --prefix=/usr/local
make
make install
cd ../

tar zxvf mhash-0.9.9.9.tar.gz
cd mhash-0.9.9.9
./configure
make
make install
cd ../

tar zxvf libmcrypt-2.5.8.tar.gz
cd libmcrypt-2.5.8/
./configure
make
make install
/sbin/ldconfig
cd libltdl/
./configure --enable-ltdl-install
make
make install
cd ../../

tar zxvf mcrypt-2.6.8.tar.gz
cd mcrypt-2.6.8/
/sbin/ldconfig
./configure
make
make install
cd ../

tar zxvf pcre-8.10.tar.gz
cd pcre-8.10
./configure
make
make install

安装MySQL,版本5.5.19

tar zxvf mysql-5.5.19.tar.gz
cd mysql-5.5.19
/usr/sbin/groupadd mysql
/usr/sbin/useradd -g mysql mysql
cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql  -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8-unicode_ci -DMYSQL_DATADIR=/usr/local/mysql/data -DWITH_INNOBASE_STORAGE_ENGINE=1 -DENABLED_LOCAL_INFILE=1 -DEXTRA_CHARSETS=all -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DSYSCONFDIR=/etc -DMYSQL_UNIX_ADDR=/tmp/mysqld.sock -DMYSQL_TCP_PORT=3306
make
make install
cd ../mysql
cp support-files/my-small.cnf /etc/my.cnf
/usr/local/mysql/scripts/mysql_install_db --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data
/usr/local/mysql/bin/mysqld_safe --user=mysql&
/usr/local/mysql/bin/mysqladmin -u root password 'XXXXXX'

安装curl,没有想到系统纯净到连curl都没有

apt-get install libcurl4-gnutls-dev

安装PHP,版本5.3.8

tar zxvf php-5.3.8.tar.gz
./configure --prefix=/usr/local/php --with-config-file-path=/usr/local/php/etc --with-mysql=/usr/local/mysql --with-mysqli=/usr/local/mysql/bin/mysql_config --with-iconv-dir=/usr/local --with-zlib --with-libxml-dir=/usr --enable-xml --disable-rpath --enable-discard-path --enable-safe-mode --enable-bcmath --enable-shmop --enable-sysvsem --enable-inline-optimization --with-curl --with-curlwrappers --enable-mbregex --enable-fastcgi --enable-fpm --enable-force-cgi-redirect --enable-mbstring --with-mcrypt --enable-gd-native-ttf --with-mhash --enable-pcntl --enable-sockets --with-xmlrpc --enable-zip --enable-soap

补充下如果需要使用LDAP、FreeType等,需要安装以下几个包

apt-get install libfreetype6-dev libjpeg8-dev libpng12-dev slapd ldap-utils db5.1-util

PHP想要使用LDAP下面这两个是需要安装的

apt-get install libldap2-dev libsasl2-dev

对应的php编译配置为

./configure --prefix=/usr/local/php --with-config-file-path=/usr/local/php/etc --with-mysql=/usr/local/mysql --with-mysqli=/usr/local/mysql/bin/mysql_config --with-iconv-dir=/usr/local --with-freetype-dir --with-jpeg-dir --with-png-dir --with-zlib --with-libxml-dir=/usr --enable-xml --disable-rpath --enable-discard-path --enable-safe-mode --enable-bcmath --enable-shmop --enable-sysvsem --enable-inline-optimization --with-curl --with-curlwrappers --enable-mbregex --enable-fastcgi --enable-fpm --enable-force-cgi-redirect --enable-mbstring --with-mcrypt --with-gd --enable-gd-native-ttf --with-openssl --with-mhash --enable-pcntl --enable-sockets --with-ldap --with-ldap-sasl --with-xmlrpc --enable-zip --enable-soap
make ZEND_EXTRA_LIBS='-liconv'
make test
make install
cp php.ini-production /usr/local/php/etc/php.ini

执行命令查看PHP相关配置,获取PHP扩展存放目录extension-dir值

/usr/local/php/bin/php-config

以上命令输出

Usage: /usr/local/php/bin/php-config [OPTION]
Options:
  --prefix            [/usr/local/php]
  --includes          [-I/usr/local/php/include/php -I/usr/local/php/include/php/main -I/usr/local/php/include/php/TSRM -I/usr/local/php/include/php/Zend -I/usr/local/php/include/php/ext -I/usr/local/php/include/php/ext/date/lib]
  --ldflags           [ -L/usr/lib/x86_64-linux-gnu -L/usr/local/lib -L/usr/local/mysql/lib]
  --libs              [-lcrypt   -lz -lresolv -lcrypt -lrt -lmysqlclient -lmcrypt -lltdl -lcurl -lz -lrt -lm -ldl -lnsl  -lrt -lxml2 -lcurl -lxml2 -lmysqlclient -lz -lm -lrt -ldl -lxml2 -lxml2 -lcrypt -lxml2 -lxml2 -lxml2 -lxml2 -lcrypt ]
  --extension-dir     [/usr/local/php/lib/php/extensions/no-debug-non-zts-20090626]
  --include-dir       [/usr/local/php/include/php]
  --man-dir           [/usr/local/php/man]
  --php-binary        [/usr/local/php/bin/php]
  --php-sapis         [cli fpm]
  --configure-options [--prefix=/usr/local/php --with-config-file-path=/usr/local/php/etc --with-mysql=/usr/local/mysql --with-mysqli=/usr/local/mysql/bin/mysql_config --with-iconv-dir=/usr/local --with-zlib --with-libxml-dir=/usr --enable-xml --disable-rpath --enable-discard-path --enable-safe-mode --enable-bcmath --enable-shmop --enable-sysvsem --enable-inline-optimization --with-curl --with-curlwrappers --enable-mbregex --enable-fastcgi --enable-fpm --enable-force-cgi-redirect --enable-mbstring --with-mcrypt --enable-gd-native-ttf --with-mhash --enable-pcntl --enable-sockets --with-xmlrpc --enable-zip --enable-soap]
  --version           [5.3.8]
  --vernum            [50308]
vi /usr/local/php/etc/php.ini

修改文件以下地方

extension_dir = "./"

修改为

extension_dir = "/usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/"

创建fastcgi配置文件

cp /usr/local/php/etc/php-fpm.conf.default /usr/local/php/etc/php-fpm.conf

修改fastcgi配置文件

vi /usr/local/php/etc/php-fpm.conf

去掉注释以下几行的注释

pid = run/php-fpm.pid
error_log = log/php-fpm.log
log_level = notice
pm.start_servers
pm.min_spare_servers
pm.max_spare_servers

修改文件以下两行,不修改启动fastcgi会报错 “fastcgi [pool www] cannot get gid for group ‘nobody’”

user = nobody
group = nobody

修改为

user = www
group = www

启动fastcgi

/usr/local/php/sbin/php-fpm

创建日志文件目录

mkdir -p /data1/logs/blog.wuwangwo.net
chmod +w /data1/logs/blog.wuwangwo.net
chown -R www:www /data1/logs/blog.wuwangwo.net

创建程序文件目录

mkdir -p /data/htdocs/blog.wuwangwo.net
chmod +w /data/htdocs/blog.wuwangwo.net
chown -R www:www /data/htdocs/blog.wuwangwo.net

安装Nginx,版本1.1.10

tar zxvf nginx-1.1.10.tar.gz
cd nginx-1.1.10/
./configure --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module
make
make install

启动Nginx

/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf

ps:感谢在博客搭建过程中给予我巨大帮助的NoSQLFan博主iammutex苹果派博主小木马