一次简单的Nginx、Apache性能压力测试

日志未经声明,均为Purekid原创。版权采用『 知识共享署名-非商业性使用 2.5 许可协议』进行许可。

物理环境:

使用阿里云节点, 按量付费,4核 内存 4G 普通硬盘

软件环境:

Ubuntu: 14.04_64 LTS

Apache: 2.4.7 (Prefork 、StartServers 4 、MinSpareServers 4 、MaxSpareServers 8、MaxRequestPerchild 64、MaxClients 2048)

Nginx: 1.1.19  (worker_processes 4 、worker_connections 512)

PHP(FPM): 5.5.18
测试方法:

在内网中的另一台机器上,

使用

ab -n 2000 -c 300 http://10.117.51.46:80/ 单apache

ab -n 2000 -c 300 http://10.117.51.46:8080/ nginx+apache

ab -n 2000 -c 300 http://10.117.51.46:8888/ nginx+fpm

分别进行压测,每个测试之间sleep 60s

压测结果信息:

总请求2000 并发 100

b

总请求2000 并发 300

a

总请求2000 并发 500

c

总请求5000 并发 800

d

总请求8000 并发 800

e

 

结论:

a. 在低并发下(2000 / 300), 三个方案的稳定性和处理能力相差无几

b. 当并发升高至(2000 / 500)的时候, nginx-fpm的速度优势非常明显,但nginx-apache稳定性很明显,单apache的速度和稳定性处于中庸水平

c. 当访问并发提供至(5000 / 800)的时候,结论与b几乎一致,此时nginx-apache和单apache的处理速度几乎相同,但单apache的请求失败数量已大幅提高,接近崩溃状态

d. 当访问并发至(8000 / 800)的时候,nginx-fpm有一定的速度优势,但nginx-apache的稳定性体现非常明显,而单apache在速度和稳定性上几乎已经崩溃

SNS实现采用的技术大多是PHP,如果采用java、 .net是否同样适用?

日志未经声明,均为Purekid原创。版权采用『 知识共享署名-非商业性使用 2.5 许可协议』进行许可。

从语言层面来讲是肯定适用的,甚至来说大部分高级语言都能做出一个像样的SNS。

存在即合理,PHP、Python和Ruby等动态语言在SNS和大量WEB2.0项目中流行肯定是有原因的。

一般来说大部分项目初创阶段都会选择成本最低,效率最高的手段打磨出产品原型,尽快发布上线以获得及时的用户反馈情况来论证项目模式的可行性,这个阶段看重 起步快、开发快、迭代快。
当产品上线运营并在获得一定成功过后,一般就会倾向于 运行稳定、性能高、扩展方便,这个时候就要具体项目具体分析了。如果当前的技术体系可以满足项目的发展需求,那这种情况最好,不需要对技术架构做大的变动(我觉得FB算这一种,他们大部分的上层应用还是PHP,而且在这种背景下他们才搞出了HIPHOP和HHVM)。但是如果之前的技术体系无法支撑可遇见地规模化发展,那变更技术体系便势在必行了(比如淘宝)。

一个大型项目选择技术体系的时候(没有历史技术包袱的情况下),语言本身的特性并不是最重要的,还要优先考虑到成本(不同的技术体系对服务器软硬件成本影响是很大的,特别像.NET这种土豪才敢用的体系一般的SNS这种前期超低现金流的项目是不敢随便上的,不同技术体系的工资差距也很大的,说到这里为广大PHPer抹把泪)、团队规模(3个人的团队你要用J2EE何必呢)、开发效率(SNS这种项目一般前期是需要很快迭代出功能原型的,动态语言的开发效率和部署效率一般来说是高于静态语言的)、招聘难易度等因素。

我是PHP的重度使用者,也是Python狂热粉丝,曾经也做过好几个J2SE和J2EE的项目,现在业余时间都在琢磨Golang。还是那句话,语言没有优劣,只有适不适合。

知乎原文:  http://www.zhihu.com/question/19764454/answer/21666667

队列是什么意思?

日志未经声明,均为Purekid原创。版权采用『 知识共享署名-非商业性使用 2.5 许可协议』进行许可。

首先,队列是一种数据结构,用链表和数组都可以实现,队列的特点就是先放入队列的数据先出队列。
不过看到话题标签有Redis,猜测题主想问的应该是现在很广泛使用的消息队列(MQ)。这里的消息不只是简单的文本信息,也可以是序列化后的对象。现在比较流行的开源消息队列系统有Beanstalkd,RabbitMQ,Redis(可以作为队列系统使用)等,其核心作用都是先将消息数据通过系统接口按顺序放入队列(暂存于内存),需要时再按放入的顺序依次取出以作后续处理。
就拿我前段时间做的邮件发送系统举例:
系统以HTTP协议提供服务,对外提供的主要功能是发送邮件,API地址为 /api/msg.send。使用者只要以POST请求此地址,传入subject,body,recipient这三个参数,即可发送一封邮件。

方案1: 不使用数据库,不使用队列
请求接口时,控制器直接调用sendmail或外部smtp服务器发送邮件,整个发送过程HTTP请求处于等待状态,待邮件发送完成,返回发送结果(只是调用发送程序是否成功的结果,不是邮件真正的发送结果,真正发送结果需要分析邮件日志)
这个方案最简单直接,平时发送少量邮件是可以的,但是缺点也很明显:
1. 因为接口调用时整个邮件发送过程都是同步进行的,每次请求都要等待邮件发送端完成处理,必然导致每次调用接口的等待时间增长。
2. 当系统接口并发请求较高时,系统可用性不仅受限于WebServer的处理能力,还完全受限于邮件发送端软件的处理能力,其中任一环节故障就会导致整个系统无法提供服务。
3. 若邮件发送端软件出现故障(比如SMTP连接超时),导致某次请求时邮件发送失败,那这封邮件内容便彻底丢失了,系统没有任何存留,不能实现自动重发。

方案2: 使用数据库,不使用队列
请求接口时,将要发送的邮件信息存入数据库,表结构如下:
id | subject | body | recipient | sent_at | failed_at | failed_times
然后在服务器上运行一个定时任务,每秒一次读取 sent_at=0 && failed_times < 10 的记录,随后调用邮件发送端发送邮件,成功后把sent_at设为当前时间,失败后设置failed_at并累加failed_times。 方案2已经用到了类似队列的思想。

相对于方案1的提升:
1. 去掉了同步发送邮件的操作,接口请求响应会快很多
2. 邮件发送失败后可以重发,邮件不会丢失
3. 当邮件发送端完全失效后系统也可以接受邮件发送请求,待发送端恢复后可以继续发送邮件。

但还是存在缺点:
每次请求都会写一次数据库,当大并发量或者大数据量(一次请求包含100万个收件人)时,数据库负载过高影响稳定性,同时也会严重增加接口的响应时间(一下子写入100万条记录不是闹着玩的)

方案3: 数据库 + 队列

请求接口时,将要发送的邮件信息以JSON格式存入队列系统,放入的单个消息形如:
{
“subject” : “今天没吃药”,
“body” : “感觉自己”,
“recipient” : “mengmeng@da.com”
}

现在的队列基本上都是内存队列,数据存取非常快,一瞬间写入100万条数据再也不是难事。
随后,在服务器上运行一个常驻进程任务(Worker),实时监听队列中是否有新的消息(Job,此处指邮件信息)。当新消息进入时,从队列中取出消息,调用邮件发送端完成处理,发送成功后将此消息销毁并将消息内容插入数据库(同方案2),如果发送失败,将此消息重新放入队列,并加入一个60秒的延时标记,意味60秒后再取出处理。

这样改进后整个系统的吞吐量和响应速度将大大提升,而且同时也让系统支持了分布式运行的能力。每个Worker进程都可以视为一个处理节点,倘若把worker分散到不同的服务器上,便实现整个系统的分布式处理了,这也是队列的一个重要特性之一。

在我实际项目中还是做了许多基于方案3的改进,对于群发还使用了邮件列表和邮件模板等设计,整个系统类似Mailgun和Sendcloud的设计,等整个系统稳定下来,我会考虑将代码开源到Github。

这个例子只是队列的一个常见使用场景,一般来说在需要缓解数据库写入压力的场景下面,都可以考虑使用消息队列,还有一些需要分布式处理的情况下,也是队列很好的使用场景。

现在大部分语言都有成熟的消息队列处理组件,可以很方便的使用各种队列系统,比如我常用的
Laravel 便原生支持了 Beanstalkd,Amazon SQS,IronMQ,Redis。

抱砖引玉,不足之处请指正,谢谢。

知乎原文:http://www.zhihu.com/question/26533799/answer/33154508

用 PHP 编写支持高并发的网站,需要做什么处理?

日志未经声明,均为Purekid原创。版权采用『 知识共享署名-非商业性使用 2.5 许可协议』进行许可。

一般来说,解决WEB高并发的有效手段都是采用可线性扩展的多层分布式架构,
我生产项目的架构是这样的,就在这里抛砖引玉一下。

  1. Webserver (Nginx) :这一层是可以轻松分布式部署的,结合智能DNS解析可以简易地防止单点故障、实现区域访问加速,结合LVS很容易实现负载均衡。这一层主要是负责处理静态请求和转发PHP请求至第二层的PHP处理节点,至于静态资源地址(misc.xxxx.com)可以单独拿出来部署,或者直接使用商用的云存储服务(国内七牛不错,国外有Amazon S3)
  2. PHP处理节点:一个节点其实就是一个监听特定端口的系统进程,webserver的请求通过负载均衡器(我用的AWS的loadbalancer)进行分发,很好实现分布式和负载均衡。我现在用的还是php自带的php-fpm,其实facebook出的hhvm性能非常强悍,但是还不能100%通过我项目的单元测试,等hhvm成熟过后可以平滑替换
  3. 高速缓存:用的memcached,这一层的作用主要是减轻数据库IO和加快热数据访问,缓存策略与程序耦合度较高,不赘述,但简单地说有两种方式,一种是在程序的全局层面加一个缓存处理,这种方法代码耦合度低,但是有效命中率不高,有些项目不一定适应,另一种是在具体的数据存取处加缓存处理,这种办法程序耦合度较高,但是缓存命中率非常高,几乎没有无效缓存存在,我用的是这种。
  4. 数据库 :我现在的项目数据规模不大,暂时只用了单台数据库,但是程序逻辑上已做好了数据库线性扩展的准备。其实数据库层的扩展是老生常谈了,常用手段是分库分表,这一块需要在前期的代码就打下基础,另外更平滑地手段是使用中间件,比如360的Atlas,阿里巴巴的cobar,淘宝的TDDL,中间件可以在不大范围变更代码的情况下扩展,但是具体的使用场景还是有限的,具体项目还需单独考察。
  5. 其他:根据不同的项目,架构还可以选择性地使用队列,我现在用的beantalkd,Redis也是一个很好的选择。队列常用的使用环境是邮件发送和站内消息推送上面,但是在某些场景下也可以作为核心数据库的缓冲,对应对大并发或者突发性流量也是不错的选择

 

知乎原文: http://www.zhihu.com/question/20049768/answer/21635940

为什么我要选择Laravel?

日志未经声明,均为Purekid原创。版权采用『 知识共享署名-非商业性使用 2.5 许可协议』进行许可。

Laravel是PHP 5.3之后开发的新框架,充分使用了PHP 5.3之后的新特性,不像很多老牌框架有一大堆历史包袱。
官方文档详尽丰富且归类科学,稍微有一点PHP基础便可很快入门,写出可用的示例程序
核心功能大量使用Composer第三方类库,在很多人看来这是Laravel的弊病之一,但我认为这正是其优雅设计哲学之体现。所谓 术业有专攻,专业的人做专业的事, 成熟的第三方类库往往是专业团队经过长时间迭代打磨的成果,比如Laravel大量选用的symfony组件,日志库 monolog,时间库 carbon 都是该类别最稳定流行的库。
我相信,短暂尝试后,很快你便会爱上Laravel,同时会爱上Composer的便捷。

THE PHP FRAMEWORK FOR WEB ARTISANS你,值得拥有。
——-
框架的性能不是不重要,只是没有重要到需要优先考虑的地步,在我很有限的几年WEB开发经验下面,我觉得90%的性能瓶颈都是在数据库层面,PHP层面即便真地出现性能瓶颈,线性地增加PHP处理节点或者使用HHVM这种开源项目也是无痛且高效的办法。

我认为WEB开发多数情况下是敏捷开发,因此选择框架是大致可以考虑以下几点:
1. 开发迅速 : 基础组件齐全且不累赘,框架的设计哲学可以助人快速写出优雅且高效地代码(相对而言)
2. 文档简明丰富和社区活跃 : 文档不是多就好,精心规划的文档内容组织和简明到位的排版可以大量降低框架的学习成本,比单纯的求多求全堆砌内容高明很多。活跃的社区可以确保问题被快速响应,拥有大量工具模块
3. 逻辑清晰 : 框架的代码逻辑清晰,代码的目录结构清晰,轻松地协作开发和代码重用
4. 可扩展和无痛版本更新 : 核心代码低耦合,便于扩展,框架设计有预见性,版本升级无需大功干戈
5. 便于测试 : 一般来说满足了 4 ,测试都不会是大问题,Codeception,phpunit 这种第三方测试工具很多
6. 性能 : 大多数WEB应用无需考虑框架层面的性能问题,当你真的需要考虑框架性能问题的时候,也有很多平滑地解决方案
7. 无重大BUG漏洞:这个当然最重要,不过一般来说成熟的开源框架不会有这个问题,放最后

知乎原文: http://www.zhihu.com/question/21617669/answer/21127210

Book List

日志未经声明,均为Purekid原创。版权采用『 知识共享署名-非商业性使用 2.5 许可协议』进行许可。

[已读      已读三次以上    准备读]

DB:
SQL反模式               
高性能MySQL(第3版)
深入浅出MySQL数据库开发、优化与管理维护
System:
Orange’S:一个操作系统的实现
汇编语言
Program:
C程序设计语言(英文版第二版)
Python核心编程
大话数据结构
UNIX环境高级编程
UNIX操作系统设计
设计模式之禅
PHP5与MySQL5 Web开发技术详解
JavaScript高级程序设计
编译原理
数据结构与算法分析
Lua游戏开发实践指南
Other:
黑客与画家
Rework 重来
Scrum要素
人月神话
大型网站技术架构 核心原理与案例分析/李智慧

Mongodm : A PHP Mongodb ORM

日志未经声明,均为Purekid原创。版权采用『 知识共享署名-非商业性使用 2.5 许可协议』进行许可。

最近通过Github的PHP排行榜了解到Laravel这个PHP框架,深入尝试过后更是爱不释手,简洁优雅的设计非常适合敏捷开发型的WEB项目。试用了一段时间,又大致过了一遍源代码,觉得各方面已经成熟,便决定将当前ZF2开发的生产项目转移到Laravel下面。数据库用的是MongoDB,之前在ZF2下面用的是Doctrine ODM,十分强大,但是使用下来也觉得有点笨重,心想正好趁此次改变框架的机会,将ORM一并换了。寻觅了一番,Laravel官方倒是推荐有一个Mongor可用,很简单的设计,倒是可以使用,但是在对象引用的处理上不太优雅,而且不原生支持静态工厂方法(虽然有magic方法实现),于是抽了一天时间自己搞了一个,现在自己项目也换上了,等有空了慢慢加上注释。

PS:Mongodm已经加入了Mongodb的推荐Libs页面 , http://docs.mongodb.org/ecosystem/drivers/php-libraries/

Github:  https://github.com/purekid/mongodm

mongodm

a PHP MongoDb ORM

Requirements

  • PHP 5.3 or greater
  • Mongodb 1.3 or greater
  • PHP Mongo extension

Features

  • ORM
  • Simple and flexible
  • Support for references (lazy loaded)
  • Support for inheritance

Linux环境SVN一键提交脚本

日志未经声明,均为Purekid原创。版权采用『 知识共享署名-非商业性使用 2.5 许可协议』进行许可。

Linux环境SVN一键提交脚本

发布于: 2010-12-15 / 作者:Michael Gan / 分类: Linux, Shell

在Linux下面进行svn提交的时候,如果本地进行了删除操作或者新增文件操作,你执行svn commit方法后并不会将这些文件commit到服务器,而是需要你手动svn add 或者svn delete该文件,使用此脚本可以实现当前目录下一键提交。

调用的时候可以传入一个变量,为该次commit的注释。