目次
質問" >質問
トラブルシューティング" >トラブルシューティング
タイムアウトの理由" >タイムアウトの理由
正确姿势" >正确姿势
源码分析" >源码分析
概要" >概要
ホームページ バックエンド開発 Golang i/o タイムアウト、この net/http パッケージの罠に踏まないことを祈ります

i/o タイムアウト、この net/http パッケージの罠に踏まないことを祈ります

Jul 25, 2023 pm 03:56 PM
timeout net/http

質問

毎日のコードを見てみましょう。

 1package main
 2
 3import (
 4    "bytes"
 5    "encoding/json"
 6    "fmt"
 7    "io/ioutil"
 8    "net"
 9    "net/http"
10    "time"
11)
12
13var tr *http.Transport
14
15func init() {
16    tr = &http.Transport{
17        MaxIdleConns: 100,
18        Dial: func(netw, addr string) (net.Conn, error) {
19            conn, err := net.DialTimeout(netw, addr, time.Second*2) //设置建立连接超时
20            if err != nil {
21                return nil, err
22            }
23            err = conn.SetDeadline(time.Now().Add(time.Second * 3)) //设置发送接受数据超时
24            if err != nil {
25                return nil, err
26            }
27            return conn, nil
28        },
29    }
30}
31
32func main() {
33    for {
34        _, err := Get("http://www.baidu.com/")
35        if err != nil {
36            fmt.Println(err)
37            break
38        }
39    }
40}
41
42
43func Get(url string) ([]byte, error) {
44    m := make(map[string]interface{})
45    data, err := json.Marshal(m)
46    if err != nil {
47        return nil, err
48    }
49    body := bytes.NewReader(data)
50    req, _ := http.NewRequest("Get", url, body)
51    req.Header.Add("content-type", "application/json")
52
53    client := &http.Client{
54        Transport: tr,
55    }
56    res, err := client.Do(req)
57    if res != nil {
58        defer res.Body.Close()
59    }
60    if err != nil {
61        return nil, err
62    }
63    resBody, err := ioutil.ReadAll(res.Body)
64    if err != nil {
65        return nil, err
66    }
67    return resBody, nil
68}
ログイン後にコピー

が行うことは比較的単純で、ループして http://www.baidu.com/ を要求し、応答を待つことです。

問題ないようです。

コードを実行すると、 実際に通常どおりメッセージを送受信できます

しかし、このコードが 一定期間実行されると、i/o timeout エラーが表示されます。


これは実は最近調査された問題で、この落とし穴に踏みやすい可能性があることがわかったので、ここでコードを簡略化しました。

実際の運用環境で発生する

現象 は、http.Transport# にもかかわらず、golang サービスが http 呼び出しを開始することです。 ##3s タイムアウトが設定されている場合、i/o timeout エラーが表示されることがあります。 しかし、ダウンストリーム サービスを確認したところ、実際にはダウンストリーム サービスが

100ms

で戻ってきたことがわかりました。

トラブルシューティング

i/o タイムアウト、この net/http パッケージの罠に踏まないことを祈ります
5 層ネットワーク プロトコルに対応するメッセージ本文の変更の分析

非常に奇妙です、サーバー処理時間は 100ms のみで、クライアント タイムアウトは 3s に設定されているのに、タイムアウト エラー i/o timeout が表示されるのはなぜですか?


#ここには 2 つの可能性があります。

  • サーバーによって出力されるログは、実際には

    サーバー アプリケーション層によって出力されるログのみであるためです。ただし、クライアント アプリケーション層がデータを送信した後、データは クライアントのトランスポート層、ネットワーク層、データリンク層、物理層 を通過し、さらに サーバーの物理層、データリンク層、ネットワークも通過します。サーバー側の層、トランスポート層からアプリケーション層まで。サーバー アプリケーション層で 100ms かかり、その後元のパスに戻ります。残りの 3 秒~100 ミリ秒 は、プロセス全体のさまざまなレイヤーで 無駄になる可能性があります。たとえば、ネットワークが良好でない場合、トランスポート層の TCP はパケットを激しく失い、再送信します。

  • ネットワークに問題はありません。クライアントからサーバーまでの送受信プロセス全体には、おそらく

    100ms 程度かかります。クライアント処理ロジックの問題によりタイムアウトが発生します。


通常、問題が発生した場合、ほとんどの場合、それは基盤となるネットワークの問題ではありません。あなた自身の問題、あなたは正しいです。、諦めたくないなら、バッグを手に取って見てください。

i/o タイムアウト、この net/http パッケージの罠に踏まないことを祈ります

パケット キャプチャ結果
分析後、3 回のハンドシェイクの最初から (

赤いボックスが表示されている場所)描かれています## #)。

到最后出现超时报错 i/o timeout画了蓝框的地方)。

time那一列从710,确实间隔3s。而且看右下角的蓝框,是51169端口发到80端口的一次Reset连接。

80端口是服务端的端口。换句话说就是客户端3s超时主动断开链接的。

但是再仔细看下第一行三次握手到最后客户端超时主动断开连接的中间,其实有非常多次HTTP请求

回去看代码设置超时的方式。

 1    tr = &http.Transport{
 2        MaxIdleConns: 100,
 3        Dial: func(netw, addr string) (net.Conn, error) {
 4            conn, err := net.DialTimeout(netw, addr, time.Second*2) //设置建立连接超时
 5            if err != nil {
 6                return nil, err
 7            }
 8            err = conn.SetDeadline(time.Now().Add(time.Second * 3)) //设置发送接受数据超时
 9            if err != nil {
10                return nil, err
11            }
12            return conn, nil
13        },
14    }
ログイン後にコピー

也就是说,这里的3s超时,其实是在建立连接之后开始算的,而不是单次调用开始算的超时。

看注释里写的是

SetDeadline sets the read and write deadlines associated with the connection.



タイムアウトの理由

誰もが知っているように、HTTP はアプリケーション層プロトコルであり、トランスポート層は TCP プロトコルを使用します。

HTTP プロトコルは、1.0 以降、デフォルトで short connection を使用しており、リクエストが行われるたびに TCP 接続が確立されます。データを送受信します。その後、接続を解除します。

すべての TCP 接続は 3 ウェイ ハンドシェイクです。それぞれの切断には 4 つの波が必要です。

実際には、毎回新しい接続を確立する必要はなく、確立された接続は切断されない限り、データを送信するたびに再利用されます。

それ以来、HTTP プロトコルは 1.1 以降、デフォルトで 長い接続を使用するようになりました。具体的な情報については、この前の記事を参照してください。

となると、golang 標準ライブラリ もこの実装と互換性があります。

接続プールを確立することで、http://baidu.comhttp:/ などの 各ドメイン名 に対して TCP ロング接続を確立します。 / golang.com は 2 つの異なるドメイン名です。

http://baidu.com に初めてアクセスすると、接続が確立され、使い果たされると、アイドル接続プールに配置されます。 http://baidu.com にアクセスすると、接続プール reuse からこの接続が取得されます。

i/o タイムアウト、この net/http パッケージの罠に踏まないことを祈ります
長い接続を再利用する


余談を挿入します。これは、この記事の最後のステートメントについても説明しています。同じドメイン名であることを強調します。ドメイン名は接続を確立し、1 つの接続は 読み取りゴルーチンと書き込みゴルーチン に対応します。同じドメイン名なので最終的には 3 個のゴルーチンが漏洩しますが、異なるドメイン名であれば 1 2*N 個のゴルーチンが漏洩します、N はドメイン名の数です。


最初のリクエストに 100ms かかると仮定し、各リクエストの後に http://baidu.com を配置します。すべての 接続プールに追加し、次回も再利用し続けます。これを 29 回繰り返し、2900ms かかります。

30 リクエストの時点で、接続は確立されてからサービスが返されるまでにすでに 3000ms かかっており、設定された # にちょうど到達しました。 ##3s タイムアウトしきい値を設定すると、クライアントはタイムアウト i/o タイムアウト を報告します。

この時点でサーバーは実際には

100ms かかっていましたが、前回の 29 回 には耐えられず、合計時間はすでに非常に長くなってしまいました。

也就是说只要通过 http.Transport 设置了 err = conn.SetDeadline(time.Now().Add(time.Second * 3)),并且你用了长连接,哪怕服务端处理再快,客户端设置的超时再长,总有一刻,你的程序会报超时错误。

正确姿势

原本预期是给每次调用设置一个超时,而不是给整个连接设置超时。

另外,上面出现问题的原因是给长连接设置了超时,且长连接会复用。

基于这两点,改一下代码。

 1package main
 2
 3import (
 4    "bytes"
 5    "encoding/json"
 6    "fmt"
 7    "io/ioutil"
 8    "net/http"
 9    "time"
10)
11
12var tr *http.Transport
13
14func init() {
15    tr = &http.Transport{
16        MaxIdleConns: 100,
17        // 下面的代码被干掉了
18        //Dial: func(netw, addr string) (net.Conn, error) {
19        //  conn, err := net.DialTimeout(netw, addr, time.Second*2) //设置建立连接超时
20        //  if err != nil {
21        //      return nil, err
22        //  }
23        //  err = conn.SetDeadline(time.Now().Add(time.Second * 3)) //设置发送接受数据超时
24        //  if err != nil {
25        //      return nil, err
26        //  }
27        //  return conn, nil
28        //},
29    }
30}
31
32
33func Get(url string) ([]byte, error) {
34    m := make(map[string]interface{})
35    data, err := json.Marshal(m)
36    if err != nil {
37        return nil, err
38    }
39    body := bytes.NewReader(data)
40    req, _ := http.NewRequest("Get", url, body)
41    req.Header.Add("content-type", "application/json")
42
43    client := &http.Client{
44        Transport: tr,
45        Timeout: 3*time.Second,  // 超时加在这里,是每次调用的超时
46    }
47    res, err := client.Do(req) 
48    if res != nil {
49        defer res.Body.Close()
50    }
51    if err != nil {
52        return nil, err
53    }
54    resBody, err := ioutil.ReadAll(res.Body)
55    if err != nil {
56        return nil, err
57    }
58    return resBody, nil
59}
60
61func main() {
62    for {
63        _, err := Get("http://www.baidu.com/")
64        if err != nil {
65            fmt.Println(err)
66            break
67        }
68    }
69}
ログイン後にコピー

看注释会发现,改动的点有两个

  • http.Transport里的建立连接时的一些超时设置干掉了。

  • 在发起http请求的时候会场景http.Client,此时加入超时设置,这里的超时就可以理解为单次请求的超时了。同样可以看下注释

Timeout specifies a time limit for requests made by this Client.

到这里,代码就改好了,实际生产中问题也就解决了。

实例代码里,如果拿去跑的话,其实还会下面的错

1Get http://www.baidu.com/: EOF
ログイン後にコピー

这个是因为调用得太猛了,http://www.baidu.com 那边主动断开的连接,可以理解为一个限流措施,目的是为了保护服务器,毕竟每个人都像这么搞,服务器是会炸的。。。

解决方案很简单,每次HTTP调用中间加个sleep间隔时间就好。


到这里,其实问题已经解决了,下面会在源码层面分析出现问题的原因。对读源码不感兴趣的朋友们可以不用接着往下看,直接拉到文章底部右下角,做点正能量的事情(点两下)支持一下。(疯狂暗示,拜托拜托,这对我真的很重要!

源码分析

用的go版本是1.12.7

从发起一个网络请求开始跟。

 1res, err := client.Do(req)
 2func (c *Client) Do(req *Request) (*Response, error) {
 3    return c.do(req)
 4}
 5
 6func (c *Client) do(req *Request) {
 7    // ...
 8    if resp, didTimeout, err = c.send(req, deadline); err != nil {
 9    // ...
10  }
11    // ...  
12}  
13func send(ireq *Request, rt RoundTripper, deadline time.Time) {
14    // ...    
15    resp, err = rt.RoundTrip(req)
16     // ...  
17} 
18
19// 从这里进入 RoundTrip 逻辑
20/src/net/http/roundtrip.go: 16
21func (t *Transport) RoundTrip(req *Request) (*Response, error) {
22    return t.roundTrip(req)
23}
24
25func (t *Transport) roundTrip(req *Request) (*Response, error) {
26    // 尝试去获取一个空闲连接,用于发起 http 连接
27  pconn, err := t.getConn(treq, cm)
28  // ...
29}
30
31// 重点关注这个函数,返回是一个长连接
32func (t *Transport) getConn(treq *transportRequest, cm connectMethod) (*persistConn, error) {
33  // 省略了大量逻辑,只关注下面两点
34    // 有空闲连接就返回
35    pc := <-t.getIdleConnCh(cm)
36
37  // 没有创建连接
38  pc, err := t.dialConn(ctx, cm)
39
40}
ログイン後にコピー

这里上面很多代码,其实只是为了展示这部分代码是怎么跟踪下来的,方便大家去看源码的时候去跟一下。

最后一个上面的代码里有个 getConn 方法。在发起网络请求的时候,会先取一个网络连接,取连接有两个来源。

  • 如果有空闲连接,就拿空闲连接

    1/src/net/http/tansport.go:810
    2func (t *Transport) getIdleConnCh(cm connectMethod) chan *persistConn {
    3 // 返回放空闲连接的chan
    4 ch, ok := t.idleConnCh[key]
    5   // ...
    6 return ch
    7}
    ログイン後にコピー
  • 没有空闲连接,就创建长连接。

1/src/net/http/tansport.go:1357
2func (t *Transport) dialConn() {
3  //...
4  conn, err := t.dial(ctx, "tcp", cm.addr())
5  // ...
6  go pconn.readLoop()
7  go pconn.writeLoop()
8  // ...
9}
ログイン後にコピー

第一次发起一个http请求时,这时候肯定没有空闲连接,会建立一个新连接。同时会创建一个读goroutine和一个写goroutine

i/o タイムアウト、この net/http パッケージの罠に踏まないことを祈ります
读写协程

注意上面代码里的t.dial(ctx, "tcp", cm.addr()),如果像文章开头那样设置了 http.Transport

 1Dial: func(netw, addr string) (net.Conn, error) {
 2   conn, err := net.DialTimeout(netw, addr, time.Second*2) //设置建立连接超时
 3   if err != nil {
 4      return nil, err
 5   }
 6   err = conn.SetDeadline(time.Now().Add(time.Second * 3)) //设置发送接受数据超时
 7   if err != nil {
 8      return nil, err
 9   }
10   return conn, nil
11},
ログイン後にコピー

那么这里就会在下面的dial里被执行到

1func (t *Transport) dial(ctx context.Context, network, addr string) (net.Conn, error) {
2   // ...
3  c, err := t.Dial(network, addr)
4  // ...
5}
ログイン後にコピー

这里面调用的设置超时,会执行到

 1/src/net/net.go
 2func (c *conn) SetDeadline(t time.Time) error {
 3    //...
 4    c.fd.SetDeadline(t)
 5    //...
 6}
 7
 8//...
 9
10func setDeadlineImpl(fd *FD, t time.Time, mode int) error {
11    // ...
12    runtime_pollSetDeadline(fd.pd.runtimeCtx, d, mode)
13    return nil
14}
15
16
17//go:linkname poll_runtime_pollSetDeadline internal/poll.runtime_pollSetDeadline
18func poll_runtime_pollSetDeadline(pd *pollDesc, d int64, mode int) {
19    // ...
20  // 设置一个定时器事件
21  rtf = netpollDeadline
22    // 并将事件注册到定时器里
23  modtimer(&pd.rt, pd.rd, 0, rtf, pd, pd.rseq)
24}
ログイン後にコピー

上面的源码,简单来说就是,当第一次调用请求的,会建立个连接,这时候还会注册一个定时器事件,假设时间设了3s,那么这个事件会在3s后发生,然后执行注册事件的逻辑。而这个注册事件就是netpollDeadline注意这个netpollDeadline,待会会提到。

i/o タイムアウト、この net/http パッケージの罠に踏まないことを祈ります
读写协程定时器事件

设置了超时事件,且超时事件是3s后之后,发生。再次期间正常收发数据。一切如常。

直到3s过后,这时候看读goroutine,会等待网络数据返回。

1/src/net/http/tansport.go:1642
2func (pc *persistConn) readLoop() {
3    //...
4    for alive {
5        _, err := pc.br.Peek(1)  // 阻塞读取服务端返回的数据
6    //...
7}
ログイン後にコピー

然后就是一直跟代码。

 1src/bufio/bufio.go: 129
 2func (b *Reader) Peek(n int) ([]byte, error) {
 3   // ...
 4   b.fill() 
 5   // ...   
 6}
 7
 8func (b *Reader) fill() {
 9    // ...
10    n, err := b.rd.Read(b.buf[b.w:])
11    // ...
12}
13
14/src/net/http/transport.go: 1517
15func (pc *persistConn) Read(p []byte) (n int, err error) {
16    // ...
17    n, err = pc.conn.Read(p)
18    // ...
19}
20
21// /src/net/net.go: 173
22func (c *conn) Read(b []byte) (int, error) {
23    // ...
24    n, err := c.fd.Read(b)
25    // ...
26}
27
28func (fd *netFD) Read(p []byte) (n int, err error) {
29    n, err = fd.pfd.Read(p)
30    // ...
31}
32
33/src/internal/poll/fd_unix.go: 
34func (fd *FD) Read(p []byte) (int, error) {
35    //...
36  if err = fd.pd.waitRead(fd.isFile); err == nil {
37    continue
38  }
39    // ...
40}
41
42func (pd *pollDesc) waitRead(isFile bool) error {
43    return pd.wait(&#39;r&#39;, isFile)
44}
45
46func (pd *pollDesc) wait(mode int, isFile bool) error {
47    // ...
48  res := runtime_pollWait(pd.runtimeCtx, mode)
49    return convertErr(res, isFile)
50}
ログイン後にコピー

直到跟到 runtime_pollWait,这个可以简单认为是等待服务端数据返回

 1//go:linkname poll_runtime_pollWait internal/poll.runtime_pollWait
 2func poll_runtime_pollWait(pd *pollDesc, mode int) int {
 3
 4    // 1.如果网络正常返回数据就跳出
 5  for !netpollblock(pd, int32(mode), false) {
 6    // 2.如果有出错情况也跳出
 7        err = netpollcheckerr(pd, int32(mode))
 8        if err != 0 {
 9            return err
10        }
11    }
12    return 0
13}
ログイン後にコピー

整条链路跟下来,就是会一直等待数据,等待的结果只有两个

  • 有可以读的数据

  • 出现报错

这里面的报错,又有那么两种

  • 连接关闭

  • 超时

1func netpollcheckerr(pd *pollDesc, mode int32) int {
2    if pd.closing {
3        return 1 // errClosing
4    }
5    if (mode == &#39;r&#39; && pd.rd < 0) || (mode == &#39;w&#39; && pd.wd < 0) {
6        return 2 // errTimeout
7    }
8    return 0
9}
ログイン後にコピー

其中提到的超时,就是指这里面返回的数字2,会通过下面的函数,转化为 ErrTimeout, 而 ErrTimeout.Error() 其实就是 i/o timeout

 1func convertErr(res int, isFile bool) error {
 2    switch res {
 3    case 0:
 4        return nil
 5    case 1:
 6        return errClosing(isFile)
 7    case 2:
 8        return ErrTimeout // ErrTimeout.Error() 就是 "i/o timeout"
 9    }
10    println("unreachable: ", res)
11    panic("unreachable")
12}
ログイン後にコピー

那么问题来了。上面返回的超时错误,也就是返回2的时候的条件是怎么满足的

1    if (mode == &#39;r&#39; && pd.rd < 0) || (mode == &#39;w&#39; && pd.wd < 0) {
2        return 2 // errTimeout
3    }
ログイン後にコピー

还记得刚刚提到的 netpollDeadline吗?

这里面放了定时器3s到点时执行的逻辑。

 1func timerproc(tb *timersBucket) {
 2    // 计时器到设定时间点了,触发之前注册函数
 3    f(arg, seq) // 之前注册的是 netpollDeadline
 4}
 5
 6func netpollDeadline(arg interface{}, seq uintptr) {
 7    netpolldeadlineimpl(arg.(*pollDesc), seq, true, true)
 8}
 9
10/src/runtime/netpoll.go: 428
11func netpolldeadlineimpl(pd *pollDesc, seq uintptr, read, write bool) {
12    //...
13    if read {
14        pd.rd = -1
15        rg = netpollunblock(pd, &#39;r&#39;, false)
16    }
17    //...
18}
ログイン後にコピー

这里会设置pd.rd=-1,是指 poller descriptor.read deadline ,含义网络轮询器文件描述符读超时时间, 我们知道在linux里万物皆文件,这里的文件其实是指这次网络通讯中使用到的socket

这时候再回去看发生超时的条件就是if (mode == 'r' && pd.rd < 0)

至此。我们的代码里就收到了 io timeout 的报错。

概要

  • http.Transport でタイムアウトを設定しないでください。これは、接続のタイムアウトではなく、接続のタイムアウトです。リクエスト。そうしないと、不可解な io timeout エラーが発生する可能性があります。

  • リクエストのタイムアウトは、作成 client で設定されます。

以上がi/o タイムアウト、この net/http パッケージの罠に踏まないことを祈りますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Nginx タイムアウトのタイムアウトを設定する方法 Nginx タイムアウトのタイムアウトを設定する方法 May 12, 2023 pm 10:07 PM

keepalive_timeouthttp にはキープアライブ モードがあり、リクエストの処理後に TCP 接続を開いたままにするよう Web サーバーに指示します。クライアントから他のリクエストを受信した場合、サーバーは別の接続を確立せずに、この閉じられていない接続を使用します。 httpkeep-alive、Web ページ上のすべてのリクエストは http (画像、CSS など) であり、http リクエストを開くには、まず TCP 接続を確立する必要があります。ページがリクエストごとに TCP 接続を開いたり閉じたりする必要がある場合keepalive_timeout の無駄は、http リクエストが完了しても、その TCP 接続が維持されることです。

win11のクロックウォッチドッグタイムアウトのブルースクリーンを解決するにはどうすればよいですか? win11のクロックウォッチドッグタイムアウトのブルースクリーンを解決するにはどうすればよいですか? Feb 14, 2024 pm 04:00 PM

Win11 システムをアップグレードした後、多くのユーザーは、クロックウォッチドッグタイムアウト ブルー スクリーンなどのブルー スクリーンを経験します。これを解決するにはどうすればよいでしょうか?ユーザーはドライバーを更新したり、過熱の問題などを確認したりできます。このサイトでは、win11のクロックウォッチドッグタイムアウトのブルースクリーンの解決策をユーザーに丁寧に紹介します。 win11 のクロックウォッチドッグタイムアウト ブルー スクリーンの解決策 1. ドライバーを更新します。CPU とマザーボードのドライバーを更新すると、問題が解決される可能性があります。製造元の Web サイトにアクセスして、最新のドライバーをダウンロードできます。 2. 過熱の問題を確認します。過熱もこのエラーの原因の 1 つである可能性があります。

Vue アプリケーションで vue-resource を使用するときに「エラー: xxxms のタイムアウトを超えました」が発生した場合はどうすればよいですか? Vue アプリケーションで vue-resource を使用するときに「エラー: xxxms のタイムアウトを超えました」が発生した場合はどうすればよいですか? Jun 24, 2023 pm 02:21 PM

Vue アプリケーション開発では、vue-resource を使用して HTTP リクエストを行うのが一般的な操作です。 vue-resource には便利な機能がたくさんありますが、場合によっては「エラー: timeoutofxxxmsexceeded」などのエラーメッセージが表示されることがあります。このエラーは通常、リクエストのタイムアウトによって発生します。では、この場合、どうやってこの問題を解決すればいいのでしょうか? 1. リクエストのタイムアウトを増やす まず、次の方法でリクエストのタイムアウトを増やすことができます。

Vue アプリケーションで axios を使用するときに「エラー: xxxms のタイムアウトを超えました」が発生した場合はどうすればよいですか? Vue アプリケーションで axios を使用するときに「エラー: xxxms のタイムアウトを超えました」が発生した場合はどうすればよいですか? Jun 24, 2023 pm 03:27 PM

Vue アプリケーションで axios を使用するときに「エラー: timeoutofxxxmsexceeded」が発生した場合はどうすればよいですか?インターネットの急速な発展に伴い、フロントエンド技術は常に更新され、改良が重ねられており、Vue は優れたフロントエンド フレームワークとして近年皆様に歓迎されています。 Vue アプリケーションでは、ネットワーク リクエストを行うために axios を使用する必要があることがよくありますが、「エラー: timeoutofxxxmsexceeded」というエラーが発生することがあります。

golang で net/http/httputil.DumpResponse 関数を使用して HTTP 応答情報を出力する方法 golang で net/http/httputil.DumpResponse 関数を使用して HTTP 応答情報を出力する方法 Nov 18, 2023 am 09:35 AM

golang で net/http/httputil.DumpResponse 関数を使用して HTTP 応答情報を出力する方法 golang では、net/http パッケージを使用して HTTP リクエストを送信し、HTTP 応答を受信できます。場合によっては、応答ヘッダーや応答本文など、HTTP 応答の詳細を表示する必要があります。この目的を達成するために、net/http/httputil パッケージは便利な DumpResponse 関数を提供します。

Go 言語ドキュメントの net/http.PostForm 関数をマスターしてフォーム データを送信する Go 言語ドキュメントの net/http.PostForm 関数をマスターしてフォーム データを送信する Nov 04, 2023 am 09:02 AM

現在、インターネットは非常に貴重なリソースとなっており、常にデータを送信する必要があります。このペースの速い時代で競争力を維持するには、さまざまなスキルを習得する必要があります。 Go言語は現在非常に人気のある言語となっています。 Go ではデータの送信がより簡単かつ効率的になりました。この記事では、フォーム データを送信するための Go 言語ドキュメントの net/http.PostForm 関数を紹介し、プログラマーがプログラムを迅速かつ簡単に実行できる簡単な方法を読者に提供します。 HTTPPOS

504ゲートウェイのタイムアウトを解決する方法 504ゲートウェイのタイムアウトを解決する方法 Nov 27, 2023 am 10:55 AM

504 ゲートウェイ タイムアウトの解決策: 1. サーバーの負荷を確認する; 2. クエリとコードを最適化する; 3. タイムアウト制限を増やす; 4. プロキシ サーバーを確認する; 5. ネットワーク接続を確認する; 6. 負荷分散を使用する; 7. 監視とログを作成する; 8 . トラブルシューティング; 9. キャッシュの追加; 10. リクエストの分析。このエラーを解決するには、多くの場合、サーバーのパフォーマンス、ネットワーク接続、プロキシ サーバーの構成、アプリケーションの最適化などの要素の組み合わせが必要になります。

golang で net/http/httputil.DumpRequest 関数を使用して HTTP リクエスト情報を出力する方法 golang で net/http/httputil.DumpRequest 関数を使用して HTTP リクエスト情報を出力する方法 Nov 18, 2023 am 09:11 AM

golang で net/http/httputil.DumpRequest 関数を使用して HTTP リクエスト情報を出力する方法の概要: Golang では、net/http パッケージによって提供される httputil.DumpRequest 関数を使用して HTTP リクエスト情報を出力できます。この関数は、リクエスト ヘッダー、リクエスト行、リクエスト本文の内容を簡単に表示するのに役立ちます。この記事では、この関数の使用方法を詳しく説明し、具体的なコード例を示します。ステップ 1: ガイド

See all articles