萬字長文 | Apache SeaTunnel 分離集群模式部署 K8s 集群實踐

文章作者:雷寶鑫

整理排版:白鯨開源 曾輝

Apache SeaTunnel官網鏈接: https://seatunnel.apache.org/

Apache SeaTunnel(以下簡稱SeaTunnel)是一款新一代高性能、分布式的數據集成同步工具,正受到業界廣泛關注和應用。SeaTunnel支持三種部署模式:本地模式(Local)、混合集群模式(Hybrid Cluster Mode)和分離集群模式(Separated Cluster Mode)。

本文嘗試介紹如何在K8s上以分離集群模式部署SeaTunnel,為有相關需求的伙伴提供完整的部署流程和配置案例參考。

前期準備

在開始部署之前,需要確保以下環境和組件已經準備就緒:

  • Kubernetes集群環境
  • kubectl命令行工具
  • docker
  • helm (option)

對于熟悉和具有Helm環境的部署,可以直接參考官網中使用Helm部署教程:

  • https://seatunnel.apache.org/docs/2.3.10/start-v2/kubernetes/helm
  • https://github.com/apache/seatunnel/tree/dev/deploy/kubernetes/seatunnel

本文主要介紹基于Kubernetes環境和kubectl工具的方式實現部署。

構建SeaTunnel Docker鏡像

目前官方已提供各版本的Docker鏡像,可直接拉取,詳細信息可參考官方文檔:Set Up With Docker

docker pull apache/seatunnel:<version_tag>

由于我們需要部署的是集群模式,接下來需要配置集群間的網絡通信。SeaTunnel集群的網絡服務是通過Hazelcast實現的,所以接下來對這部分內容進行配置。

Hazelcast集群相關配置

Headless Service配置

Hazelcast 集群是由運行 Hazelcast 的集群成員組成的網絡,集群成員自動聯合起來形成一個集群,這種自動加入是通過集群成員用于查找彼此的各種發現機制實現的。

Hazelcast 支持以下發現機制:

  • 自動發現機制,支持以下環境:
    • AWS
    • Azure
    • GCP
    • Kubernetes
  • TCP
  • Multicast
  • Eureka
  • Zookeeper

在本文的集群部署中,我們基于HazelcastKubernetes自動發現機制來配置文件,詳細的原理可以參考官網文檔:Kubernetes Auto Discovery。

Hazelcast的k8s自動發現機制(DNS Lookup mode)需要借助于k8s的Headless Service功能來實現。

Headless Service在查詢服務域名時,會將域名解析為所有匹配PodIP地址列表,以此來實現Hazelcast集群成員互相發現彼此。

為此,首先我們創建K8s Headless Service服務:

# use for hazelcast cluster join
apiVersion: v1
kind: Service
metadata:name: seatunnel-cluster
spec:type: ClusterIPclusterIP: Noneselector:app.kubernetes.io/instance: seatunnel-cluster-appapp.kubernetes.io/version: 2.3.10ports:- port: 5801name: hazelcast

上述配置中的關鍵部分:

  • metadata.name: seatunnel-cluster: 服務名稱,Hazelcast 客戶端/節點將通過該名稱發現集群
  • spec.clusterIP: None:關鍵配置,聲明為 Headless Service,不分配虛擬 IP
  • spec.selector: 選擇器匹配的 Pod 標簽,包含相應標簽的pod會被該Service識別和代理
  • spec.port:Hazelcast的暴露端口

同時,為了能從系統外部利用rest api訪問集群,我們定義另一個Service來包含Master的節點pod

# use for access seatunnel from outside system via rest api
apiVersion: v1
kind: Service
metadata:name: seatunnel-cluster-master
spec:type: ClusterIPclusterIP: Noneselector:app.kubernetes.io/instance: seatunnel-cluster-appapp.kubernetes.io/version: 2.3.10app.kubernetes.io/name: seatunnel-cluster-masterapp.kubernetes.io/component: masterports:- port: 8080name: "master-port"targetPort: 8080protocol: TCP

定義好上述K8s的Service服務后,接下來根據Hazelcast的k8s發現機制來配置hazelcast-master.yamlhazelcast-worker.yaml文件。

Hazelcast master和worker的yaml配置

對于SeaTunnel分離集群模式來說,所有網絡相關的配置都在hazelcast-master.yamlhazelcast-worker.yaml文件中。

hazelcast-master.yaml的配置如下所示:

hazelcast:cluster-name: seatunnel-clusternetwork:rest-api:enabled: trueendpoint-groups:CLUSTER_WRITE:enabled: trueDATA:enabled: truejoin:kubernetes:enabled: trueservice-dns: seatunnel-cluster.bigdata.svc.cluster.localservice-port: 5801port:auto-increment: falseport: 5801properties:hazelcast.invocation.max.retry.count: 20hazelcast.tcp.join.port.try.count: 30hazelcast.logging.type: log4j2hazelcast.operation.generic.thread.count: 50hazelcast.heartbeat.failuredetector.type: phi-accrualhazelcast.heartbeat.interval.seconds: 30hazelcast.max.no.heartbeat.seconds: 300hazelcast.heartbeat.phiaccrual.failuredetector.threshold: 15hazelcast.heartbeat.phiaccrual.failuredetector.sample.size: 200hazelcast.heartbeat.phiaccrual.failuredetector.min.std.dev.millis: 200

上述配置文件中的關鍵配置項如下:

cluster-name

該配置用于確定多個節點是否屬于同一個集群,即只有相同cluster-name的節點才會屬于同一個集群。如果兩個節點之間的cluster-name名稱不同,Hazelcast 將會拒絕服務請求。

網絡配置
  • rest-api.enabled:在ST 2.3.10版本中Hazelcast REST 服務默認在配置中禁用,需要手動顯式指定開啟。
  • service-dns(必填):Headless Service 的完整域名,通常為 S E R V I C E ? N A M E . {SERVICE-NAME}. SERVICE?NAME.{NAMESPACE}.svc.cluster.local。
  • service-port(可選):Hazelcast 端口;如果指定的值大于 0,則覆蓋默認值(默認端口 = 5701)

使用上述基于k8s的join機制,在Hazelcast Pod啟動時會解析service-dns,獲取所有成員pod的IP列表(通過Headless Service),然后成員之間通過5801端口嘗試建立TCP連接。

同樣的,對于hazelcast-worker.yaml配置文件如下所示:

hazelcast:cluster-name: seatunnel-clusternetwork:rest-api:enabled: trueendpoint-groups:CLUSTER_WRITE:enabled: trueDATA:enabled: truejoin:kubernetes:enabled: trueservice-dns: seatunnel-cluster.bigdata.svc.cluster.localservice-port: 5801port:auto-increment: falseport: 5801properties:hazelcast.invocation.max.retry.count: 20hazelcast.tcp.join.port.try.count: 30hazelcast.logging.type: log4j2hazelcast.operation.generic.thread.count: 50hazelcast.heartbeat.failuredetector.type: phi-accrualhazelcast.heartbeat.interval.seconds: 30hazelcast.max.no.heartbeat.seconds: 300hazelcast.heartbeat.phiaccrual.failuredetector.threshold: 15hazelcast.heartbeat.phiaccrual.failuredetector.sample.size: 200hazelcast.heartbeat.phiaccrual.failuredetector.min.std.dev.millis: 200member-attributes:rule:type: stringvalue: worker

通過上述流程,我們就創建好了與Hazelcast集群相關的配置和服務,實現了Hazecast基于Kubernetes的集群成員發現。

接下來,繼續完成有關SeaTunnel引擎的相關配置。

配置SeaTunnel引擎

SeaTunnel引擎的相關配置都在seatunnel.yaml文件中,下面給出seatunnel.yaml配置示例以供參考:

seatunnel:engine:history-job-expire-minutes: 1440backup-count: 1queue-type: blockingqueueprint-execution-info-interval: 60print-job-metrics-info-interval: 60classloader-cache-mode: truehttp:enable-http: trueport: 8080enable-dynamic-port: falseport-range: 100slot-service:dynamic-slot: truecheckpoint:interval: 300000timeout: 60000storage:type: hdfsmax-retained: 3plugin-config:namespace: /tmp/seatunnel/checkpoint_snapshotstorage.type: hdfsfs.defaultFS: hdfs://xxx:8020 # Ensure that the directory has written permissiontelemetry:metric:enabled: true

包含以下配置信息:

  • history-job-expire-minutes:任務歷史記錄保留時長為 24 小時(1440 分鐘),超時自動清理。
  • backup-count: 1:任務狀態備份副本數為 1。
  • queue-type: blockingqueue:使用阻塞隊列管理任務,避免資源耗盡。
  • print-execution-info-interval: 60:每分鐘打印一次任務執行狀態。
  • print-job-metrics-info-interval: 60:每分鐘輸出一次任務指標(如吞吐量、延遲)。
  • classloader-cache-mode: true:啟用類加載緩存,減少重復加載開銷,提升性能。
  • dynamic-slot: true:允許根據負載動態調整任務槽(Slot)數量,優化資源利用率。
  • checkpoint.interval: 300000:每 5 分鐘觸發一次檢查點(Checkpoint)。
  • checkpoint.timeout: 60000:檢查點超時時間為 1 分鐘。
  • telemetry.metric.enabled: true:啟用任務運行指標采集(如延遲、吞吐量),便于監控。

創建k8s yaml文件部署應用

在完成上面的工作流程后,我們就可以進入到最后一步:創建Master和Worker節點的k8s yaml文件定義部署的相關配置。

為了將配置文件與應用程序解耦,我們將上文中列出的配置文件合并到一個ConfigMap中,并掛載到容器的配置路徑下,便于對配置文件的統一管理和更新。

以下是針對 seatunnel-cluster-master.yamlseatunnel-cluster-worker.yaml 的配置示例,涵蓋了配置 ConfigMap 掛載、容器啟動命令以及部署資源定義等相關內容。

seatunnel-cluster-master.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:name: seatunnel-cluster-master
spec:replicas: 2  # modify replicas according to your casestrategy:type: RollingUpdaterollingUpdate:maxUnavailable: 25%maxSurge: 50%selector:matchLabels:app.kubernetes.io/instance: seatunnel-cluster-appapp.kubernetes.io/version: 2.3.10app.kubernetes.io/name: seatunnel-cluster-masterapp.kubernetes.io/component: mastertemplate:metadata:annotations:prometheus.io/path: /hazelcast/rest/instance/metricsprometheus.io/port: "5801"prometheus.io/scrape: "true"prometheus.io/role: "seatunnel-master"labels:app.kubernetes.io/instance: seatunnel-cluster-appapp.kubernetes.io/version: 2.3.10app.kubernetes.io/name: seatunnel-cluster-masterapp.kubernetes.io/component: masterspec:affinity:nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:- matchExpressions:- key: nodeAffinity-keyoperator: Existscontainers:- name: seatunnel-masterimage: seatunnel:2.3.10imagePullPolicy: IfNotPresentports:- containerPort: 5801name: hazelcast- containerPort: 8080name: "master-port"command:- /opt/seatunnel/bin/seatunnel-cluster.sh- -r- masterresources:requests:cpu: "1"memory: 4GvolumeMounts:- mountPath: "/opt/seatunnel/config/hazelcast-master.yaml"name: seatunnel-configssubPath: hazelcast-master.yaml- mountPath: "/opt/seatunnel/config/hazelcast-worker.yaml"name: seatunnel-configssubPath: hazelcast-worker.yaml- mountPath: "/opt/seatunnel/config/seatunnel.yaml"name: seatunnel-configssubPath: seatunnel.yaml- mountPath: "/opt/seatunnel/config/hazelcast-client.yaml"name: seatunnel-configssubPath: hazelcast-client.yaml- mountPath: "/opt/seatunnel/config/log4j2_client.properties"name: seatunnel-configssubPath: log4j2_client.properties- mountPath: "/opt/seatunnel/config/log4j2.properties"name: seatunnel-configssubPath: log4j2.propertiesvolumes:- name: seatunnel-configsconfigMap:name: seatunnel-cluster-configs
部署策略
  • 采用多副本(replicas=2)部署確保服務高可用
  • 滾動更新策略(RollingUpdate)實現零停機部署:
    • maxUnavailable: 25%:保證更新期間至少75%的Pod保持運行
    • maxSurge: 50%:允許臨時增加50%的Pod資源用于平滑過渡
標簽選擇器
  • 采用Kubernetes推薦的標準標簽體系
  • spec.selector.matchLabels: 根據標簽定義Deployment管理Pod的范圍
  • spec.template.labels: 定義新創建Pod的標簽,標識Pod的元數據。
節點親和性
  • 配置affinity屬性指定Pod調度的節點,需要根據自己k8s環境的節點標簽進行替換。
配置文件掛載
  • 核心配置文件統一管理在ConfigMap中,便于管理以及與應用程序解耦
  • 通過subPath指定掛載的單個文件

seatunnel-cluster-worker.yaml配置文件如下:

apiVersion: apps/v1
kind: Deployment
metadata:name: seatunnel-cluster-worker
spec:replicas: 3  # modify replicas according to your casestrategy:type: RollingUpdaterollingUpdate:maxUnavailable: 25%maxSurge: 50%selector:matchLabels:app.kubernetes.io/instance: seatunnel-cluster-appapp.kubernetes.io/version: 2.3.10app.kubernetes.io/name: seatunnel-cluster-workerapp.kubernetes.io/component: workertemplate:metadata:annotations:prometheus.io/path: /hazelcast/rest/instance/metricsprometheus.io/port: "5801"prometheus.io/scrape: "true"prometheus.io/role: "seatunnel-worker"labels:app.kubernetes.io/instance: seatunnel-cluster-appapp.kubernetes.io/version: 2.3.10app.kubernetes.io/name: seatunnel-cluster-workerapp.kubernetes.io/component: workerspec:affinity:nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:- matchExpressions:- key: nodeAffinity-keyoperator: Existscontainers:- name: seatunnel-workerimage: seatunnel:2.3.10imagePullPolicy: IfNotPresentports:- containerPort: 5801name: hazelcastcommand:- /opt/seatunnel/bin/seatunnel-cluster.sh- -r- workerresources:requests:cpu: "1"memory: 10GvolumeMounts:- mountPath: "/opt/seatunnel/config/hazelcast-master.yaml"name: seatunnel-configssubPath: hazelcast-master.yaml- mountPath: "/opt/seatunnel/config/hazelcast-worker.yaml"name: seatunnel-configssubPath: hazelcast-worker.yaml- mountPath: "/opt/seatunnel/config/seatunnel.yaml"name: seatunnel-configssubPath: seatunnel.yaml- mountPath: "/opt/seatunnel/config/hazelcast-client.yaml"name: seatunnel-configssubPath: hazelcast-client.yaml- mountPath: "/opt/seatunnel/config/log4j2_client.properties"name: seatunnel-configssubPath: log4j2_client.properties- mountPath: "/opt/seatunnel/config/log4j2.properties"name: seatunnel-configssubPath: log4j2.propertiesvolumes:- name: seatunnel-configsconfigMap:name: seatunnel-cluster-configs

定義好上述master和worker的yaml文件后,就可以執行以下命令進行部署到k8s集群了:

kubectl apply -f seatunnel-cluster-master.yaml
kubectl apply -f seatunnel-cluster-worker.yaml

正常情況下會看到SeaTunnel集群中共有2個master節點和3個worker節點:

$ kubectl get pods | grep seatunnel-clusterseatunnel-cluster-master-6989898f66-6fjz8                        1/1     Running                0          156m
seatunnel-cluster-master-6989898f66-hbtdn                        1/1     Running                0          155m
seatunnel-cluster-worker-87fb469f7-5c96x                         1/1     Running                0          156m
seatunnel-cluster-worker-87fb469f7-7kt2h                         1/1     Running                0          155m
seatunnel-cluster-worker-87fb469f7-drm9r                         1/1     Running                0          156m

至此,我們已成功在Kubernetes環境中以分離集群模式部署了SeaTunnel集群。

如今,集群已就緒,如何在客戶端向其提交任務呢?

客戶端提交任務到集群

使用命令行工具提交任務

有關SeaTunnel客戶端的配置都在hazelcast-client.yaml文件中。

首先需要在客戶端本地下載二進制安裝包(包含bin、config文件),并保證SeaTunnel的安裝路徑與服務端一致,這也就是官網中所說的:Setting the?SEATUNNEL_HOME?the same as the server,否則,可能會導致出現諸如無法在服務器端找到連接器插件路徑等錯誤(因為服務端插件路徑與客戶端路徑不一致)。

進入安裝路徑下,只需要修改config/hazelcast-client.yaml文件,配置指向剛剛創建的Headless Service服務地址即可:

hazelcast-client:cluster-name: seatunnel-clusterproperties:hazelcast.logging.type: log4j2connection-strategy:connection-retry:cluster-connect-timeout-millis: 3000network:cluster-members:- seatunnel-cluster.bigdata.svc.cluster.local:5801

客戶端配置完成后,即可將任務提交至集群執行。任務提交時的JVM參數配置方式主要有兩種:

  • config/jvm_client_options文件中配置任務提交時的JVM參數

    此方法配置的JVM參數將應用于所有通過seatunnel.sh提交的任務,無論運行于本地模式還是集群模式。所有提交的任務都將共享相同的JVM參數配置。

  • 在提交任務的命令行中指定JVM參數。

    使用seatunnel.sh提交任務時,可在命令行中直接指定JVM參數,例如:sh bin/seatunnel.sh --config $SEATUNNEL_HOME/config/v2.batch.config.template -DJvmOption=-Xms2G -Xmx2G。此方法允許為每個提交的任務獨立配置JVM參數。

接下來通過一個案例來演示客戶端提交任務至集群執行的完整流程:

env {parallelism = 2job.mode = "STREAMING"checkpoint.interval = 2000
}source {FakeSource {parallelism = 2plugin_output = "fake"row.num = 16schema = {fields {name = "string"age = "int"}}}
}sink {Console {}
}

在客戶端使用以下命令提交任務:

sh bin/seatunnel.sh --config config/v2.streaming.example.template -m cluster -n st.example.template -DJvmOption="-Xms2G -Xmx2G"

在Master節點,使用如下命令列出正在運行的任務列表:

$ sh bin/seatunnel.sh -lJob ID              Job Name             Job Status  Submit Time              Finished Time            
------------------  -------------------  ----------  -----------------------  -----------------------  
964354250769432580  st.example.template  RUNNING     2025-04-15 10:39:30.588  

可以看到,我們剛剛向集群中提交的st.example.template任務已經處于RUNNING狀態了。現在我們可以在Worker節點日志中看到如下日志打印:

2025-04-15 10:34:41,998 INFO  [.a.s.c.s.c.s.ConsoleSinkWriter] [st-multi-table-sink-writer-1] - subtaskIndex=0  rowIndex=1:  SeaTunnelRow#tableId=fake SeaTunnelRow#kind=INSERT : bdaUB, 110348049
2025-04-15 10:34:41,998 INFO  [.a.s.c.s.c.s.ConsoleSinkWriter] [st-multi-table-sink-writer-1] - subtaskIndex=1  rowIndex=1:  SeaTunnelRow#tableId=fake SeaTunnelRow#kind=INSERT : mOifY, 1974539087
2025-04-15 10:34:41,999 INFO  [.a.s.c.s.c.s.ConsoleSinkWriter] [st-multi-table-sink-writer-1] - subtaskIndex=0  rowIndex=2:  SeaTunnelRow#tableId=fake SeaTunnelRow#kind=INSERT : jKFrR, 1828047742
2025-04-15 10:34:41,999 INFO  [.a.s.c.s.c.s.ConsoleSinkWriter] [st-multi-table-sink-writer-1] - subtaskIndex=1  rowIndex=2:  SeaTunnelRow#tableId=fake SeaTunnelRow#kind=INSERT : gDiqR, 1177544796
2025-04-15 10:34:41,999 INFO  [.a.s.c.s.c.s.ConsoleSinkWriter] [st-multi-table-sink-writer-1] - subtaskIndex=0  rowIndex=3:  SeaTunnelRow#tableId=fake SeaTunnelRow#kind=INSERT : bCVxc, 909343602
...

說明我們的任務成功提交至所創建的SeaTunnel集群,并且確認其正常運行。

使用Rest Api接口提交任務

SeaTunnel提供了通過Rest Api接口的方式來查詢運行作業的狀態和統計信息,以及提交/停止作業等操作。

在上文中我們配置了只包含Master節點的Headless Service,并指定暴露的端口為8080。因此,我們就可以在客戶端使用Rest API接口的方式來實現任務的提交。

SeaTunnel Rest API接口提供了通過上傳配置文件來提交任務,命令如下:

 $ curl 'http://seatunnel-cluster-master.bigdata.svc.cluster.local:8080/submit-job/upload' --form 'config_file=@"/opt/seatunnel/config/v2.streaming.example.template"' --form 'jobName=st.example.template'{"jobId":"964553575034257409","jobName":"st.example.template"}

如果作業提交成功,會返回jobIdjobName,如上所示。

接下來,通過Rest API接口獲取集群正在運行的所有任務,觀察剛剛提交的任務信息:

curl 'http://seatunnel-cluster-master.bigdata.svc.colo.gzgalocal:8080/running-jobs'
[{"jobId":"964553575034257409","jobName":"st.example.template","jobStatus":"RUNNING","envOptions":{"job.mode":"STREAMING","checkpoint.interval":"2000","parallelism":"2"}, ...]

可以看到接口返回顯示了任務狀態和其他額外的元數據信息,說明我們通過Rest Api接口提交任務的方式也成功執行。更多Rest Api接口介紹可以參考官網:RESTful API V2

總結

本文著重介紹了如何以推薦的分離集群模式(Separated Cluster Mode)部署k8s集群的實踐,總結下來,部署過程主要包含以下步驟:

  1. 準備 Kubernetes 環境

    確保已搭建并運行一個可用的 Kubernetes 集群,并安裝所有必要的組件。

  2. 構建 SeaTunnel Docker 鏡像

    如果沒有二次開發需求,可直接使用官方提供的鏡像。否則,在本地編譯打包后,編寫 Dockerfile 并構建 SeaTunnel 鏡像。

  3. 配置Headless Service和Hazelcast集群

    Hazelcast的k8s自動發現機制的DNS Lookup模式是基于k8s的Headless Service功能來實現的,因此首先創建Headless Service服務,并在hazelcast的yaml配置文件中通過service-dns來指定服務地址。

    Headless Service會在域名解析時解析成所包含pod的IP地址集合,以此實現hazelcast集群成員之間的彼此發現。

  4. 配置 SeaTunnel 引擎

    修改seatunnel.yaml文件,配置SeaTunnel引擎參數。

  5. 創建k8s yaml部署文件

    分別創建Master和Worker的k8s yaml文件,配置節點標簽、啟動命令、資源和數據卷掛載等內容,最終將其部署到k8s集群。

  6. 配置 SeaTunnel 客戶端

    在客戶端安裝SeaTunnel,并確保客戶端的安裝路徑 (SEATUNNEL_HOME) 與服務端一致。修改 hazelcast-client.yaml 文件,配置客戶端連接到集群Service服務的地址。

  7. 任務提交與執行:

    完成以上步驟后,即可在客戶端提交任務并由 SeaTunnel 集群執行。

本文上述配置案例僅供參考,可能仍有很多配置項和配置內容未涉及,歡迎各位補充與討論,希望有各位有所幫助!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/78227.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/78227.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/78227.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

深入解析YOLO v1:實時目標檢測的開山之作

目錄 YOLO v1 算法詳解? ?1. 核心思想? ?2. 算法優勢? ?3. 網絡結構&#xff08;Unified Detection&#xff09;?? ?4. 關鍵創新? ?5. 結構示意圖&#xff08;Fig1&#xff09;? Confidence Score 的計算? 類別概率與 Bounding Box 的關系? 后處理&…

信令與流程分析

WebRTC是h5支持的重要特征之一&#xff0c;有了它&#xff0c;不再需要借助音視頻相關的客戶端&#xff0c;直接通過瀏覽器的Web頁面就可以實現音視頻聊天功能。 WebRTC項目是開源的&#xff0c;我們可以借助WebRTC&#xff0c;構建自己的音視頻聊緹娜功能。無論是前端JS的Web…

BIOS主板(非UEFI)安裝fedora42的方法

BIOS主板(非UEFI)安裝fedora42的方法 現實困難&#xff1a;將Fedora-Workstation-Live-42-1.1.x86_64.iso寫入U盤制作成可啟動U盤啟動fedora42&#xff0c;按照向導將fedora42安裝到真機的sda7分區中得到報錯如下內容&#xff1a; /boot/efi 必需的 /boot/efi必須位于格式化為e…

安卓 Compose 相對傳統 View 的優勢

安卓 Compose 相對傳統 View 的優勢 文章目錄 安卓 Compose 相對傳統 View 的優勢1. 引言2. 核心概念&#xff1a;Compose的革新性設計2.1 Jetpack Compose2.2 傳統安卓View系統 3. 開發體驗&#xff1a;Compose大幅提升效率3.1 使用Jetpack Compose構建UI3.2 使用傳統View系統…

SIEMENS PLC 程序 GRAPH 程序解讀 車型入庫

1、程序載圖1 2、程序截圖2 3、程序解釋 這是一個基于西門子 GRAPH 編程的車型 1 入庫順序控制流程圖&#xff0c;通過狀態機結構&#xff08;狀態框 S 與轉移條件 T&#xff09;描述完整工作流程&#xff0c;具體如下&#xff1a; 整體流程概述 初始化&#xff1a;從 S1&am…

VuePress可以做什么?

VuePress 可以做什么 VuePress 是一個基于 Vue.js 的靜態站點生成器,專注于文檔和內容展示。它結合了 Markdown 的簡潔性和 Vue 的靈活性,適合多種場景的開發需求。以下是 VuePress 的主要用途和功能: 1. 技術文檔網站 VuePress 最初是為編寫 Vue.js 官方文檔而設計的,因…

架構-系統可靠性分析與設計

一、可靠性相關基本概念 1. 可靠性與可用性 可靠性&#xff1a;軟件系統在遇到錯誤、意外操作或系統故障時&#xff0c;仍能維持自身功能特性的能力。 舉例&#xff1a;手機銀行APP在用戶誤操作&#xff08;如快速點擊多次轉賬&#xff09;時&#xff0c;仍能正確處理交易并避…

再談String

1、字符串常量池 1.1 創建對象的思考 下面是兩種創建字符串對象的代碼 public static void main1(String[] args) {String s1 "hello";String s2 "hello";System.out.println(s1 s2);//trueString s3 new String("hello");String s4 new …

《深入淺出ProtoBuf:從環境搭建到高效數據序列化》?

ProtoBuf詳解 1、初識ProtoBuf2、安裝ProtoBuf2.1、ProtoBuf在Windows下的安裝2.2、ProtoBuf在Linux下的安裝 3、快速上手——通訊錄V1.03.1、步驟1&#xff1a;創建.proto文件3.2、步驟2&#xff1a;編譯contacts.proto文件&#xff0c;生成C文件3.3、步驟3&#xff1a;序列化…

基于PHP+Uniapp的互聯網醫院源碼:電子處方功能落地方案

隨著“互聯網醫療”政策紅利持續釋放&#xff0c;互聯網醫院已成為推動醫療數字化轉型的重要方向。在這一趨勢下&#xff0c;電子處方功能模塊作為核心環節&#xff0c;不僅直接關系到線上問診閉環的實現&#xff0c;也成為系統開發中技術難度較高、業務邏輯最為復雜的一部分。…

ARM Cortex-M (STM32)如何調試HardFault

目錄 步驟 1: 實現一個有效的 HardFault 處理程序 步驟 2: 復現 HardFault 并使用調試器分析 步驟 3: 解讀故障信息 步驟 4: 定位并修復源代碼 HardFault 是 ARM Cortex-M 處理器中的一種異常。當處理器遇到無法處理的錯誤&#xff0c;或者配置為處理特定類型錯誤&#xff…

基于歸納共形預測的大型視覺-語言模型中預測集的**數據驅動校準**

摘要 本研究通過分離共形預測&#xff08;SCP&#xff09;框架&#xff0c;解決了大型視覺語言模型&#xff08;LVLMs&#xff09;在視覺問答&#xff08;VQA&#xff09;任務中幻覺緩解的關鍵挑戰。雖然LVLMs在多模態推理方面表現出色&#xff0c;但它們的輸出常常表現出具有…

LangChain4j 搭配 Kotlin:以協程、流式交互賦能語言模型開發

Kotlin 支持 | LangChain4j Kotlin 是一種面向 JVM&#xff08;及其他平臺&#xff09;的靜態類型語言&#xff0c;能夠實現簡潔優雅的代碼&#xff0c;并與 Java 庫無縫互操作。 LangChain4j 利用 Kotlin 擴展和類型安全構建器來增強 Java API&#xff0c;為其增添特定于 Ko…

正大模型視角下的市場結構判斷邏輯

正大模型視角下的市場結構判斷邏輯 在多數交易策略中&#xff0c;結構識別往往先于方向判斷。以正大的數據研判風格為例&#xff0c;其核心邏輯是&#xff1a;價格行為不能孤立解讀&#xff0c;必須結合時間與成交效率來判斷當前結構的有效性。 例如&#xff0c;一個上漲過程&…

Django 入門實戰:從環境搭建到構建你的第一個 Web 應用

Django 入門實戰&#xff1a;從環境搭建到構建你的第一個 Web 應用 恭喜你選擇 Django 作為你學習 Python Web 開發的起點&#xff01;Django 是一個強大、成熟且功能齊全的框架&#xff0c;非常適合構建中大型的 Web 應用程序。本篇將通過一個簡單的例子&#xff0c;帶你走完…

Unity 打包后 無陰影 陰影不顯示

在項目設置里面->質量 這里面顯示的是打包之后的質量 PS:注意運行質量 點擊左鍵選擇運行質量,這倆不一致就會導致,運行有陰影但是打包出來的平臺沒有陰影,原因就在這. 質量等級選擇好之后 往下滑,在這里打開陰影,如果距離過遠不顯示陰影,就增加陰影距離.

python——面向對象編程

一、編程思想 面向過程編程&#xff08;典型&#xff1a;c語言&#xff09;&#xff1a;是一種以過程為中心的編程思想。它強調流程化、線性化、步驟化的思考方式&#xff0c;實現思路就是函數。 面向對象編程&#xff1a;強調整體性和差異性。它將任何事物看做一個統一整個&…

宿主機和容器 ping 不通域名解決方法

目錄 一、問題描述 二、宿主機解決方法 三、容器解決辦法 一、問題描述 宿主機是Ubuntu&#xff0c;在宿主機上 ping 不通域名&#xff1a;xxxx.cn&#xff0c;但是個人電腦能 ping 通。 同時宿主機上的啟動的k8s容器也無法ping通。 二、宿主機解決方法 ①編輯文件&#xff…

windows作業job介紹

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄 前言一、作業job是什么&#xff1f;二、使用步驟1.代碼示例 總結 前言 提示&#xff1a;這里可以添加本文要記錄的大概內容&#xff1a; winapi網站&#xff1a; h…

ESG跨境電商如何為國內的跨境電商企業打開國外的市場

現在不管是國內還是國外&#xff0c;做電商的企業都非常的多&#xff0c;那么既然有這么多大電商公司&#xff0c;就要有為這些電商公司提供服務的公司&#xff0c;這就是ESG&#xff0c;它是專門為跨境電商服務的公司&#xff0c;那么這家公司的主要業務是什么呢&#xff1f;它…