1. Giriş
Bu codelab'de, C++ ile yazılmış bir rota eşleme uygulamasının temelini oluşturan bir istemci ve sunucu oluşturmak için gRPC'yi kullanacaksınız.
Eğitimin sonunda, gRPC OpenTelemetry eklentisiyle donatılmış basit bir gRPC HelloWorld uygulamanız olacak ve dışa aktarılan gözlemlenebilirlik metriklerini Prometheus'ta görebileceksiniz.
Neler öğreneceksiniz?
- Mevcut gRPC C++ uygulaması için OpenTelemetry eklentisi nasıl ayarlanır?
- Yerel bir Prometheus örneği çalıştırma
- Metrikleri Prometheus'a aktarma
- Prometheus kontrol panelinden metrikleri görüntüleme
2. Başlamadan önce
İhtiyacınız olanlar
Linux Environmentgitcurlbuild-essentialclangbazelBu codelab'deki örnekleri oluşturmak için
Ön koşulları yükleyin:
sudo apt-get update -y
sudo apt-get upgrade -y
sudo apt-get install -y git curl build-essential clang
bazel, bazelisk üzerinden yüklenebilir. En yeni sürümü burada bulabilirsiniz.
Bunu ayarlamanın basit bir yolu, PATH'inize aşağıdaki gibi bazel ikili dosyası olarak yüklemektir:
sudo cp bazelisk-linux-amd64 /usr/local/bin/bazel
sudo chmod a+x /usr/local/bin/bazel
Alternatif olarak CMake'i de kullanabilirsiniz. CMake'i kullanmayla ilgili talimatları burada bulabilirsiniz.
Kodu alın
Bu codelab, öğrenme sürecinizi kolaylaştırmak için başlamanıza yardımcı olacak önceden oluşturulmuş bir kaynak kodu iskeleti sunar. Aşağıdaki adımlar, bir uygulamada gRPC OpenTelemetry eklentisini kullanma konusunda size yol gösterecektir.
grpc-codelabs
Bu codelab'in iskele kaynak kodu şu GitHub dizininde mevcuttur. Kodu kendiniz uygulamayı tercih etmezseniz tamamlanmış kaynak kodu completed dizininde bulabilirsiniz.
Öncelikle grpc codelab deposunu klonlayın ve grpc-cpp-opentelemetry klasörüne gidin:
git clone https://github.com/grpc-ecosystem/grpc-codelabs.git
cd grpc-codelabs/codelabs/grpc-cpp-opentelemetry/
Alternatif olarak, yalnızca codelab dizinini içeren .zip dosyasını indirebilir ve manuel olarak sıkıştırmasını açabilirsiniz.
Bazel kullanarak gRPC kitaplığını oluşturun:
bazel build start_here/...
3. OpenTelemetry eklentisini kaydetme
gRPC OpenTelemetry eklentisini eklemek için bir gRPC uygulamasına ihtiyacımız var. Bu codelab'de, gRPC OpenTelemetry eklentisiyle donatacağımız basit bir gRPC HelloWorld istemcisi ve sunucusu kullanacağız.
İlk adımınız, istemcide Prometheus dışa aktarıcısıyla yapılandırılmış OpenTelemetry eklentisini kaydetmektir. codelabs/grpc-cpp-opentelemetry/start_here/greeter_callback_client.cc dosyasını favori düzenleyicinizle açın ve main() dosyasını aşağıdaki gibi görünecek şekilde dönüştürün:
int main(int argc, char **argv) {
absl::ParseCommandLine(argc, argv);
// Codelab Solution: Register a global gRPC OpenTelemetry plugin configured
// with a prometheus exporter.
opentelemetry::exporter::metrics::PrometheusExporterOptions opts;
opts.url = absl::GetFlag(FLAGS_prometheus_endpoint);
auto prometheus_exporter =
opentelemetry::exporter::metrics::PrometheusExporterFactory::Create(opts);
auto meter_provider =
std::make_shared<opentelemetry::sdk::metrics::MeterProvider>();
// The default histogram boundaries are not granular enough for RPCs. Override
// the "grpc.client.attempt.duration" view as recommended by
// https://github.com/grpc/proposal/blob/master/A66-otel-stats.md.
AddLatencyView(meter_provider.get(), "grpc.client.attempt.duration", "s");
meter_provider->AddMetricReader(std::move(prometheus_exporter));
auto status = grpc::OpenTelemetryPluginBuilder()
.SetMeterProvider(std::move(meter_provider))
.BuildAndRegisterGlobal();
if (!status.ok()) {
std::cerr << "Failed to register gRPC OpenTelemetry Plugin: "
<< status.ToString() << std::endl;
return static_cast<int>(status.code());
}
// Continuously send RPCs.
RunClient(absl::GetFlag(FLAGS_target));
return 0;
}
Sonraki adım, OpenTelemetry eklentisini sunucuya eklemektir. codelabs/grpc-cpp-opentelemetry/start_here/greeter_callback_server.cc dosyasını açın ve ana dosyayı aşağıdaki gibi olacak şekilde dönüştürün:
int main(int argc, char** argv) {
absl::ParseCommandLine(argc, argv);
// Register a global gRPC OpenTelemetry plugin configured with a prometheus
// exporter.
opentelemetry::exporter::metrics::PrometheusExporterOptions opts;
opts.url = absl::GetFlag(FLAGS_prometheus_endpoint);
auto prometheus_exporter =
opentelemetry::exporter::metrics::PrometheusExporterFactory::Create(opts);
auto meter_provider =
std::make_shared<opentelemetry::sdk::metrics::MeterProvider>();
// The default histogram boundaries are not granular enough for RPCs. Override
// the "grpc.server.call.duration" view as recommended by
// https://github.com/grpc/proposal/blob/master/A66-otel-stats.md.
AddLatencyView(meter_provider.get(), "grpc.server.call.duration", "s");
meter_provider->AddMetricReader(std::move(prometheus_exporter));
auto status = grpc::OpenTelemetryPluginBuilder()
.SetMeterProvider(std::move(meter_provider))
.BuildAndRegisterGlobal();
if (!status.ok()) {
std::cerr << "Failed to register gRPC OpenTelemetry Plugin: "
<< status.ToString() << std::endl;
return static_cast<int>(status.code());
}
RunServer(absl::GetFlag(FLAGS_port));
return 0;
}
Gerekli üstbilgi dosyaları ve derleme bağımlılıkları, kolaylık sağlamak için önceden eklenmiştir.
#include "opentelemetry/exporters/prometheus/exporter_factory.h"
#include "opentelemetry/exporters/prometheus/exporter_options.h"
#include "opentelemetry/sdk/metrics/meter_provider.h"
#include <grpcpp/ext/otel_plugin.h>
Derleme bağımlılıkları da BUILD dosyasına eklenmiştir:
cc_binary(
name = "greeter_callback_client",
srcs = ["greeter_callback_client.cc"],
defines = ["BAZEL_BUILD"],
deps = [
"//util:util",
"@com_github_grpc_grpc//:grpc++",
"@com_github_grpc_grpc//:grpcpp_otel_plugin",
"@com_google_absl//absl/flags:flag",
"@com_google_absl//absl/flags:parse",
"@io_opentelemetry_cpp//exporters/prometheus:prometheus_exporter",
"@io_opentelemetry_cpp//sdk/src/metrics",
],
)
4. Örneği çalıştırma ve metrikleri görüntüleme
Sunucuyu çalıştırmak için şunu çalıştırın:
bazel run start_here:greeter_callback_server
Kurulum başarılı olduğunda sunucu için aşağıdaki çıkışı görürsünüz:
Server listening on 0.0.0.0:50051
Sunucu çalışırken başka bir terminalde istemciyi çalıştırın:
bazel run start_here:greeter_callback_client
Başarılı bir çalıştırma şöyle görünür:
Greeter received: Hello world
Greeter received: Hello world
Greeter received: Hello world
Greeter received: Hello world
Greeter received: Hello world
Greeter received: Hello world
Greeter received: Hello world
Greeter received: Hello world
Greeter received: Hello world
Greeter received: Hello world
Greeter received: Hello world
Prometheus kullanarak metrikleri dışa aktarmak için gRPC OpenTelemetry eklentisini kurduğumuzdan. Bu metrikler, sunucu için localhost:9464, istemci için ise localhost:9465 adresinde kullanılabilir.
Müşteri metriklerini görmek için:
curl localhost:9465/metrics
Sonuç şu biçimde olur:
# HELP exposer_transferred_bytes_total Transferred bytes to metrics services
# TYPE exposer_transferred_bytes_total counter
exposer_transferred_bytes_total 0
# HELP exposer_scrapes_total Number of times metrics were scraped
# TYPE exposer_scrapes_total counter
exposer_scrapes_total 0
# HELP exposer_request_latencies Latencies of serving scrape requests, in microseconds
# TYPE exposer_request_latencies summary
exposer_request_latencies_count 0
exposer_request_latencies_sum 0
exposer_request_latencies{quantile="0.5"} Nan
exposer_request_latencies{quantile="0.9"} Nan
exposer_request_latencies{quantile="0.99"} Nan
# HELP target Target metadata
# TYPE target gauge
target_info{otel_scope_name="grpc-c++",otel_scope_version="1.67.0-dev",service_name="unknown_service",telemetry_sdk_version="1.13.0",telemetry_sdk_name="opentelemetry",telemetry_sdk_language="cpp"} 1 1721958543107
# HELP grpc_client_attempt_rcvd_total_compressed_message_size_bytes Compressed message bytes received per call attempt
# TYPE grpc_client_attempt_rcvd_total_compressed_message_size_bytes histogram
grpc_client_attempt_rcvd_total_compressed_message_size_bytes_count{grpc_method="helloworld.Greeter/SayHello",grpc_status="OK",grpc_target="dns:///localhost:50051",otel_scope_name="grpc-c++",otel_scope_version="1.67.0-dev"} 96 1721958543107
grpc_client_attempt_rcvd_total_compressed_message_size_bytes_sum{grpc_method="helloworld.Greeter/SayHello",grpc_status="OK",grpc_target="dns:///localhost:50051",otel_scope_name="grpc-c++",otel_scope_version="1.67.0-dev"} 1248 1721958543107
grpc_client_attempt_rcvd_total_compressed_message_size_bytes_bucket{grpc_method="helloworld.Greeter/SayHello",grpc_status="OK",grpc_target="dns:///localhost:50051",otel_scope_name="grpc-c++",otel_scope_version="1.67.0-dev",le="0"} 0 1721958543107
grpc_client_attempt_rcvd_total_compressed_message_size_bytes_bucket{grpc_method="helloworld.Greeter/SayHello",grpc_status="OK",grpc_target="dns:///localhost:50051",otel_scope_name="grpc-c++",otel_scope_version="1.67.0-dev",le="5"} 0 1721958543107
grpc_client_attempt_rcvd_total_compressed_message_size_bytes_bucket{grpc_method="helloworld.Greeter/SayHello",grpc_status="OK",grpc_target="dns:///localhost:50051",otel_scope_name="grpc-c++",otel_scope_version="1.67.0-dev",le="10"} 0 1721958543107
grpc_client_attempt_rcvd_total_compressed_message_size_bytes_bucket{grpc_method="helloworld.Greeter/SayHello",grpc_status="OK",grpc_target="dns:///localhost:50051",otel_scope_name="grpc-c++",otel_scope_version="1.67.0-dev",le="25"} 96 1721958543107
grpc_client_attempt_rcvd_total_compressed_message_size_bytes_bucket{grpc_method="helloworld.Greeter/SayHello",grpc_status="OK",grpc_target="dns:///localhost:50051",otel_scope_name="grpc-c++",otel_scope_version="1.67.0-dev",le="50"} 96 1721958543107
grpc_client_attempt_rcvd_total_compressed_message_size_bytes_bucket{grpc_method="helloworld.Greeter/SayHello",grpc_status="OK",grpc_target="dns:///localhost:50051",otel_scope_name="grpc-c++",otel_scope_version="1.67.0-dev",le="75"} 96 1721958543107
Benzer şekilde, sunucu tarafı metrikleri için:
curl localhost:9464/metrics
5. Prometheus'ta metrikleri görüntüleme
Burada, prometheus kullanarak metrikleri dışa aktaran gRPC örnek istemcimizi ve sunucumuzu kazıyacak bir prometheus örneği ayarlayacağız.
Platformunuz için Prometheus'un en son sürümünü indirin, ardından çıkarıp çalıştırın:
tar xvfz prometheus-*.tar.gz
cd prometheus-*
Aşağıdaki bilgileri içeren bir Prometheus yapılandırma dosyası oluşturun:
cat > grpc_otel_cpp_prometheus.yml <<EOF
scrape_configs:
- job_name: "prometheus"
scrape_interval: 5s
static_configs:
- targets: ["localhost:9090"]
- job_name: "grpc-otel-cpp"
scrape_interval: 5s
static_configs:
- targets: ["localhost:9464", "localhost:9465"]
EOF
Prometheus'u yeni yapılandırmayla başlatın:
./prometheus --config.file=grpc_otel_cpp_prometheus.yml
Bu işlem, istemci ve sunucu codelab süreçlerindeki metriklerin 5 saniyede bir kazınacak şekilde yapılandırılmasını sağlar.
Metrikleri görüntülemek için http://localhost:9090/graph adresine gidin. Örneğin, şu sorgu:
histogram_quantile(0.5, rate(grpc_client_attempt_duration_seconds_bucket[1m]))
, nicelik hesaplaması için zaman aralığı olarak 1 dakika kullanılarak ortalama deneme gecikmesini gösteren bir grafik gösterir.
Sorgu oranı:
increase(grpc_client_attempt_duration_seconds_bucket[1m])
6. (İsteğe bağlı) Kullanıcı için egzersiz
Prometheus kontrol panellerinde QPS'nin düşük olduğunu görürsünüz. Örnekte, saniyedeki sorgu sayısını sınırlayan şüpheli bir kod olup olmadığını belirleyin.
İstekli kullanıcılar için istemci kodu, belirli bir anda yalnızca tek bir bekleyen RPC'ye sahip olacak şekilde sınırlandırılmıştır. Bu, istemcinin önceki RPC'lerin tamamlanmasını beklemeden daha fazla RPC gönderecek şekilde değiştirilebilir. (Bu sorunun çözümü sağlanmamıştır.)