개발/영상통화

[언택트 기술 시리즈]webrtc 서버 구축 4편 - 시그널시 서버 분산처리(feat zookeeper)

키드 뮤지션 2021. 12. 10. 13:45

webrtc 서버 구축 시리즈 4편

 

그렇다면 어떻게 webrtc 채널 서버의 분산을 할수 있는가?

 

드디어 고대하던 webrtc 채널 서버 분산 처리 이야기가 시작 되었다. 해당 글은 socket.io나 websocket 분산처리에 대해서 알고 싶은 사람들도 읽어도 된다. 충분히 읽을 가치있는 글이다. 읽으면 많은 도움이 될거다! 결국 핵심은 같다. 그럼 글 들어갑니다.

 

시그널링 서버는 두가지종류의 서버로 구성된다고 했었다.

(이어지는 webrtc 서버 구축 시리즈이기 때문에 전에글을 꼭 읽고 오길 바란다.)

https://kid-dev.tistory.com/6

 

webrtc 서버 구축 3편 -시그널링 서버 분산처리(세션정보 관리)

이어지는 시리즈이기 때문에 https://kid-dev.tistory.com/4 [언택트 기술 시리즈]webrtc 서버 구축 1편 -기초 아자르, 스무디, 행아웃 언택트 시대하면 위 서비스들을 한번쯤은 들어보거나 사용해봤을 것

kid-dev.tistory.com

 

세션 서버: room에 누가 있는지, 그리고 누가 들어오는지 나가는지를 관여할 Http 서버

채널 서버: offer/answer를 중계하기 위한 websocket 서버

 

 

 

여기서 webrtc 세션서버의 역할은 두가지이다. 

1. client가 요청시 room에 정보를 알려준다. (전편에서 다뤘다. 알고 싶으면 전편 읽어라 https://kid-dev.tistory.com/6 )

 

webrtc 서버 구축 3편 -시그널링 서버 분산처리(세션정보 관리)

이어지는 시리즈이기 때문에 https://kid-dev.tistory.com/4 [언택트 기술 시리즈]webrtc 서버 구축 1편 -기초 아자르, 스무디, 행아웃 언택트 시대하면 위 서비스들을 한번쯤은 들어보거나 사용해봤을 것

kid-dev.tistory.com

 

2. webrtc 채널 서버의 부하분산

오늘 다룰 내용은 바로 '채널서버의 부하분산'이다. 채널서버는 websoket 서버이기 때문에 클라우드의 L7 로드밸런서로는 부하분산을 할수 없다. nginx와 같은 proxy gateway를 통해서 로드 밸런싱을 할수 없다. 그래서 세션서버를 사용해서 다음과 같이 channel server를 로드 밸런싱 해야만 한다. 

1. session server에서 어떤 서버에게 접속할지 요청한다.

2. session server에게 받은 channel server로 접속한다.

 

간단하지 않은가? 하지만 우리는 한가지 문제에 해결해야 한다. 

 

어떤 부하분산 알고리즘을 사용할것인가?

 

로드 밸런싱 알고리즘은 '라운드 로빈', '가중치 라운드 로빈', '최소 연결 방식', '가중치 최소 연결 방식', '해싱'이 있다. 여러분의 상황에 맞게 선택하면 된다. 필자는 'consistent hasing'이라는 알고리즘을 사용했다. 하지만 'consistent hasing'은 일반 알고리즘보다 복잡하므로 이해를 돕기 위해 '최소 연결 방식'으로 설명하겠다. 

 

최소 연결 방식을 위해선 하나의 맵이 필요하다. 이를테면 다음과 같은 맵이다.

 

channel_server_name connection_count
A_channel 100
B_channel 50

 

이맵을 이제부터 '채널 분산처리 맵'이라고 부르겠다.webrtc session server는 이 '채널 분산처리 맵'을 이용하여, room 생성 요청이 있을시 가장 connection_count가 적은 채널서버를 선택해서 return 해주면 된다. 

 

session server에서 위와 같은 맵을 가지고 있으려면 두가지 정보를 알고 있어야만 한다.

각 channel server가 몇명의 user를 가지고 있는지
어떤 channel server가 있는지 

 

뿐만 아니라 session server는 두가지 정보를 지속적으로 트래킹 해야만 한다. 이를 위해서 필자는 zookeeper를 사용했다. zookeeper를 사용하면 channel server의 생사여부를 알수 있을 뿐만 아니라, connection 수를 넣어 지속적으로 session server에 데이터를 tracking 할수 있다. 이를테면 다음과 같다. 

 

webrtc 채널서버가 새로 생성되었을때,

1. channel serverC가 생성됬다.

2. zookeeper는 channel serverC가 생성되었음을 session server에게 알린다.

3. session server는 '채널 분산처리 맵'에 serverC를 추가 한다.

 

channel_server_name connection_count
A_channel 100
B_channel 50
C_channel 0

 

채널서버가 죽었을떄, 또는 제거 되었을때,

1. channel serverB가 죽었다.

2. zookeeper는 channel serverB가 생성되었음을 session server에게 알린다.

3. session server는 '채널 분산처리 맵'에 serveB를 제거한다.

 

channel_server_name connection_count
A_channel 100
C_channel 50

 

하지만 여기서 궁금한점이 하나 있을 것이다. 

 

connection count는 계속 바뀌는 값인데 이걸 매번 바꿔야만 할까?

 

그럴필요는 없다.

 

channel_server_name grade
A_channel 2
B_channel 3
C_channel 1

 

위와 같이 connection_count 대신 grade를 사용하면 된다. connection 수가 100명이 되면 grade를 4로 바꾼다. 이런식으로 우리는 매번 새로운 client가 접속할때 마다 connection_count를 update 안해도 된다. 그리고 나중에 다른 가중치도 넣을수 있다. 물론 편한 설명을 위해서 예를 넣을 것일뿐 방식은 여러분 자유이다. 

 

우리는 이렇게 webrtc 시그널링서버를 만들수 있었다.

webrtc 시그널링 서버를 분산처리 할수 있었다.

 

하지만 이게 끝이 아니다.

channel server가 죽었을때 fail over를 어떻게 할것인가?

배포를 할때 어떻게 무중단 배포를 할것인가?

 

우리는 아직 가야할 길이 멀다.

 

 

 

코드 오랑우탄 시크