全部产品
Search
文档中心

Function Compute:Analisis Tracing

更新时间:Jun 24, 2025

Topik ini menjelaskan fitur Analisis Tracing dalam lingkungan runtime Java 11.

Latar Belakang

Alibaba Cloud Analisis Tracing mengadopsi standar OpenTracing dan kompatibel dengan komunitas open source. Fitur ini memungkinkan pengembang aplikasi terdistribusi untuk menanyakan dan mendiagnosis jejak terdistribusi, menemukan topologi terdistribusi secara dinamis, serta merangkum performa aplikasi secara real-time.

Function Compute terintegrasi dengan Analisis Tracing. Anda dapat menggunakan Jaeger SDK atau OpenTelemetry untuk mengunggah informasi jejak sehingga Anda dapat melacak pemanggilan fungsi. Analisis Tracing membantu Anda menganalisis dan mendiagnosis hambatan performa dalam arsitektur serverless, meningkatkan efisiensi pengembangan dan diagnosis dalam skenario serverless.

Ikhtisar

Anda dapat mengonfigurasi Analisis Tracing di konsol Function Compute. Untuk informasi lebih lanjut, lihat Aktifkan Analisis Tracing.

Setelah mengaktifkan Analisis Tracing untuk suatu layanan, Function Compute secara otomatis mencatat waktu yang dikonsumsi dalam sistem, termasuk waktu cold start, waktu eksekusi Fungsi inisialisasi, dan waktu eksekusi fungsi. Untuk informasi lebih lanjut tentang rentang sistem pada gambar berikut, lihat Deskripsi nama rentang. Tracing Analysis

Anda juga dapat mencatat waktu yang dikonsumsi oleh fungsi di sisi bisnis. Sebagai contoh, Anda dapat mencatat waktu yang diperlukan untuk mengakses layanan seperti ApsaraDB RDS dan File Storage NAS dalam fungsi dengan menggunakan Buat rentang kustom.

Kode contoh

Analisis Tracing untuk Function Compute dalam lingkungan runtime Java memungkinkan Anda membuat rentang kustom dengan menggunakan metode berikut berdasarkan implementasi Jaeger dari spesifikasi OpenTracing.

Gunakan SDK untuk OpenTelemetry (direkomendasikan)

Dalam kode Java, Anda dapat menggunakan SDK untuk OpenTelemetry untuk melakukan instrumentasi data dan melaporkan data ke Analisis Tracing. Untuk kode contoh lengkap, lihat java-tracing-openTelemetry.

Berikut adalah detail dari kode contoh:

  • Tambahkan dependensi ke file pom.xml.

      <dependencies>
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>3.8.1</version>
          <scope>test</scope>
        </dependency>
        <dependency>
          <groupId>com.aliyun.fc.runtime</groupId>
          <artifactId>fc-java-core</artifactId>
          <version>1.4.1</version>
        </dependency>
        <dependency>
          <groupId>io.opentelemetry</groupId>
          <artifactId>opentelemetry-api</artifactId>
          <version>1.19.0</version>
        </dependency>
        <dependency>
          <groupId>io.opentelemetry</groupId>
          <artifactId>opentelemetry-sdk</artifactId>
          <version>1.19.0</version>
        </dependency>
        <dependency>
          <groupId>io.opentelemetry</groupId>
          <artifactId>opentelemetry-semconv</artifactId>
          <version>1.19.0-alpha</version>
        </dependency>
        <dependency>
          <groupId>io.opentelemetry</groupId>
          <artifactId>opentelemetry-exporter-jaeger-thrift</artifactId>
          <version>1.19.0</version>
        </dependency>
        <dependency>
          <groupId>io.jaegertracing</groupId>
          <artifactId>jaeger-thrift</artifactId>
          <version>1.8.1</version>
        </dependency>
        <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-simple</artifactId>
          <version>1.6.6</version>
        </dependency>
      </dependencies>
  • Laporkan data ke Analisis Tracing.

    public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
        String endpoint = context.getTracing().getJaegerEndpoint();
        try {
            ExampleConfiguration.initOpenTelemetry(endpoint);
        } catch (TTransportException e) {
            throw new RuntimeException(e);
        }
    
        SpanContext spanContext = contextFromString(context.getTracing().getSpanContext());
    
        startMySpan(io.opentelemetry.context.Context.current().with(Span.wrap(spanContext)));
    }
  • Buat objek OpenTelemetry global yang menyediakan akses ke tracer.

    static OpenTelemetry initOpenTelemetry(String jaegerEndpoint) throws TTransportException {
        // Ekspor jejak ke Jaeger.
        JaegerThriftSpanExporter jaegerExporter =
            JaegerThriftSpanExporter.builder()
            .setThriftSender(new Builder(jaegerEndpoint).build())
            .setEndpoint(jaegerEndpoint)
            .build();
    
        Resource serviceNameResource =
            Resource.create(Attributes.of(ResourceAttributes.SERVICE_NAME, "otel-jaeger-example"));
    
        // Tentukan eksportir Jaeger sebagai prosesor rentang.
        SdkTracerProvider tracerProvider =
            SdkTracerProvider.builder()
            .addSpanProcessor(SimpleSpanProcessor.create(jaegerExporter))
            .setResource(Resource.getDefault().merge(serviceNameResource))
            .build();
        OpenTelemetrySdk openTelemetry =
            OpenTelemetrySdk.builder().setTracerProvider(tracerProvider).buildAndRegisterGlobal();
    
        // Nonaktifkan SDK saat Java virtual machine (JVM) keluar.
        Runtime.getRuntime().addShutdownHook(new Thread(tracerProvider::close));
    
        return openTelemetry;
    }
  • Peroleh informasi tracing dari Context dan konversikan informasi tracing menjadi SpanContext.

    SpanContext contextFromString(String value) throws IOException {
        {
            if (value != null && !value.equals("")) {
                String[] parts = value.split(":");
                if (parts.length != 4) {
                    throw new RuntimeException(value);
                } else {
                    String traceId = parts[0];
                    if (traceId.length() <= 32 && traceId.length() >= 1) {
                        return SpanContext.createFromRemoteParent("0000000000000000"+parts[0], parts[1], TraceFlags.getSampled(), TraceState.getDefault());
                    } else {
                        throw new RuntimeException("Panjang ID jejak [" + traceId + "] tidak berada antara 1 dan 32");
                    }
                }
            } else {
                throw new RuntimeException();
            }
        }
    }
  • Buat tracer dan gunakan konteks yang telah dikonversi untuk membuat rentang anak. Rentang mewakili potongan kode yang dapat dieksekusi secara terus-menerus yang diberi nama dan waktu dalam jejak pemanggilan. Anda juga dapat membuat rentang anak berdasarkan rentang tersebut.

    void startMySpan(io.opentelemetry.context.Context ctx){
        Tracer tracer = GlobalOpenTelemetry.getTracer("fc-Trace");
        Span parentSpan = tracer.spanBuilder("fc-operation").setParent(ctx).startSpan();
        parentSpan.setAttribute("version","fc-v1");
        try {
            TimeUnit.MILLISECONDS.sleep(150);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        child(parentSpan.storeInContext(ctx));
        parentSpan.end();
    }
    
    void child(io.opentelemetry.context.Context ctx){
        Tracer tracer = GlobalOpenTelemetry.getTracer("fc-Trace");
        Span childSpan = tracer.spanBuilder("fc-operation-child").setParent(ctx).startSpan();
        childSpan.addEvent("timeout");
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        childSpan.end();
    }

Gunakan SDK untuk Jaeger

Anda dapat menggunakan SDK untuk Jaeger untuk melakukan instrumentasi kode dan melaporkan data ke Analisis Tracing. Untuk kode contoh lengkap, lihat java-tracing.

Berikut adalah detail dari kode contoh:

  • Tambahkan dependensi ke file pom.xml.

    <dependencies>
      <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>3.8.1</version>
        <scope>test</scope>
      </dependency>
      <dependency>
        <groupId>com.aliyun.fc.runtime</groupId>
        <artifactId>fc-java-core</artifactId>
        <version>1.4.1</version>
      </dependency>
      <dependency>
        <groupId>io.jaegertracing</groupId>
        <artifactId>jaeger-client</artifactId>
        <version>1.8.1</version>
      </dependency>
      <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-simple</artifactId>
        <version>1.6.6</version>
      </dependency>
    </dependencies>
  • Laporkan data ke Analisis Tracing.

    public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
    
        registerTracer(context);
    
        JaegerSpanContext spanContext = contextFromString(context.getTracing().getSpanContext());
    
        startMySpan(spanContext);
    }
  • Buat objek tracer berdasarkan informasi tracing dalam Context.

    void registerTracer(Context context){
        io.jaegertracing.Configuration config = new io.jaegertracing.Configuration("FCTracer");
        io.jaegertracing.Configuration.SenderConfiguration sender = new io.jaegertracing.Configuration.SenderConfiguration();
        sender.withEndpoint(context.getTracing().getJaegerEndpoint());
        config.withSampler(new io.jaegertracing.Configuration.SamplerConfiguration().withType("const").withParam(1));
        config.withReporter(new io.jaegertracing.Configuration.ReporterConfiguration().withSender(sender).withMaxQueueSize(10000));
        GlobalTracer.register(config.getTracer());
    }
  • Konversikan SpanContext dan buat rentang kustom. Anda juga dapat membuat rentang anak berdasarkan rentang tersebut.

    static JaegerSpanContext contextFromString(String value) throws MalformedTracerStateStringException, EmptyTracerStateStringException {
        if (value != null && !value.equals("")) {
            String[] parts = value.split(":");
            if (parts.length != 4) {
                throw new MalformedTracerStateStringException(value);
            } else {
                String traceId = parts[0];
                if (traceId.length() <= 32 && traceId.length() >= 1) {
                    return new JaegerSpanContext(0L, (new BigInteger(traceId, 16)).longValue(), (new BigInteger(parts[1], 16)).longValue(), (new BigInteger(parts[2], 16)).longValue(), (new BigInteger(parts[3], 16)).byteValue());
                } else {
                    throw new TraceIdOutOfBoundException("Panjang ID jejak [" + traceId + "] tidak berada antara 1 dan 32");
                }
            }
        } else {
            throw new EmptyTracerStateStringException();
        }
    }