3

PHP 部分改造为 go 与全部改造为 go 是否会提升性能?

 2 years ago
source link: https://www.v2ex.com/t/953035
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

V2EX  ›  Go 编程语言

PHP 部分改造为 go 与全部改造为 go 是否会提升性能?

  dandankele · 4 小时 48 分钟前 · 2076 次点击
由于 php-fpm 是以进程为单位提供服务的,大量 php-fpm 进程运行并接收客户端请求,当 php-fpm 极其依赖缓存、数据库等外部服务时,php-fpm 与外部服务之间的网络连接交互也会多,导致网络 IO 频繁,进而导致 php-fpm 进程间的频繁切换问题。这种情况经常在监控上显示为进程的墙钟时间比较大,cpu 消耗时间比较小。

所以在考虑如果用 go 改造的话,使用 go 去连接缓存、数据库等外部服务,php-fpm 充当纯前端 SSR 从 go 那里获取数据渲染页面。那么,在服务器资源配置不变的情况下,请求量与之前不变的情况下,应用性能是否会有所提高?这里主要指 RT 响应时间是否会缩短?

但是我觉得假设改造前是 100 个 fpm 进程,改造后还是 100 个 fpm 进程,并且还要增加一个 go 进程,100 个 fpm 依然要与 go 连接,依然会在 100 个 fpm 进程之间切换进程,所以在资源配置不变的情况下,RT 响应时间应该也不会变化太大吧?
难道需要 go 把 php-fpm 全部替代了?
60 条回复    2023-06-30 20:27:04 +08:00
EmptyDX

EmptyDX      4 小时 47 分钟前   ❤️ 1

可以一步到位,不过 golang 写业务有点难受
Nazz

Nazz      4 小时 42 分钟前

团队没人懂 golang 的话可以先试试 swoole
flyqie

flyqie      4 小时 42 分钟前   ❤️ 1

go 写业务还是有点难受的。。

你确定要这么干?
flyqie

flyqie      4 小时 42 分钟前

@flyqie #3

而且 php 是弱类型。。。

迁移起来。。可能不太容易。
wangritian

wangritian      4 小时 41 分钟前

先确定是否真的需要走这一步,看看实际 QPS 是多少
如果你团队的技术栈都是 php ,换 swoole 比较好
yekern

yekern      4 小时 41 分钟前

部分业务并发高的地方, 可以用 go 写, 然后用 nginx 转发过去 这样 原来 100 个 fpm 就可以降低到 50 个以下了.
INCerry

INCerry      4 小时 40 分钟前   ❤️ 1

并不只有 Go 才有协程,PHP/C#/TS/Java/C++都有协程,你这个场景可以直接上协程,swoole 搞起来 IO 问题就解决了
Vegetable

Vegetable      4 小时 39 分钟前   ❤️ 1

不靠谱
建议不要做这种重构, 而是先把高负载高占用的服务挑出来, 重新设计实现.
yekern

yekern      4 小时 39 分钟前

其实 不建议用 swoole 如果是个大团队 有人可以搞 swoole 源码和二开可以搞搞, 没有不建议弄 可以试试 workman 或者 webman
dandankele

dandankele      4 小时 39 分钟前

@EmptyDX 主要 php 在组装数据方面写的比较爽。。所以我也不太想全部改掉
dandankele

dandankele      4 小时 38 分钟前

@flyqie 那一般 go 用来干啥啊?不是说用 go 来提升 php 性能是比较好的选择吗?
dandankele

dandankele      4 小时 35 分钟前

@yekern 好像有点道理,可以减少 fpm 的数量了,go 的 rt 时间相比原先 fpm 缩短了,如果并发量不变的话,少量的 fpm 是可以承住的
flyqie

flyqie      4 小时 33 分钟前

@dandankele #11

话是这么说。。但是得看你实际情况啊。

老项目除非真的项目瓶颈,不然不建议大改。

改最好也是慢慢改,go 跟 php 比虽然会提升性能,但是 php 的很多东西在 go 写起来是有些麻烦的。

他俩走的路子区别还是挺大的。
brader

brader      4 小时 31 分钟前

花精力研究这个,不如用 Go 重构。要么就别改
coffeygao

coffeygao      4 小时 30 分钟前

看你当下这个场景,我觉得 swoole 可能是成本最低的。
dandankele

dandankele      4 小时 29 分钟前

@flyqie 是啊。。所以我来这问问没有经历过类似这样情况的的朋友。。换语言改造提升性能我也是想着只把性能瓶颈的地方换了。。但在考虑的时候想了主题中提到的问题,所以怀疑只把这部分瓶颈的地方换掉是不是不会有提升?所以才有了这主题帖
japeth

japeth      4 小时 26 分钟前

之前团队有个项目,单纯把 php 翻译起 go,没做任何优化,性能翻倍了
leonshaw

leonshaw      4 小时 23 分钟前

换 go 不是一样依赖外部服务?先找到瓶颈在哪
dandankele

dandankele      4 小时 23 分钟前

@japeth 具体怎么说?性能翻倍表现在哪里?相同 qps 下 cpu 降了?还是相同配置下 qps 升了?还是啥的?
flyqie

flyqie      4 小时 22 分钟前

@japeth #17

php 翻译到 go 。。

有点接近小重构了,这俩区别还是挺大的,你们原来 php 用的是 php-fpm 还是 workerman/swoole 这种?
star7th

star7th      4 小时 21 分钟前

我的建议是,先把系统拆分,按功能拆也行,按业务拆也行。拆开后,看哪个有性能问题,就哪个用 go 重写。
如果没办法拆,那就整个重写,或者保持现状。
dandankele

dandankele      4 小时 21 分钟前

@leonshaw 瓶颈分析了啊。。就是依赖外部服务导致网络 IO 大,fpm 进程切换频繁消耗 cpu 资源。。用 go 的话至少是协程、线程级别的上下文切换。。。但是相同服务器配置下,两个放一起能否提升性能就是本文要问的问题
hewiefsociety

hewiefsociety      4 小时 21 分钟前

8355

8355      4 小时 19 分钟前

webman 和 swoole 改 go 提升是很有限的
改 go 的主要目的是提高单机并发数
至于原来的业务假如有调大量的外部接口和流式执行依赖查库性能并不会有多少提升。
提升比较大的是需要从数据库查询大量数据之后做处理这个部分的耗时
laravel 的性能确实比较垃圾 毫无疑义 但已经不是现代 php 了
用 laravel 的底线是要上 octane
dandankele

dandankele      4 小时 16 分钟前

@8355 意思是改用 go 的话对于响应时间优化并不会有太大帮助?依赖外部服务查询数据的瓶颈主要还是在于网络传输性能与外部服务的性能吗?
herozzm

herozzm      4 小时 16 分钟前   ❤️ 1

我是反着走,之前有 go 写的,业务一繁杂,go 写来相当难受,一个普通的用户权限控制,go 啥都没有,而 php 就几行代码搞定了
leonshaw

leonshaw      4 小时 13 分钟前

@dandankele 不知道这个结论是想出来的还是测出来的?进程大概有多少,IO 并发有多少?
defunct9

defunct9      4 小时 5 分钟前

会。比如 www.huabbao.com ,之前是 ThinkPHP+K8S ,后来瓶颈部分统统用 go 拆出来了。很不错
dandankele

dandankele      4 小时 4 分钟前

@leonshaw 目前只是根据少部分监控数据猜测出来的。。php 的调用栈的监控数据显示,每个慢的请求中,都是慢在了从外部服务获取数据的过程(如 fread 、Memcached::get 、Redis::get 之类的),而且消耗的时间上,wall time 挺大的,但是 cpu time 很小。并且服务器网络监控上,服务器带宽、收发数据包 pps 都没有打满。。所以目前是猜测在等待网络 IO 传输数据的过程中进程切换导致的时间消耗。。。进程目前大概是 cpu 核数的 8 倍,但再增加导致 RT 时间变长,减少的话也会变长。。
QlanQ

QlanQ      3 小时 36 分钟前

@dandankele 基于你上面的分析,如果真的是你说的这个问题,是在请求外部服务的时候,延迟高,那你只能整个重构才能解决吧,具体的就是直接使用 外部服务的时候,由目前的单次连接,改成连接池?

我以前遇到过的是,redis 所在服务带宽满了,阿里的 redis ,出口带宽很低,缓存的单个 key 数据量不能大

感觉还要是基于 目前的 qps 和瓶颈解决问题
php 性能确实不如 go
但是绝大部分项目,都触碰不到 php 的性能瓶颈的
在团队主要技术栈是 php 的情况下,没有必要硬上 go 吧
如果真的要上,可以按功能,甚至按接口来拆分,这样影响最小,效果明显,代价也小

当然其实我还是建议上 swoole 的,切 hyperf
pota

pota      3 小时 29 分钟前

go 我用来解决 php 异步的问题切换了部分业务过去,单纯业务还是 php 舒服
seth19960929

seth19960929      3 小时 28 分钟前

之前重构过一个服务, 日 3000w 请求. 常见的缓存接口, 还有一些个人中心收藏接口. 从 16 个 pod 降到了 5 个.
你可以参考一下.
8355

8355      3 小时 13 分钟前

@dandankele #25
举个例子说明下
情况 1
假设你提供一个接口 A
接口的功能是通过 Http 调用外部接口接口 B 接口响应时间是 100ms
那你的接口响应时间 100ms+ 无论是 go 还是 php 对吧。。。

情况 2
假设你提供一个接口 A
接口的功能是通过 Http 调用外部接口接口 B 接口响应时间是 100ms
同时还要再依赖接口 B 的返回值去调接口 C 接口响应时间是 100ms
那你的接口响应时间 200ms+ 无论是 go 还是 php 对吧。。。

情况 3
假设你提供一个接口 A
接口的功能是通过 Http 调用外部接口接口 B 接口响应时间是 100ms
另外去调接口 C 不需要依赖 B 的返回值 接口响应时间是 100ms
使用 go 和 swoole A 接口响应时间是 100ms+ 因为是协程并发调用 等待时间以最长的为准。
这种情况下用 go/swoole 可以改善响应时间 但 swoole 和 go 的差距并没有那么大

同样逻辑适用于写库 调接口各种 io 等待的同理
串行依赖意义不大,可以并行才能降低响应时间

你需要考虑有哪些业务是适合用 go/swoole 去写 而不是说上来就重构。。。
几个接口的任务量和一个系统重构的业务量是两码事。。。
FrankAdler

FrankAdler      3 小时 11 分钟前   ❤️ 1

go 的学习成本没那么高,用业务切入边写边学,几天就能上手了,哪怕用的不精通,写出来的东西性能也吊打 php-fpm ,所以收益非常高投入低。
切多少就看你想投入多少精力动老代码了。
daley

daley      3 小时 8 分钟前

什么框架啊,如果是 laravel ,把版本升到 8 ,用 go 或者 swoole 开个 octane 加速,从此告别 fpm ,除了手写的单例代码基本不用改
everyx

everyx      3 小时 6 分钟前

看描述是 php-fpm 由于没有连接池不能复用 IO 导致的 IO 拥堵,切换到 Go 可以用连接池来解决这个问题,那为什么不把这部分用 swoole 这类支持连接池的来重构呢?还能复用之前的 PHP 代码。

或者另一个角度,能否优化缓存来降低 IO 呢?前端页面缓存,API 缓存,数据库缓存这些
hongfs

hongfs      3 小时 3 分钟前

@everyx mysql redis 这些配置成长连接,算是连接池了吧。
japeth

japeth      2 小时 57 分钟前

@dandankele qps cpu 我当时没看 因为也不是我重构的 季会的时候 做的那个人汇报的
japeth

japeth      2 小时 57 分钟前

@flyqie php-fpm 用的 larval 框架
japeth

japeth      2 小时 54 分钟前

@dandankele 相同配置下 qps 升了
dw2693734d

dw2693734d      2 小时 52 分钟前   ❤️ 1

go 写业务我觉得还行啊
leonshaw

leonshaw      2 小时 52 分钟前

@dandankele
要确认进程等待时间是在等待 IO 还是等待调度(大致看一下 CPU 利用率和 load ,做 profiling )。考虑把一些同步阻塞的 IO 异步化。
Bazingal

Bazingal      2 小时 52 分钟前

@japeth 说不定用 php 重写一遍 qps 也升了
huangwei8ku

huangwei8ku      2 小时 51 分钟前   ❤️ 1

golang 发展到如今,其实在微服务领域已经有一些不错的方案了,字节也好,bilibili 也好。都有开源的项目。我局的吧,如果你要用 golang 来重构,心里上要接受一些不同,甚至是认知上的改变,比如我很多同事,以前搞 java 的,喜欢了封装继承多态那套东西,用了 golang 水土不服了很长一段时间。但是,当你能驾驭 golang 这批烈马之后,你会发现,以前你看不上的 2 核 4G 的 ESC 原来也可以这么顺眼。还有就是,当我们进入了 golang 的世界后。你写微服务方式大概率都会改变。
japeth

japeth      2 小时 45 分钟前

@Bazingal 你可以试试哈哈哈哈哈
zhangtest

zhangtest      2 小时 39 分钟前

我们公司项目日活百万+,目前用的 php 绰绰有余,一些业务 PHP 不好搞用的 GO ,比如某个时间点要推送几十万营销消息,go 协程速度才能满足需求。
adoal

adoal      2 小时 34 分钟前

“从 A 语言换为 B 语言导致性能提升 XYZ 倍”这种事一般不是因为换语言本身,而是换语言这个大动作不可能以对旧版系统慢慢重构的方式进行,那么本质上就是重写一遍,那么就要重新架构,重新思考,“终于特喵的有机会偿还技术债了” ^_^
coderxy

coderxy      2 小时 16 分钟前

用 go 写业务挺爽的, 就是你原来是 php ,迁移到 go 强类型,数据库等各个方面很可能有字段类型不一致的坑。
p1gd0g

p1gd0g      2 小时 15 分钟前

这不就是我司吗,从 php 逐渐迁移到 go ,机器数量少了 90%(当然一部分原因是旧 php 代码写的太烂)
yanue

yanue      2 小时 3 分钟前

go 写业务主要是 orm 不顺畅, 其他很爽的
mooniitt

mooniitt      1 小时 55 分钟前

F 墙( base64 ) aHR0cHM6Ly9jaG5yb3V0ZS5jb20vYXV0aC9yZWdpc3Rlcj9jb2RlPUZUSzZJRQ==
OMGZui

OMGZui      1 小时 45 分钟前

业务还是 php 吧,一些要求高性能的点可以切到 go
happy321

happy321      1 小时 11 分钟前 via iPhone

@yanue 请问这个 orm 不顺畅 具体是哪些问题啊?
vmlinz

vmlinz      1 小时 1 分钟前 via iPhone

试试 roadrunner ?
jiangshanmeta

jiangshanmeta      44 分钟前

增加性能我不确定
但是能增加就业
happy321

happy321      41 分钟前 via iPhone

PHP 哪有你说的这么高级,有进程切换都笑哭了。。应该就是你的 io 慢吧? 下面是网上找的:
1 、nginx 和 php-fpm 都是多进程,一个进程只有一个线程;
2 、nginx 一个线程是非阻塞/io 多路复用/epoll 模型,将请求分发后无需等待,仅监听回调结果
3 、php-fpm 一个线程是阻塞模型,必须等待该客户端请求 php 服务端返回数据,下一个 nginx 发过来的请求才能被受理
vmlinz

vmlinz      41 分钟前 via iPhone

https://habr.com/en/articles/646397/

nginx php-fpm
nginx unit
Laravel octane(roadrunner, swoole)
Huelse

Huelse      18 分钟前

说实话不如加机器,除非重构

</div


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK