재설계된 Redis 상태 페이지

13712 단어
Blazor Server와 Redis를 사용하여 상태 페이지를 만들었을 때 이전 게시물을 기억할 수도 있습니다. 이전 게시물에서 저는 Redis를 사용한 데이터 모델링에 대한 순진한 접근 방식으로 인해 LINQ 및 Redis.OM에 대한 과도한 의존이라는 구현의 단점 중 하나를 언급했습니다.

이 새 버전에서는 서비스 가동 시간 데이터를 더 잘 저장하기 위해 Redis 데이터 구조(목록, 설정 및 해시)의 사용을 최대화하여 저장 및 쿼리가 더 쉬워지도록 노력했습니다.

새로운 기능



첫 번째 버전



첫 번째 버전에서는 Redis.OM을 사용하여 데이터를 저장하고 LINQ를 사용하여 데이터를 쿼리하고 형식을 지정합니다. 이 접근 방식을 사용하면 데이터를 테이블처럼 모델링하려고 했기 때문에 데이터 저장 및 쿼리가 빠르게 복잡해졌습니다.

데이터 저장:

// save to redis using OM
var collection = _cnProvider.RedisCollection<MonitoringSnapshot>();
await collection.InsertAsync(new MonitoringSnapshot
{
    UnixTimestamp = timestamp.ToUnixSeconds(),
    ServiceName = serviceName,
    Healthy = healthy,
    Latency = latency
});

그렇게 나쁘지 않죠?

데이터 쿼리:

// get collection
var collection = _cnProvider.RedisCollection<MonitoringSnapshot>();

// query all data
var query = collection
    .Where(x => x.UnixTimestamp > nowUnixEpoch)
    .ToList();
var timestamps = query
    .GroupBy(x => x.ServiceName)
    .First()
    .OrderBy(x => x.UnixTimestamp)
    .Select(x => DateTimeHelpers.FromUnixSeconds((long)x.UnixTimestamp))
    .ToList();
var serviceLatency = query
    .GroupBy(x => x.ServiceName)
    .ToDictionary(x => x.Key, y => y.OrderBy(i => i.UnixTimestamp).Select(p => p.Latency).ToList());

너무 많은GroupBy 및 기타 명령이 있으며 쿼리 프로세스가 약간 복잡할 뿐만 아니라 저장된 데이터도 RedisInsight에서 스캔하기가 쉽지 않습니다.


새 버전



새 버전에서는 Set, List, Hash를 사용하여 나만의 키 패턴으로 데이터를 저장해 보았습니다. 결과는 쿼리하기 훨씬 더 깔끔하고 쉬운 데이터입니다.

데이터 저장:

// get today date
var timestampDate = timestamp.ToString("yyyy-MM-dd");

// save to redis using OM
var timestampKey = string.Format(TimestampKey, serviceName, timestampDate);
var latencyKey = string.Format(LatencyKey, serviceName, timestampDate);
var healthKey = string.Format(HealthKey, serviceName, timestampDate);

// get redis db
var db = _cn.GetDatabase();

// set current status
await db.HashSetAsync(ServiceLastStatusKey, serviceName, healthy);

// add to set
await db.SetAddAsync(ServicesSetKey, serviceName);

// add timestamp, health, and latency status
await db.ListRightPushAsync(timestampKey, DateTimeHelpers.ToUnixSeconds(timestamp));
await db.ListRightPushAsync(latencyKey, latency);
await db.ListRightPushAsync(healthKey, healthy);

데이터 쿼리:

// query all data
var timestampKey = string.Format(TimestampKey, services.First(), nowDate);
var timestampValues = await db.ListRangeAsync(timestampKey);
var timestamps = timestampValues
    .Select(x => DateTimeHelpers.FromUnixSeconds(Convert.ToInt64(x)))
    .ToList();

// get latency data from all services
var latencyDict = new Dictionary<string, List<int>>();
foreach (var service in services)
{
    // get latency history
    var latencyKey = string.Format(LatencyKey, service, nowDate);
    var latencyHistory = (await db.ListRangeAsync(latencyKey))
        .Select(x => Convert.ToInt32(x))
        .ToList();

    // add to dict
    latencyDict.Add(service, latencyHistory);
}



쿼리 논리가 훨씬 간단할 뿐만 아니라 이제 RedisInsight에서 저장된 데이터를 훨씬 더 쉽게 읽을 수 있습니다. Grafana와 같은 다른 데이터 시각화 도구를 사용하여 수집된 데이터를 시각화할 수 있기 때문에 이는 큰 이점입니다.

내 저장소에서 코드를 업데이트했으며 간단히 복제하고 다시 실행할 수 있습니다!


fahminlb33 / RedisStatusPage


마이크로서비스 앱의 상태 페이지





RedisStatusPage


차세대 마이크로서비스 백엔드 앱의 상태 페이지!

이 앱은 제 다른 프로젝트ritsu-pi에 통합하려는 아이디어로 시작되었습니다. 모든 종류의 앱을 단일 RPi(또는 클러스터)에 배포할 수 있는 Raspberry Pi 홈 서버 프로젝트입니다. Redis Hackathon은 이 프로젝트를 완료할 수 있는 추가적인 동기를 부여할 적절한 순간에 찾아옵니다 :)
이 프로젝트는 기본적으로 Blazor Server 및 Redis 위에 구축된 상태 페이지(예: Github 상태, Azure 상태, Atlassian 상태 페이지 또는 이와 유사한 것)입니다. 여기에서 "상태 확인"을 정의하고 서비스 중 하나가 다운될 때 보고서를 얻을 수 있습니다. 또한 서비스 상태 중 하나가 변경되면 메시지를 보내는 Discord 웹후크 클라이언트가 있습니다.
  • HTTP/TCP 서비스 가동 시간 모니터링
  • 시간 경과에 따른 단순 대기 시간 그래프
  • 서비스 상태 중 하나가 변경된 경우 사건 보고서


  • View on GitHub

    좋은 웹페이지 즐겨찾기