国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

k8s部署elk+filebeat;springCloud集成elk+filebeat+kafka+zipkin實現(xiàn)多個服務(wù)日志鏈路追蹤聚合到es

這篇具有很好參考價值的文章主要介紹了k8s部署elk+filebeat;springCloud集成elk+filebeat+kafka+zipkin實現(xiàn)多個服務(wù)日志鏈路追蹤聚合到es。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

一、目的

如今2023了,大多數(shù)javaweb架構(gòu)都是springboot微服務(wù),一個前端功能請求后臺可能是多個不同的服務(wù)共同協(xié)做完成的。例如用戶下單功能,js轉(zhuǎn)發(fā)到后臺網(wǎng)關(guān)gateway服務(wù),然后到鑒權(quán)spring-sercurity服務(wù),然后到業(yè)務(wù)訂單服務(wù),然后到支付服務(wù),后續(xù)還有發(fā)貨、客戶標(biāo)簽等等服務(wù)。
其中每個服務(wù)會啟動多個實例做負(fù)載均衡,這樣一來我們想看這個功能的完成流程日志,需要找到對應(yīng)的服務(wù)器ip,日志文件在哪,其中又要確定具體負(fù)載轉(zhuǎn)發(fā)到哪些臺服務(wù)器上了。 如果是生產(chǎn)問題想要快速定位原因,需要一套解決方案!
k8s部署elk+filebeat;springCloud集成elk+filebeat+kafka+zipkin實現(xiàn)多個服務(wù)日志鏈路追蹤聚合到es,Java,spring cloud,elk,kafka

二、涉及技術(shù)棧

  1. 基本架構(gòu):spring cloud(springBoot+服務(wù)發(fā)現(xiàn)+網(wǎng)關(guān)+負(fù)載熔斷等netflex)。本人目前使用的是springboot+eureka+gateway+springSercurity+openfeign+springConfig 配合業(yè)務(wù)功能涉及中間件redis、quartz、kafka、mysql、elasticsearch
  2. 日志采集處理展現(xiàn):ELK
    • elasticsearch:海量json數(shù)據(jù)存儲即席查詢
    • logstash: 源頭采集數(shù)據(jù)(tcp、file、redis、mq)、格式化處理、推送es存儲
    • kibana: 官方es可視化交互curd工具
  3. 高效輕量數(shù)據(jù)采集工具: filebeat。 監(jiān)控日志文件實時獲取,可以推送到kafka
  4. kafka:接收filebeat數(shù)據(jù),供logstash消費
  5. 多服務(wù)鏈路追蹤:sleuth-zipkin。無代碼侵入。簡單來說就是打印的日志內(nèi)容新增了tranceId、spanId。例如 k8s部署elk+filebeat;springCloud集成elk+filebeat+kafka+zipkin實現(xiàn)多個服務(wù)日志鏈路追蹤聚合到es,Java,spring cloud,elk,kafka

三、流程

  1. js發(fā)起ajax請求后臺網(wǎng)關(guān)服務(wù)

  2. 網(wǎng)關(guān)服務(wù)集成了maven<artifactId>spring-cloud-starter-zipkin</artifactId>依賴,會自動給當(dāng)前的請求header中添加tranceId字段和spanId字段。這兩個字段值隨機(jī)生成。其中tranceId等于spanId在header中沒有這兩個字段的時候:例如tranceId=123a,spanId=123a 并添加到header中。并且打印日志的時候會把這個信息打印出來

  3. 之后網(wǎng)關(guān)根據(jù)請求路徑轉(zhuǎn)發(fā)到業(yè)務(wù)服務(wù)A,A服務(wù)的zipkin發(fā)現(xiàn)header中有tranceId信息,就只生成spanId,例如tranceId=123a,spanId=231b 并添加到header中。并且打印日志的時候會把這個信息打印出來。

  4. A服務(wù)又rpc調(diào)用了B服務(wù)。B服務(wù)的zipkin發(fā)現(xiàn)header中有tranceId信息,就只生成spanId,例如tranceId=123a,spanId=342h 并添加到header中。并且打印日志的時候會把這個信息打印出來。

  5. 調(diào)用完結(jié)返回前端響應(yīng)。

  6. 到此服務(wù)器的日志文件就會新增上述的日志。然后filebeat工具監(jiān)聽到了各個服務(wù)的新日志,讀取并推送到kafka

  7. 消息隊列的topic下生產(chǎn)新數(shù)據(jù),logstash工具提前配置并啟動消費kafka, 處理并保存數(shù)據(jù)到elasticsearch。這里好奇為什么不直接通過filebeat直接推送es,或者springboot的log框架直接通過appender直接推送es呢?

    • 使用filebeat解耦,不影響springboot性能。并且輕量
    • 使用kafka是應(yīng)對大量并發(fā)數(shù)據(jù),減少logstash壓力
    • 最終經(jīng)過logstash推送es是為了加工格式化源數(shù)據(jù),再保存到es,這樣更加方便es查詢?nèi)罩?/li>
  8. 持久化es之后,通過kibana查詢?nèi)罩荆樵儣l件是tranceId=123a即可查詢出完整的日志。

四、整合配置filebeat、kafka、logstash例子

我分了兩部分,有些是部署在服務(wù)器上的jar,我就通過filebeat采集;有些是部署到本地筆記本上的服務(wù),直接在logback.xml配置一個appender輸出到kafka,不經(jīng)過filebeat。

  1. java的pom引入依賴
<dependency>
    <groupId>net.logstash.logback</groupId>
    <artifactId>logstash-logback-encoder</artifactId>
    <version>6.6</version>
</dependency>
  1. logback-spring.xml文件配置輸出格式(部分內(nèi)容)
        <appender name="fileUserLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <!--   配置我們自己寫的包的日志信息,目的是為了方便查看自己的類日志,此日志文件只有我們自己的的log         -->
            <File>${logdir}/user.${appname}.${serverport}.${KPHOSTNAME}.log</File>
            <!--滾動策略,按照時間滾動 TimeBasedRollingPolicy-->
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <!--文件路徑,定義了日志的切分方式——把每一天的日志歸檔到一個文件中,以防止日志填滿整個磁盤空間-->
                <FileNamePattern>${logdir}/history/user.${appname}.${serverport}.%d{yyyy-MM-dd}.${KPHOSTNAME}.log</FileNamePattern>
                <!--只保留最近90天的日志-->
                <maxHistory>90</maxHistory>
                <!--用來指定日志文件的上限大小,那么到了這個值,就會刪除舊的日志-->
                <totalSizeCap>1GB</totalSizeCap>
            </rollingPolicy>
            <!--日志輸出編碼格式化-->
            <encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
                <providers>
                    <pattern>
                        <pattern>
                            {
                            "dateTime": "%d{yyyy-MM-dd HH:mm:ss.SSS}",
                            "message": "%message",
                            "stackTrace": "%exception",
                            "level": "%level",
                            "traceId": "%X{X-B3-TraceId:-}",
                            "spanId": "%X{X-B3-SpanId:-}",
                            "service": "${appname}",
                            "thread": "%thread",
                            "class": "%logger.%method[%line]"
                            }
                        </pattern>
                    </pattern>
                    <timestamp>
                        <timeZone>GMT+8</timeZone>
                    </timestamp>
                </providers>
            </encoder>
        </appender>

logstash.conf

input {
  kafka{
    bootstrap_servers => "ssx-kafka-dmsv.ssx:9092"
    client_id => "logstash_kafka_consumer_id"
    group_id => "logstash_kafka_consumer_group"
    auto_offset_reset => "latest" 
    consumer_threads => 1
    decorate_events => true 
    topics => ["logstash"]
  }
}

filter {
  json {
    source => "message"
  }
} 

output{
    elasticsearch{
    hosts => ["ssx-elk-dmsv.ssx:9200"]
    index => "logstash-%{+YYYY.MM.dd}"
    }
}

kibana

$ cat kibana.yml 
server.host: "0.0.0.0"
server.shutdownTimeout: "5s"
elasticsearch.hosts: [ "http://localhost:9200" ]
monitoring.ui.container.elasticsearch.enabled: true
i18n.locale: "zh-CN"

$ cat node.options 
--unhandled-rejections=warn
--dns-result-order=ipv4first
## enable OpenSSL 3 legacy provider
#--openssl-legacy-provider

filebeat.yml

filebeat.modules:
filebeat.inputs:
- type: log
  enabled: true
  paths:
    - /spring-boot-logs/*/user.*.log
  #include_lines: ["^ERR", "^WARN"]
      # 適用于日志中每一條日志占據(jù)多行的情況,比如各種語言的報錯信息調(diào)用棧
  multiline:
    pattern: '^[[:space:]]'
    negate: false
    match: after

processors:
  - drop_fields:
      fields: ["metadata", "prospector", "offset", "beat", "source","type"]

output.kafka:
  hosts: ["ssx-kafka-dmsv.ssx:9092"]
  topic: logstash
  codec.format:
    string: '%{[message]}'

日志文件內(nèi)容,我想看這個請求完整的流程
k8s部署elk+filebeat;springCloud集成elk+filebeat+kafka+zipkin實現(xiàn)多個服務(wù)日志鏈路追蹤聚合到es,Java,spring cloud,elk,kafka
k8s部署elk+filebeat;springCloud集成elk+filebeat+kafka+zipkin實現(xiàn)多個服務(wù)日志鏈路追蹤聚合到es,Java,spring cloud,elk,kafka文章來源地址http://www.zghlxwxcb.cn/news/detail-563735.html

k8s的yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: ssx-elk-dmsv
  namespace: ssx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ssx-elk-dmsv
  template:
    metadata:
      labels:
        app: ssx-elk-dmsv
    spec:
      hostAliases:
        - ip: "192.168.0.101"
          hostnames:
            - "node101"
        - ip: "192.168.0.102"
          hostnames:
            - "node102"
        - ip: "192.168.0.103"
          hostnames:
            - "node103"
        - ip: "127.0.0.1"
          hostnames:
            - "elasticsearch"
      containers:
        - name: ssx-elasticsearch8-c
          image: docker.elastic.co/elasticsearch/elasticsearch:8.10.2
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 9200
          env:   #容器運行前需設(shè)置的環(huán)境變量列表
            - name: discovery.type  #環(huán)境變量名稱
              value: "single-node" #環(huán)境變量的值 這是mysqlroot的密碼 因為是純數(shù)字,需要添加雙引號 不然編譯報錯
            - name: xpack.security.enabled  #禁用登錄驗證
              value: "false" #環(huán)境變量的值 這是mysqlroot的密碼 因為是純數(shù)字,需要添加雙引號 不然編譯報錯
            - name: ES_JAVA_OPTS
              value: -Xms512m -Xmx512m
          volumeMounts:
            - mountPath: /usr/share/elasticsearch/data   #這是mysql容器內(nèi)保存數(shù)據(jù)的默認(rèn)路徑
              name: c-v-path-elasticsearch8-data
            - mountPath: /usr/share/elasticsearch/logs   #這是mysql容器內(nèi)保存數(shù)據(jù)的默認(rèn)路徑
              name: c-v-path-elasticsearch8-logs
            - mountPath: /usr/share/elasticsearch/.cache   #這是mysql容器內(nèi)保存數(shù)據(jù)的默認(rèn)路徑
              name: c-v-path-elasticsearch8-cache
            - mountPath: /etc/localtime   #時間同步
              name: c-v-path-lt
        - name: ssx-kibana-c
          image: docker.elastic.co/kibana/kibana:8.10.2
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 5601  # 開啟本容器的80端口可訪問
          volumeMounts:
            - mountPath: /usr/share/kibana/data   #無用,我先看看那些掛載需要
              name: c-v-path-kibana8-data
            - mountPath: /usr/share/kibana/config
              name: c-v-path-kibana8-config
            - mountPath: /etc/localtime   #時間同步
              name: c-v-path-lt
        - name: ssx-logstash-c
          image: docker.elastic.co/logstash/logstash:8.10.2
          imagePullPolicy: IfNotPresent
          env:   #容器運行前需設(shè)置的環(huán)境變量列表
            - name: xpack.security.enabled  #禁用登錄驗證
              value: "false" #環(huán)境變量的值 這是mysqlroot的密碼 因為是純數(shù)字,需要添加雙引號 不然編譯報錯
            - name: LOG_LEVEL  #禁用登錄驗證
              value: "info" #環(huán)境變量的值 這是mysqlroot的密碼 因為是純數(shù)字,需要添加雙引號 不然編譯報錯
            - name: MONITORING_ENABLED  #禁用登錄驗證
              value: "false" #環(huán)境變量的值 這是mysqlroot的密碼 因為是純數(shù)字,需要添加雙引號 不然編譯報錯
          args: ["-f","/myconf/logstash.conf"]
          volumeMounts:
            - mountPath: /myconf   #配置
              name: c-v-path-logstash8-conf
            - mountPath: /usr/share/logstash/data   #data
              name: c-v-path-logstash8-data
            - mountPath: /etc/localtime   #時間同步
              name: c-v-path-lt
        - name: ssx-filebeat-c
          image: docker.elastic.co/beats/filebeat:8.10.2
          imagePullPolicy: IfNotPresent
          volumeMounts:
            - mountPath: /usr/share/filebeat/filebeat.yml   #配置
              name: c-v-path-filebeat8-conf
            - mountPath: /usr/share/filebeat/data  #配置
              name: c-v-path-filebeat8-data
            - mountPath: /spring-boot-logs  #data
              name: c-v-path-filebeat8-spring-logs
            - mountPath: /etc/localtime   #時間同步
              name: c-v-path-lt
      volumes:
        - name: c-v-path-elasticsearch8-data #和上面保持一致 這是本地的文件路徑,上面是容器內(nèi)部的路徑
          hostPath:
            path: /home/app/apps/k8s/for_docker_volume/elk/elasticsearch8/data  #此路徑需要實現(xiàn)創(chuàng)建 注意要給此路徑授權(quán)777權(quán)限 不然pod訪問不到
        - name: c-v-path-elasticsearch8-logs #和上面保持一致 這是本地的文件路徑,上面是容器內(nèi)部的路徑
          hostPath:
            path: /home/app/apps/k8s/for_docker_volume/elk/elasticsearch8/logs  #此路徑需要實現(xiàn)創(chuàng)建 注意要給此路徑授權(quán)777權(quán)限 不然pod訪問不到
        - name: c-v-path-elasticsearch8-cache #和上面保持一致 這是本地的文件路徑,上面是容器內(nèi)部的路徑
          hostPath:
            path: /home/app/apps/k8s/for_docker_volume/elk/elasticsearch8/.cache  #此路徑需要實現(xiàn)創(chuàng)建 注意要給此路徑授權(quán)777權(quán)限 不然pod訪問不到
        - name: c-v-path-kibana8-data #和上面保持一致 這是本地的文件路徑,上面是容器內(nèi)部的路徑
          hostPath:
            path: /home/app/apps/k8s/for_docker_volume/elk/kibana8/data  #此路徑需要實現(xiàn)創(chuàng)建 注意要給此路徑授權(quán)777權(quán)限 不然pod訪問不到
        - name: c-v-path-kibana8-config #和上面保持一致 這是本地的文件路徑,上面是容器內(nèi)部的路徑
          hostPath:
            path: /home/app/apps/k8s/for_docker_volume/elk/kibana8/config  #此路徑需要實現(xiàn)創(chuàng)建 注意要給此路徑授權(quán)777權(quán)限 不然pod訪問不到
        - name: c-v-path-logstash8-conf
          hostPath:
            path: /home/app/apps/k8s/for_docker_volume/elk/logstash8/myconf
        - name: c-v-path-logstash8-data
          hostPath:
            path: /home/app/apps/k8s/for_docker_volume/elk/logstash8/data
        - name: c-v-path-lt
          hostPath:
            path: /etc/localtime   #時間同步
        - name: c-v-path-filebeat8-conf
          hostPath:
            path: /home/app/apps/k8s/for_docker_volume/elk/filebeat8/myconf/filebeat.yml
        - name: c-v-path-filebeat8-data
          hostPath:
            path: /home/app/apps/k8s/for_docker_volume/elk/filebeat8/data
        - name: c-v-path-filebeat8-spring-logs
          hostPath:
            path: /home/ssx/appdata/ssx-log/docker-log
      nodeSelector: #把此pod部署到指定的node標(biāo)簽上
        kubernetes.io/hostname: node101
---
apiVersion: v1
kind: Service
metadata:
  name: ssx-elk-dmsv
  namespace: ssx
spec:
  ports:
    - port: 9200
      name: ssx-elk8-9200
      protocol: TCP
      targetPort: 9200
    - port: 5601 #我暫時不理解,這個設(shè)置 明明沒用到?
      name: ssx-kibana8
      protocol: TCP
      targetPort: 5601 # 容器nginx對外開放的端口 上面的dm已經(jīng)指定了
  selector:
    app: ssx-elk-dmsv
  type: ClusterIP

到了這里,關(guān)于k8s部署elk+filebeat;springCloud集成elk+filebeat+kafka+zipkin實現(xiàn)多個服務(wù)日志鏈路追蹤聚合到es的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • k8s部署 elk(Elasticsearch,Kibana,Logstash,Redis,Filebea)

    目錄 一、nfs存儲 二、部署鏡像,制作tag 三、?filebeat收集數(shù)據(jù) ?四、logstash過濾數(shù)據(jù) 五、elasticsearch存儲數(shù)據(jù)+nfs做存儲(自動注冊pv詳見前文) 六、kibana展示數(shù)據(jù) 七、驗證安裝 參考鏈接:k8s 配置hadoop集群,nfs作為存儲_瘋飆的蝸牛的博客-CSDN博客

    2024年02月11日
    瀏覽(21)
  • Jenkins K8S Docker 一鍵部署SpringCloud微服務(wù)

    Jenkins K8S Docker 一鍵部署SpringCloud微服務(wù)

    一鍵部署springcloud微服務(wù),需要用到 Jenkins K8S Docker等工具,若未安裝,請參考《Centos 7 安裝K8S》 本文使用jenkins部署,流程如下圖 開發(fā)者將代碼push到git 運維人員通過jenkins部署,自動到git上pull代碼 通過maven構(gòu)建代碼 將maven構(gòu)建后的jar打包成docker鏡像 并 push docker鏡像到docker

    2024年02月02日
    瀏覽(26)
  • k8s kafka部署實戰(zhàn)

    k8s kafka部署實戰(zhàn)

    魚弦:CSDN內(nèi)容合伙人、CSDN新星導(dǎo)師、51CTO(Top紅人+專家博主) 、github開源愛好者(go-zero源碼二次開發(fā)、游戲后端架構(gòu) https://github.com/Peakchen) ? Kubernetes (k8s) 是一個用于自動化容器操作的開源平臺,而 Kafka 是一個分布式流數(shù)據(jù)處理平臺。在 k8s 上部署 Kafka 可以使得 Kafka 的部署

    2024年02月11日
    瀏覽(23)
  • 持續(xù)集成部署-k8s-部署利器-Helm

    Helm 是一個用于 Kubernetes 應(yīng)用程序部署和管理的開源工具。它可以幫助簡化 Kubernetes 應(yīng)用程序的打包、發(fā)布、配置和升級過程。 Helm 使用稱為 “ chart ” 的預(yù)定義模板來定義應(yīng)用程序的結(jié)構(gòu)和配置,并提供了命令行工具來管理這些 charts 。 Helm 的重要概念: Charts :是創(chuàng)建 Ku

    2024年02月06日
    瀏覽(25)
  • 持續(xù)集成部署-K8s 簡單使用

    這里將 HTTPD 服務(wù)映射到 Kubernetes 集群的 8080 端口上,直接在Master節(jié)點上操作即可。 創(chuàng)建一個名為 httpd-deployment.yaml 的 YAML 文件,內(nèi)容如下:

    2024年02月12日
    瀏覽(32)
  • 部署ELK+Kafka+Filebeat日志收集分析系統(tǒng)

    部署ELK+Kafka+Filebeat日志收集分析系統(tǒng)

    ELK是三個軟件的統(tǒng)稱,即Elasticsearch、Logstash和Kibana三個開源軟件的縮寫。這三款軟件都是開源軟件,通常配合使用,并且都先后歸于Elastic.co企業(yè)名下,故被簡稱為ELK協(xié)議棧。ELK主要用于部署在企業(yè)架構(gòu)中,收集多臺設(shè)備上多個服務(wù)的日志信息,并將其統(tǒng)一整合后提供給用戶。

    2024年02月16日
    瀏覽(22)
  • 在Kubernetes(k8s)上部署整個SpringCloud微服務(wù)應(yīng)用

    在Kubernetes(k8s)上部署整個SpringCloud微服務(wù)應(yīng)用

    視頻教程地址:https://www.bilibili.com/video/BV1Xh4y1q7aW/ 這次我準(zhǔn)備了一個微服務(wù)項目,是依照RuoYi-Cloud(http://doc.ruoyi.vip/ruoyi-cloud/)進(jìn)行了一些修改所得到的微服務(wù)項目。重點是修改了如圖根據(jù)不同環(huán)境添加了不同的配置文件: 項目代碼地址為:https://gitcode.net/m0_51510236/yueyang-cloud 我

    2024年02月05日
    瀏覽(16)
  • Zookeeper、Kafka集群與Filebeat+Kafka+ELK架構(gòu)、部署實例

    Zookeeper、Kafka集群與Filebeat+Kafka+ELK架構(gòu)、部署實例

    Zookeeper是一個開源的分布式的,為分布式框架提供協(xié)調(diào)服務(wù)的Apache項目。 Zookeeper:一個領(lǐng)導(dǎo)者(Leader),多個跟隨者(Follower)組成的集群。 Zookeeper集群中只要有半數(shù)以上節(jié)點存活,Zookeeper集群就能正常服務(wù)。所以Zookeeper適合安裝奇數(shù)臺服務(wù)器。 全局?jǐn)?shù)據(jù)一致:每個Server保

    2024年02月08日
    瀏覽(27)
  • k8s的jenkins部署java項目到k8s集群cicd持續(xù)集成

    k8s的jenkins部署java項目到k8s集群cicd持續(xù)集成

    k8s1.16.0-k8s的jenkins部署java項目到k8s集群cicd(ci成,cd手動部署的) 注意: 本文檔只是實現(xiàn)了ci,cd是通過ci生成的鏡像,再手工再k8s-master執(zhí)行的部署(只因pod部署的jenkins連接k8s的認(rèn)證不知怎么操作,若jenkins是單獨部署在k8s-master機(jī)器上,能直接在master執(zhí)行kubectl命令就沒這個問題了

    2024年02月03日
    瀏覽(37)
  • 【ELK 使用指南 3】Zookeeper、Kafka集群與Filebeat+Kafka+ELK架構(gòu)(附部署實例)

    【ELK 使用指南 3】Zookeeper、Kafka集群與Filebeat+Kafka+ELK架構(gòu)(附部署實例)

    分布式應(yīng)用管理框架 。 Zookeeper是個開源的,分布式的,為分布式框架提供協(xié)調(diào)服務(wù)的Apach項目。 主要用于解決分布式應(yīng)用集群中 應(yīng)用系統(tǒng)的一致性問題 。 作為 文件系統(tǒng) ,用于注冊各種分布式應(yīng)用, 儲存管理分布式應(yīng)用的元信息 ; 作為 通知機(jī)制 ,如果節(jié)點或者服務(wù)本身的

    2024年02月08日
    瀏覽(54)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包