Golang 接続プール アプリケーションの実践

1.背景紹介

サービスとサービス間の接続は、開発プロセスにおける非常に一般的な操作です. サービスを分離し、相互依存を減らし、システムの安定性と柔軟性を高めるために、多くのサービス通信リンクが追加されます. サービス通信チェーンにより、道路の増加に伴い,ネットワーク通信の数が指数関数的に増加し、帯域幅、接続数、CPU、メモリなどのネットワーク リソースの消費が増加するため、システムの柔軟性と安定性を確保するにはどうすればよいでしょうか?サービス間の通信を可能な限り効率的かつ低コストにすることが、このテキストで解決したい中心的な問題です。

2. 問題分析

当社のサービスにはhttpサービスとrpcサービスがあり、これらのサービスは大きく分けると同期型サービスと非同期型サービスの2つに分けられます。

1.非同期サービス

メッセージミドルウェア (kafka など) を介してサービスを切り離すと、サービスは複数の非同期サービスになり、サービスはサービス間のデータ送信を kafka に依存し、サービスと kafka の間には tcp 接続が存在します。 tcp 接続と Kafka 通信の両方が制限されているため、リクエストの数が増えると、ビジネス サービスと Kafka へのプレッシャーが 2 倍になり、システムの安定性についてはまったく議論できなくなります。

2.同期サービス

同期サービスを複数の同期サービスに変えたい場合、サービス間のデータ転送に tcp が使用されますが、大量の tcp 接続通信も必要になります. リクエストの数が増えると、ビジネス サービスへのプレッシャーは 2 倍になります.システムの安定性は保証できません。

3. 接続解釈

次に、接続の本質からソリューションを調査および探索します。

1. 各接続が確立されると、ソケット バッファ用のメモリに適用されます。

2. 接続ごとに 3 回握手をし、4 回手を振る必要があります

3. 各接続が閉じられたときにメモリ スペースを解放する

4. 同時実行性が高い場合、多数の接続が生成され、システムのスケジューリングに影響を与え、システム リソースを占有しすぎます。

4.突破口

問題分析における接続の解釈を通じて、いくつかのブレークスルー ポイントを簡単に見つけることができます。

    • バッファの多重化
      - ハンドシェイクとウェーブの数を減らす
      - 接続閉鎖を減らす
      - 接続数を減らす

5.コネクションプールの機能ポイント

上記のブレークスルー ポイントにより、次の機能を備えた接続プールを開発できます。

    • 接続数を固定し、柔軟に調整可能
      - 接続のライフサイクルを延長
      - 接続を複数回再利用可能

3. 接続プール(connPool)の適用

接続プールを作成する

connPool = connPool.NewConnPool(&connPool.Options{
    
    
    Dialer:             dial,                   //dial拨号方法
    PoolSize:           200,                    //连接池的最大连接数
    PoolTimeout:        time.Second * 250,      //等待连接分配的超时时间
    IdleTimeout:        time.Second * 100,      //每个连接的存活超时时间
    IdleCheckFrequency: time.Millisecond * 500, //检测连接存活频率
})
func dial() (conn net.Conn, err error) {
    
            //拨号方法
    ...
    conn, err = net.DialTimeout(...)
    ...
}

接続の取得とリサイクル

func release() {
    
                                           
    conn, _, err = connPool.GetConn(pool)               //从连接池里获取连接
    ...
    _, e := conn.ReleaseConn(pool, err, isBadConn)      //释放连接到连接池
    ...
}()
 
func isBadConn(err error) bool {
    
                            //判断连接是否失效
    if _, ok := err.(*net.OpError); ok {
    
    
        return true
    }
    return false
}

4.フローチャート

1

おすすめ

転載: blog.csdn.net/zhw21w/article/details/129500376