V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
zjtsunshine
V2EX  ›  程序员

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

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

    目前状况: 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 重构吧,重构之后回过头来看你会发现其实有其他更好的方案
    webluoye
        13
    webluoye  
       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   ·   实用小工具   ·   5795 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 03:27 · PVG 11:27 · LAX 19:27 · JFK 22:27
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.