alkee-allm / k2proto

grpc service sample
6 stars 2 forks source link

ping timeout 처리 #37

Closed alkee-allm closed 4 years ago

alkee-allm commented 4 years ago

일정시간동안 ping 이 없는 서버들의 경우 장애처리.

상황에 대한 함수를 별도로 만들어 추후에 정책적인 부분이 변경되더라도 해당 함수를 수정하는 것으로 반영되도록.

unique backend service 의 경우 별도 issue(#38) 에서 진행.

alkee-allm commented 4 years ago

ping-timeout 시간 설정은 일단 K2svc.DefaultValues 에 두도록 하고 추후에 configuration 변경(#39)후 configuration 에 반영하는 것이 좋겠다.

alkee-allm commented 4 years ago

https://github.com/alkee-allm/k2proto/blob/da7869daf42dfd1c2d68f03031f05f7ff5e677b0/K2svc/Backend/ServerManagerBackend.cs#L128-L152

servers 는 항상 LastPingTime 으로 정렬되어있는 구조이므로, 항상 마지막 요소만 검사하는 방식으로 구현이 가능할 것. 별도의 timer 를 두기보다 Ping 요청시마다 검사하면 효율적일 것. 현재는 ServerManager 역시 ServerManagementBackground를 통해 항상 스스로에게(default value) ping 하고 있기 때문에, 지속적으로 업데이트(ping 요청이 많을 수록 잦은 업데이트) 가능할 것.

alkee-allm commented 4 years ago

PingTimout 이 발생하면 로깅하고 ServerManager가 가지고 있는 목록에서 제외(Unregister 와 같은 동작)하는 동작과 함께, 필요한 추가 작업

  1. 해당 서버의 backend address 가 사용 가능한지 확인하고
  2. 사용 가능하다면 SessionManager 에 해당 서버가 서비스중이던 user 제거

ping-timeout 은 발생했지만, 아직 backend(push 등) 서비스가 남아있는 경우, 사용자 연결상태와 session manager 의 데이터가 일치하지 않게 되어 예상할 수 없는 문제들이 발생할 수 있을 것. 따라서, backend(push)가 이용 가능한 경우 연결되어있는 모든 유저들의 연결을 해제하도록 할 필요가 있다.

서버 backend 가 사용가능한지 확인

GrpcChannel class가 직접적인 연결 테스트를 할 수 있는 interface 를 제공하고있지 않다. grpc-dotnet 이 아닌 grpc-csharp 에는 Channel class 가 있고 여기에는 connect method 가 있다. 따라서, Grpc.Core package 를 추가하고 connection test 를 수행.

하지만, ConnectAsync 함수가 올바르지 않은 address(uri)에 대해 기대했던 동작(exception 발생 등)은 하지않고 멈춰있는(Task.Wait()시) 현상만 나타나 이를 이용할 수 있을 것 같지 않다. State 또한 Idle 로 유지.

따라서, grpc core 를 직접 이용할 수 없어, 별도의 test protocol 을 만들어 이를 호출해 연결 확인. 테스트를 해보니, 호출 후 약 20초 쯤 후에 응답-오류 발생. ConnectAsync 도 충분히 기다리면 같은 결과가 있었을 수 있겠다. 이 timeout(deadline) 시간을 줄여서 설정할 필요가 있어보인다.

// TEST
using var channel = Grpc.Net.Client.GrpcChannel.ForAddress("http://19.168.0.44"); // 연결불가능한 임의의 channel
var client = new ServerHost.ServerHostClient(channel);
client.Test(new Null(), deadline: DateTime.UtcNow.AddSeconds(1));

Grpc.Core.Channel.ConnectAsync를 이용할 수도 있겠지만, credentials 등 초기에 지정해주어야 하는 low-level 정보들이 불편하기 때문에 별도의 protocol 을 이용해 연결확인

alkee-allm commented 4 years ago

복잡하게 session 단위로 연결끊기 작업을 하는 것 보다, 해당 backend 를 stop 시키는 것이 훨씬 효율적일 것. !!