手順だけ記録しておきます。
基本
qiita.com
ここで Dockerfile を記述しているけど
FROM mcr.microsoft.com/dotnet/core/runtime:2.2 WORKDIR /app COPY . .
とエントリポイントを削除
あとサーバー側の実装で引数一個目で port 番号を受け取って利用するようにしておく。
using Grpc.Core; using MagicOnion.Hosting; using MagicOnion.Server; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; using System.Threading.Tasks; namespace CubeWalk.Server { class Program { static async Task Main(string[] args) { if (1 > args.Length || !int.TryParse(args[0], out int port)) return; GrpcEnvironment.SetLogger(new Grpc.Core.Logging.ConsoleLogger()); // for SSL/TLS connection //var config = new ConfigurationBuilder().AddEnvironmentVariables().Build(); //var certificates = new List<KeyCertificatePair> { new KeyCertificatePair(File.ReadAllText("server.crt"), File.ReadAllText("server.key")) }; //var credential = new SslServerCredentials(certificates); await MagicOnionHost.CreateDefaultBuilder() .UseMagicOnion( new MagicOnionOptions(isReturnExceptionStackTraceInErrorDetail: true), new ServerPort("0.0.0.0", port, ServerCredentials.Insecure)) // for SSL/TLS Connection //new ServerPort(config.GetValue<string>("MAGICONION_HOST", "127.0.0.1"), 12345, credential)) .RunConsoleAsync(); } } }
out フォルダをカレントにイメージをビルドして
docker build . -t cubewalkroom:1.0
次の run コマンドで port フォワードして、とりあえず 12000 ポートでサーバーを立てます。
$ docker run -d --rm -p 12000-12100:12000-12100 --name cubewalkroom cubewalkroom:1.0 dotnet CubeWalkServer.dll 12000
続いて、ポートを一つずつ消費しながらサーバーを立てます。
$ docker exec -d cubewalkroom dotnet CubeWalkServer.dll 12001 $ docker exec -d cubewalkroom dotnet CubeWalkServer.dll 12002 $ docker exec -d cubewalkroom dotnet CubeWalkServer.dll 12003 . . .
それぞれの port に対して接続して利用することができました。
追記:
なんのためにポートを複数使う?
プロセスを分離できるので、分けたあとのお互いの影響 0 じゃん
と思っていたけど、内心パフォーマンスの分散にもなるかなって感じてました→原理的にむしろ悪くする
同じポートを使って詰まることはなく、ソケットを作ってお互い通信し、そのソケットにカーネルがパケットを振り分けるので
つまり、ポート一つに全アクセスが集中するのではなく、分散したソケット同士で通信するので、ポート一つでも分散できていたという話
こんな書式で複数ポートをフォワーディングできるという、ただそれだけの記事になったが
副次的にいろいろとポートとソケット、Linux の NIC, hard IRQ とか知ることができた