OpenTelemetry系列 - 第4篇 OpenTelemetry K8S生态

news2025/1/25 4:45:00

目录

    • 一、【Helm】添加OTel Helm repo
    • 二、【Helm Chart】OTel Collector
      • 2.1 daemonset
      • 2.2 deloyment
    • 三、【K8S Operator】OTel Operator
      • 3.1 安装OTel Operator
      • 3.2 部署OpenTelemetryCollector
        • 3.2.1 Deloyment Mode
        • 3.2.2 DeamonSet Mode
        • 3.2.3 StatefulSetMode
        • 3.2.4 Sidecar Mode
      • 3.3 部署Instrumentation - 配置应用端自动注入OTel Agent
        • 3.3.1 全局配置Instrumentation
        • 3.3.2 工作负载通过annotation启用自动注入
        • 3.3.3 Pod内多个container注入
        • 3.3.4 Java Pod自动注入
        • 3.3.5 剔除/actuator/health

一、【Helm】添加OTel Helm repo

helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts
helm repo update

二、【Helm Chart】OTel Collector

收集器可以部署为以下四种模式之一:

  • deployment(默认)
  • daemonSet
  • statefulSet

默认模式为deployment。

helm install otel-collector open-telemetry/opentelemetry-collector \
--set mode=<value>
helm install otel-collector open-telemetry/opentelemetry-collector \
--values <path where you saved the chart>

2.1 daemonset

部署OpenTelemetry Collector的daemonset实例,以收集节点(node)和运行在这些节点上的工作负载(workloads)相关的遥测数据(telemetry)。使用daementset来保证在所有节点上都安装了这个收集器实例。daemenset收集器的每个实例将只从其运行的节点收集数据。

收集器的实例将使用以下组件:

  • OTLP Receiver:收集应用程序跟踪、度量和日志。
  • Kubernetes Attributes Processor:将Kubernetes元数据添加到传入的应用遥测中。
  • Kubeletstats Receiver:从kubelet上的API服务器提取节点、pod和容器指标。
  • Filelog Receiver:用于收集写入stdout/stderr的Kubernetes日志和应用程序日志(/var/log/pods/*/*/*.log)。

values-for-daemonset.yaml:

mode: daemonset

presets:
  # enables the k8sattributesprocessor and adds it to the traces, metrics, and logs pipelines
  kubernetesAttributes:
    enabled: true
  # enables the kubeletstatsreceiver and adds it to the metrics pipelines
  kubeletMetrics:
    enabled: true
  # Enables the filelogreceiver and adds it to the logs pipelines
  logsCollection:
    enabled: true
## The chart only includes the loggingexporter by default
## If you want to send your data somewhere you need to
## configure an exporter, such as the otlpexporter
# config:
# exporters:
#   otlp:
#     endpoint: "<SOME BACKEND>"
# service:
#   pipelines:
#     traces:
#       exporters: [ otlp ]
#     metrics:
#       exporters: [ otlp ]
#     logs:
#       exporters: [ otlp ]

2.2 deloyment

部署Collector的deloyment实例,以收集与整个集群相关的遥测数据。只有一个副本的部署确保我们不会产生重复的数据。

收集器的实例将使用以下组件:

  • Kubernetes Cluster Receiver:收集集群级指标和实体事件。
  • Kubernetes Objects Receiver:从Kubernetes API服务器收集对象,例如events。

values-for-deloyment

mode: deployment

# We only want one of these collectors - any more and we'd produce duplicate data
replicaCount: 1

presets:
  # enables the k8sclusterreceiver and adds it to the metrics pipelines
  clusterMetrics:
    enabled: true
  # enables the k8sobjectsreceiver to collect events only and adds it to the logs pipelines
  kubernetesEvents:
    enabled: true
## The chart only includes the loggingexporter by default
## If you want to send your data somewhere you need to
## configure an exporter, such as the otlpexporter
# config:
# exporters:
#   otlp:
#     endpoint: "<SOME BACKEND>"
# service:
#   pipelines:
#     traces:
#       exporters: [ otlp ]
#     metrics:
#       exporters: [ otlp ]
#     logs:
#       exporters: [ otlp ]


三、【K8S Operator】OTel Operator

OTel K8S整体架构:
在这里插入图片描述

3.1 安装OTel Operator

$ helm install \
--set admissionWebhooks.certManager.enabled=false \
--set admissionWebhooks.certManager.autoGenerateCert=true \
opentelemetry-operator open-telemetry/opentelemetry-operator
helm uninstall opentelemetry-operator

收集器可以部署为以下四种模式之一:

  • deployment(默认)
  • daemonSet
  • statefulSet
  • sidecar

默认模式为deployment。

3.2 部署OpenTelemetryCollector

3.2.1 Deloyment Mode

独立部署、运维Collector,方便scale、回滚版本。

$ kubectl apply -f - <<EOF
apiVersion: opentelemetry.io/v1alpha1
kind: OpenTelemetryCollector
metadata:
  name: my-collector
spec:
  mode: deployment # This configuration is omittable.
  config: |
    receivers:
      jaeger:
        protocols:
          grpc:
    processors:

    exporters:
      debug:

    service:
      pipelines:
        traces:
          receivers: [jaeger]
          processors: []
          exporters: [debug]
EOF
3.2.2 DeamonSet Mode

作为DaemonSet运行Collector于每个K8s Node之上,收集Node上pod信息。

$ kubectl apply -f - <<EOF
apiVersion: opentelemetry.io/v1alpha1
kind: OpenTelemetryCollector
metadata:
  name: my-collector
spec:
  mode: daemonset
  hostNetwork: true
  config: |
    receivers:
      jaeger:
        protocols:
          grpc:
    processors:

    exporters:
      debug:
        verbosity: detailed

    service:
      pipelines:
        traces:
          receivers: [jaeger]
          processors: []
          exporters: [debug]
EOF
3.2.3 StatefulSetMode

将Collector部署为StatefulSet基本上有三个主要优势:

  • Collector实例的name可预测
    如果使用上述两种方法来部署Collector,则Collector实例的pod名称将是唯一的(它的名称加上随机序列)。但是,statfulset中的每个Pod都从statfulset的名称和Pod的序号(my-col-0、my-col-1、my-col-2等)中派生其主机名。
  • 当Collector副本失败时,将安排重新调度
    如果Collector pod在StatefulSet中失败,Kubernetes将尝试重新调度具有相同名称的新pod到同一节点。Kubernetes也会尝试将相同的粘性身份(例如volumnes)附加到新的pod上。
$ kubectl apply -f - <<EOF
apiVersion: opentelemetry.io/v1alpha1
kind: OpenTelemetryCollector
metadata:
  name: my-collector
spec:
  mode: statefulset
  replicas: 3
  config: |
    receivers:
      jaeger:
        protocols:
          grpc:
    processors:

    exporters:
      debug:

    service:
      pipelines:
        traces:
          receivers: [jaeger]
          processors: []
          exporters: [debug]
EOF
3.2.4 Sidecar Mode

将Collector作为sidecar注入Pod中,
sidecar模式的最大优点是,它允许人们尽可能快速、可靠地从应用程序中卸载遥测数据。这个Collector实例将在容器级别上工作,不会创建新的pod,这对于保持Kubernetes集群的整洁和易于管理是完美的。此外,当您希望使用不同的收集/导出策略时,还可以使用sidecar模式,这正好适合此应用程序。
一旦Collector Sidecar实例存在于给定的名称空间中,您就可以从该名称空间为deployment注入sidecar(以下2种方式任选1种即可):

  • 为Deployment添加annontation - sidecar.opentelemetry.io/inject: true
  • 为Namespace添加annontation - sidecar.opentelemetry.io/inject: true
$ kubectl apply -f - <<EOF
apiVersion: opentelemetry.io/v1alpha1
kind: OpenTelemetryCollector
metadata:
  name: sidecar-for-my-app
spec:
  mode: sidecar
  config: |
    receivers:
      jaeger:
        protocols:
          thrift_compact:
    processors:

    exporters:
      debug:

    service:
      pipelines:
        traces:
          receivers: [jaeger]
          processors: []
          exporters: [debug]
EOF
$ kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  labels:
    app: my-app
spec:
  selector:
    matchLabels:
      app: my-app
  replicas: 1
  template:
    metadata:
      labels:
        app: my-app
      annotations:
        sidecar.opentelemetry.io/inject: "true" # CORRECT
    spec:
      containers:
      - name: myapp
        image: jaegertracing/vertx-create-span:operator-e2e-tests
        ports:
          - containerPort: 8080
            protocol: TCP
EOF

3.3 部署Instrumentation - 配置应用端自动注入OTel Agent

operator可以注入和配置OpenTelemetry自动注入agent。目前支持:

  • Apache HTTPD
  • DotNet
  • Go
  • Java
  • Nginx
  • NodeJS
  • Python
3.3.1 全局配置Instrumentation
kubectl apply -f - <<EOF
apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata:
  name: my-instrumentation
spec:
  exporter:
    endpoint: http://otel-collector:4317
  propagators:
    - tracecontext
    - baggage
    - b3
  sampler:
    type: parentbased_traceidratio
    argument: "0.25"
  python:
    env:
      # Required if endpoint is set to 4317.
      # Python autoinstrumentation uses http/proto by default
      # so data must be sent to 4318 instead of 4317.
      - name: OTEL_EXPORTER_OTLP_ENDPOINT
        value: http://otel-collector:4318
  dotnet:
    env:
      # Required if endpoint is set to 4317.
      # Dotnet autoinstrumentation uses http/proto by default
      # See https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/blob/888e2cd216c77d12e56b54ee91dafbc4e7452a52/docs/config.md#otlp
      - name: OTEL_EXPORTER_OTLP_ENDPOINT
        value: http://otel-collector:4318
  go:
    env:
      # Required if endpoint is set to 4317.
      # Go autoinstrumentation uses http/proto by default
      # so data must be sent to 4318 instead of 4317.
      - name: OTEL_EXPORTER_OTLP_ENDPOINT
        value: http://otel-collector:4318
EOF

以上部署成功的CR Instrumentation可以通过如下命令查询:

kubectl get otelinst.
3.3.2 工作负载通过annotation启用自动注入

通过添加annotation启动自动注入:

  • 向pod添加annotation以启用注入
  • 将annotation添加到namespace中,以便该名称空间中的所有pod都将获得检测
  • 将annotation添加到单独的PodSpec对象中,这些对象可以作为Deployment、Statefulset和其他资源的一部分使用

Java:

instrumentation.opentelemetry.io/inject-java: "true"
# 注入到指定的container中(适用于一个Pod中有多个container)
# 如不指定则默认注入到第一个container中,
# 可通过此配置避免向istio-proxy中注入
instrumentation.opentelemetry.io/container-names: "myapp,myapp2"

NodeJS:

instrumentation.opentelemetry.io/inject-nodejs: "true"

Python:

instrumentation.opentelemetry.io/inject-python: "true"

.NET:

.NET auto-instrumentation also honors an annotation that will be used to set the .NET Runtime Identifiers(RIDs). Currently, only two RIDs are supported: linux-x64 and linux-musl-x64. By default linux-x64 is used.

instrumentation.opentelemetry.io/inject-dotnet: "true"
instrumentation.opentelemetry.io/otel-dotnet-auto-runtime: "linux-x64" # for Linux glibc based images, this is default value and can be omitted
instrumentation.opentelemetry.io/otel-dotnet-auto-runtime: "linux-musl-x64"  # for Linux musl based images

Go:

Go auto-instrumentation also honors an annotation that will be used to set the OTEL_GO_AUTO_TARGET_EXE env var. This env var can also be set via the Instrumentation resource, with the annotation taking precedence. Since Go auto-instrumentation requires OTEL_GO_AUTO_TARGET_EXE to be set, you must supply a valid executable path via the annotation or the Instrumentation resource. Failure to set this value causes instrumentation injection to abort, leaving the original pod unchanged.

instrumentation.opentelemetry.io/inject-go: "true"
instrumentation.opentelemetry.io/otel-go-auto-target-exe: "/path/to/container/executable"

Go auto-instrumentation also requires elevated permissions. The below permissions are set automatically and are required.

securityContext:
    privileged: true
    runAsUser: 0

Apache HTTPD:

instrumentation.opentelemetry.io/inject-apache-httpd: "true"

Nginx:

instrumentation.opentelemetry.io/inject-nginx: "true"

OpenTelemetry SDK environment variables only:

instrumentation.opentelemetry.io/inject-sdk: "true"

可选值:

  • true - inject and Instrumentation resource from the namespace.
  • my-instrumentation - name of Instrumentation CR instance in the current namespace.
  • my-other-namespace/my-instrumentation - name and namespace of Instrumentation CR instance in another namespace.
  • false - do not inject
3.3.3 Pod内多个container注入
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment-with-multi-containers-multi-instrumentations
spec:
  selector:
    matchLabels:
      app: my-pod-with-multi-containers-multi-instrumentations
  replicas: 1
  template:
    metadata:
      labels:
        app: my-pod-with-multi-containers-multi-instrumentations
      annotations:
        instrumentation.opentelemetry.io/inject-java: "true"
        instrumentation.opentelemetry.io/java-container-names: "myapp,myapp2"
        instrumentation.opentelemetry.io/inject-python: "true"
        instrumentation.opentelemetry.io/python-container-names: "myapp3"
    spec:
      containers:
      - name: myapp
        image: myImage1
      - name: myapp2
        image: myImage2
      - name: myapp3
        image: myImage3
3.3.4 Java Pod自动注入

Java Pod被OTel自动注入后,Pod定义被修改如下:

apiVersion: v1
kind: Pod
metadata:
  labels:
    app: app-atom
    version: v1
  name: app-atom-6c97b8dd84-mw222
  namespace: otel-poc
spec:
  containers:
  - env:
    - name: SPRING_OUTPUT_ANSI_ENABLED
      value: NEVER
    - name: LOGGING_CONFIG
      value: /config/logback-spring.xml
    - name: JAVA_TOOL_OPTIONS
      value: ' -javaagent:/otel-auto-instrumentation-java/javaagent.jar'
    - name: OTEL_SERVICE_NAME
      value: app-atom
    - name: OTEL_EXPORTER_OTLP_ENDPOINT
      value: http://otel-collector.opentelemetry-operator-system.svc.cluster.local:4317
    - name: OTEL_RESOURCE_ATTRIBUTES_POD_NAME
      valueFrom:
        fieldRef:
          apiVersion: v1
          fieldPath: metadata.name
    - name: OTEL_RESOURCE_ATTRIBUTES_NODE_NAME
      valueFrom:
        fieldRef:
          apiVersion: v1
          fieldPath: spec.nodeName
    - name: OTEL_PROPAGATORS
      value: tracecontext,baggage,b3
    - name: OTEL_TRACES_SAMPLER
      value: parentbased_traceidratio
    - name: OTEL_TRACES_SAMPLER_ARG
      value: "0.25"
    - name: OTEL_RESOURCE_ATTRIBUTES
      value: k8s.container.name=app-atom,k8s.deployment.name=app-atom,k8s.namespace.name=otel-poc,k8s.node.name=$(OTEL_RESOURCE_ATTRIBUTES_NODE_NAME),k8s.pod.name=$(OTEL_RESOURCE_ATTRIBUTES_POD_NAME),k8s.replicaset.name=app-atom-6c97b8dd84,service.version=latest
    image: otel-poc/app-atom:latest
    imagePullPolicy: IfNotPresent
    livenessProbe:
      failureThreshold: 3
      httpGet:
        path: /actuator/health
        port: 8080
        scheme: HTTP
      initialDelaySeconds: 60
      periodSeconds: 10
      successThreshold: 1
      timeoutSeconds: 5
    name: app-atom
    ports:
    - containerPort: 8080
      name: http
      protocol: TCP
    - containerPort: 9999
      name: http-xxljob
      protocol: TCP
    readinessProbe:
      failureThreshold: 3
      httpGet:
        path: /actuator/health
        port: 8080
        scheme: HTTP
      initialDelaySeconds: 60
      periodSeconds: 10
      successThreshold: 1
      timeoutSeconds: 5
    resources:
      limits:
        cpu: "1"
        memory: 1000Mi
      requests:
        cpu: 10m
        memory: 128Mi
    terminationMessagePath: /dev/termination-log
    terminationMessagePolicy: File
    volumeMounts:
    - mountPath: /config/
      name: app-config
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: kube-api-access-vxx27
      readOnly: true
    - mountPath: /otel-auto-instrumentation-java
      name: opentelemetry-auto-instrumentation-java
  dnsPolicy: ClusterFirst
  enableServiceLinks: true
  initContainers:
  - command:
    - cp
    - /javaagent.jar
    - /otel-auto-instrumentation-java/javaagent.jar
    image: ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-java:231128
    imagePullPolicy: IfNotPresent
    name: opentelemetry-auto-instrumentation-java
    resources:
      limits:
        cpu: 500m
        memory: 64Mi
      requests:
        cpu: 50m
        memory: 64Mi
    terminationMessagePath: /dev/termination-log
    terminationMessagePolicy: File
    volumeMounts:
    - mountPath: /otel-auto-instrumentation-java
      name: opentelemetry-auto-instrumentation-java
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: kube-api-access-vxx27
      readOnly: true
  nodeName: k-node1
  preemptionPolicy: PreemptLowerPriority
  priority: 0
  restartPolicy: Always
  schedulerName: default-scheduler
  securityContext: {}
  serviceAccount: default
  serviceAccountName: default
  terminationGracePeriodSeconds: 30
  tolerations:
  - effect: NoExecute
    key: node.kubernetes.io/not-ready
    operator: Exists
    tolerationSeconds: 300
  - effect: NoExecute
    key: node.kubernetes.io/unreachable
    operator: Exists
    tolerationSeconds: 300
  volumes:
  - configMap:
      defaultMode: 420
      name: app-atom
    name: app-config
  - name: kube-api-access-vxx27
    projected:
      defaultMode: 420
      sources:
      - serviceAccountToken:
          expirationSeconds: 3607
          path: token
      - configMap:
          items:
          - key: ca.crt
            path: ca.crt
          name: kube-root-ca.crt
      - downwardAPI:
          items:
          - fieldRef:
              apiVersion: v1
              fieldPath: metadata.namespace
            path: namespace
  - emptyDir:
      sizeLimit: 200Mi
    name: opentelemetry-auto-instrumentation-java
3.3.5 剔除/actuator/health

https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/1060
在这里插入图片描述


参考:
https://opentelemetry.io/docs/kubernetes/
https://opentelemetry.io/docs/kubernetes/operator/
https://github.com/open-telemetry/opentelemetry-helm-charts
https://github.com/open-telemetry/opentelemetry-operator
阿里技术 - 深入浅出eBPF|你要了解的7个核心问题

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1279247.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

思维模型 莫扎特效应

本系列文章 主要是 分享 思维模型&#xff0c;涉及各个领域&#xff0c;重在提升认知。音乐激发无限潜能。 1 莫扎特效应的应用 1.1 莫扎特效应在教育领域的应用-Baby Einstein”公司 在美国&#xff0c;有一家名为“Baby Einstein”的公司&#xff0c;该公司生产和销售专门为…

SQL自学通之简介

目录 一、SQL 简史 二、数据库简史 1、Dr. Codds 对关系型数据库系统的十二条规则 2、设计数据库的结构 3、数据库的前景 4、对于什么是客户机/服务器型电脑系统 BernardH.Boar的定义如下&#xff1a; 5、交互式语言 6、易于实现 7、SQL 总览 三、流行的 SQL 开发工具…

前端小记--2.element-ui中级联选择器cascader如何默认展开下拉框

最近做项目时&#xff0c;遇到一个需求&#xff1a;在一个排班表中&#xff0c;展示人员的值班情况&#xff0c;点击单元格&#xff0c;弹出下拉框&#xff0c;修改人员排班信息。 由于下拉框选择内容是树状结构&#xff0c;这里使用了element-ui中级联组件cascader&#xff0c…

一起学docker系列之十七Docker Compose 与手动操作的比较与优势分析

目录 1 前言2 不使用 Docker Compose2.1 启动 MySQL 容器2.2 启动 Redis 容器2.3 启动微服务容器 3 使用 Docker Compose4 使用 Docker Compose 的优势5 结语参考地址 1 前言 在当今容器化应用的开发与部署中&#xff0c;容器编排工具的选择对于简化流程、提高效率至关重要。本…

6-69.鸭子也是鸟

按要求完成下面的程序&#xff1a; 1、定义一个Bird类&#xff0c;包含一个void类型的无参的speak方法&#xff0c;输出“Jiu-Jiu-Jiu”。 2、定义一个Duck类&#xff0c;公有继承自Bird类&#xff0c;其成员包括&#xff1a; &#xff08;1&#xff09;私有string类型的成员na…

WPF实现文字纵向排布的TabItem

文章目录 基本用法文字竖排显示 WPF布局 基本用法 WPF中的TabControl是一个容器控件&#xff0c;用于在单个窗体或页面中承载多个选项卡。每个选项卡可以包含不同的控件&#xff0c;用于显示不同的内容&#xff0c;其最简单的调用方法如下&#xff0c;只需在TabControl中无脑…

德迅云安全的日常网站安全性措施、以及更多网站安全工具的推荐与使用。

要确保网站的安全性&#xff0c;可以采取以下措施&#xff1a; 更新和维护&#xff1a;定期更新网站的操作系统、应用程序和插件&#xff0c;确保使用的是最新版本&#xff0c;以修复已知的安全漏洞。 强密码策略&#xff1a;使用强密码&#xff0c;包含字母、数字和特殊字符的…

合成相机模型【图形学】

相机在计算机图形学中有两个方面的考虑&#xff1a;相机的位置和相机的形状。 要了解后者&#xff0c;我们需要了解相机的工作原理。 NSDT工具推荐&#xff1a; Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 可编程3D场景编辑器 - R…

BearPi Std 板从入门到放弃 - 1 引气入体篇

安装相关开发工具 Keil MDK 工具下载 略, 自行体会 Keil 芯片支持包下载 Keil 包 网址 https://www.keil.com/pack 此处下载的是STM32L4xx的支持包 https://www.keil.com/pack/Keil.STM32L4xx_DFP.2.6.2.pack STM32CubeMX 下载与包下载 i. 下载&#xff08;需要使用用户&…

爬虫学习(三)用beautiful 解析html

安装库 import requests from bs4 import BeautifulSoup headers {"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36 Edg/119.0.0.0"} for start_num in range(0,250…

【Gstreamer】自定义Plugin及调用Plugin

Gstreamer自定义Plugin及调用自定义Plugin Gstreamer支持开发者自己创建Plugin&#xff0c;创建后的Plugin可以通过工具gst-inspect-1.0查看&#xff0c;并在代码中调用自定义的plugin。 Gstreamer 官网中给出了Plugin创建教程&#xff0c;但实际上如果按照教程一步步走&…

机器学习笔记 - 异常检测之OneClass SVM算法简述

一、异常检测是什么? 如下图,理想中我们可以找到一个框住大部分正常样本的决策边界,而在边界外部的数据点(蓝点)即视为异常。 但实际情况下数据都没有标签,因此很难定义正常还是不正常。异常检测的主要挑战如下:正常与异常行为之间的界限往往并不明确、不同的应…

org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource

DynamicDataSource-CSDN博客 /** Copyright 2002-2020 the original author or authors.** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the L…

uni-app 微信小程序之自定义中间圆形tabbar

文章目录 1. 自定义tabbar效果2. pages新建tabbar页面3. tabbar 页面结构4. tabbar 页面完整代码 1. 自定义tabbar效果 2. pages新建tabbar页面 首先在 pages.json 文件中&#xff0c;新建一个 tabbar 页面 "pages": [ //pages数组中第一项表示应用启动页&#xff…

Spark大数据集群日常开发过程遇到的异常及解决思路汇总

原创/朱季谦 在开发Spark任务过程中&#xff0c;遇到过不少新人经常可能会遇到的坑&#xff0c;故而将这些坑都总结了下来&#xff0c;方便日后遇到时&#xff0c;可以快速定位解决&#xff0c;壁面耗费过多时间在查找问题之上。 一、出现java.lang.IllegalAccessError: tried…

Docker常见命令介绍

命令说明 docker pull 拉取镜像 docker push 推送镜像到DockerRegistry docker images 查看本地镜像 docker rmi 删除本地镜像 docker run 创建并运行容器&#xff08;不能重复创建&#xff09; docker stop 停止指定容器 docker start 启动指定容器 docker rest…

设计模式之道:解构结构型设计模式的核心原理

解构常见的三种结构型设计模式的核心原理 一、引言&#xff1a;如何学习设计模式&#xff1f;二、责任链模式2.1、代码结构2.2、符合的设计原则2.3、案例分析&#xff1a;nginx 阶段处理2.4、小结 三、装饰器模式3.1、代码结构3.2、符合的设计原则3.3、小结 四、组合模式4.1、代…

深度学习——第03章 Python程序设计语言(3.1 Python语言基础)

无论是在机器学习还是深度学习中&#xff0c;Python已经成为主导性的编程语言。而且&#xff0c;现在许多主流的深度学习框架&#xff0c;例如PyTorch、TensorFlow也都是基于Python。本课程主要是围绕“理论实战”同时进行&#xff0c;所以本章将重点介绍深度学习中Python的必备…

JOSEF 快速中间继电器 KZJ-4H-L DC220V 导轨安装

快速中间继电器KZJ-4H-LDC220V导轨安装导轨安装是广泛用于电力系统&#xff0c;能够断货开或开通大负载&#xff0c;并且具有较强的断弧能力&#xff0c;适用于交流50/60Hz。电压24380V,直流电压24280V自动控制电路中以增加保护和控制回路的触点数量与触点容量。 KZJ系列快速中…

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《市场环境下运行的光热电站子系统容量优化配比研究》

这个标题涉及到对市场环境下运行的光热电站子系统进行容量优化配比的研究。让我们逐步解读&#xff1a; 市场环境下运行的光热电站&#xff1a; 这指的是光热电站在实际市场环境中的运行&#xff0c;可能包括了市场相关的经济、政策、竞争等因素。 子系统&#xff1a; 光热电站…