一文让你知道为什么学了PHP的都要转学Go语言( 五 )


GO的语言描述效率毋庸置疑,对上述所有公共组件的实现,均未超过1000行代码,就解决了某个面上的问题 。
(以上的部分代码已经在Uwork开源项目seine中提供)
性能评测压力测试环境说明:

  • 服务运行机器:单台空闲B6,24核CPU、64G内存 。
  • PHP API环境:Nginx+PHP-FPM,CI框架 。其中Nginx启动10个子进程,每个子进程最大接收1024个连接,php-fpm使用static模式,启动2000个常驻子进程 。
  • Golang API环境:使用go1.8.6编译,直接拉起Golang API Server进程(HttpServer),不考虑调优 。
  • 客户发起请求测试程序:使用Golang编写,协程并发,运行在独立的另外一台空闲B6上,24核CPU,64G内存,依次在1-2000个不同级别(并发数步长为50)的并发上分别请求20000次 。
压力测试结果对比
一文让你知道为什么学了PHP的都要转学Go语言

文章插图
 
在Golang API框架中,当并发数>50时,处理QPS在6.5w/s附近波动 。表现稳定,压力测试过程无报错 。
Nginx+php-fpm,只在index.php中输出exit('ok'),当并发数>50时,处理QPS在1w/s附近波动 。表现稳定,压力测试过程无报错 。
Nginx+php-fpm+CI框架中,逻辑执行到具体业务逻辑点,输出exit('ok'),当并发数>50时,处理QPS在750/s附近波动 。并且表现不稳定,压力测试过程中随着并发数的增大,错误量随之增加 。
通过压力测试可以发现,Golang和PHP在执行性能上,并没有什么可比性;而使用Golang实现的HTTP API框架,空载时单机性能QPS达到6.5w/s,还是非常令人满意的 。
开发过程中需要注意的点以下是在实际开发过程中遇到的一些问题,仅供参考:
异常处理统一使用error,不要使用panic/recover来模拟throw…catch,最初我是这么做的,后来发现这完全是自以为是的做法 。
原生的error过于简单,而在实际的API开发过程中,不同的异常情况需要附带不同的返回码,基于此,有必要对error再进行一层封装 。
任何协程逻辑执行体,逻辑最开始处必须要有defer recover()异常恢复处理,否则goroutine内出现的panic,将导致整个进程宕掉,需要避免部分逻辑BUG造成全局影响 。
在Golang中,变量(chan类型除外)的操作是非线程安全的,也包括像int这样的基本类型,因此并发操作全局变量时一定要考虑加锁,特别是对map的并发操作 。
所有对map键值的获取,都应该判断存在性,最好是对同类操作进行统一封装,避免出现不必要的运行时异常 。
定义slice数据类型时,尽量预设长度,避免内部出现不必要的数据重组 。

【一文让你知道为什么学了PHP的都要转学Go语言】


推荐阅读