使用 PHP 实现的的内网穿透工具 “Spike” - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
爱意满满的作品展示区。
slince

使用 PHP 实现的的内网穿透工具 “Spike”

  •  
  •   slince Jun 27, 2017 10718 views
    This topic created in 3225 days ago, the information mentioned may be changed or developed.

    Spike https://github.com/slince/spike;

    之前由于要与一个同事远程协作开发一款 app 需要用到内网穿透服务,在网上找到了 frp 与 ngrok ;后来我在想能不能用 php 也写出来一个这样的服务软件?大家都知道 php 多进程多线程不够友好,在 window 上还不支持;写服务确实很吃力;不过幸运的是有ReactPHP的存在,关于 ReactPHP 不做赘述有兴趣的同学可以自行百度。

    基于 ReactPHP 的 IO 多路复用,使得 Spike 并没有比 Frp 性能差太多;下面是我简单做的一个 benchmark,基于 apache ab 检验 http 隧道的服务性能;客户端与服务端都搭在本地,代理同事电脑上的 http 服务。不是特别符合应用场景,大家简单看一下。

    从下面的信息可以看出 Spike 性能似乎是稍微好点的,不过这个地方有点不公平,我在做 spike 的测试时只开启了服务端的日志,客户端的日志是关闭的;而 FRP 的两端日志都是开启的;我不知道怎么关 frp 的日志;

    在这里简单提一点由于 Spike 的日志 IO 是同步的所以日志的读写会耗掉部分性能,提升日志等级减少日志写入可以提升不少的性能;

    这个项目是我比较上心的一个作品,算是证明了一点,php 除了可以做网站也可以做服务,并且也没有太差。 最后再次附上项目地址: https://github.com/slince/spike 欢迎 star,欢迎 fork

    Spike:

    Concurrency Level: 10 Time taken for tests: 37.727 seconds Complete requests: 100 Failed requests: 0 Total transferred: 2569900 bytes HTML transferred: 2514600 bytes Requests per second: 2.65 [#/sec] (mean) Time per request: 3772.747 [ms] (mean) Time per request: 377.275 [ms] (mean, across all concurrent requests) Transfer rate: 66.52 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.4 0 3 Processing: 533 3602 591.9 3714 4096 Waiting: 516 3587 592.3 3701 4076 Total: 534 3602 591.9 3715 4097 Percentage of the requests served within a certain time (ms) 50% 3715 66% 3791 75% 3822 80% 3844 90% 3970 95% 4015 98% 4053 99% 4097 100% 4097 (longest request) 

    Frp:

    Concurrency Level: 10 Time taken for tests: 38.230 seconds Complete requests: 100 Failed requests: 0 Total transferred: 2569900 bytes HTML transferred: 2514600 bytes Requests per second: 2.62 [#/sec] (mean) Time per request: 3823.045 [ms] (mean) Time per request: 382.304 [ms] (mean, across all concurrent requests) Transfer rate: 65.65 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.2 0 1 Processing: 379 3650 644.4 3809 4140 Waiting: 360 3633 645.5 3789 4124 Total: 380 3650 644.4 3809 4140 Percentage of the requests served within a certain time (ms) 50% 3809 66% 3847 75% 3909 80% 3923 90% 4026 95% 4053 98% 4129 99% 4140 100% 4140 (longest request) 
    Supplement 1    Jun 28, 2017

    ReactPHP是个不错的东西,打破了已有的php执行方式;对php有兴趣的同学可以关注下,https://github.com/reactphp;类似的项目还有https://github.com/amphp; 都是异步单进程的执行方式;php并没有大家想的那么局限。

    35 replies    2017-06-30 12:53:39 +08:00
    kuxiazi
        1
    kuxiazi  
       Jun 27, 2017 via Android
    有公网 ip 还有必要折腾穿透吗?
    slince
        2
    slince  
    OP
       Jun 27, 2017
    @kuxiazi 看应用场景;如果你要开发微信公众号或者远程协作开发 app ; 你每敲完一个功能是不是还得把代码部署到服务器上呢?直接让远程的人访问自己本地多好
    lyhiving
        3
    lyhiving  
       Jun 27, 2017 via Android
    赞一个
    wwqgtxx
        4
    wwqgtxx  
       Jun 28, 2017
    其实还可以在局域网用 ipref3 试试看单线程能不能跑满带宽
    liuxu
        5
    liuxu  
       Jun 28, 2017 via Android
    马克,明天详细看看代码
    GoBeyond
        6
    GoBeyond  
       Jun 28, 2017 via Android
    竟然是用 php 实现的。。感觉一些技术值得借鉴
    askfilm
        7
    askfilm  
       Jun 28, 2017
    赞啊
    airycanon
        8
    airycanon  
       Jun 28, 2017
    看了 Github 才发现是南京的大牛,再看以前发过的帖子,我好像去你们公司面试过……
    Clarencep
        9
    Clarencep  
       Jun 28, 2017
    话说即使不用 frp 与 ngrok 也可以直接用 ssh -f -NT -R ... 何必自己造个轮子

    不过为 LZ 的研发精神点赞~
    slince
        10
    slince  
    OP
       Jun 28, 2017
    @Clarencep 就是鼓捣呗 全凭兴趣
    slince
        11
    slince  
    OP
       Jun 28, 2017
    @airycanon shein 是吧 我已经离职了 没更新资料算是怀念吧 不错的公司 在的时候各种抱怨 走的时候各种不舍
    slince
        12
    slince  
    OP
       Jun 28, 2017
    @GoBeyond 哈哈,php 其实并不差, 只不过在某些领域没有应用场景
    batnss
        13
    batnss  
       Jun 28, 2017
    我这几天还想用 workerman 弄一个类似的来着 看来不用了
    slince
        14
    slince  
    OP
       Jun 28, 2017
    @batnss workerman 使用的是多进程模型,用到了 pcntl 扩展,这个在 window 是用不了的
    batnss
        15
    batnss  
       Jun 28, 2017
    @slince 可以单进程啊 有 win 版 毛估估是可以 哈 还没去试 瞎说的
    imagecap
        16
    imagecap  
       Jun 28, 2017
    内网穿透还是要有公网 IP,
    不过内网穿透好处自然有很多,比如: 内网可以配个好点的机器跑复杂点的程序,换成公网高配的成本比内网自己配的要高很多。
    airycanon
        17
    airycanon  
       Jun 28, 2017
    @slince #11 不是 shein,是你现在的公司,不是在双龙大道么,我去那里面试的。
    wu1990
        18
    wu1990  
       Jun 28, 2017
    swoole 欢迎你
    slowgen
        19
    slowgen  
       Jun 28, 2017
    终于看到有用 reactphp 做的东西了,赞
    slince
        20
    slince  
    OP
       Jun 28, 2017
    @batnss 单进程再同步阻塞的话效率让人难受; reactphp 也是单进程的不过机制是 io 多路复用,类似于 nodejs 的执行方式;这个效率会高很多,尤其是写这种 socket 服务;
    slince
        21
    slince  
    OP
       Jun 28, 2017
    @wu1990 swoole 一样的问题 win 下面不可用
    slince
        22
    slince  
    OP
       Jun 28, 2017
    @shuimugan react 其实有一些实际应用了,不过基本上都被当做实验性质,这点比较遗憾;

    ps: 除了 reactphp 还有一个项目也值得关注 amphp( https://github.com/amphp ) 跟 reactphp 一样的原理,名气差点
    ajan
        23
    ajan  
       Jun 28, 2017
    ngrok 不是有 php 版么?
    slince
        24
    slince  
    OP
       Jun 28, 2017
    @ajan 那个服务端还有一定的功能阉割而且用起来不方便,包装成可执行命令更方便;
    ajan
        25
    ajan  
       Jun 28, 2017
    @slince #24 表示只是看到过,没有玩过。 要是不用命令行运行就爽了
    hhacker
        26
    hhacker  
       Jun 28, 2017
    已 star 好东西啊
    slince
        27
    slince  
    OP
       Jun 28, 2017
    @ajan 命令行不是更方便吗;现在的 php 项目基本都是多文件的;不像以前都写着一个文件里;把文件下载下来执行下了事了
    slince
        28
    slince  
    OP
       Jun 28, 2017
    jz361
        29
    jz361  
       Jun 28, 2017
    顶,来学习的
    Actrace
        30
    Actrace  
       Jun 28, 2017
    CLI 领域,PHP 确实有很多独到之处,因为 PHP 核心代码是很稳定的。比菜鸡自己用其他语言实现相同功能更稳定跟快速。

    但是,php 封装了不少挺潮流的东西,本身来说,socket 也只是给标准 socket 库套了一下。其他类似的东西,比如 ev,libev,event 都有,什么多路复用,多线程都能搞。问题就在于大多数的库都没有把 bug 修完,偶尔会埋个坑,然后隔个几年才发现。对于生产环境来说,这是难以接受的(以前用 pthreads 写过服务,发现很多坑,隔了一年才修复)。

    另外的一点就是内存的控制了,因为自动类型,这一块完全就是由 PHP 内核在管理,然后目前为止,内存的回收都还没有做完美。有些服务要运行个 1 年 2 年,结果就是内存不够用了,悲剧。
    slince
        31
    slince  
    OP
       Jun 28, 2017 via Android
    @Actrace 对的内存回收是个麻烦,这个也是我目前比较担心的问题,为此我在项目中加了不少定时器去维护几个核心的集合防止内存溢出,好在现在看起来并没有什么异常
    Actrace
        32
    Actrace  
       Jun 28, 2017
    @slince 目前唯一靠谱的解决方案是学 apache 或者 fastcgi,就是负责业务的进程在执行一定次数的业务后结束掉,由守护进程再开新的业务进程。然后守护进程尽量写简单一些,尽量少点在守护进程里进行创建变量之类的操作。
    dailaosan
        33
    dailaosan  
       Jun 28, 2017 via iPhone
    Jj
    a308057848
        34
    a308057848  
       Jun 30, 2017
    厉害了.
    slince
        35
    slince  
    OP
       Jun 30, 2017
    About     Help     Advertise     Blog     API     FAQ     Solana     3215 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 74ms UTC 14:23 PVG 22:23 LAX 07:23 JFK 10:23
    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