V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Get Google Chrome
Vimium · 在 Chrome 里使用 vim 快捷键
ooh
V2EX  ›  Chrome

哈哈哈,今天才知道谷歌浏览器同时只能对同一个 URL 提出一个请求。

  •  
  •   ooh · 2019-03-29 06:11:41 +08:00 · 5674 次点击
    这是一个创建于 2057 天前的主题,其中的信息可能已经有所发展或是发生改变。
    今天在写一个功能的时候需要保证同时只有一个请求来执行某个业务功能,而且这个功能还比较耗时,又不能作成后台处理,就在里面加了个变量来锁住,如果锁住就直接返回,但是我发现测试的时候第二次请求怎么都无法立刻返回,后面发现怎么好像怎么请求都在等前一个请求完成后再发出后面一个,想不到啊,真是学海无涯苦做舟,搜了下没有找到这么设计的官方说法,IE 下面没有这个问题,哎...
    第 1 条附言  ·  2019-03-29 08:26:25 +08:00

    // 我用的测试代码

    package main
    
    import (
        "log"
        "net/http"
        "time"
    )
    
    type Server struct {
        lock bool
    }
    
    func (s *Server) listen(port string) {
        mux := http.NewServeMux()
        mux.HandleFunc("/a", s.testHandler)
        mux.HandleFunc("/b", s.testHandler)
        mux.HandleFunc("/c", s.testHandler)
        mux.HandleFunc("/d", s.testHandler)
        mux.HandleFunc("/e", s.testHandler)
        mux.HandleFunc("/f", s.testHandler)
        mux.HandleFunc("/g", s.testHandler)
        mux.HandleFunc("/h", s.testHandler)
        mux.HandleFunc("/i", s.testHandler)
        mux.HandleFunc("/j", s.testHandler)
        http.ListenAndServe(":"+port, mux)
    }
    
    func (s *Server) testHandler(w http.ResponseWriter, r *http.Request) {
        log.Println("here")
        if s.lock == true {
            w.Write([]byte("locked"))
            log.Println("locked")
            return
        }
        s.lock = true
    
        time.Sleep(60 * time.Second)
        s.lock = false
        log.Println("unlocked")
        w.Write([]byte("unlocked"))
    }
    
    func main() {
        server := Server{
            lock: false,
        }
    
        server.listen("8888")
    }
    

    Console 控制台测试同时打开

    // console 控制台同时打开下面这组会阻塞,但是过几秒很奇怪的是后面九条是同时完成
    window.open("http://127.0.0.1:8888/a");
    window.open("http://127.0.0.1:8888/a");
    window.open("http://127.0.0.1:8888/a");
    window.open("http://127.0.0.1:8888/a");
    window.open("http://127.0.0.1:8888/a");
    window.open("http://127.0.0.1:8888/a");
    
    // console 控制台不会阻塞
    window.open("http://127.0.0.1:8888/a");
    window.open("http://127.0.0.1:8888/b");
    window.open("http://127.0.0.1:8888/c");
    window.open("http://127.0.0.1:8888/d");
    window.open("http://127.0.0.1:8888/e");
    window.open("http://127.0.0.1:8888/f");
    
    16 条回复    2019-08-08 16:25:59 +08:00
    geelaw
        1
    geelaw  
       2019-03-29 06:45:44 +08:00
    可能这就是学海无涯的奥义:让人难懂。
    woscaizi
        2
    woscaizi  
       2019-03-29 06:48:00 +08:00 via iPhone
    http 429 状态码呢?
    cs8425
        3
    cs8425  
       2019-03-29 08:38:29 +08:00   ❤️ 1
    `s.lock == true`
    你这个操作不是 atomic, 也没有上锁
    在 golang, 每个 http request 是一个 goroutine, 是能并发的
    有机会同时进入`time.Sleep(60 * time.Second)`这行
    当然会造成 9 个卡住又同时完成
    yrom
        4
    yrom  
       2019-03-29 08:51:29 +08:00
    不是变量叫 lock 就是锁了 ==
    des
        5
    des  
       2019-03-29 08:56:06 +08:00 via Android
    我佛了,就不能换 post,或者加个随机参数吗?
    0ZXYDDu796nVCFxq
        6
    0ZXYDDu796nVCFxq  
       2019-03-29 09:01:46 +08:00 via Android   ❤️ 2
    同时暴露了 golang,HTTP 协议,浏览器三者都不熟
    AngryPanda
        7
    AngryPanda  
       2019-03-29 09:08:52 +08:00 via Android
    OMG
    Zzdex
        8
    Zzdex  
       2019-03-29 09:34:37 +08:00
    第一次见这样上锁的。。。
    ooh
        9
    ooh  
    OP
       2019-03-29 09:47:53 +08:00
    @cs8425
    @yrom
    @des
    @gstqc
    @AngryPanda
    @Zzdex

    求楼上诸位大神放过菜鸡,我只是没想到更好的方法方便大家能快速复现这个问题,但是我觉得这个锁这么用也不影响这个问题的讨论吧,我抓包看了看,确实 Chrome 下,相同的 url 是有排队请求的现象,只是像问问有没有知道这个设计的大神,大家不要被我的代码带偏了方向😂
    est
        10
    est  
       2019-03-29 10:23:07 +08:00
    控制变量,用 nginx 先试试。
    runze
        11
    runze  
       2019-03-29 10:28:42 +08:00
    ooh
        12
    ooh  
    OP
       2019-03-29 10:32:58 +08:00
    @est 已经抓包测试了,是浏览器控制了访问顺序,第一个请求发出如果服务器没返回,就会阻塞后面的请求,查过有的说是缓存策略,但是我禁止缓存,还是这样的,暂时没找到权威的资料,中午有空再研究看看
    Zzdex
        13
    Zzdex  
       2019-03-29 11:11:45 +08:00
    试了下,先不考虑锁的问题,确实是标题这样的,

    同时只能对同一个 URL 提出一个请求
    第二个请求会阻塞在 stalled,等待上一个请求完成
    ![]( )

    把 disabled cache 打开就好了,也就是请求头中增加 `Cache-Control: no-cache`
    c4f36e5766583218
        14
    c4f36e5766583218  
       2019-03-29 19:15:29 +08:00
    弱弱问下: 这是什么语言、
    ooh
        15
    ooh  
    OP
       2019-03-29 22:50:55 +08:00
    q540374501
        16
    q540374501  
       2019-08-08 16:25:59 +08:00
    确实是这样的,气死我了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1296 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 37ms · UTC 18:01 · PVG 02:01 · LAX 10:01 · JFK 13:01
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.