아키텍처 흐름도
gRPC 서비스 발견
gRPC 리졸버 인터페이스 설계
// gRPC 리졸빌더
type Builder interface {
Build(target Target, cc ClientConn, opts BuildOptions) (Resolver, error)
Scheme() string
}
// gRPC 리졸버
type Resolver interface {
ResolveNow(ResolveNowOptions)
Close()
}
메시지 전달 순서도
소스 코드
Gitee: https://gitee.com/luyue_zhang/go_rpc_2/tree/master/server_register_and_found/resolver_demo
테스트 방법
비디오 설명
gRPC 리졸버 사용 방법 비디오 설명
서비스 등록 및 발견 구현
인터페이스 설계
type ServiceRegistry interface {
RegisterService(ctx context.Context, instance ServiceInfo) error
UnRegisterService(ctx context.Context, instance ServiceInfo) error
ListService(ctx context.Context, serviceName string) ([]ServiceInfo, error)
Subscribe(serviceName string) <-chan ServiceEvent
io.Closer
}
소스 코드
데모 실행
질의응답
실행 중에 클라이언트가 레지스트리에 연결할 수 없는 경우 어떻게 해야 하나요?
네트워크 문제 또는 레지스트리 장애 등이 원인일 수 있습니다.
일관성 측면에서는 클라이언트가 레지스트리 연결이 복구될 때까지 서비스 호출을 즉시 중단해야 합니다.
가용성 측면에서는 클라이언트가 서비스를 계속 제공하고 레지스트리 재연결을 시도하며, 이 기간 동안 캐시 데이터를 사용합니다. 일정 시간 연결이 실패하면 서비스를 중단합니다.
실행 중에 클라이언트가 레지스트리 데이터를 가져왔지만 해당 서버에 연결할 수 없는 경우 어떻게 해야 하나요?
클라이언트와 서버 방화벽 문제일 수 있습니다. 서버에 연결할 수 없을 때 클라이언트는 로컬 사용 가능 노드 목록에서 해당 서비스 인스턴스를 제거해야 합니다. 서비스가 복구되면 다시 노드 목록에 추가합니다.
레지스트리가 장애가 발생하면 클라이언트와 서버는 어떻게 해야 하나요?
이 문제는 클라이언트가 레지스트리에 연결할 수 없는 경우와 동일하므로, 1번 질문을 참조하세요: 실행 중에 클라이언트가 레지스트리에 연결할 수 없는 경우 어떻게 해야 하나요?
서버가 장애가 발생한 후 클라이언트가 얼마나 빨리 인지하게 되나요?
서버와 레지스트리의 상호작용 방식에 따라 다릅니다:
서버가 주기적으로 갱신하는 경우(하트비트 없음): 임대 시간 초과 및 레지스트리 임대 시간 초과 재시도 메커니즘에 따라 다릅니다.
레지스트리가 서버와 하트비트를 유지하는 경우: 하트비트 재시도 횟수와 간격에 따라 다릅니다.
컨테이너 내부 IP 문제
예제의 etcd에서는 IP+포트를 사용하여 서비스 인스턴스를 식별합니다. 마이크로서비스가 Docker 컨테이너에서 실행되는 경우 IP는 항상 localhost가 됩니다.
해결책:
- 컨테이너 전용 서비스 등록 및 발견 방식 사용
- 컨테이너 시작 시 가상 네트워크가 아닌 호스트 네트워크 사용
- 컨테이너 시작 시 호스트 IP를 환경 변수로 주입
서버와 레지스트리에 연결할 수 없는 경우 어떻게 해야 하나요?
서버는 연결될 때까지 재시도하고 오류 로그를 출력합니다. 일반적으로 서버는 레지스트리에 연결되지 않아서 서비스를 중단하지 않습니다. 레지스트리는 서버에 연결할 수 없을 때 재시도하며, 여러 번 재시도에 실패하면 서버가 다운된 것으로 간주하고 클라이언트에 알립니다.