paint-brush
স্প্রিং বুটে ওপেনটেলিমেট্রি ট্রেসিং: এর জন্য জাভা এজেন্ট এবং মাইক্রোমিটারের মধ্যে নির্বাচন করা দ্বারা@nfrankel
205 পড়া

স্প্রিং বুটে ওপেনটেলিমেট্রি ট্রেসিং: এর জন্য জাভা এজেন্ট এবং মাইক্রোমিটারের মধ্যে নির্বাচন করা

দ্বারা Nicolas Fränkel8m2024/08/11
Read on Terminal Reader

অতিদীর্ঘ; পড়তে

এই পোস্টটি জাভা এজেন্ট v1, জাভা এজেন্ট v2 এবং মাইক্রোমিটার ট্রেসিং ব্যবহার করে একটি স্প্রিং বুট অ্যাপ্লিকেশনে OpenTelemetry ট্রেসিং সমাধানের তুলনা করে। এটি কনফিগারেশন, কার্যকারিতা এবং ট্রেসিং ক্ষমতার পার্থক্য তুলে ধরে, পর্যবেক্ষণের জন্য প্রতিটি পদ্ধতির কার্যকারিতা এবং প্রয়োগের অন্তর্দৃষ্টি প্রদান করে।
featured image - স্প্রিং বুটে ওপেনটেলিমেট্রি ট্রেসিং: এর জন্য জাভা এজেন্ট এবং মাইক্রোমিটারের মধ্যে নির্বাচন করা
Nicolas Fränkel HackerNoon profile picture

ওপেনটেলিমেট্রি ট্রেসিংয়ের আমার ডেমোতে দুটি স্প্রিং বুট উপাদান রয়েছে। একজন জাভা এজেন্ট ব্যবহার করে, এবং আমি একটি ভিন্ন আচরণ লক্ষ্য করেছি যখন আমি সম্প্রতি এটিকে v1.x থেকে v2.x এ আপগ্রেড করেছি। অন্যটিতে, আমি মাইক্রোমিটার ট্রেসিং ব্যবহার করছি কারণ আমি GraalVM নেটিভ কম্পাইল করি, এবং এটি জাভা এজেন্টকে প্রক্রিয়া করতে পারে না।



এই পোস্টে, আমি এই তিনটি পদ্ধতির তুলনা করতে চাই: জাভা এজেন্ট v1, জাভা এজেন্ট v2 এবং মাইক্রোমিটার ট্রেসিং।

বেস অ্যাপ্লিকেশন এবং এর অবকাঠামো

আমি একই বেস অ্যাপ্লিকেশন ব্যবহার করব: একটি সাধারণ স্প্রিং বুট অ্যাপ্লিকেশন, কোটলিনে কোড করা। এটি একটি একক শেষ পয়েন্ট অফার করে।


  • শেষবিন্দুর বাইরের ফাংশনটির নাম entry()
  • এটি intermediate() নামে আরেকটি ফাংশনকে কল করে
  • পরেরটি একটি WebClient উদাহরণ ব্যবহার করে, RestTemplate এর প্রতিস্থাপন, উপরের এন্ডপয়েন্টে কল করার জন্য
  • অসীম লুপিং এড়াতে, আমি একটি কাস্টম অনুরোধ শিরোনাম পাস করি: যদি entry() ফাংশনটি এটি খুঁজে পায় তবে এটি আর এগিয়ে যাবে না


নমুনা অ্যাপ সিকোয়েন্স ডায়াগ্রাম


এটি নিম্নলিখিত কোডে অনুবাদ করে:


 @SpringBootApplication class Agent1xApplication @RestController class MicrometerController { private val logger = LoggerFactory.getLogger(MicrometerController::class.java) @GetMapping("/{message}") fun entry(@PathVariable message: String, @RequestHeader("X-done") done: String?) { logger.info("entry: $message") if (done == null) intermediate() } fun intermediate() { logger.info("intermediate") RestClient.builder() .baseUrl("http://localhost:8080/done") .build() .get() .header("X-done", "true") .retrieve() .toBodilessEntity() } }


প্রতিটি সেটআপের জন্য, আমি দুটি পর্যায় পরীক্ষা করব: প্রাথমিক পর্যায়, OpenTelemetry সক্ষম সহ, এবং অতিরিক্ত অভ্যন্তরীণ স্প্যান তৈরি করার জন্য একটি কাস্টমাইজেশন পর্যায়।

মাইক্রোমিটার ট্রেসিং

মাইক্রোমিটার ট্রেসিং মাইক্রোমিটার থেকে উদ্ভূত হয়, এটি একটি "বিক্রেতা-নিরপেক্ষ অ্যাপ্লিকেশন অবজারভেবিলিটি ফ্যাকেড"।


মাইক্রোমিটার ট্রেসিং সবচেয়ে জনপ্রিয় ট্রেসার লাইব্রেরিগুলির জন্য একটি সাধারণ সম্মুখভাগ প্রদান করে, যা আপনাকে বিক্রেতা লক-ইন ছাড়াই আপনার JVM-ভিত্তিক অ্যাপ্লিকেশন কোডের উপকরণ দিতে দেয়। এটি এমনভাবে ডিজাইন করা হয়েছে যাতে আপনার ট্রেসিং সংগ্রহের ক্রিয়াকলাপে সামান্য থেকে কোন ওভারহেড যোগ না করা যায় এবং আপনার ট্রেসিং প্রচেষ্টার বহনযোগ্যতাকে সর্বাধিক করা হয়।


-- মাইক্রোমিটার ট্রেসিং সাইট


মাইক্রোমিটার ট্রেসিং দিয়ে শুরু করতে, একজনকে কয়েকটি নির্ভরতা যোগ করতে হবে:


  • স্প্রিং বুট অ্যাকচুয়েটর, org.springframework.boot:spring-boot-starter-actuator
  • মাইক্রোমিটার নিজেই ট্রেসিং, io.micrometer:micrometer-tracing
  • লক্ষ্য ট্রেসিং ব্যাকএন্ড API-এ একটি "সেতু"। আমার ক্ষেত্রে, এটি OpenTelemetry, তাই io.micrometer:micrometer-tracing-bridge-otel
  • ব্যাকএন্ডে একটি কংক্রিট রপ্তানিকারক, io.opentelemetry:opentelemetry-exporter-otlp


আমাদের একটি BOM দরকার নেই কারণ সংস্করণগুলি ইতিমধ্যেই স্প্রিং বুট প্যারেন্টে সংজ্ঞায়িত করা হয়েছে।


তবুও, আমাদের দুটি রানটাইম কনফিগারেশন প্যারামিটার দরকার: ট্রেসগুলি কোথায় পাঠানো উচিত এবং উপাদানটির নাম কী। এগুলি MANAGEMENT_OTLP_TRACING_ENDPOINT এবং SPRING_APPLICATION_NAME ভেরিয়েবল দ্বারা নিয়ন্ত্রিত৷


 services: jaeger: image: jaegertracing/all-in-one:1.55 environment: - COLLECTOR_OTLP_ENABLED=true #1 ports: - "16686:16686" micrometer-tracing: build: dockerfile: Dockerfile-micrometer environment: MANAGEMENT_OTLP_TRACING_ENDPOINT: http://jaeger:4318/v1/traces #2 SPRING_APPLICATION_NAME: micrometer-tracing #3
  1. Jaeger-এর জন্য OpenTelemetry সংগ্রাহক সক্ষম করুন
  2. Jaeger OpenTelemetry gRPC এন্ডপয়েন্টের সম্পূর্ণ URL
  3. OpenTelemetry এর পরিষেবার নাম সেট করুন


এখানে ফলাফল:

কোন কাস্টমাইজেশন ছাড়া Jaeger উপর মাইক্রোমিটার ট্রেস


কোনো কাস্টমাইজেশন ছাড়াই, মাইক্রোমিটার স্প্যান তৈরি করে যখন HTTP অনুরোধ গ্রহণ এবং পাঠানো হয়।


ফ্রেমওয়ার্ক পাঠানোর জন্য RestClient এ যাদু ইনজেক্ট করতে হবে। আমাদের অবশ্যই পূর্ববর্তীটিকে তার জন্য পরবর্তীটিকে তাত্ক্ষণিক করতে দিতে হবে:


 @SpringBootApplication class MicrometerTracingApplication { @Bean fun restClient(builder: RestClient.Builder) = builder.baseUrl("http://localhost:8080/done").build() }


আমরা বিভিন্ন উপায়ে ম্যানুয়াল স্প্যান তৈরি করতে পারি, একটি OpenTelemetry API এর মাধ্যমে। যাইহোক, সেটআপের জন্য প্রচুর বয়লারপ্লেট কোড প্রয়োজন। সবচেয়ে সহজ উপায় হল মাইক্রোমিটারের পর্যবেক্ষণ API । এর প্রধান সুবিধা হল একটি একক API ব্যবহার করা যা মেট্রিক্স এবং ট্রেস উভয়ই পরিচালনা করে।


পর্যবেক্ষণ API ক্লাস ডায়াগ্রাম

এখানে আপডেট করা কোড:


 class MicrometerController( private val restClient: RestClient, private val registry: ObservationRegistry ) { @GetMapping("/{message}") fun entry(@PathVariable message: String, @RequestHeader("X-done") done: String?) { logger.info("entry: $message") val observation = Observation.start("entry", registry) if (done == null) intermediate(observation) observation.stop() } fun intermediate(parent: Observation) { logger.info("intermediate") val observation = Observation.createNotStarted("intermediate", registry) .parentObservation(parent) .start() restClient.get() .header("X-done", "true") .retrieve() .toBodilessEntity() observation.stop() } }


যোগ করা পর্যবেক্ষণ কলগুলি উত্পন্ন ট্রেসগুলির উপর প্রতিফলিত হয়:


অবজারভেশন এপিআই দিয়ে জাইগারে মাইক্রোমিটার ট্রেস করে

OpenTelemetry Agent v1

মাইক্রোমিটার ট্রেসিংয়ের একটি বিকল্প হল জেনেরিক ওপেনটেলিমেট্রি জাভা এজেন্ট । এর প্রধান সুবিধা হল এটি কোড বা ডেভেলপারদেরকে প্রভাবিত করে না; এজেন্ট একটি বিশুদ্ধ রানটাইম-স্কোপড উদ্বেগ.


 java -javaagent:opentelemetry-javaagent.jar agent-one-1.0-SNAPSHOT.jar


এজেন্ট পরিবেশের ভেরিয়েবলের সাথে OpenTelemetry এর কনফিগারেশন মেনে চলে:


 services: agent-1x: build: dockerfile: Dockerfile-agent1 environment: OTEL_EXPORTER_OTLP_ENDPOINT: http://jaeger:4317 #1 OTEL_RESOURCE_ATTRIBUTES: service.name=agent-1x #2 OTEL_METRICS_EXPORTER: none #3 OTEL_LOGS_EXPORTER: none #4 ports: - "8081:8080"
  1. প্রোটোকল, ডোমেইন এবং পোর্ট সেট করুন। লাইব্রেরি /v1/traces যুক্ত করে
  2. OpenTelemetry এর পরিষেবার নাম সেট করুন
  3. মেট্রিক্স বা লগ উভয়ই রপ্তানি করুন


আর কোন কনফিগারেশন ছাড়া, আমরা নিম্নলিখিত ট্রেস পেতে পারি:


এজেন্ট v1 কোন কাস্টমাইজেশন ছাড়া Jaeger উপর ট্রেস


এজেন্ট স্বয়ংক্রিয়ভাবে অনুরোধগুলি ট্র্যাক করে, প্রাপ্ত এবং পাঠানো উভয়ই, সেইসাথে স্প্রিং-সম্পর্কিত টীকা দিয়ে চিহ্নিত ফাংশনগুলি । কল স্ট্যাক অনুসারে ট্রেসগুলি একে অপরের ভিতরে সঠিকভাবে নেস্ট করা হয়। অতিরিক্ত ফাংশন ট্রেস করতে, আমাদের কোডবেসে একটি নির্ভরতা যোগ করতে হবে, io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations । আমরা এখন @WithSpan টীকা দিয়ে পূর্বে অনুসৃত ফাংশন টীকা করতে পারি।

@WithSpan ক্লাস ডায়াগ্রাম


value() অংশটি ট্রেসের লেবেলকে নিয়ন্ত্রণ করে, যখন kind একটি span.kind বৈশিষ্ট্য হিসাবে অনুবাদ করে। যদি মানটি একটি খালি স্ট্রিং-এ সেট করা থাকে, যা ডিফল্ট, এটি ফাংশনের নাম আউটপুট করে। আমার উদ্দেশ্যে, ডিফল্ট মান যথেষ্ট ভাল।


 @WithSpan fun intermediate() { logger.info("intermediate") RestClient.builder() .baseUrl("http://localhost:8080/done") .build() .get() .header("X-done", "true") .retrieve() .toBodilessEntity() }


এটি প্রত্যাশিত নতুন intermediate() ট্রেস প্রদান করে:

এজেন্ট v1 টীকা সহ Jaeger-এ ট্রেস করে

OpenTelemetry Agent v2

OpenTelemetry এই বছরের জানুয়ারিতে এজেন্টের একটি নতুন প্রধান সংস্করণ প্রকাশ করেছে। আমি এটি দিয়ে আমার ডেমো আপডেট করেছি; ট্রেসগুলি এখন শুধুমাত্র তখনই তৈরি হয় যখন অ্যাপটি অনুরোধ গ্রহণ করে এবং পাঠায়।

কোন কাস্টমাইজেশন ছাড়া Jaeger এ এজেন্ট v2 ট্রেস


পূর্ববর্তী সংস্করণ হিসাবে, আমরা @WithSpan টীকা দিয়ে ট্রেস যোগ করতে পারি। শুধুমাত্র পার্থক্য হল যে আমাদের অবশ্যই entry() ফাংশনটি টীকা দিতে হবে। এটি ডিফল্টরূপে ট্রেস করা হয় না.

এজেন্ট v2 টীকা সহ Jaeger-এ ট্রেস করে


আলোচনা

স্প্রিং দুটি কারণে সফল হয়েছে: এটি জটিল সমাধানগুলিকে সরলীকৃত করেছে, যেমন , EJBs 2, এবং প্রতিযোগী লাইব্রেরির উপর একটি বিমূর্ত স্তর প্রদান করেছে। মাইক্রোমিটার ট্রেসিং জিপকিন এবং জেগারের উপর একটি বিমূর্ত স্তর হিসাবে শুরু হয়েছিল এবং এটি সম্পূর্ণ অর্থবহ ছিল। ওপেনটেলিমেট্রি প্রোগ্রামিং ভাষা এবং ট্রেস সংগ্রাহক জুড়ে বেশিরভাগ লাইব্রেরি দ্বারা সমর্থিত হওয়ায় এই যুক্তিটি বিতর্কিত হয়ে ওঠে। পর্যবেক্ষণ API এখনও মাইক্রোমিটার ট্রেসিংয়ের একটি উল্লেখযোগ্য সুবিধা, কারণ এটি মেট্রিক্স এবং ট্রেসের উপর একটি একক API ব্যবহার করে।


জাভা এজেন্টের দিকে, ওপেনটেলিমেট্রি কনফিগারেশন সমস্ত টেক স্ট্যাক এবং লাইব্রেরি - পরিবেশ ভেরিয়েবল জুড়ে একই রকম। আমি যখন v1 থেকে v2 তে আপগ্রেড করেছিলাম তখন আমি কিছুটা হতাশ হয়েছিলাম, কারণ নতুন এজেন্ট স্প্রিং-সচেতন নয়: স্প্রিং-টীকাযুক্ত ফাংশনগুলি ডিফল্টরূপে ট্রেস করা হয় না।


শেষ পর্যন্ত, এটি একটি বুদ্ধিমান সিদ্ধান্ত। আপনি দেখতে চান না এমন কিছু সরানোর চেয়ে আপনি যে স্প্যানগুলি চান সেগুলি সম্পর্কে স্পষ্ট হওয়া অনেক ভাল৷


জোনাটান ইভানভকে তার সাহায্য এবং তার পর্যালোচনার জন্য ধন্যবাদ


এই পোস্টের জন্য সম্পূর্ণ উৎস কোড GitHub এ পাওয়া যাবে:

আরও যেতে:


মূলত 3রা আগস্ট, 2024-এ A Java Geek এ প্রকাশিত