Thread Pool
Source code
https://github.com/teamsmiley/gitbook-sample/tree/main/ThreadTest
Thread
Thread๋ ํ๋์ ํ๋ก์ธ์ค์์ ์คํ๋๋ ์์ ์ ๋จ์์ด๋ค. Thread๋ฅผ ์ฌ์ฉํ๋ฉด ์ฌ๋ฌ ์์ ์ ๋์์ ์คํํ ์ ์๋ค. Thread๋ฅผ ์ฌ์ฉํ๋ฉด ์ฌ๋ฌ ์์ ์ ๋์์ ์คํํ ์ ์์ง๋ง, Thread๋ฅผ ์์ฑํ๊ณ ๊ด๋ฆฌํ๋ ๊ฒ์ ๋น์ฉ์ด ๋ง์ด ๋ ๋ค. ๊ทธ๋์ .NET์์๋ Thread Pool์ ์ ๊ณตํ๋ค.
Thread Pool
Thread Pool์ Thread๋ฅผ ๊ด๋ฆฌํ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค. Thread Pool์ ์ฌ์ฉํ๋ฉด Thread๋ฅผ ์์ฑํ๊ณ ๊ด๋ฆฌํ๋ ๋น์ฉ์ ์ค์ผ ์ ์๋ค. Thread Pool์ Thread๋ฅผ ์์ฑํ๊ณ ๊ด๋ฆฌํ๋ ๊ฒ์ ์๋์ผ๋ก ์ฒ๋ฆฌํ๋ค. Thread Pool์ ์ฌ์ฉํ๋ฉด Thread๋ฅผ ์์ฑํ๊ณ ๊ด๋ฆฌํ๋ ๊ฒ์ ์๋์ผ๋ก ์ฒ๋ฆฌํ๊ธฐ ๋๋ฌธ์ Thread๋ฅผ ์ฌ์ฉํ ๋๋ณด๋ค ๋ ์ ์ ๋น์ฉ์ผ๋ก Thread๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
webapi
ํ๋ก์ ํธ๋ง๋ค ๋ค๋ฅด๊ฒ์ง๋ง dotnet์ผ๋ก webapi๋ฅผ ์ฌ์ฉ์ kestrel์ด๋ผ๋ ์น์๋ฒ๋ฅผ ์ฌ์ฉํ๋ค. kestrel์ ๊ธฐ๋ณธ์ ์ผ๋ก thread pool์ ์ฌ์ฉํ๋ค. ํ์ธํด๋ณด์.
cd ~/Desktop
dotnet new webapi --name ThreadTest
cd ThreadTest
vi controllers/ValuesController.cs
using System.Diagnostics;
using Microsoft.AspNetCore.Mvc;
namespace ThreadTest.Controllers;
[ApiController]
[Route("values")]
public class ValuesController : ControllerBase
{
private readonly ILogger<ValuesController> _logger;
public ValuesController(ILogger<ValuesController> logger)
{
_logger = logger;
}
[HttpGet(Name = "GetValues")]
public int Get()
{
Console.WriteLine($"The number of processors on this computer is {Environment.ProcessorCount}.");
var maxWorkerThreads = 0;
var maxCompletionPortThreads = 0;
ThreadPool.GetMaxThreads(out maxWorkerThreads, out maxCompletionPortThreads);
Console.WriteLine("Maximum worker threads: {0}", maxWorkerThreads);
var availableWorkerThreads = 0;
var completionPortThreads = 0;
ThreadPool.GetAvailableThreads(out availableWorkerThreads, out completionPortThreads);
Console.WriteLine($"Available Worker threads: {availableWorkerThreads}", availableWorkerThreads);
var usedWorkerThread = maxWorkerThreads - availableWorkerThreads;
Console.WriteLine($"Used worker threads: {usedWorkerThread}");
Thread.Sleep(10000); // Sleep for 10 seconds
return usedWorkerThread;
}
}
์ปจํธ๋กค๋ฌ๋ฅผ ๋ง๋ค๊ณ ์คํํด๋ณด์.
dotnet run
curl http://localhost:5007/values
ํ์ฌ ์ปดํจํฐ๋ 6์ฝ์ด 12์ค๋ ๋์ด๋ค. 12๊ฐ์ cpu๋ฅผ ํ์ธํ ์ ์๋ค.
์ต๋ worker thread๋ 32767๊ฐ์ด๋ค.
์ฌ์ฉ๋ worker thread๋ 2๊ฐ์ด๋ค. (1๋ฒ์ ํธ์ถ์ ํ ์คํธํด๋ณด์๋ค.) 1๊ฐ๋ ๊ธฐ๋ณธ์ฐ๋ ๋์ธ๊ฐ? ํธ์ถ ํ๋ฒ์ 2๋ฒ์งธ ์ค๋ ๋๊ฐ ์์ฑ์ด ๋์๋ค.
์ฌ์ฉ๊ฐ๋ฅํ worker thread๋ 32765๊ฐ์ด๋ค.
The number of processors on this computer is 12.
Maximum worker threads: 32767
Available Worker threads: 32765
Used worker threads: 2
ํ ์คํธ๋ฅผ ๊ณ์ํด๋ณด๋ฉด usedWorkerThread๊ฐ ๊ณ์ ๋์ด๋๋๊ฒ์ ์์ ์๋ค. ๊ทธ๋ฆฌ๊ณ ์๊ฐ์ด ๋๊ณ ๋๋ฉด usedWorkerThread๊ฐ ์ค์ด๋๋๊ฒ์ ํ์ธํ ์ ์๋ค.

์ฐ๋ ๋๊ฐ ์ฆ๊ฐํ๋ค๊ฐ ๋ฆฌํด๋๋๊ฒ์ ๋ณผ์ ์๋ค.
32000๊ฐ์ ์ฐ๋ ๋๊ฐ ํ์๋ ๋ง๋ค์ด์ ธ์๋๊ฑฐ๊ฐ๋ค. ๊ทธ๋ฌ๋ฉด 32000๊ฐ๋ฅผ ๋ฏธ๋ฆฌ ๋ค ๋ง๋ค์ด๋๋๊ฒ์ธ๊ฐ? ์๋๋ฉด ํ์ํ ๋๋ง๋ค ๋ง๋๋๊ฒ์ธ๊ฐ? ์ด๊ฒ์ ํ์ธํด๋ณด์.
dotnet-counters
dotnet tool install --global dotnet-counters
dotnet-counters monitor -n ThreadTest # ํ๋ก์ธ์ค ์ด๋ฆ

์์ฒญ์ ๋ณด๋ด๋ฉด ์ฌ๋ผ๊ฐ๋ ์ฐ๋ ๋๋ฅผ ํ์ธํ ์ ์๋ค.

์์ฒญ์ ๊ณ์ ๋ง๋ค์ด๋ณด๋ฉด์ que์ ๋ค์ด๊ฐ๋์ง ํ์ธํด๋ณด์.
locust.io
๋ง์ ์์ฒญ์ ๋ง๋ค๊ธฐ ์ํด์ ์ด๊ฑธ ์ฌ์ฉํ๋ค.
pip install locust
mkdir locust
cd locust
cat > locust.py <<EOF
import time
from locust import HttpUser, between, task
class WebsiteUser(HttpUser):
wait_time = between(1, 2)
def on_start(self):
self.client.verify = False
@task
def launch(self):
self.client.get(url="/values")
EOF
locust -f locust.py --host http://localhost:5007 --users 1000 --spawn-rate 200
์คํ์ ํด๋ณด๋ฉด ๊ฒฐ๊ณผ๋ฅผ ๋ณผ์ ์๋ค.


๊ฒฐ๊ณผ๊ฐ ์ ํ์ธ๋จ์ ์์ ์๋ค.
container
์ค์ ์๋น์คํ๊ฒฝ์์๋ ์ปจํ ์ด๋๋ฅผ ์ฌ์ฉํ๋ค. ์ด์ ์ง๊ธ๊น์ง ํ๋ก๊ทธ๋จ์ ์ปจํ ์ด๋๋ก ๋ง๋ค๊ณ ํ์ฉํด๋ณด์.
vi Dockerfile
FROM mcr.microsoft.com/dotnet/sdk:6.0-alpine AS build-env
WORKDIR /app
COPY . .
RUN dotnet publish "ThreadTest.csproj" -c Release -o /app/publish
# Install dotnet debug tools
RUN dotnet tool install --tool-path /tools dotnet-trace \
&& dotnet tool install --tool-path /tools dotnet-counters \
&& dotnet tool install --tool-path /tools dotnet-dump \
&& dotnet tool install --tool-path /tools dotnet-gcdump
# Build runtime image
FROM mcr.microsoft.com/dotnet/aspnet:6.0-alpine
# Copy dotnet-tools
WORKDIR /tools
COPY --from=build-env /tools .
RUN apk add icu-libs
ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=false
WORKDIR /app
COPY --from=build-env /app/publish .
EXPOSE 80
ENTRYPOINT ["dotnet", "ThreadTest.dll"]
vi docker-compose.yaml
version: '3'
services:
web:
build:
context: .
ports:
- 80:80
deploy:
resources:
limits:
cpus: '1'
reservations:
cpus: '1'
cpu๋ฅผ 1๊ฐ๋ง ํ ๋น์ ํ์๋ค. ์ด์ ์ปจํ ์ด๋๋ฅผ ์คํํด๋ณด์.
docker-compose up --build
docker ps -a
์ด์ locust๋ฅผ ์คํํด๋ณด์. ๊ทธ๋ฆฌ๊ณ ๋ก๊ทธ๋ฅผ ๋ด๋ณด์.
docker logs -f threadtest-web-1
๊ทธ๋ฆฌ๊ณ ๋ชจ๋ํฐ๋ง๋ ํด๋ณด์.
docker exec -it threadtest-web-1 /tools/dotnet-counters monitor --process-id 1

์ ๋ณด์ธ๋ค.
ํ
์คํธ ๊ฒฐ๊ณผ
cpu๋ฅผ 1๊ฐ๋ง ํ ๋นํ๊ณ ๊ทธ๋ฆฌ๊ณ 12๊ฐ๋ฅผ ํ ๋นํ๊ณ ํ ์คํธํด๋ณด๋ ๋ค์๊ณผ ๊ฐ๋ค.
1
32767
1
32766
12
32767
2
32765
cpu ๊ฐฏ์์ ์๊ด์ด ์์ด Thread๋ 32767๊ฐ๋ก ๊ณ ์ ๋์ด์๋๊ฒ์ ํ์ธํ ์ ์๋ค.
์ฐ๋ ๋์ ๊ธฐ๋ณธ ๊ฐฏ์๊ฐ ์๊ณ ๊ทธ๊ฒ ๋์ด๊ฐ๋ฉด ์๋์ผ๋ก ์์ฑ์ ํ๋๊ฒ์ผ๋ก ์๊ณ ์๋ค. ๊ทธ๋ผ ๊ธฐ๋ณธ๊ฐ์ด ๋ค๋ฅธ๊ฒ์ผ๊ฐ?
์ฝ๋์ ๋ค์์ ์ถ๊ฐํ๊ณ ์คํํด๋ณด์.
var usedWorkerThread = maxWorkerThreads - availableWorkerThreads;
Console.WriteLine($"Used worker threads: {usedWorkerThread}");
# ์ด๊ฑฐ ์ถ๊ฐ
int minWorker, minIOC;
// Get the current settings.
ThreadPool.GetMinThreads(out minWorker, out minIOC);
Console.WriteLine("Minimum worker threads: {0}", minWorker);
Thread.Sleep(1000000); // Sleep for 10 seconds
Console.WriteLine("Thread completed. go back to the pool.");
return usedWorkerThread;
minWorker๋ฅผ ํ์ธํด๋ณด์.
1
1
12
12
minWorker๋ cpu ๊ฐฏ์์ ๊ฐ์๊ฒ์ ํ์ธํ ์ ์๋ค.
cpu๋ฅผ 1๊ฐ๋ก ํ๊ณ minworker๋ฅผ 1000๊ฐ๋ก ํด๋ณผ๊ฐ?
vi ThreadTest.csproj
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ThreadPoolMinThreads>1000</ThreadPoolMinThreads> <!-- ์ด๊ฑฐ ์ถ๊ฐ -->
</PropertyGroup>
</Project>
๋ค์ ์คํํด๋ณด์.

๊ธฐ๋ณธ์ ์ผ๋ก 1000๊ฐ์ ์ฐ๋ ๋๋ฅผ ๊ฐ์ง๊ณ ์์ผ๋ฏ๋ก usedWorkerThread๊ฐ 1000๊ฐ๋ก ๋์จ๋ค.
๋ฆฌํ์คํธ๊ฐ ์๊น์ผ๋ก์จ ์ฐ๋ ๋๊ฐ ๋์ด๋๋๊ฒ์ ํ์ธํ ์ ์๋ค. 1000์ด ๋์ผ๋ฉด ์ฆ๊ฐ๋ฅผ ํ ๊ฑฐ ๊ฐ๋ค.

1000์ด ๋์ด๊ฐ๋ฉด ํ์ ๋ค์ด๊ฐ๊ณ ํ๋์ฉ ์์ฑ์ด ๋จ์ ์์ ์๋ค.
๋ค์ ๊ณ ๋ฏผ
์น๊ตฌ์ ๋ฌธ์ ๋ ์ฐ๋ ๋๊ฐ ์๊ธฐ๋๊ฒ ์ค๋ ๊ฑธ๋ฆฐ๋ค๋๊ฒ์ด๋ค. ๊ทธ๋์ ์ฐ๋ ๋๋ฅผ ๋ฏธ๋ฆฌ ๋ง๋ค์ด๋๋๊ฒ์ด ์ข์๊ฑฐ ๊ฐ๋ค. ๊ทธ๋ฐ๋ฐ ์๋ฌด๋ฆฌ ํ ์คํธ๋ฅผ ํด๋ด๋ ๊ฐ๋จํ ์์ ์ Thread๊ฐ ๋ง๋ค์ด์ง๋๊ฒ์ด ์ฒ์ 10๊ฐ์ 1000๊ฐ์ ์ฐจ์ด๊ฐ ์๋ค. ์๋ฌด๋๋ ์ฐ๋ ๋์ ์์ฑ์ด ๋ฌธ์ ๋ ์๋๊ฑฐ ๊ฐ๋ค. ๊ทธ๋ผ ๋ค๋ฅธ๊ฒ์ ์ฐพ์๋ด์ผ๊ฒ ๋ค.
entity framework
entity framework๋ฅผ ์ฌ์ฉ์์ ์ปค๋ฅ์ pool์ด ๋ฌธ์ ๋ฅผ ์ผ์ผํค๋๊ฑด ์๋๊ฐ?
๋ค์ ๊ธ์์ ํ์ธํด๋ณด์.
Last updated
Was this helpful?