首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
beego
V2EX  ›  Go

有偿求助抢单软件优化,报酬 500~800,最好懂 Go

  •  
  •   yulon · 2018-07-18 20:53:54 +08:00 · 3731 次点击
    这是一个创建于 453 天前的主题,其中的信息可能已经有所发展或是发生改变。

    目前已做出软件,但是速度不够,希望大佬们能提供些意见,我自己还是想独立完成的,顺便学习,所以不太想外包,也就不存在骗源码的情况,如果有可以明显提升效率的建议就会按程度给报酬,多人就均分,相同建议只给第一个人,当然实在想接外包的也不是不可以,但是金额范围不变,也是有效果才会给报酬。

    整个抢单流程是:刷新单子信息是否出单→开始抢单。

    在刷新单子信息时,我现在是用百个 goroutine 循坏执行“ HTTP 请求+读 body+解析 body ”,我觉得“解析 body ”的部分是肯定可以提升效率的,但是“ HTTP 请求”或“读 body ”会不会互斥更高效?

    就我自己搭的小服务器来说,是所有操作都并发能更快的得到网站的更改,但这适不适用于大型服务器呢?原谅我不能直接在发单的服务器上做实验。

    如果有比较快的 Go 的 HTTP 包或是 JSON 包也可以推荐一下,fasthttp 我试了好像对客户端的提升并不明显,而第三方的 JSON 包使用风格都各不相同,就没有尝试了。

    而上面“读 body+解析 body ”是我现在的方案,整个 body 的数据是 JSON 的,但读取前 10 个字符就已经能知道是否出单,所以知道出单后我会用一个 buffer 缓存 body 的数据,通过自己读 {} 是否闭合来知道是否读完,而不是直接读到 EOF,我观测到读 EOF 可能会有延迟,在 Go 的实现里是否只有服务器主动断开时才会得到 EOF ?

    然后直接 json.Unmarshal(buf.Bytes()),我是觉得先 I/O 再解析完整的内存数据比较好,但因为我已经有一个检查 {} 的操作了,这里如果把开头的 10 字节和 body 封装成 io.Reader 接口,丢给 json.Decoder 边读边解析会不会更好呢?但 json.Decoder 是解析到 {} 闭合为止,还是要读到 EOF ?

    接着是抢单,抢单的请求也需要并发执行吗?我是觉得第一个连接丢包的话可能没有其他并发的请求快。

    而抢单请求时,之前未被关闭的刷新信息的请求会阻塞抢单请求吗?如果会,那么有没有好的 HTTP 请求池方案,能够达到关闭之前请求的时间比被阻塞的时间更少?

    其他,代理 IP 对抢单有提升吗,是用“本机带宽 /单 IP 最大不被封带宽”数量的代理好,还是用尽可能多的代理占“本机带宽 /代理数量”的带宽好呢?

    就先说到这里吧,其他的想到再补充,其实我更想知道有没有被我忽视的地方,多线程数据同步的话,除了最后的结果我是用 channel 发送到主线程,在并发任务里我都是通过 atomic 变量判断有没有完成该任务,应该不存在阻塞,问题就是上面说的过时的请求要不要主动关闭😂

    33 回复  |  直到 2018-07-20 14:03:13 +08:00
        1
    wenbinwu   2018-07-18 20:56:18 +08:00
    最多才 800,还可能跟别人平分?
        2
    torbrowserbridge   2018-07-18 20:58:48 +08:00 via Android   ♥ 3
    看完你这段描述浪费的时间都不止 800 了
        3
    yulon   2018-07-18 21:00:20 +08:00
    @wenbinwu 要求是有效,其实我不觉得能有太多不同的建议。
        4
    gam2046   2018-07-18 21:04:41 +08:00   ♥ 2
    @torbrowserbridge 老哥收入有点厉害的。算看的慢一点,30 分钟看完,值 800。一天 8 小时工作,12800 元了。一个月 21.75 个工作日,税前月薪 27.84 万。

    对于楼主的情况,是否能够先解构一下各个部分的大致耗时占比?先看一下目前的情况,主要时间消耗在哪里。是网络请求,解析内容,还是其他方面慢了,再做针对性的操作。
        5
    aru   2018-07-18 21:04:44 +08:00   ♥ 1
    1. 正常情况下,解析 json 要比 http 请求快很多倍,你可以通过多次循环并打印日志来验证这点
    2. 并发抢单服务器端可以做了限制
    3. 代理一般都挺慢的,不可靠。如果会达到限制,那就用多代理吧,最后下单最好直接本机下
        6
    torbrowserbridge   2018-07-18 21:10:20 +08:00 via Android
    @gam2046 夸张的手法😄
        7
    angryRabbit   2018-07-18 21:20:55 +08:00
    没看完,太长了
        8
    gamexg   2018-07-18 22:09:07 +08:00   ♥ 2
    不知道你抢的什么网站的单,但是数百个并发请求不怕被封?

    >在 Go 的实现里是否只有服务器主动断开时才会得到 EOF ?
    Body.Read ?
    http 协议有 3 种表示 body 结束的方式,其中两种不依靠 tcp 连接关闭,go 能够正确识别,另一种依赖 tcp 连接关闭,不过 http 服务器发送完内容会立刻关闭,不会影响速度。

    json 流式解析不需要解析到 EOF,到 } 就结束,你可以试下,连续多个 {} 可以解析多次。

    go http 内部有个 tcp 连接池,池空了会立刻创建新连接,但是不确定是否有连接数限制,应该没有。
    一般 http 池不会出问题,极端情况基本见不到不需要考虑。

    实际觉得不需要在意本地 json 解析等的速度,这个相对于网络耗时应该可以忽略不计。
    真想提高速度,先确定对方服务器位置,直接租同一机房的。
        9
    pathbox   2018-07-18 22:14:02 +08:00 via iPhone
    耗时在网络上,办个网速贼好的服务器,离抢单服务越近越好,速度可能可以翻翻
        10
    zhs227   2018-07-18 22:32:28 +08:00
    一般耗时都在网络上,解析库上来说不是最关键的。如果想优化解析这部分的逻辑的话,直接把 rsp.Body[:10]出来,用 string match 一下,不需要做 unmarshal。觉得有必要再 unmarshal,这样可以做到 zero copy。
        11
    yulon   2018-07-18 22:33:43 +08:00
    @gamexg 某国企网站,只是流量大的时候会封 IP 几分钟,外包的网站估计员工也不怎么会用,流量大的几天都是强制人员驻点抢单,已经拉了条本地企业宽带专供一台主机😂
        12
    yulon   2018-07-18 22:40:15 +08:00
    @zhs227 恩,所以我说了知道出单才会继续读,因为信息数据有点多,原来全部读完再解析都要比别的公司慢一秒,现在是同一秒了,但还是差那么几百毫秒。。。
        13
    RangerWolf   2018-07-18 22:42:45 +08:00
    不知道目前你说的不够, 是个什么程度。 什么程度才够?

    另外真的很好奇贵司的业务。。。 强制抢单?
        14
    realpg   2018-07-18 22:50:08 +08:00
    上海拍车牌?
        15
    LucasLee92   2018-07-18 22:54:14 +08:00
    拍车牌,抢火车票之类的业务
        16
    yulon   2018-07-18 22:59:03 +08:00
    @RangerWolf 某物流公司,网站是抢货单的,而且还和网站有点 PY 交易,但是某段时间开始所有物流公司都开始用工具,我们老板有很多别司没有的权限,但在工具面前毫无优势,其实现在已经优化到所有公司平均水平了,就是想争第一吧🤣
        17
    xiangyuecn   2018-07-18 23:02:23 +08:00
    时间(单位毫秒) | 事件
    00.000 | 发起请求
    05.000 | 远程服务器接收请求并处理
    25.000 | 远程服务器处理完毕,开始回传数据
    35.000 | 数据接收完毕,开始解析
    35.001 | 数据解析完毕,拿到了 json 对象

    来试试负优化:
    1、网速有点影响,提高点网速,在他们家同一机房开个服务器吧,速度妥妥的
    2、网速有点影响,按你的思路,流式读取数据,接收前几个字节能判断出结果就直接关闭连接返回,省一点点时间
    3、重量级的还是人家的服务器处理速度,卡个 10-20ms 才开始返回第一个字节数据很正常,基本上没法优化
    4、json 解析不耗时间,优化了也没叼用


    实际情况是一个完整请求至少耗时 100-300 毫秒(滑稽
        18
    Lax   2018-07-18 23:13:02 +08:00
    网络请求时间,一般远远大于在本地 cpu 中计算的时间消耗,看看服务器之间的网络延时,尽量优化一下 /换个机房。

    只读前几个字节可能会少占用几个计算周期。不过网络传输数据包的长度相对固定( MTU ),不会因为少读后面的字节而减少传输时间。可以让程序在 TCP 层面进行处理,减少 HTTP 的额外等待。

    并行太多,调度开销就大,有条件可以试试减少并行任务数。
        19
    IvanLi127   2018-07-19 01:51:48 +08:00 via Android
    基本上是网络问题,你在他服务器同机房里租个机子吧
        20
    fiht   2018-07-19 08:03:11 +08:00
    发个 HTTP 包带上 etag 信息试试?
    或者自己构造一个 HTTP 报文用 socket 发过去只取前 2048 个字节?
        21
    reus   2018-07-19 09:07:00 +08:00
    想独占蛋糕,就不怕同行把桌子掀了?
        22
    soulmine   2018-07-19 10:05:22 +08:00
    你这都快是高频交易了吧 这么在意延迟 为什么不用 C++写
        23
    lihongjie0209   2018-07-19 10:22:28 +08:00
    @soulmine #22 高 io 操作用 c++能上天?
        24
    yulon   2018-07-19 10:51:10 +08:00
    @reus 问题就是之前被一个同行独占了,所以都开始搞了。

    @soulmine 想过 C++,但是 goroutine 并发比较成熟,或者有什么 C++ 高频 HTTP 请求库推荐的吗?

    @fiht 单子信息请求响应都是即时的,没有 If-None-Match 和 ETag,现在已经对请求报文做过缓存了😂
        25
    hoosin   2018-07-19 11:09:13 +08:00
    我觉得看完这个需求,就值 800 了
        26
    luw2007   2018-07-19 11:35:08 +08:00
    以前用 go 做过 p2p 金融抢单,大致说一下软件思路。
    调度进程,业务进程分离。采用 tcp 协议,内网部署。
    调度进程负责管理资源(帐号,对方服务器的外网地址列表,代理列表,业务进程 ...)
    业务进程只管获取资源和请求和解析并回传。

    最终干赢其他对手,甚至于把金融网站打崩(调度里面的动态计算任务间隔,配置成 0 了)。
    起到最大作用的原因并非代码层面。

    ==>价值 800 元的经验在这里<==
    而是找到对方服务器所在机房,并且拿到了源服务器。请求相应时间从 200ms 下降到 40ms。
        27
    pxlxh   2018-07-19 12:10:19 +08:00
    看完楼上的感觉楼主是来羞辱知乎 er 的。
        28
    2379920898   2018-07-19 12:27:27 +08:00
    给 1 万都不干, 免费送你 黄马褂 手套
        29
    yulon   2018-07-19 13:07:57 +08:00
    @2379920898 你这种水平要能干成我给你 5 万,要走开源众包还是码市?
        30
    yjd   2018-07-19 13:15:20 +08:00
    你们考虑过那个网站服务器,带宽的感受吗。被你们这么多家抢单再分摊下,还怎么快。23333
        31
    woscaizi   2018-07-19 13:24:42 +08:00 via iPhone
    搞过类似的,是一个虚拟货币网站抢交易单子。
    开始我能把网站所有单子抢了。
    50 个线程,每个线程间隔 10ms,单台电脑,带宽 100M。
    后来网站做了限制,单账号对单子列表的刷新限制到 1 分钟 1 次。
    然后我就放弃了。

    针对你的情况。
    我想网络层不是问题,增加账号做新订单的刷新检测,检测到后发给想下单的账号做下单操作。试想下,如果你 1000 个账号做刷新,每个账号每次检测间隔 30 秒,一秒钟起码你可以有 30 个账号做检测,相当于 30ms 刷一次。
        32
    luw2007   2018-07-20 14:01:03 +08:00
        33
    luw2007   2018-07-20 14:03:13 +08:00
    @woscaizi 如果有利可图,频次限制都解决不了这种问题。帐号,代理都有人提供。频次限制总不能影响掉普通用户吧。
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2765 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 24ms · UTC 12:58 · PVG 20:58 · LAX 05:58 · JFK 08:58
    ♥ Do have faith in what you're doing.