Laravel 如何将部分 api 一步步使用 golang 进行重构 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
zjtsunshine
V2EX    程序员

Laravel 如何将部分 api 一步步使用 golang 进行重构

  •  
  •   zjtsunshine 2019-04-28 13:44:19 +08:00 8180 次点击
    这是一个创建于 2408 天前的主题,其中的信息可能已经有所发展或是发生改变。

    目前状况: 1 )有 2 台 8 核 16G 服务器,tps1000 多。

    2 )使用 nginx+php-fpm+laravel。

    3 ) php-fpm 进程占有的 cpu 较高,经常飙到 80%以上。

    目前想一步步地将 laravel 上的 api 接口,逐步使用 golang 重构,并部署到生产环境,但又不影响生产环境功能的正常使用。比如今天先把某个使用频率较高的 api,重构成 golang,部署上去;明天再部署新的 api,一步步操作。

    1 )如果使用 Laravel-Swoole 测试了下并发性能确实提到了几十倍,但是有很多坑,怕部署到生产环境出问题。。。

    2 )若使用 golang 重构,是要在 nginx 中配置,当请求某个 api 的时候,给他转发到 go 服务器吗?有没有具体的教程,在网上没有找到了的解决方法,有没有大神求助下

    76 条回复    2019-04-29 14:43:46 +08:00
    liqihang
        1
    liqihang  
       2019-04-28 13:47:39 +08:00
    或者 golang 做服务通过 RPC 串起来呢
    alpha2016
        2
    alpha2016  
       2019-04-28 14:00:55 +08:00
    尝试用 swoole 来替换 nginx 的分发呢,可以在某台机器上小规模测试一下,效果不错的话全站引入。
    zjtsunshine
        3
    zjtsunshine  
    OP
       2019-04-28 14:02:15 +08:00
    @liqihang 使用 laravel,php-fpm,就只返回个“ hello world ”,单机最多也就几百并发,cpu 就 80%多,所以通过 RPC 恐怕不行,资源消耗,主要集中在 laravel 的环境初始化中了
    zjtsunshine
        4
    zjtsunshine  
    OP
       2019-04-28 14:04:30 +08:00
    @alpha2016 使用 laravel-swoole 有一些坑,session 混乱,上传,下载 excel 等都会有点问题,可能还有很多其他没有发现的问题,不敢部署到生产环境
    freefcw
        5
    freefcw  
       2019-04-28 14:08:03 +08:00
    并不一定需要重构,或者全部重构,先找到热点在哪里吧,这么高 cpu,肯定某些接口造成的


    @zjtsunshine 对于某些 swoole 不影响的可以直接切换 swoole,对于 swoole 可能会影响到的,就继续用 fpm,这都是解决方案
    oneonesv
        6
    oneonesv  
       2019-04-28 14:08:50 +08:00
    用 golang 也会遇到新的问题并且还要重写,何不把现有代码兼容 swoole 呢
    zjtsunshine
        7
    zjtsunshine  
    OP
       2019-04-28 14:10:35 +08:00
    @freefcw 多谢知道~~
    alpha2016
        8
    alpha2016  
       2019-04-28 14:10:44 +08:00
    @zjtsunshine session 是个问题,不过一般来说引入个新语言不是优先的方案
    zjtsunshine
        9
    zjtsunshine  
    OP
       2019-04-28 14:11:25 +08:00
    @oneonesv 嗯嗯,我们试一试 swoole 兼容
    zjtsunshine
        10
    zjtsunshine  
    OP
       2019-04-28 14:13:23 +08:00
    @oneonesv 你有将 laravel-swoole 部署到生产环境中吗?总感觉有点虚
    Kilerd
        11
    Kilerd  
       2019-04-28 14:16:03 +08:00
    拆成小服务,然后用灰度发布的方式来逐步迁移过去就行了。
    sunmonster
        12
    sunmonster  
       2019-04-28 14:19:04 +08:00
    @zjtsunshine 用 Go 重构吧,重构之后回过头来看你会发现其实有其他更好的方案
    LuoyeBug
        13
    LuoyeBug  
       2019-04-28 14:19:35 +08:00
    可以 nginx 指定路由,反向代理到后端的 go 服务
    oneonesv
        14
    oneonesv  
       2019-04-28 14:21:23 +08:00
    @zjtsunshine 我们前公司再用 量也不小 没啥问题
    zjsxwc
        15
    zjsxwc  
       2019-04-28 14:22:05 +08:00
    把要 替换部分匹配的 api 通过 nginx 转发到你 golang 服务器里
    blless
        16
    blless  
       2019-04-28 14:22:05 +08:00 via Android
    用 go 做转发效率也还可以,先写一个转发层,然后重写后的业务不转发 自己处理,随着版本更新可以慢慢把旧业务全部覆盖掉
    xioxu
        17
    xioxu  
       2019-04-28 14:23:27 +08:00
    nginx 中配置特定 location 进行反向代理, 例如^~ /api/users 意思是以 /api/users 开头的所有 http 请求, 直接 proxy_pass 到 golang 的 http 地址即可。
    当然这也要看你们 api 的认证方式了, 如果是较规范的认证方式的话这样没有问题, 否则如果是使用 session 认证的话就需要做些额外工作了。
    m939594960
        18
    m939594960  
       2019-04-28 14:24:10 +08:00
    用 openresty 做转发的逻辑,逐渐用 golang 编写的部分接口替换 laravel 的接口,等到 lravel 彻底没流量后直接干掉 laravel
    zjtsunshine
        19
    zjtsunshine  
    OP
       2019-04-28 14:39:12 +08:00
    回复好快,各位多谢多谢指导~~
    robot1
        20
    robot1  
       2019-04-28 15:45:50 +08:00
    可以参考知乎的 golang 重构方案,漫长稳妥的方案
    peinhu
        21
    peinhu  
       2019-04-28 16:07:06 +08:00   1
    不建议使用 laravel-swoole 和 laravel-s 等方案,虽然看上去很方便,性能也有不小提升,但原项目要改的地方太多,有点像针对这种方案开发项目了,得不偿失。
    要上 swoole 只能使用完全基于 swoole 开发的框架,不过现在这种框架都不成熟,周边生态也不完善,要是学那个还不如学其它语言的成熟框架了。
    mscb
        22
    mscb  
       2019-04-28 16:09:07 +08:00 via Android
    建议先 swoole
    PHPJit
        23
    PHPJit  
       2019-04-28 16:11:43 +08:00
    easyswoole 吧,有一个项目生产环境已经用上了。
    另外一个用 laravels 的也用上生产环境了
    flashrick
        25
    flashrick  
       2019-04-28 16:55:24 +08:00
    我也在纠结是 go 还是 swoole 。能说下你的机器配置么
    jswh
        26
    jswh  
       2019-04-28 17:09:24 +08:00
    go 承接所有请求,对于还没有实现的部分,转发到 nginx 上去。
    triptipstop
        27
    triptipstop  
       2019-04-28 17:34:06 +08:00
    仅仅把消耗过大的业务用 Go 写成 api
    Laravel 用 Go 的 api
    ROR 已经是很好的设计了
    smallX
        28
    smallX  
       2019-04-28 17:41:42 +08:00 via Android
    果断上 go 啊。楼主的问题已经很具体了,还怕找不到解决方法。撸 go 将是另一片天地...
    loading
        29
    loading  
       2019-04-28 17:46:49 +08:00 via Android
    解决 session 共用,然后 nginx 匹配后转发。
    namek
        30
    namek  
       2019-04-28 17:49:48 +08:00
    helloworld 8 核 16G 80%cpu 单这一点 我觉得是代码的问题 跟语言没关系
    zarte
        31
    zarte  
       2019-04-28 17:50:23 +08:00
    golang 本身是不需要 nginx 的并发性能也 ok。
    要用 nginx 的话反代到对应地址就可以了。
    zjtsunshine
        32
    zjtsunshine  
    OP
       2019-04-28 17:54:01 +08:00
    @namek 老哥你用下 laravel 就知道了
    namek
        33
    namek  
       2019-04-28 18:02:11 +08:00
    @zjtsunshine 我们是 lumen+hprose+swoole laravel 初始化确实会占用 fpm 更多的内存跟 cpu 关系不大,laravel 写接口尝试去掉意义不大的中间件比如是否初始化了 session,6 楼和 26 楼的建议都很好,几百 tps 的 hellworld cpu80%有点高了。
    OMGZui
        34
    OMGZui  
       2019-04-28 18:18:50 +08:00
    这么好的写 go 经验,干吧
    tanszhe
        35
    tanszhe  
       2019-04-28 18:28:23 +08:00
    我也用过 laravel 确实有点慢,你的瓶颈是 php 本身还是数据库?
    你可以看看 one 框架 和 laravel 非常像,性能保守估计比 laravel 高 10 倍以上
    https://github.com/lizhichao/one
    snail404
        36
    snail404  
       2019-04-28 18:30:14 +08:00
    hello world 几百并发不至于 80% 吧,什么配置,opcache 开启了吗?
    veike
        37
    veike  
       2019-04-28 18:30:20 +08:00
    8 核几百并发就彪到 80%了吗,有点恐怖啊。
    KgM4gLtF0shViDH3
        38
    KgM4gLtF0shViDH3  
       2019-04-28 18:31:42 +08:00 via iPhone
    还是用 go 吧,变成体验完全不一样,php 在内网做管理后台比较适合
    Trim21
        39
    Trim21  
       2019-04-28 19:09:06 +08:00 via Android
    可以看看知乎 Python 迁移 golang 的做法
    ben1024
        40
    ben1024  
       2019-04-28 19:27:13 +08:00
    建议先考虑下项目本身的优化和问题定位
    runningman
        41
    runningman  
       2019-04-28 19:32:17 +08:00 via iPhone
    @tanszhe one 你搞连接池没 为啥快呢 或者加你微信聊聊
    zhchyu999
        42
    zhchyu999  
       2019-04-28 19:39:32 +08:00 via Android
    低配多台机器比高配更少太机器更好用
    zjtsunshine
        43
    zjtsunshine  
    OP
       2019-04-28 20:27:35 +08:00
    @namek 感谢
    king2014
        44
    king2014  
       2019-04-28 21:35:30 +08:00
    8 核几百并发就彪到 80%,听到也有点诧异
    blless
        45
    blless  
       2019-04-28 22:16:13 +08:00 via Android
    php 不知道 不过 python 切换过来那个延迟跟 cpu 内存突然下降成一条直线简直不能再爽
    dawniii
        46
    dawniii  
       2019-04-28 22:16:19 +08:00
    @snail404
    @king2014 我去年压过 laravel,开启 opcache,关闭 session debug 等。 就两行代码,sleep 50ms 模拟业务耗时,然后直接返回 4kb 数据。 100 并发 cpu 就爆了,4 核心的机器。。。
    xiaolanger
        47
    xiaolanger  
       2019-04-28 23:22:48 +08:00
    现在是越来越感觉,laravel 似乎有些臃肿?多余?
    xiaotianhu
        48
    xiaotianhu  
       2019-04-28 23:43:47 +08:00
    swoole+laravels 基本上没啥问题,性能提升很大
    xiaotianhu
        49
    xiaotianhu  
       2019-04-28 23:44:25 +08:00
    swoole+laravels 提升很大,稳定性也 ok 没啥问题.不放心的就启一个 fpm 实例,用负载均衡兜底.

    我们线上就这么干了很久了.很爽.
    2kCS5c0b0ITXE5k2
        50
    2kCS5c0b0ITXE5k2  
       2019-04-28 23:48:30 +08:00
    不是有 lumen 吗...
    autogen
        51
    autogen  
       2019-04-29 01:49:55 +08:00
    额。。。遇到点问题就想着换语言。。。。

    tps1000 不算高,
    php-fpm 占 CPU 高可能是 php-fpm.conf 配置不正确,

    1. 可以考虑固定下 php-fpm 进程数:
    > pm = static
    > pm.max_children = 300

    2. 关闭超时链接:
    > request_terminate_timeout 10s

    3. 记录 slow log:
    > slowlog = logs/slow.log
    > request_slowlog_timeout = 3s

    4. 如果 slow log 太多,考虑代码问题(有没有用 cache,db 连接数,查看 sql slow query log,优化索引、查询语句等。。)

    5. 在 php-fpm 前面加一层 nginx,把静态页面(html/js/css/jpg/gif/png)放到 nginx 和 CDN


    -
    nine
        52
    nine  
       2019-04-29 06:29:19 +08:00
    用 go 就没有坑了么?
    虽然 7、8 年没用过 PHP 了,也没用过 laravel,但直觉告诉我,是你运维工作没做到位。
    前年受人所托,优化了一个 PHP 线上业务,每天 2000 万+访问,简单优化后单台 4 核 VPS,CPU 平均负载 25%左右。业务框架是 ThinkPHP,代码几乎没动。
    lestat
        53
    lestat  
       2019-04-29 07:39:41 +08:00 via Android
    2c4g,laravel5.5+php-fpm 7.3,并发只能到 60 多,开了 opcache 之后的...不开只有不到 20...也在考虑怎么提升性能,之前用 laravels 没有解决 jwt 在多用户表切换时候的 token 解析错误的问题,先 mark 一下
    Zhongwei
        54
    Zhongwei  
       2019-04-29 08:53:25 +08:00
    Laravel 对于 CPU 的占用确实高的离谱,即使开了 opcache 也没法满足要求。

    建议后台管理部分继续使用 Laravel ;
    API 接口按照调用的频繁程度,从高到低逐步替换成 Golang。
    king2014
        55
    king2014  
       2019-04-29 08:54:13 +08:00
    @lestat
    @dawniii
    额,看到你们这么说,laravel 这性能可以上生产环境吗?
    klgd
        56
    klgd  
       2019-04-29 09:01:47 +08:00
    没有分析是哪里的问题吗?我们线上也有 laravel 项目在跑,目前也没遇到你这样吃 cpu 的情况
    我觉得找出问题点可能比你迁移更划算
    flashrick
        57
    flashrick  
       2019-04-29 09:09:44 +08:00
    我觉得 laravel 就做后台管理不错 API 还是算了吧
    hanzhao
        58
    hanzhao  
       2019-04-29 09:21:29 +08:00
    我司有一个项目是使用 Laravel-Swoole 部署的,不过是全新做起来的,没遇到什么问题。3 台 4 核 8G 的服务器,常年 TPS 在 2000 左右。
    triptipstop
        59
    triptipstop  
       2019-04-29 09:23:09 +08:00
    17 年 1 核 1G 单机 生成二维码海报 2000W PV 高峰 1000 并发 瓶颈在 MySQL
    线上跑的 Laravel 一万个总有吧 你这种问题 能算万一了
    tanszhe
        60
    tanszhe  
       2019-04-29 09:23:30 +08:00
    @runningman 有连接池啊,github 首页就是大概介绍。看一篇你应该就知道了,最下面有 qq
    triptipstop
        61
    triptipstop  
       2019-04-29 09:24:26 +08:00
    动不动就 Go 的人
    换成任何语言 结果都一样
    dawniii
        62
    dawniii  
       2019-04-29 09:53:14 +08:00
    @king2014 虽然很吃 cpu 但是不妨碍上生产环境,无非就是堆机器了。 而且大部分项目并发都到不了 100。
    qbhy
        63
    qbhy  
       2019-04-29 09:58:47 +08:00
    swoole 挺好,坑都是些现成的。而且大多坑也不是因为 swoole 本身的原因,而是从 fpm 模式转变到类似 node 这种常驻脚本模式带来的问题,或者说 laravel 的设计本就不适合使用这种模式来启动程序,但是也都有相应的解决方案了。我司已经上 swoole
    oops1900
        64
    oops1900  
       2019-04-29 10:16:36 +08:00
    两台 2 核 8G 单台机器并发可以轻松扛起 1000+ 并发,采用的是 FPM 工作模式,楼主需要先优化 laravel 框架的一些配置缓存,然后把 FPM 设置成 static 模式,一个进程大概 20 M 你需要根据自己内存设置,然后开启 opcache,优化 nginx,问题不是出在框架上,而且优化上面,laravel 框架是比其他框架加载稍微慢了些,但是也提供了优化配置方案。

    按照楼主机器这个配置负载均衡后到 1000 ~ 2000 不是问题
    oops1900
        65
    oops1900  
       2019-04-29 10:18:23 +08:00
    另外 laravel-swoole 性能的确显著,不过会有一些坑。楼主可以尝试解决。
    fuxiaohei
        66
    fuxiaohei  
       2019-04-29 10:55:53 +08:00
    先优化,实在没办法再换语言
    runningman
        67
    runningman  
       2019-04-29 11:52:19 +08:00
    @tanszhe 好。加群了
    jxgccaaron
        68
    jxgccaaron  
       2019-04-29 12:19:58 +08:00 via iPhone
    贵公司还要人么
    zjtsunshine
        69
    zjtsunshine  
    OP
       2019-04-29 12:32:23 +08:00
    @xiaotianhu 多谢,我们这几天就在测试 swooles,还在兼容一些代码。。。今天服务器爆炸了,紧急加了 2 台 8 核 16G,好蛋疼
    raysonlu
        70
    raysonlu  
       2019-04-29 13:21:10 +08:00
    @nine 有什么运维上的工作可以优化呢?能否举例一下?
    raysonlu
        71
    raysonlu  
       2019-04-29 13:22:15 +08:00
    @zjtsunshine 紧急加了 2 台 8 核 16G ?已经是负载均衡了?
    jhdxr
        72
    jhdxr  
       2019-04-29 13:31:31 +08:00
    虽然 laravel 是很臃肿,但是也没这么夸张吧。你有做 profiling 看过么?
    eslizn
        73
    eslizn  
       2019-04-29 13:56:16 +08:00
    与其用不支持协程的 laravel swoole 解决方案,不如考虑下 zend expressive swoole ?
    nine
        74
    nine  
       2019-04-29 14:04:28 +08:00
    @raysonlu 你先看下 64 楼的吧,我就是按默认该怎么配置怎么配置的,没做什么特殊优化,因为都是早期积累的经验,你问我怎么优化的,我也说不上来,因为默认认为这么配置就行了,反而不知道错误的配置是什么样。
    barbery
        75
    barbery  
       2019-04-29 14:31:30 +08:00
    今年有个活动我们用了 laravel-s 上生产,挺稳定的没啥问题,就是协程的特征没办法用,不过实例可以长连接,在高并发场景还是不错的,省下不少创建连接的消耗,还有就是很省内存,8core16g 机器,跑 16 个 worker,内存占用率只用了 1 个 g
    allenhu
        76
    allenhu  
       2019-04-29 14:43:46 +08:00
    不着到问题的根源,下次慢了,继续换?
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2764 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 32ms UTC 12:41 PVG 20:41 LAX 04:41 JFK 07:41
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86