출처 : http://funcreators.net/wp/c%ec%9c%bc%eb%a1%9c-%ea%b2%8c%ec%9e%84%ec%84%9c%eb%b2%84%eb%a5%bc-%ea%b0%9c%eb%b0%9c%ed%95%9c%eb%8b%a4%eb%a9%b4/

 

 

 

c# 서버 제작하시는 분 있으신가요?

게임 코디에 올라온 c# 서버 제작하시는 분 있으신가요?1라는 질문에 대해 나름대로 답변을 하고자 한다.

구글 검색, GPG 검색으로 c# 개발에 대해 부정적인 시각이 매우 많네요.
그런데 요즘 구인 글 보면 c# 서버 개발 가능자란 문구가 좀 보이는데요…
아직까지 캐주얼 게임에만 적용된 C#서버만 보였는데,
MMORPG 개발사인데 C#서버 개발 가능자를 뽑긴 하던데…
요즘엔 MMORPG에 C#서버로 돌리나요?
업계 동향 보니깐 아예 c#으로 가는 팀도 많아 보이던데….
혹시 경험 및 사례 있으시면 조금 공유 부탁 드려봅니다.

질문과 답변 형식으로 궁금증을 해소하는 편이 읽는 이가 이해하기에 나을 듯 싶다.

참고로 굳이 C#을 고려한 걸 보면 C#을 도입했을 때의 장점은 분명히 알리라 믿고 이 글에서는 성능 문제에만 초점을 맞춘다.

C#이 느리다던데요?

무엇과 비교하는냐에 달렸다. C/C++과 비교하면 느리다. 그런데 얼마나?

2

C# versus C++ versus Java performance comparison2에서 가져온 이 자료에 따르면 Windows에서 C++은 C#보다 단지 15%가 빠를 뿐이다. 2009년도에 성능 차이가 이 정도였으니 현재는 격차가 더 적을 것이다. 물론 벤치마크의 방식과 샘플 데이터에 따라 결과는 달라진다. 하지만 대부분의 벤치마크에서 비슷한 수치를 보고한다.

그런데 왜 사람들은 C#이 느리다고 하죠?

C# 응용프로그램이 느리다고 느끼는 이유는 몇 가지 있다.

Just-in-time 컴파일

.NET Framework 는 JIT 컴파일을 한다. 여러분이 Visual Studio 에서 C#을 컴파일하면 바이너리 코드가 아닌 VM(가상머신) 언어로 결과가 나올 뿐이다. 나중에 응용프로그램을 실행할 때 .NET Framework 런타임이 VM 언어를 다시 네이티브 바이너리로 컴파일한다.

이런 까닭에 응용프로그램의 초기 구동시 반응이 느릴 수밖에 없다. 대부분의 프로그래머는 코드를 몇 줄 고치고 프로그램을 실행하고 닫는다. 이런 과정을 반복하기 때문에 장시간 운영되는 라이브 환경에서 나오는 성능보다 훨씬 낮은 체감 성능을 느낀다.

.NET Framework 에는 C# 코드를 바로 네이티브 코드로 컴파일하는 도구가 있긴 하다. 하지만 이런 도구를 사용하면 JIT가 제공하는 최적화를 놓치게 된다. 이러한 도구는 구동 시간이 중요한 클라이언트에 써야지 전체 처리량(Throughput)이 중요한 서버에 쓸 게 아니다.

가비지 컬렉션 방식

.NET Framework의 메모리 할당 방식은 간단히 말해 스택 할당이다. 따라서 할당 속도는 C++ 보다 빠르다. 물론 C++ 처럼 메모리 할당 전략을 프로그래머가 마음껏 바꿀 재량권은 상당히 박탈당한다.

빠른 할당에 비해 해제는 상당히 느린 편이다. 메모리가 부족하다 싶을 때 가비지 콜렉터가 한꺼번에 정리하기 때문이다. .NET Framework 의 런타임은 전체 처리량에 맞춰 최적화했다. 따라서 이러한 전략은 웹 서버와 같이 일시적인 느려짐이 크게 문제되지 않는 곳에 매우 적합하다. .NET Framework 초기에 ASP .NET 에 초점을 맞춰 마케팅이 이뤄진 점만 봐도 이러한 설계 철학이 이해가 된다.

따라서 C# 으로 서버를 개발한다면 소위 말하는 렉이 주기적으로 발생한다. 렉이 가끔 발생해도 문제되지 않는 서버에 쓰는 게 좋다. 렉이 발생해도 플레이어가 크게 불평하지 않는 캐주얼 게임이 아니라면 게임서버보다는 캐시서버 등에 적합하다고 보면 된다.

메모리 부족

같은 양의 데이터를 처리한다고 볼 때 C# 응용프로그램이 메모리 소모량이 심하다. 몇 가지 이유가 있지만 무엇보다 가비지 콜렉션을 최후까지 미루는 탓도 크다.

이렇다 보니 메모리가 부족한 환경에서는 가비지 콜렉션을 자주 해야 한다. 그뿐 아니라 스왑도 자주 발생한다. I/O 가 서버 성능에 가장 큰 영향을 미치는 요소 중 하나라는 점을 생각해야 한다.

단, 라이브 환경에서는 값싼 메모리를 마구 투입하면 되므로 큰 문제가 되지 않을 수도 있다.

참고로 .NET Framework 는 COM 을 통해 메모리 할당 전략을 어느 정도 바꿀 수 있다. 다만 해제 전략과 관련된 어떠한 API 도 제공하지 않는다.

C# 으로 구현한 상용 게임이 있어요?

있다. 마비노기 영웅전3! 그 외에도 개발 중인 MMORPG 도 있다. 단, 프로젝트마다 아키텍처와 문제해결 방식이 다르다. 고민 많이 해야 한다.

나쁘지 않은데?4

그렇게 좋다면 왜 C# 서버를 도입한 곳이 별로 없죠?

렉 문제와 설계의 어려움

앞서 말한 렉 문제가 게임 플레이에 크게 악영향을 주는 경우가 있다. 각 서버군 별로 나눠서 필요한 곳에만 C#을 적용해도 된다. 하지만 여러 개의 프로그래밍 언어를 개발팀이 익히고 유지보수해야 하는 문제가 있다. 또한 어떻게 아키텍처를 설계해야 C# 도입의 장점을 최대한 살리고 그 단점을 최소로 줄일 수 있는지 파악하기 힘들다.

느리다

어라, 방금 전까지 C#의 성능이 훌륭하다고 말하지 않았나? 아니, 그건 오해다. 15%? 작다면 작지만 어떤 경우에는 크다. 그게 핵심 엔진 코드라면 치명적일 수도 있다. 대체로 이러한 성능 차이는 분산 서비스로 설계하면 문제가 되지 않지만 단일 게임 서버에 하는 일이 몰린다면 심각한 문제가 야기될 가능성이 있다.

설계의 유연성이 부족하다

C++ 과 같은 네이티브 프로그래밍 환경이 주는 최대 장점은 설계의 유연성이다. 메모리 할당 및 해제 전략을 내 취미대로 고친다거나 무잠금 알고리즘을 적용한다던가(C#에서도 가능하지만, 그냥 해보면 안다) 초고성능을 추구하는 이에게 C# 환경은 답답한 면이 많다.

결론

여기까지 경험담을 정리했다. 잘 알고 잘 알아서 설계해서 알차게 살아보자. 어차피 내가 여러분의 프로젝트 책임자도 아니니 여기서부턴 나도 모르겠다.

급소 가격

 

http://thankee.tistory.com/91

 

점점 C#이 아름답다고 느껴지고 있습니다.

'기타 언어 프로그래밍 > C# 관련' 카테고리의 다른 글

C#으로 게임서버를 개발한다면?  (0) 2012.10.09
윈도우에서 mongoDB는 C#으로  (0) 2012.09.25
C#게임 서버 (IOCP)  (0) 2007.11.11

얼마전 mongoDB를 좀 갖고 놀았다.

DBA는 DB 저장 프로시져가 당연히 첫번째 관심사항이겠지만
서버 개발자의 경우 DB와 연결하는 드라이버가 첫번째 관심사항이다.
당연히 개발자답게 Windows용 C++ Driver부터 빌드하였다.
소문대로 mongoDB 빌드는 무척 더러웠다.
mongoDB 소스를 갖고 Windows용 C++ 드라이버를 빌드한다는 것이 좀 이해가 안된다.

그리고 내린 결론은...
Windows 서버에서는 C++로 mongoDB 서버를 짜지 말자는 것이다.
추천언어는 C#.

이런 결정이 내려진 이유는...

1) scons에서 더이상 force32로 옵션으로 32비트 빌드가 안된다.
32비트 드라이버를 빌드할려면 32비트 PC나 가상 머신을 띄워 빌드 시켜야 한다.
64비트로만 서버를 짜겠다면 할말은 없지만 최소 클라이언트에서는 문제가 된다.
(사실 mongoDB 데몬을 따로 개조 & 빌드하여 Access를 대신하는 용도로 써볼까 생각을 해봤었다.
물론 이와 같은 문제로 안됨.
그리고 32비트에서는 mongoDB 역시 데이터 사이즈 2GB가 한계.)

2) boost를 1.42로만 써야한다.
mongoDB를 빌드시키는 것뿐만 아니라, mongoDB 드라이버를 이용하는 프로젝트는 역시 boost 1.42를 써야한다.

서버상에서 가장 큰 이유는 물론 두번째 항목이다.
boost 1.45에서 interface가 많이 바뀌었는데 mongoDB만으로 위해서 boost 1.42 를 따로 관리하고 빌드시 참조해야 한다는게 말도 안된다.
일괄빌드에 치명적인 문제를 안긴다. 소위 말하는 빌드비용의 증가 문제가 따라온다.

그래서 C++은 포기했다.
아니 애시당초 이렇게 복잡한 빌드 방법이라니 mongoDB는 Windows에서 C++로 쓰지 말라는 말같다. ㄴㅁ...

기왕 좀 삽질한 거, 서비스로 드라이버인 mongoclient.lib를 포스트에 올려드리고 싶지만,
용량이 무려 150 메가 이상이라 차마 올려드리진 못하겠다.

대신 mongoDB 드라이버 빌드팁을 적어본다.

0) 비쥬얼 스튜디오에서 빌드하는게 아니라면 Spider Monkey는 필요없다.
Scons로 빌드하므로 괜히 복잡하게 다운받고 어디에 설치해야 하는지 고민말자.

1) 몽고 DB소스(DB+ C++ 드라이버) 다운 https://github.com/mongodb/mongo , https://github.com/mongodb/mongo/downloads
(드라이버-리눅스-가 아님.)

2) 파이썬 32비트 설치

3) Scons 설치- 설치시 Python\Scripts 라는 기본 위치에 설치
Scons은 *.mak 파일 빌드를 대체하는 개념인데 파이썬을 쓰므로 이렇게 설치를 한다.

4) MongoDB는 boost 1.42에서 빌드되었음으로 MongoDB홈페이지에서 제공하는 해당버전 다운하고 적당한 폴더에 푼다.
http://www.mongodb.org/pages/viewpageattachments.action?pageId=12157032
이것은 앞으로 boost 빌드뿐만 아니라 mongoDB 드라이버를 이용하는 모든 프로젝트에서 사용해야 한다. 좆같다.

5) 4)에서 받은 mongoDB를 SconStruct 파일에서 boost 경로 지정.
대략 640라인으로 이동,
def find_boost():
for x in ('', ' (x86)'):
boostDir = "C:/boost" <-- 4)에서 지정한 경로로 적어줌.
if os.path.exists( boostDir ):
return boostDir
for bv in reversed( range(33,50) ):
for extra in ('', '_0', '_1'):
boostDir = "C:/Program Files" + x + "/Boost/boost_1_" + str(bv) + extra
if os.path.exists( boostDir ):
return boostDir
if os.path.exists( "C:/boost" ):
return "C:/boost"
if os.path.exists( "/boost" ):
return "/boost"
return None


6) 콘솔창에서 1)에서 받은 mongoDB 소스 폴더로 가서 PATH 명령어로 파이썬경로와 파이썬 아래 script 경로(Scons) 설정.
기존 PATH에 있는 것 쓸일 없으니까 단순히 아래대로 자신의 파이썬 경로를 적어주자.
SET PATH=D:\Program Files (x86)\Python27;D:\Program Files (x86)\Python27\Scripts

7) 클라이언트 빌드
--> 8)에서 몽고DB를 64로 빌드하면 클라이언트도 64, 몽고DB를 32로 빌드하면 클라이언트도 32...인데 Scons가 더이상 64비트에서 32비트로 강제 빌드가 안된다.
따라서 32비트 드라이버가 필요하면 32비트 머신이나 가상머신 필요...

8) Client 개발시 ws2_32.lib 추가
까보진 않았지만 mongoDB 데몬과 통신시 역시나 TCP/IP를 쓰는 듯 하다.
님들, 걍 C# 쓰세요~

님들, 걍 C# 쓰세요~

 

 

출처 : http://rhea.pe.kr/496

+ Recent posts