Skip to main content

DashScope SDK の接続再利用の設定

接続の再利用を行わない場合、API 呼び出しごとに新しい TCP 接続が開始され、TLS ハンドシェイクが実行されるため、レイテンシーが増加します。高同時実行シナリオでは、このオーバーヘッドがタイムアウトやリソースの浪費を引き起こします。接続の再利用により、繰り返しのセットアップが不要になり、レイテンシーとリソース消費を削減できます。

DashScope SDK は、Java と Python の両方で接続の再利用をサポートしています。
  • Java SDK : 組み込みのコネクションプールがデフォルトで有効になっています。最大接続数やタイムアウト期間などのパラメータを設定できます。
  • Python SDK : カスタムセッションを渡すことで接続の再利用を有効にします。同期呼び出しと非同期呼び出しの両方をサポートしています。

事前準備

コード例を実行する前に、次の準備が必要です。
  1. API キーを環境変数としてエクスポートする必要があります。
  2. 最新の SDK をインストールする必要があります。

Java SDK

Java SDK には、デフォルトで有効になっている組み込みのコネクションプールが含まれています。ワークロードに合わせて、最大接続数とタイムアウト設定を調整してください。

パラメータ

パラメータ説明デフォルト値単位
connectTimeout接続確立のタイムアウト。120秒
readTimeoutデータ読み取りのタイムアウト。300秒
writeTimeoutデータ書き込みのタイムアウト。60秒
connectionIdleTimeoutプール内のアイドル接続のタイムアウト。300秒
connectionPoolSizeプール内の最大接続数。32接続
maximumAsyncRequestsすべてのホストにわたる最大同時リクエスト数 (グローバル上限)。32リクエスト
maximumAsyncRequestsPerHostホストごとの最大同時リクエスト数。32リクエスト
パラメータの制約:
  • maximumAsyncRequests は connectionPoolSize 以下である必要があります。そうでない場合、リクエストがブロックされる可能性があります。
  • maximumAsyncRequestsPerHost は maximumAsyncRequests 以下である必要があります。
チューニングガイドライン:
  • connectTimeout : 低レイテンシーのシナリオでは、タイムアウトを短く設定すると、待機時間を短縮できます。
  • connectionIdleTimeout : 高同時実行シナリオでは、アイドルタイムアウトを延長すると、頻繁な接続作成を回避し、リソース消費を削減できます。
  • connectionPoolSize : 高同時実行シナリオでは、接続数が少なすぎるとブロッキング、タイムアウト、頻繁な再接続 (リソース使用量の増加) が発生します。接続数が多すぎると、サーバーに過負荷がかかります。ワークロードに基づいて接続数のバランスを取ってください。

コード例

次の例では、コネクションプールのパラメータ (タイムアウト、最大接続数) を設定し、モデルサービスを呼び出します。パラメータを調整して、同時実行性とリソース使用量を最適化してください。
// 推奨される DashScope SDK のバージョン >= 2.12.0
import java.time.Duration;
import java.util.Arrays;

import com.alibaba.dashscope.aigc.generation.Generation;
import com.alibaba.dashscope.aigc.generation.GenerationParam;
import com.alibaba.dashscope.aigc.generation.GenerationResult;
import com.alibaba.dashscope.common.Message;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.protocol.ConnectionConfigurations;
import com.alibaba.dashscope.protocol.Protocol;
import com.alibaba.dashscope.utils.Constants;

public class Main {
    public static GenerationResult callWithMessage() throws ApiException, NoApiKeyException, InputRequiredException {
        // これはシンガポールリージョンの URL です。WorkspaceId を実際のワークスペース ID に置き換えてください。URL はリージョンによって異なります。
        Generation gen = new Generation(Protocol.HTTP.getValue(), "https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1");
        Message systemMsg = Message.builder()
                .role(Role.SYSTEM.getValue())
                .content("You are a helpful assistant.")
                .build();
        Message userMsg = Message.builder()
                .role(Role.USER.getValue())
                .content("Who are you?")
                .build();
        GenerationParam param = GenerationParam.builder()
                // シンガポールリージョンと北京リージョンの API キーは異なります。API キーの取得については、https://www.alibabacloud.com/help/model-studio/get-api-key をご参照ください。
                // 環境変数を設定していない場合は、次の行を実際の Model Studio の API キーに置き換えてください:.apiKey("sk-xxx")
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                // この例では qwen-plus を使用しています。必要に応じてモデル名を変更してください。モデルリスト:https://www.alibabacloud.com/help/model-studio/getting-started/models
                .model("qwen-plus")
                .messages(Arrays.asList(systemMsg, userMsg))
                .resultFormat(GenerationParam.ResultFormat.MESSAGE)
                .build();

        System.out.println(userMsg.getContent());
        return gen.call(param);
    }
    public static void main(String[] args) {
        // コネクションプールの設定
        Constants.connectionConfigurations = ConnectionConfigurations.builder()
                .connectTimeout(Duration.ofSeconds(10))  // 接続確立のタイムアウト、デフォルト 120 秒
                .readTimeout(Duration.ofSeconds(300)) // データ読み取りのタイムアウト、デフォルト 300 秒
                .writeTimeout(Duration.ofSeconds(60)) // データ書き込みのタイムアウト、デフォルト 60 秒
                .connectionIdleTimeout(Duration.ofSeconds(300)) // コネクションプール内のアイドル接続のタイムアウト、デフォルト 300 秒
                .connectionPoolSize(256) // コネクションプール内の最大接続数、デフォルト 32
                .maximumAsyncRequests(256)  // 最大同時リクエスト数、デフォルト 32
                .maximumAsyncRequestsPerHost(256) // ホストごとの最大同時リクエスト数、デフォルト 32
                .build();

        try {
            GenerationResult result = callWithMessage();
            System.out.println(result.getOutput().getChoices().get(0).getMessage().getContent());
        } catch (ApiException | NoApiKeyException | InputRequiredException e) {
            // ロギングフレームワークを使用して例外情報を記録します
            System.err.println("An error occurred while calling the generation service: " + e.getMessage());
        }
        System.exit(0);
    }
}

Python SDK

Python SDK は、カスタムセッションを渡すことで接続の再利用をサポートします。非同期 HTTP (コルーチンベース) と同期 HTTP の 2 つの呼び出しメソッドをサポートしています。

非同期 HTTP

非同期シナリオでは、aiohttp.ClientSession と aiohttp.TCPConnector を使用して接続の再利用を有効にします。TCPConnector は、接続制限などのパラメータ設定をサポートしています。
パラメータ説明デフォルト値注
limit接続総数の上限 (すべてのホスト)。100高同時実行シナリオでは、この値を大きくすると同時実行性が向上します。
limit_per_hostホストごとの接続数上限。0 (無制限)単一ホストへの接続数を制限し、過剰な負荷を防ぎます。
sslSSL コンテキストの設定。NoneHTTPS の SSL 証明書検証。

コード例

次の例では、接続の再利用を設定し、モデルサービスを非同期で呼び出します。
import asyncio
import httpx
import os
import dashscope

async def main():
    # 接続パラメータを設定します
    limits = httpx.Limits(
        max_connections=100,           # 接続総数の上限
        max_keepalive_connections=30,  # keep-alive 接続の最大数
    )

    # カスタム HTTP クライアントを作成し、Client コンストラクターに渡します
    async with httpx.AsyncClient(limits=limits) as http_client:
        # 以下の構成はシンガポールリージョン用です。{WorkspaceId} を実際のワークスペース ID に置き換えてください。構成はリージョンごとに異なります。
        # シンガポールリージョンと北京リージョンの API キーは異なります。API キーを取得するには、https://www.alibabacloud.com/help/model-studio/get-api-key をご参照ください
        # 環境変数を設定していない場合は、API キーを直接設定してください: api_key = "sk-xxx"
        aclient = dashscope.AsyncClient(
            api_key=os.getenv("DASHSCOPE_API_KEY"),
            workspace="{WorkspaceId}",
            region="ap-southeast-1",
            http_client=http_client,  # カスタム HTTP クライアントを渡します
        )
        response = await aclient.chat.completions.create(
            model='qwen-plus',
            messages=[{"role": "user", "content": 'Hello, please introduce yourself'}],
        )
        print(response)

asyncio.run(main())

同期 HTTP

同期シナリオでは、requests.Session を使用して接続の再利用を有効にします。同一セッション内の複数のリクエストは、基盤となる TCP 接続を再利用するため、接続を繰り返し確立するオーバーヘッドを回避できます。

コード例:単一呼び出し

次の例では、接続の再利用を設定し、モデルサービスを同期で呼び出します。
import httpx
import os
import dashscope

# with ステートメントを使用して、HTTP クライアントが正しくクローズされるようにします
with httpx.Client() as http_client:
    # 以下の構成はシンガポールリージョン用です。{WorkspaceId} を実際のワークスペース ID に置き換えてください。構成はリージョンごとに異なります。
    # シンガポールリージョンと北京リージョンの API キーは異なります。API キーを取得するには、https://www.alibabacloud.com/help/model-studio/get-api-key をご参照ください
    # 環境変数を設定していない場合は、API キーを直接設定してください: api_key = "sk-xxx"
    client = dashscope.Client(
        api_key=os.getenv("DASHSCOPE_API_KEY"),
        workspace="{WorkspaceId}",
        region="ap-southeast-1",
        http_client=http_client,  # カスタム HTTP クライアントを渡します
    )
    response = client.chat.completions.create(
        model='qwen-plus',
        messages=[{"role": "user", "content": 'Hello'}],
    )
    print(response)

コード例:共有セッションでの複数回呼び出し

複数の呼び出しでセッションを再利用するには、次のようにします。
import httpx
import os
import dashscope

# HTTP クライアントオブジェクトを作成し、接続再利用のパラメータを設定します
http_client = httpx.Client(
    limits=httpx.Limits(
        max_connections=100,          # 接続総数の上限
        max_keepalive_connections=30, # keep-alive 接続の最大数
    ),
)

# 以下の構成はシンガポールリージョン用です。{WorkspaceId} を実際のワークスペース ID に置き換えてください。構成はリージョンごとに異なります。
# シンガポールリージョンと北京リージョンの API キーは異なります。API キーを取得するには、https://www.alibabacloud.com/help/model-studio/get-api-key をご参照ください
# 環境変数を設定していない場合は、API キーを直接設定してください: api_key = "sk-xxx"
client = dashscope.Client(
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    workspace="{WorkspaceId}",
    region="ap-southeast-1",
    http_client=http_client,  # カスタム HTTP クライアントを渡します
)

try:
    # 複数の呼び出しで同じ HTTP クライアントを再利用します
    response1 = client.chat.completions.create(
        model='qwen-plus',
        messages=[{"role": "user", "content": 'Hello'}],
    )
    print(response1)

    response2 = client.chat.completions.create(
        model='qwen-plus',
        messages=[{"role": "user", "content": 'Introduce yourself'}],
    )
    print(response2)
finally:
    # HTTP クライアントが正しくクローズされるようにします
    http_client.close()

ベストプラクティス

  • Java SDK : ワークロードに基づいて connectionPoolSize と maximumAsyncRequests を設定してください。接続数のバランスを取ってください。少なすぎるとブロッキングが発生し、多すぎるとサーバーに過負荷がかかります。
  • Python SDK : with ステートメントを使用してセッションのライフサイクルを管理し、リソースが正しくクリーンアップされるようにしてください。
  • 適切なメソッドの選択 : 非同期アプリケーション (asyncio、FastAPI) には非同期呼び出しを、従来の同期アプリケーションには同期呼び出しを使用してください。

エラーコード

モデルの呼び出しが失敗した場合は、エラーメッセージ を参照して問題を解決してください。