kubernetes(4) 微服務

一、什么是微服務

在 Kubernetes 中,控制器負責維持業務副本,但真正把業務“暴露”出去的是 Service
一句話理解:

  • Service = 一組 Pod 的穩定訪問入口 + 4 層負載均衡

  • Ingress = 7 層路由 + 統一入口 + 灰度 / 認證 / 重寫等高級能力

默認情況下,Service 僅具備 4 層(TCP/UDP)能力,如需 7 層(HTTP/HTTPS)請使用 Ingress。


二、微服務(Service)的四種類型總覽

類型作用與適用場景
ClusterIP默認值,集群內部虛擬 IP;僅供集群內部訪問,自動 DNS 與服務發現。
NodePort在每個節點打開固定端口(30000-32767),外部通過?節點IP:端口?即可訪問服務。
LoadBalancer基于 NodePort,再申請外部云負載均衡(或 MetalLB);適用于公有云或裸金屬+MetalLB。
ExternalName將集群內請求通過 CNAME 轉發到任意指定域名;常用于外部服務遷移或跨集群調用。

三、Service 的默認實現:iptables vs IPVS

  • iptables 模式(默認)

    • 規則多、刷新慢,萬級 Pod 場景下 CPU 抖動明顯。

  • IPVS 模式(推薦生產)

    • 內核級四層負載,支持 10w+ 連接,性能穩定。

    • 切換后自動生成虛擬網卡 kube-ipvs0,所有 ClusterIP 被綁定到該接口。

3.1 一鍵切換到 IPVS 模式

1.所有節點安裝工具

yum install ipvsadm -y

2.修改 kube-proxy 配置

    kubectl -n kube-system edit cm kube-proxy
    # 找到 mode 字段,改為 "ipvs"

    如果什么都沒有,說明是默認的使用iptables,這里我們加上ipvs

    修改配置后,要重啟,這里可以刪掉之前的網絡配置pod,重新刷新新的pod出來,此時就是新策略的pod

    3.滾動重啟 kube-proxy Pod

      kubectl -n kube-system get pods | awk '/kube-proxy/{system("kubectl -n kube-system delete pod "$1)
      }'

      4.驗證

        ipvsadm -Ln | head
        # 出現 10.96.x.x:xx rr 即成功

        四、微服務類型詳解

        4.1 ClusterIP —— 集群內默認訪問方式

        4.1.1 標準 ClusterIP 示例
        apiVersion: v1
        kind: Service
        metadata:labels:app: timingleename: timinglee
        spec:ports:- port: 80          # Service 端口protocol: TCPtargetPort: 80    # Pod 端口selector:app: timinglee    # 綁定到標簽一致的 Podtype: ClusterIP     # 可省略,默認即 ClusterIP
        kubectl apply -f clusterip.yml
        kubectl get svc timinglee
        # NAME      TYPE       CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE
        # timinglee ClusterIP  10.99.127.134 <none>        80/TCP    16s

        clusterip模式只能在集群內訪問,并對集群內的pod提供健康檢測和自動發現功能

        追加內容,此時微服務和控制器就在一個配置文件里了

        只有集群內部的IP,集群外部的不暴露

        4.1.2 DNS 自動解析驗證
        # 集群內部可直接解析
        dig timinglee.default.svc.cluster.local @10.96.0.10
        # ;; ANSWER SECTION:
        # timinglee.default.svc.cluster.local. 30 IN A 10.99.127.134


        4.2 Headless —— 無 ClusterIP 的直連模式

        適用場景:StatefulSet 的穩定網絡標識、客戶端自己做負載均衡、自定義 DNS 策略。

        apiVersion: v1
        kind: Service
        metadata:name: timinglee
        spec:clusterIP: None          # 關鍵字段ports:- port: 80targetPort: 80selector:app: timinglee

        之前有了無頭服務,要刪掉,不然影響實驗

        沒有了IP以后,后端就沒有調度了

        此時我們可以用dns來寫,把要訪問的server直接指定到后端的服務器中去

        #開啟一個busyboxplus的pod測試

        kubectl apply -f headless.yml
        kubectl get svc timinglee
        # NAME      TYPE       CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
        # timinglee ClusterIP  None         <none>        80/TCP    6s

        DNS 結果直接返回所有 Pod IP:

        dig timinglee.default.svc.cluster.local @10.96.0.10
        # ANSWER SECTION:
        # timinglee.default.svc.cluster.local. 20 IN A 10.244.2.14
        # timinglee.default.svc.cluster.local. 20 IN A 10.244.1.18

        4.3 NodePort —— 節點端口暴露

        4.3.1 快速示例
        apiVersion: v1
        kind: Service
        metadata:name: timinglee-service
        spec:type: NodePortports:- port: 80targetPort: 80nodePort: 31771          # 可省略,自動分配 30000-32767selector:app: timinglee
        kubectl apply -f nodeport.yml
        kubectl get svc timinglee-service
        # NAME      TYPE      CLUSTER-IP    EXTERNAL-IP  PORT(S)        AGE
        # timinglee NodePort 10.98.60.22   <none>       80:31771/TCP   8s

        之前的服務設置了無頭服務,這里要刪除之前環境,重新運行

        多了一個端口

        這個端口用來直接對外暴露

        外部訪問測試:

        curl 172.25.254.100:31771/hostname.html
        # timinglee-c56f584cf-fjxdk

        nodeport在集群節點上綁定端口,一個端口對應一個服務

        直接負載到下面兩個

        用clusterip來訪問后端的

        訪問模式

        對應的端口是不固定的,但是我們可以直接指定,但是有范圍限制最大30000

        但是想要超過限制也可以,修改配置文件就行。但是集群會掛掉,要等待自愈

        加上這句話- --service-node-port-range=30000-40000

        剛剛還不能超過的限制,現在就可以了

        NodePort 默認端口范圍 30000-32767;如需自定義范圍,請修改 kube-apiserver 參數 --service-node-port-range=30000-40000

        4.4 LoadBalancer —— 云或裸金屬的外部 VIP

        4.4.1 公有云場景
        apiVersion: v1
        kind: Service
        metadata:name: timinglee-service
        spec:type: LoadBalancerports:- port: 80targetPort: 80selector:app: timinglee

        云廠商(AWS/GCP/阿里云) 上,提交 YAML 后會自動為 Service 分配一個公網 VIP:

        kubectl get svc timinglee-service
        # NAME      TYPE           CLUSTER-IP     EXTERNAL-IP      PORT(S)        AGE
        # timinglee LoadBalancer  10.107.23.134  203.0.113.10     80:32537/TCP   4s
        4.4.2 裸金屬場景:MetalLB

        MetalLB 為裸金屬或私有集群實現 LoadBalancer 功能。

        ① 安裝 MetalLB
        # 1) 確保 kube-proxy 為 IPVS 模式(見第 3.1 節)
        kubectl edit cm -n kube-system kube-proxy   # mode: "ipvs"
        kubectl -n kube-system get pods | awk '/kube-proxy/{system("kubectl -n kube-system delete pod "$1)}'# 2) 下載官方清單
        wget https://raw.githubusercontent.com/metallb/metallb/v0.13.12/config/manifests/metallb-native.yaml# 3) 修改鏡像地址(私有倉庫)
        sed -i 's#quay.io/metallb/controller:v0.14.8#reg.timinglee.org/metallb/controller:v0.14.8#' \metallb-native.yaml
        sed -i 's#quay.io/metallb/speaker:v0.14.8#reg.timinglee.org/metallb/speaker:v0.14.8#' \metallb-native.yaml# 4) 推送鏡像到 Harbor
        docker pull quay.io/metallb/controller:v0.14.8
        docker pull quay.io/metallb/speaker:v0.14.8
        docker tag ... && docker push ...# 5) 部署
        kubectl apply -f metallb-native.yaml
        kubectl -n metallb-system wait --for=condition=ready pod -l app=metallb --timeout=120s
        ② 配置 IP 地址池
        # configmap.yml
        apiVersion: metallb.io/v1beta1
        kind: IPAddressPool
        metadata:name: first-poolnamespace: metallb-system
        spec:addresses:- 172.25.254.50-172.25.254.99     # 與本地網絡同段
        ---
        apiVersion: metallb.io/v1beta1
        kind: L2Advertisement
        metadata:name: examplenamespace: metallb-system
        spec:ipAddressPools:- first-pool
        kubectl apply -f configmap.yml

        再次查看 Service:

        kubectl get svc timinglee-service
        # NAME      TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)        AGE
        # timinglee LoadBalancer  10.109.36.123   172.25.254.50   80:31595/TCP   9m9s

        集群外直接訪問 VIP:

        curl 172.25.254.50
        # Hello MyApp | Version: v1 | ...

        部署安裝

        必須要把集群做成ipvs的模式

        并且重啟網絡方面的pod

        這個文檔里的路徑已經修改好了,如果是未修改的,記得把路徑換成自己的軟件倉庫

        這個生效了之后,才能改配置

        之前這里還是正在生效,現在已經有了IP

        #通過分配地址從集群外訪問服務

        已經自動分配對外IP


        4.5 ExternalName —— DNS CNAME 轉發

        開啟services后,不會被分配IP,而是用dns解析CNAME固定域名來解決ip變化問題

        一般應用于外部業務和pod溝通或外部業務遷移到pod內時

        在應用向集群遷移過程中,externalname在過度階段就可以起作用了。

        集群外的資源遷移到集群時,在遷移的過程中ip可能會變化,但是域名+dns解析能完美解決此問題

        • 業務尚在集群外(如 RDS、COS、第三方 API)。

        • 遷移過程中保持調用方 域名不變,僅改 DNS 指向。

        apiVersion: v1
        kind: Service
        metadata:name: timinglee-service
        spec:type: ExternalNameexternalName: www.timinglee.org   # 目的域名
        kubectl apply -f externalname.yml
        kubectl get svc timinglee-service
        # NAME      TYPE           CLUSTER-IP   EXTERNAL-IP         PORT(S)   AGE
        # timinglee ExternalName   <none>       www.timinglee.org   <none>    2m58s

        集群內 Pod 訪問 timinglee-service 時,DNS 會直接返回 www.timinglee.org 的地址,無需維護 IP 變化。

        集群內部的IP在訪問時,做的是域名解析

        把真實的微服務轉化成其他主機上

        沒有IP時如何被訪問的,通過dns的域名解析

        驗證 DNS 解析

        這行命令測試 Kubernetes 集群內部 DNS(10.96.0.10是集群 DNS 服務的 IP)是否能正確解析ext-service對應的域名:

        結果顯示ext-service.default.svc.cluster.local(集群內部服務域名)被解析為www.baidu.com
        最終解析到百度的實際 IP 地址(103.235.46.115和103.235.46.102)

        得到了集群內部的主機

        微服務把集群外部的資源映射到集群內部,讓集群內部可以使用


        五、Ingress-Nginx 全景實戰

        Ingress = 7 層路由 + 多域名 + 灰度 + 認證 + TLS + 重寫

        在service前面在加一個nginx

        在集群暴露時,再加一個反向代理

        一種全局的、為了代理不同后端 Service 而設置的負載均衡服務,支持7層

        Ingress由兩部分組成:Ingress controller和Ingress服務

        Ingress Controller 會根據你定義的 Ingress 對象,提供對應的代理能力。

        業界常用的各種反向代理項目,比如 Nginx、HAProxy、Envoy、Traefik 等,都已經為Kubernetes 專門維護了對應的 Ingress Controller。

        5.1 部署 Ingress-Nginx(裸金屬)

        # 1) 下載官方清單
        wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.11.2/deploy/static/provider/baremetal/deploy.yaml# 2) 鏡像同步到私有倉庫
        docker tag registry.k8s.io/ingress-nginx/controller:v1.11.2 \reg.timinglee.org/ingress-nginx/controller:v1.11.2
        docker tag registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.4.3 \reg.timinglee.org/ingress-nginx/kube-webhook-certgen:v1.4.3
        docker push ...# 3) 修改清單中的鏡像地址
        sed -i 's#registry.k8s.io/ingress-nginx/controller#reg.timinglee.org/ingress-nginx/controller#' deploy.yaml
        sed -i 's#registry.k8s.io/ingress-nginx/kube-webhook-certgen#reg.timinglee.org/ingress-nginx/kube-webhook-certgen#' deploy.yaml# 4) 部署 & 等待就緒
        kubectl apply -f deploy.yaml
        kubectl -n ingress-nginx wait --for=condition=ready pod -l app.kubernetes.io/name=ingress-nginx --timeout=120s

        在部署文件里

        上傳ingress所需鏡像到harbor

        運行配置文件,并且查看是否建立了新的命名空間

        此時查看還是沒有對外開放的ip的,因為微服還沒有修改,現在還是只能集群內部訪問

        #修改微服務為loadbalancer

        此時就有對外開放的IP了

        在ingress-nginx-controller中看到的對外IP就是ingress最終對外開放的ip

        測試ingress

        生成一下模板

        上面是控制器,下面是微服務

        默認 Service 類型為 NodePort,如需 LoadBalancer

        kubectl -n ingress-nginx edit svc ingress-nginx-controller
        # 把 type: NodePort 改為 type: LoadBalancer
        kubectl -n ingress-nginx get svc
        # NAME                       TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)
        # ingress-nginx-controller   LoadBalancer   10.103.33.148   172.25.254.50   80:34512/TCP,443:34727/TCP

        5.2 基于路徑的多版本分流

        5.2.1 部署兩套版本業務
        # myapp-v1.yaml
        apiVersion: apps/v1
        kind: Deployment
        metadata:name: myapp-v1
        spec:replicas: 1selector:matchLabels: {app: myapp-v1}template:metadata:labels: {app: myapp-v1}spec:containers:- name: myappimage: myapp:v1
        ---
        apiVersion: v1
        kind: Service
        metadata:name: myapp-v1
        spec:selector:app: myapp-v1ports:- port: 80targetPort: 80
        kubectl apply -f myapp-v1.yaml
        # 同理再建 myapp-v2.yaml(鏡像改為 v2,service 名為 myapp-v2)

        ?

        裝了兩臺主機,兩臺主機呈現不同web頁面

        核心動作都是nginx完成的

        調用nginx類,訪問微服務的80端口

        當我們去訪問我們剛剛設立的對外IP時,它帶我們去看的時myappv1的80端口里的內容

        5.2.2 創建基于路徑的 Ingress
        # ingress-path.yaml
        apiVersion: networking.k8s.io/v1
        kind: Ingress
        metadata:name: ingress-pathannotations:nginx.ingress.kubernetes.io/rewrite-target: /
        spec:ingressClassName: nginxrules:- host: myapp.timinglee.orghttp:paths:- path: /v1pathType: Prefixbackend:service:name: myapp-v1port: {number: 80}- path: /v2pathType: Prefixbackend:service:name: myapp-v2port: {number: 80}
        kubectl apply -f ingress-path.yamlcurl http://myapp.timinglee.org/v1   # Version: v1
        curl http://myapp.timinglee.org/v2   # Version: v2

        此時直接訪問是不行的,因為沒有設定默認發布目錄

        可以設定一下


        5.3 基于域名的多業務入口

        # ingress-domain.yaml
        apiVersion: networking.k8s.io/v1
        kind: Ingress
        metadata:name: ingress-domain
        spec:ingressClassName: nginxrules:- host: myappv1.timinglee.orghttp:paths:- path: /pathType: Prefixbackend:service: {name: myapp-v1, port: {number: 80}}- host: myappv2.timinglee.orghttp:paths:- path: /pathType: Prefixbackend:service: {name: myapp-v2, port: {number: 80}}
        kubectl apply -f ingress-domain.yamlcurl http://myappv1.timinglee.org   # Version: v1
        curl http://myappv2.timinglee.org   # Version: v2

        子集寫在最前面也行,寫最后面也行

        此時我們


        5.4 HTTPS(TLS)一鍵啟用

        5.4.1 自簽證書 & Secret
        openssl req -x509 -newkey rsa:2048 -nodes -keyout tls.key -out tls.crt -days 365 \-subj "/CN=myapp-tls.timinglee.org"kubectl create secret tls web-tls-secret --cert=tls.crt --key=tls.key
        5.4.2 啟用 TLS 的 Ingress
        # ingress-tls.yaml
        apiVersion: networking.k8s.io/v1
        kind: Ingress
        metadata:name: ingress-tls
        spec:ingressClassName: nginxtls:- hosts: [myapp-tls.timinglee.org]secretName: web-tls-secretrules:- host: myapp-tls.timinglee.orghttp:paths:- path: /pathType: Prefixbackend:service: {name: myapp-v1, port: {number: 80}}
        kubectl apply -f ingress-tls.yamlcurl -k https://myapp-tls.timinglee.org   # HTTPS 成功

        生成證書去加密

        設置非交互式輸入

        此時生成的證書與集群無關

        把證書變成資源,能被集群調用

        里面有兩個文件

        查看資源信息,它們以鍵值的方式保存了

        要把加密的模式保存到配置文件中去

        一次性可以給多個設備加密 host

        最終要調用的資源里的證書

        ?

        查看新建的ingress的詳細情況,是否加密成功

        此時直接訪問已經不行了

        https:// 表示使用 HTTPS 協議 訪問,符合 Ingress 配置中強制 HTTPS 的要求,因此不會被重定向。
        -k 參數的作用是 跳過 SSL 證書驗證。如果你的 Ingress 使用的是自簽名證書(而非可信 CA 頒發的證書),curl 會默認驗證證書并報錯(如 SSL certificate problem)。加上 -k 后會忽略證書驗證,從而成功建立連接并獲取響應。


        5.5 Basic Auth 用戶認證

        5.5.1 生成密碼文件并寫入 Secret
        dnf install -y httpd-tools
        htpasswd -cm auth lee        # 輸入兩次密碼
        kubectl create secret generic auth-web --from-file=auth
        5.5.2 在 Ingress 中開啟認證
        # ingress-auth.yaml
        apiVersion: networking.k8s.io/v1
        kind: Ingress
        metadata:name: ingress-authannotations:nginx.ingress.kubernetes.io/auth-type: basicnginx.ingress.kubernetes.io/auth-secret: auth-webnginx.ingress.kubernetes.io/auth-realm: "Please input username and password"
        spec:ingressClassName: nginxtls:- hosts: [myapp-tls.timinglee.org]secretName: web-tls-secretrules:- host: myapp-tls.timinglee.orghttp:paths:- path: /pathType: Prefixbackend:service: {name: myapp-v1, port: {number: 80}}

        用戶級別的訪問限制

        此時的文件還是沒有關系和集群

        要通過這個命令,把這個叫做htpasswd的文件抽象成集群中的資源

        編輯配置文件,要用到參數

        在調用時,也會驗證這些參數

        錯誤情況:

        這里會錯誤,是因為他默認調用auth這個名字,而之前創建用戶密碼時,儲存的文件名不是它,系統此時訪問不了

        修改名字:

        刪除之前儲存的資源

        重新建立資源

        刪除之前運行的配置文件

        重新運行一次就行了

        kubectl apply -f ingress-auth.yamlcurl -k https://myapp-tls.timinglee.org          # 401 Unauthorized
        curl -k -u lee:lee https://myapp-tls.timinglee.org   # 200 OK


        5.6 URL 重寫(Rewrite)與正則

        5.6.1 根路徑重定向
        nginx.ingress.kubernetes.io/app-root: /hostname.html
        5.6.2 正則捕獲與重寫
        # ingress-rewrite.yaml
        metadata:annotations:nginx.ingress.kubernetes.io/use-regex: "true"nginx.ingress.kubernetes.io/rewrite-target: /$2
        spec:rules:- host: myapp-tls.timinglee.orghttp:paths:- path: /lee(/|$)(.*)          # 匹配 /lee 或 /lee/xxxpathType: ImplementationSpecificbackend:service: {name: myapp-v1, port: {number: 80}}
        curl -k -u lee:lee https://myapp-tls.timinglee.org/lee/hostname.html
        # 實際返回 /hostname.html 內容

        匹配正則表達式

        測試:


        六、金絲雀(Canary)發布

        6.1 核心思路

        • 先少量、后全量:降低新版本全量故障風險

        • Ingress-Nginx 支持 Header / Cookie / 權重 三種灰度策略

        • 發布過程 只增不減:Pod 總數 ≥ 期望值,業務無中斷

        6.2 基于 Header 的灰度

        6.2.1 正式流量 Ingress(v1)
        # myapp-v1-ingress.yaml
        apiVersion: networking.k8s.io/v1
        kind: Ingress
        metadata:name: myapp-v1-ingress
        spec:ingressClassName: nginxrules:- host: myapp.timinglee.orghttp:paths:- path: /pathType: Prefixbackend:service: {name: myapp-v1, port: {number: 80}}

        部署老版本的

        升級后的訪問是要基于什么情況下訪問

        要寫參數來設置了

        當攜帶timinglee的值是6時,就訪問new的

        6.2.2 灰度流量 Ingress(v2)
        # myapp-v2-canary-header.yaml
        apiVersion: networking.k8s.io/v1
        kind: Ingress
        metadata:name: myapp-v2-canaryannotations:nginx.ingress.kubernetes.io/canary: "true"nginx.ingress.kubernetes.io/canary-by-header: "version"nginx.ingress.kubernetes.io/canary-by-header-value: "2"
        spec:ingressClassName: nginxrules:- host: myapp.timinglee.orghttp:paths:- path: /pathType: Prefixbackend:service: {name: myapp-v2, port: {number: 80}}
        kubectl apply -f myapp-v1-ingress.yaml
        kubectl apply -f myapp-v2-canary-header.yaml# 測試
        curl http://myapp.timinglee.org                # v1
        curl -H "version: 2" http://myapp.timinglee.org # v2

        6.3 基于權重(Weight)的灰度

        # myapp-v2-canary-weight.yaml
        metadata:annotations:nginx.ingress.kubernetes.io/canary: "true"nginx.ingress.kubernetes.io/canary-weight: "10"   # 10%nginx.ingress.kubernetes.io/canary-weight-total: "100"
        kubectl apply -f myapp-v2-canary-weight.yaml# 100 次采樣腳本
        for i in {1..100}; do curl -s myapp.timinglee.org | grep -c v2; done | awk '{v2+=$1} END{print "v2:"v2", v1:"100-v2}'
        # v2:10, v1:90   # 符合 10% 權重

        腳本測試:

        測試沒有問題了

        就修改權重

        直到最后沒有問題,old的版本就可以刪除了

        調整權重只需修改 annotation 后 kubectl apply,即可實現 平滑全量滾動


        七、一鍵清理

        kubectl delete ingress --all
        kubectl delete svc --all -l app=myapp-v1,app=myapp-v2
        kubectl delete deploy --all -l app=myapp-v1,app=myapp-v2

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

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

        相關文章

        Pandas 2.0 + Arrow 加速、Dask vs Ray、Plotly 可視化:數據分析的未來

        在大數據與人工智能時代,數據分析與可視化的技術棧正在快速演進。過去十年,Pandas 幾乎是數據科學家的“瑞士軍刀”,Matplotlib 和 Seaborn 是最常用的可視化工具。但如今,隨著數據規模與分析需求的增長,新的趨勢正在出現: Pandas 2.0 引入 Apache Arrow 后端,性能顯著提…

        windows擴展(外接)顯示器位置調節

        概述有的時候我們想把屏幕往左或往右拖動&#xff0c;默認情況下&#xff0c;屏幕都是默認往右拖動的&#xff0c;如果想往左拖動&#xff0c;則需要進行設置。具體步驟如下&#xff1a;當然不止這些還可以往上調&#xff0c;下調等多個位置可調至&#xff0c;這里只顯示左右調…

        【分數求和2】

        題目&#xff1a;分數求和&#xff08;1/22/33/44/55/66/77/88/9&#xff09;代碼實現&#xff1a;#include <stdio.h>int main(){double sum 0.0;int i;for(i2;i<10;i){sum((i-1.0)/i);}printf("1/22/33/44/55/66/77/88/9%f\n",sum);return 0;} 注&#x…

        軟件SPI實現(3):SPI協議測試(使用W25Q64)

        0 參考資料 SPI通信協議中文版(SPIV3).pdf 1 SPI協議測試(使用W25Q64) 1.1 測試方法 這里使用W25Q64作為SPI從機,測試實現的軟件SPI工作是否正常。測試步驟如下: (0)使用SPI模式0 (1)使用sw_spi_tx_rx_nbyte API向W25Q64起始地址0寫入32字節數據 (2)使用sw_spi_tx_…

        Redis 04 Reactor

        Reactor 設計模式是事件驅動的并發處理模式&#xff0c;高效處理多個輸入源的請求。多路分解事件&#xff0c;同步分發到處理器。 單線程 reactor 模型 redis6.0 之前采用單線程 reactor 模型。即業務線程完成網絡IO及命令處理。 reactor 模型處理三類事件&#xff1a; 連接事件…

        基于多分類的工業異常聲檢測及應用

        摘 要 隨著工業4.0的快速發展&#xff0c;工業設備的智能化監測與維護成為保障生產安全與效率的關鍵環節。工業異常聲檢測作為一種非侵入式、實時性強的監測手段&#xff0c;能夠有效識別設備運行中的潛在故障&#xff0c;具有重要的應用價值。本文提出了一種基于多分類的工業…

        AirReceiverLite:輕松實現手機隔空投屏

        在多設備互聯的今天&#xff0c;屏幕鏡像功能成為了許多用戶在演示、教學、娛樂等場景中的重要需求。AirReceiverLite作為一款運行在Android平臺上的應用程序&#xff0c;為用戶提供了便捷的解決方案。它允許用戶通過AirPlay協議將iPhone、iPad、Macbook等iOS設備以及Windows P…

        雙指針和codetop復習

        雙指針和codetop復習1.雙指針1.[移動零](https://leetcode.cn/problems/move-zeroes/description/)遞歸1.[計算布爾二叉樹的值](https://leetcode.cn/problems/evaluate-boolean-binary-tree/)2.[Pow(X,n)](https://leetcode.cn/problems/powx-n/)3.[兩兩交換鏈表中的節點](htt…

        抽絲剝繭丨PostgreSQL 系國產數據庫%SYS CPU newfstatat() high 調優一例(一)

        最近一個客戶從 Oracle 遷移到 PostgreSQL 系的國產數據庫后&#xff0c;CPU一直接近100%&#xff0c;但是再仔細分析&#xff0c;發現%system CPU占到60%左右&#xff0c;當然這是一種不正常的現象。之前我寫過《如何在 Linux 上診斷高%Sys CPU》&#xff08;https://www.anbo…

        [Linux] Linux提權管理 文件權限管理

        目錄 Linux提權管理 su命令 準備一個用戶 sudo命令 sudo配置 Linux文件權限管理 文件系統權限介紹 rwx 權限解讀 文件系統權限管理 chmod 命令 針對文件 針對目錄 chown chgrp 命令 驗證文件權限rwx效果 驗證目錄權限rwx效果 權限補充說明 管理文件默認權限 u…

        Kubernetes(2)pod的管理及優化

        【一】Kubernetes 資源管理與操作方式 1.1 資源管理介紹 Kubernetes 把一切抽象為“資源”&#xff0c;用戶通過操作資源來管理集群。 集群中運行服務 運行容器&#xff0c;而容器必須放在 Pod 內。 最小管理單元是 Pod&#xff0c;但通常不直接操作 Pod&#xff0c;而是借…

        深入剖析 TOTP 算法:基于時間的一次性密碼生成機制

        標準原文&#xff1a;https://datatracker.ietf.org/doc/html/rfc6238 在數字化時代&#xff0c;信息安全至關重要&#xff0c;身份驗證成為保障系統和數據安全的第一道防線。傳統的用戶名加密碼方式已難以應對日益復雜的安全挑戰&#xff0c;基于時間的一次性密碼&#xff08;…

        Centos7 服務管理

        注&#xff1a;從Centos7開始systemd代替了init&#xff0c;使用systemd機制來管理服務優勢&#xff1a;并行處理所有服務&#xff0c;加速開機流程命令相對簡單&#xff1a;所有操作均有systemctl命令來執行服務依賴性檢測&#xff1a;systemctl命令啟動服務時會自動啟動依賴服…

        數據庫索引視角:對比二叉樹到紅黑樹再到B樹

        當我們談論數據庫索引時&#xff0c;選擇合適的數據結構至關重要。不同的數據結構在性能、復雜度以及適用場景上都有所不同。本文將通過對比二叉樹、紅黑樹和B樹&#xff0c;探討它們如何影響數據庫索引的表現。一、二叉樹特性定義&#xff1a;每個節點最多有兩個子節點。應用場…

        Redis-plus-plus 安裝指南

        &#x1f351;個人主頁&#xff1a;Jupiter.&#x1f680; 所屬專欄&#xff1a;Redis 歡迎大家點贊收藏評論&#x1f60a;目錄1.安裝 hiredis2.下載 redis-plus-plus 源碼3.編譯/安裝 redis-plus-plusC 操作 redis 的庫有很多. 此處使? redis-plus-plus.這個庫的功能強?, 使…

        vue3動態的控制表格列的展示簡單例子

        動態的控制表格列的展示&#xff0c; 可以勾選和取消某一列的顯示本地存儲上一次的配置表格內容支持通過slot自定義內容例子1 <script setup> import { reactive, ref, watch } from "vue"; import one from "./components/one.vue"; import One fro…

        微積分[4]|高等數學發展簡史(兩萬字長文)

        文章目錄前言解析幾何學微積分學級數理論常微分方程&#xff5c;(1) 萌芽階段&#xff5c;(2) 初創階段&#xff5c;(3) 奠基階段&#xff5c;(4) 現代發展階段前言 高等數學通常僅是相對初等數學而言的&#xff0c;其內容并無身份確切的所指&#xff0c;大凡初等數學以外的數…

        系統思考—啤酒游戲經營決策沙盤認證

        下周&#xff0c;我們將為企業交付——《啤酒游戲經營決策沙盤—應對動態復雜系統的思考智慧》內部講師認證課。啤酒游戲沙盤&#xff0c;我已交付過上百場。但這次的講師認證班&#xff0c;不僅僅是分享課程技巧&#xff0c;更多的是分享“心法”。有些關鍵點&#xff0c;直到…

        深入詳解PCB布局布線技巧-去耦電容的擺放位置

        目錄 一、基礎概念與核心作用 二、布局五大黃金原則 三、模擬電路的特殊處理 四、高頻場景優化方案 和旁路電容是保障電源穩定性和信號完整性的核心元件。盡管它們的原理和作用常被討論,但實際布局中的細節往往決定成敗。 一、基礎概念與核心作用 去耦電容:主要用于抑制…

        布隆過濾器的原理及使用

        背景介紹在互聯網中&#xff0c;我們經常遇到需要在大量數據中判斷目標數據是否存在的情況。例如&#xff0c;在網絡爬蟲中&#xff0c;我們需要判斷某個網址是否已經被訪問過。為了實現這一功能&#xff0c;通常需要使用一個容器來存儲已訪問過的網址。如果將這些數據直接存儲…