목표
30000명이 동시에 접속할 수 있는 TCP 서버 만들기
30000명의 클라이언트는 전송 - 수신 - 전송 - 수신 을 반복한다.
30000명의 클라이언트를 켜 놓고, 다음날 서버가 에러 없이 살아 있는 것을 목표한다.
목표를 성취한 후에는 평균 응답 시간을 줄여보도록 하겠다.
프로젝트 Git Hub Repository 링크
https://github.com/MatorMirne/SocketCommunicate-TCP
이전 포스트
- 1일차 : 2023.06.26 - [일지/C#] - [프로젝트 예수 - 1일차] 대규모 동시접속 TCP 서버
- 2일차 : 2023.06.27 - [일지/C#] - [프로젝트 예수 - 2일차] 대규모 동시접속 TCP 서버 제작기
- 3일차 : 2023.06.28 - [일지/C#] - [프로젝트 김필여 - 3일차] 대규모 동시접속 TCP C# 서버 제작기
- 4일차 : 2023.06.29 - [일지/미니프로젝트] - [프로젝트 김필여 - 4일차] 대규모 동시접속 TCP C# 서버 제작기
현재 필(사람 이름으로 하니 프로젝트를 부르기가 조심스럽네요 ㅠㅠ 필 이라고 애칭으로 부르겠습니다.)의 문제점은 Remote 오브젝트를 제대로 반환하지 않는 연결이 존재한다는 것입니다.
이녀석들이 누구인지 파악하기 위해서는 어떻게 해야 할까요 ?
출력을 해보고, 디버깅도 해보면 좋을것같습니다.
우선 출력을 해 보았습니다. 오브젝트 반환 후에 현재 Remote Pool 의 상태를 출력하는 코드를 추가했습니다.
그런데 ... 결과가 아주 충격적입니다. 아래는 출력의 전문입니다. (매우 깁니다)
오브젝트 반환
오브젝트 반환
오브젝트 반환
오브젝트 반환
오브젝트 반환
Conncect:1 | Available:0
Conncect:1 | Available:0
오브젝트 반환
오브젝트 반환
오브젝트 반환
오브젝트 반환
오브젝트 반환
오브젝트 반환
오브젝트 반환
오브젝트 반환
Conncect:1 | Available:2
Conncect:1 | Available:2
Conncect:1 | Available:2
Conncect:1 | Available:2
오브젝트 반환
오브젝트 반환
오브젝트 반환
오브젝트 반환
Conncect:1 | Available:6
오브젝트 반환
오브젝트 반환
Conncect:1 | Available:6
오브젝트 반환
Conncect:1 | Available:7
오브젝트 반환
Conncect:1 | Available:8
Conncect:1 | Available:9
Conncect:1 | Available:7
오브젝트 반환
오브젝트 반환
오브젝트 반환
오브젝트 반환
Conncect:1 | Available:12
Conncect:1 | Available:12
오브젝트 반환
Conncect:1 | Available:12
Conncect:1 | Available:14
오브젝트 반환
오브젝트 반환
오브젝트 반환
오브젝트 반환
Conncect:1 | Available:16
오브젝트 반환
오브젝트 반환
오브젝트 반환
Conncect:1 | Available:17
Conncect:1 | Available:17
오브젝트 반환
오브젝트 반환
Conncect:1 | Available:19
Conncect:1 | Available:19
오브젝트 반환
오브젝트 반환
Conncect:1 | Available:21
Conncect:1 | Available:21
오브젝트 반환
오브젝트 반환
오브젝트 반환
Conncect:1 | Available:23
Conncect:1 | Available:23
오브젝트 반환
Conncect:1 | Available:25
Conncect:1 | Available:25
오브젝트 반환
Conncect:1 | Available:26
오브젝트 반환
오브젝트 반환
오브젝트 반환
Conncect:1 | Available:28
오브젝트 반환
Conncect:1 | Available:28
오브젝트 반환
Conncect:1 | Available:29
Conncect:1 | Available:30
오브젝트 반환
오브젝트 반환
오브젝트 반환
오브젝트 반환
Conncect:1 | Available:32
Conncect:1 | Available:32
오브젝트 반환
오브젝트 반환
Conncect:1 | Available:34
Conncect:1 | Available:34
오브젝트 반환
Conncect:1 | Available:36
오브젝트 반환
오브젝트 반환
Conncect:1 | Available:0
Conncect:1 | Available:37
오브젝트 반환
오브젝트 반환
Conncect:1 | Available:39
Conncect:1 | Available:39
오브젝트 반환
오브젝트 반환
오브젝트 반환
Conncect:1 | Available:40
오브젝트 반환
Conncect:1 | Available:40
Conncect:1 | Available:41
오브젝트 반환
Conncect:1 | Available:44
오브젝트 반환
오브젝트 반환
Conncect:1 | Available:45
오브젝트 반환
Conncect:1 | Available:45
Conncect:1 | Available:46
오브젝트 반환
Conncect:1 | Available:0
Conncect:1 | Available:48
오브젝트 반환
Conncect:1 | Available:50
Conncect:1 | Available:1
오브젝트 반환
오브젝트 반환
오브젝트 반환
Conncect:1 | Available:52
Conncect:1 | Available:52
Conncect:1 | Available:52
오브젝트 반환
오브젝트 반환
Conncect:1 | Available:55
Conncect:1 | Available:55
오브젝트 반환
오브젝트 반환
오브젝트 반환
Conncect:1 | Available:57
오브젝트 반환
오브젝트 반환
Conncect:1 | Available:58
오브젝트 반환
Conncect:1 | Available:59
오브젝트 반환
Conncect:1 | Available:60
Conncect:1 | Available:61
Conncect:1 | Available:2
오브젝트 반환
Conncect:1 | Available:63
오브젝트 반환
Conncect:1 | Available:64
Conncect:1 | Available:2
오브젝트 반환
오브젝트 반환
Conncect:1 | Available:2
Conncect:1 | Available:66
오브젝트 반환
오브젝트 반환
Conncect:1 | Available:68
오브젝트 반환
오브젝트 반환
Conncect:1 | Available:69
Conncect:1 | Available:69
Conncect:1 | Available:6
Conncect:1 | Available:7
Conncect:1 | Available:7
오브젝트 반환
Conncect:1 | Available:74
Conncect:1 | Available:12
Conncect:1 | Available:16
Conncect:1 | Available:17
Conncect:1 | Available:17
Conncect:1 | Available:19
오브젝트 반환
Conncect:1 | Available:80
오브젝트 반환
Conncect:1 | Available:81
오브젝트 반환
Conncect:1 | Available:82
오브젝트 반환
Conncect:1 | Available:83
Conncect:1 | Available:28
오브젝트 반환
Conncect:1 | Available:85
Conncect:1 | Available:32
Conncect:1 | Available:32
오브젝트 반환
Conncect:1 | Available:88
오브젝트 반환
Conncect:1 | Available:89
Conncect:1 | Available:37
오브젝트 반환
Conncect:1 | Available:91
오브젝트 반환
Conncect:1 | Available:92
오브젝트 반환
Conncect:1 | Available:93
오브젝트 반환
Conncect:1 | Available:94
Conncect:1 | Available:40
Conncect:1 | Available:57
Conncect:1 | Available:57
Conncect:1 | Available:66
Conncect:1 | Available:69
의문점이 너무 많습니다.
1. '오브젝트 반환'이 100번 출력되지 않았는데, Connect가 0이 되었다. << 오브젝트 반환보다 출력이 느렸을 것으로 예상
2. 그렇다 한덜 반환을 다 했는데, Connect가 1개 남았다. 잘못된 시점을 알기 어렵다.
3. Available이 순차적으로 줄어들지 않는다. << 현재 연결당 하나의 스레드를 갖기 때문에, 스레드의 할당 순서 때문일 것으로 예상
1,3번은 원인이 예측되지만 2번이 조금 어렵습니다. 아마도 멀티스레드 환경에서 오브젝트 풀이 제대로 동작하지 않고 있는 것 같습니다. 여러 스레드가 하나의 객체에 접근하므로, 작업이 누락된 것 같습니다.
갑자기 생긴 고민
그런데 여기서, 한가지 고민이 생겼습니다. 문제점이 무엇인지 정확하게 파악하지 않고, '문제점은 이것일 것이다!' 라며 어림짐작하는 것은 안 좋은 습관일 것 같습니다. 그런데... 자꾸 이런 식으로 문제를 해결해 보려 할 때마다... 해결이 됩니다 ... 그래서 더 이렇게 행동하게 되는 것 같습니다.🥲 사실 이렇게 문제점이 무엇인지 문득 '혹시 이거 때문 아냐?' 하고 떠오르는 것이 나쁘지만은 않습니다. 문제가 해결이 되고 있으니까요. 이렇게 번뜩번뜩 떠오르는 해결 아이디어(?)를 위해 대학에서 문제의 종류에 대해 강의하는 것이겠죠? 언젠가는 컴퓨터를 100% 이해하여 제가 뭘 놓치고 있는지 정확히 알 수 있으면 좋겠습니다. 그리고 그래야만 문제를 알 수 있을 정도로 난해한 문제가 발생하는 날이 오겠죠? 지금 읽고 있는 C# 서적을 다 읽고 나면 운영체제 전공 서적을 다시 정독해봐야 할 것 같습니다.
오브젝트 풀 할당, 반환에 lock 설정
우려했던 것보다 아주 간단하게 조치가 되었습니다. 스레드풀에 lock을 걸어 주는 방식으로 해결이 되었습니다.
코드 변화는 고작 이것뿐입니다. 왼쪽이 변경 후, 오른쪽이 변경 전입니다.
저는 바로 풀에 lock을 걸어서 문제를 해결했습니다. 오브젝트를 할당받거나 할당할때 모두 풀에 접근하므로 풀 접근에 관련된 작업들을 순차적으로 처리하게 되면 스레드 동시 접근에 의한 피해를 줄일 수 있을 것 같습니다!
수정 후 로그 (좀 깁니다.)
... (생략) ...
95 오브젝트 반환
Conncect:4 | Available:96
97 오브젝트 반환
Conncect:3 | Available:97
98 오브젝트 반환
Conncect:2 | Available:98
99 오브젝트 반환
Conncect:1 | Available:99
100 오브젝트 반환
Conncect:0 | Available:100
오브젝트 할당
오브젝트 할당
오브젝트 할당
오브젝트 할당
오브젝트 할당
오브젝트 할당
오브젝트 할당
오브젝트 할당
... (100개 클라이언트 접속 중) ...
오브젝트 할당
오브젝트 할당
오브젝트 할당
오브젝트 할당
오브젝트 할당
오브젝트 할당
오브젝트 할당
오브젝트 할당
오브젝트 할당
오브젝트 할당
Conncect:100 | Available:0
Conncect:100 | Available:0
Conncect:100 | Available:0
Conncect:100 | Available:0
101 오브젝트 반환
Conncect:99 | Available:1
103 오브젝트 반환
Conncect:98 | Available:2
102 오브젝트 반환
Conncect:97 | Available:3
106 오브젝트 반환
Conncect:96 | Available:4
105 오브젝트 반환
Conncect:95 | Available:5
109 오브젝트 반환
Conncect:94 | Available:6
108 오브젝트 반환
Conncect:93 | Available:7
107 오브젝트 반환
Conncect:92 | Available:8
111 오브젝트 반환
Conncect:91 | Available:9
... (생략) ...
그런데 문제가 있습니다. 오브젝트 할당이 너무 느립니다. 현재 코드에서는 1명의 Remote 오브젝트 할당에 1.5초 정도가 걸립니다. 너무 느립니다... 아마 모든 코드가 동시에 실행되게 하기 위해 클라이언트가 입력될때마다 매번 스레드를 발급하는 방식이 문제가 된 것 같습니다. 안양 시민 3만명을.. 아니 잠깐만 검색해보니까 안양시민 60만이네 와 저 정말 숫자 감각 없었네요 놀랍습니다... 한 10만 할줄 알았는데 수용하기 위해서 스레드가 3만+@개 발행된다니 .... 지금 상태로는 다들 접속하는데만 12시간 반이 걸릴 겁니다^^... 제 다음 목표는 스레드 사용을 줄이고 비동기식 Task 작업으로 변경하는 것입니다. 그렇게 한다면 상당 시간이 절약될 것으로 보입니다. 저는 아직 비동기식 코드 작성에 굉장히 미숙합니다. 아마 다음 프로젝트:필 관련 포스팅은 한참 후에나 작성할 수 있게 될 것 같습니다.
의문점
왼쪽과 같은 상황에서는 어떻게 될까요?
이미 사용중인 오브젝트에 lock 을 걸려고 시도하면, 누가 이길까요.
저는 우선 서적을 다 읽어 보고 lock 에 관련된 부분을 다시 공부해 보려고 합니다.
아시는 분이 계시다면 제보 부탁드립니다...
>> 오 바로 알게 되었습니다. 제가 두 가지를 모르고 있었군요
1. 첫 번째는 lock은 같은 오브젝트에 접근하려는 lock만 제어한다는 것입니다. 오브젝트 a에 lock을 걸어 놓은 상태에서, Console.PrintLine(a) 는 실행할 수 있습니다. 제지되지 않습니다.
2. 하지만, lock(a) 는 저지됩니다. 이미 lock 이 걸려 있는데 다시 lock을 걸려고 하면 안됩니다.
따라서 위 같은 상황이 발생했을 때, 저는 A 스레드에서는 lock 없이 풀을 사용 중인 것으로 가정했습니다. 따라서 문제 없이 A 스레드와 B스레드 모두 풀에 접근이 가능합니다. 이 때 자원 공유 문제가 발생할 수 있으니 조심하면 되겠습니다!
끝
다음 글 : 2023.07.24 - [일지/미니프로젝트] - [프로젝트 김필여 - 6일차] 대규모 동시접속 TCP C# 서버 제작기
[프로젝트 김필여 - 6일차] 대규모 동시접속 TCP C# 서버 제작기
목표 30000명이 동시에 접속할 수 있는 TCP 서버 만들기 30000명의 클라이언트는 전송 - 수신 - 전송 - 수신 을 반복한다. 30000명의 클라이언트를 켜 놓고, 다음날 서버가 에러 없이 살아 있는 것을 목
develop-jen.tistory.com
'Side Project > 안양시장 프로젝트 - TCP 서버개발' 카테고리의 다른 글
[프로젝트 김필여 - 7일차] 대규모 동시접속 TCP C# 서버 제작기 (0) | 2023.07.25 |
---|---|
[프로젝트 김필여 - 6일차] 대규모 동시접속 TCP C# 서버 제작기 (0) | 2023.07.24 |
[프로젝트 김필여 - 4일차] 대규모 동시접속 TCP C# 서버 제작기 (0) | 2023.06.29 |
[프로젝트 김필여 - 3일차] 대규모 동시접속 TCP C# 서버 제작기 (0) | 2023.06.28 |
[프로젝트 예수 - 2일차] 대규모 동시접속 TCP C# 서버 제작기 (0) | 2023.06.27 |