Kubernetes網絡性能測試-calico插件環境

Kubernetes 網絡性能測試-calico插件環境

本次主要針對calico網絡插件k8s集群的網絡性能進行摸底及測試方法探索實踐。

1. 測試準備

1.1 測試環境

測試環境為VMware Workstation虛擬機搭建的一套K8S環境,版本為1.28.2,網絡插件使用calico,版本為3.28.0。

hostnameip配置備注
master192.168.0.612C4Gmaster
node1192.168.0.622C4Gworker
node2192.168.0.632C4Gworker

已經部署測試應用sample-webapp,三個副本:

root@master1:~# kubectl get svc
NAME            TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)        AGE
kubernetes      ClusterIP      10.96.0.1        <none>          443/TCP        15d
sample-webapp   ClusterIP      10.106.172.112   <none>          8000/TCP       47s
root@master1:~# kubectl get pod
NAME                            READY   STATUS    RESTARTS   AGE
sample-webapp-77745d4db-57rbx   1/1     Running   0          50s
sample-webapp-77745d4db-vprjc   1/1     Running   0          50s
sample-webapp-77745d4db-wltzl   1/1     Running   0          12s

備注:

  1. 本文測試環境,master節點取消了NoSchedule的Taints,使得master節點也可以調度業務pod。
  2. 測試用到的demo程序可以訪問以下倉庫獲取:https://gitee.com/lldhsds/distributed-load-testing-using-k8s.git,僅部署sample-webapp即可。當然也可以使用其他應用進行測試,比如nginx等。

1.2 測試場景

  • Kubernetes 集群 node 節點上通過 Cluster IP 方式訪問
  • Kubernetes 集群內部通過 service 訪問
  • Kubernetes 集群外部通過 metalLB暴露的地址訪問

1.3 測試工具

  • curl
  • 測試程序:sample-webapp,源碼見 Github kubernetes 的分布式負載測試。

1.4 測試說明

通過向 sample-webapp 發送 curl 請求獲取響應時間,直接 curl 后的結果為:

root@master1:~# curl "http://10.106.172.112:8000"
Welcome to the "Distributed Load Testing Using Kubernetes" sample web app

2. 網絡延遲測試

2.1 Kubernetes 集群 node 節點上通過 Cluster IP 訪問

測試命令

curl -o /dev/null -s -w '%{time_connect} %{time_starttransfer} %{time_total}' "http://10.106.172.112:8000"

測試10組數據,取平均結果:

[root@k8s-node1 ~]# echo "time_connect  time_starttransfer time_total"; for i in {1..10}; do curl -o /dev/null -s -w '%{time_connect} %{time_starttransfer} %{time_total}\n' "http://10.106.172.112:8000"; done
time_connect  time_starttransfer time_total
0.000362 0.001538 0.001681
0.000456 0.002825 0.003137
0.000744 0.003152 0.003394
0.000388 0.001750 0.001847
0.000617 0.002405 0.003527
0.000656 0.002153 0.002390
0.000204 0.001597 0.001735
0.000568 0.002759 0.003117
0.000826 0.002278 0.002463
0.000582 0.002062 0.002120

平均響應時間:2.541 ms

指標說明:

  • time_connect:建立到服務器的 TCP 連接所用的時間

  • time_starttransfer:在發出請求之后,Web 服務器返回數據的第一個字節所用的時間

  • time_total:完成請求所用的時間

2.2 Kubernetes 集群內部通過 service 訪問

# 進入測試的客戶端
root@master1:~# kubectl exec -it test-78bcb7b45d-t9mvw -- /bin/bash
# 執行測試
test-78bcb7b45d-t9mvw:/# echo "time_connect  time_starttransfer time_total"; for i in {1..10}; do curl -o /dev/null -s -w '%{time_connect} %{time_starttransfer} %{time_total}\n' "http://sample-webapp:8000/"; done
time_connect  time_starttransfer time_total
0.001359 0.004808 0.005001
0.001470 0.003394 0.003508
0.001888 0.003702 0.004018
0.001630 0.003267 0.003622
0.001621 0.003235 0.003491
0.001008 0.002891 0.002951
0.001508 0.003137 0.003313
0.004427 0.006035 0.006293
0.001512 0.002924 0.002962
0.001649 0.003774 0.003981

平均響應時間:約3.914 ms

2.3 在外部通過ingress 訪問

本文使用LB service類型,也可以將service改為NodePort類型進行測試。

root@master1:~# kubectl get svc
NAME            TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)          AGE
kubernetes      ClusterIP      10.96.0.1        <none>          443/TCP          15d
sample-webapp   LoadBalancer   10.98.247.190    192.168.0.242   80:31401/TCP     6m16s

在外部的客戶端添加域名解析sample-webapp.test.com 192.168.0.242,進行訪問測試:

$ echo "time_connect  time_starttransfer time_total"; for i in {1..10}; do curl -o /dev/null -s -w '%{time_connect} %{time_starttransfer} %{time_total}\n' "http://sample-webapp.test.com/"; done
time_connect  time_starttransfer time_total
0.015586 0.017507 0.028004
0.039582 0.042034 0.052532
0.006702 0.008856 0.019461
0.041783 0.046729 0.057053
0.005912 0.008222 0.019276
0.006669 0.009513 0.020058
0.006592 0.010141 0.020598
0.011113 0.014444 0.026173
0.006471 0.008854 0.019571
0.041217 0.043651 0.055667

平均響應時間:31.839 ms

2.4 測試結果

在這三種場景下的響應時間測試結果如下:

  1. Kubernetes 集群 node 節點上通過 Cluster IP 方式訪問:2.541 ms
  2. Kubernetes 集群內部通過 service 訪問:3.914 ms
  3. Kubernetes 集群外部通過 traefik ingress 暴露的地址訪問:31.839 ms

說明:

  1. 執行測試的 node 節點 / Pod 與 serivce 所在的 pod 的距離(是否在同一臺主機上),對前兩個場景可能會有一定影響。
  2. 測試結果僅作參考,與具體的資源配置、網絡環境等因素有關系。

3. 網絡性能測試

網絡使用 flannel 的 vxlan 模式,使用 iperf 進行測試。

服務端命令:

iperf3 -s -p 12345 -i 1

客戶端命令:

iperf3 -c ${server-ip} -p 12345 -i 1 -t 10

3.1 node節點之間

# node1啟動iperf服務端
[root@node1 ~]# iperf3 -s -p 12345 -i 1
-----------------------------------------------------------
Server listening on 12345# node2啟動iperf客戶端測試
root@node2:~# iperf3 -c 192.168.0.62 -p 12345 -i 1 -t 60
Connecting to host 192.168.0.62, port 12345
[  5] local 192.168.0.63 port 40948 connected to 192.168.0.62 port 12345
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec   325 MBytes  2.72 Gbits/sec  107   1.53 MBytes
...
[  5]  59.00-60.00  sec   339 MBytes  2.84 Gbits/sec    2   1.29 MBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-60.00  sec  19.9 GBytes  2.85 Gbits/sec  421             sender
[  5]   0.00-60.00  sec  19.9 GBytes  2.85 Gbits/sec                  receiver

3.2 不同node的 Pod 之間(Native Routing-BGP模式)

查看calico當前的網絡模式,也是calico默認的配置:

root@master1:~# calicoctl node status
Calico process is running.IPv4 BGP status
+--------------+-------------------+-------+----------+-------------+
| PEER ADDRESS |     PEER TYPE     | STATE |  SINCE   |    INFO     |
+--------------+-------------------+-------+----------+-------------+
| 192.168.0.62 | node-to-node mesh | up    | 04:06:45 | Established |
| 192.168.0.63 | node-to-node mesh | up    | 04:06:39 | Established |
+--------------+-------------------+-------+----------+-------------+IPv6 BGP status
No IPv6 peers found.root@master1:~# calicoctl get ipPool default-ipv4-ippool -o wide
NAME                  CIDR            NAT    IPIPMODE   VXLANMODE     DISABLED   DISABLEBGPEXPORT   SELECTOR
default-ipv4-ippool   10.244.0.0/16   true   Never      CrossSubnet   false      false              all()# 查看節點路由表,跨節點pod通信走節點網卡(ens33)直接轉發
root@master1:~# ip route
default via 192.168.0.1 dev ens33 proto static
10.244.44.0/24 via 192.168.0.63 dev ens33 proto 80 onlink
10.244.154.0/24 via 192.168.0.62 dev ens33 proto 80 onlink
...

當前的網絡模式為bgp,VXLANMODE為CrossSubnet,只有在跨子網(node節點)轉發時才進行Vxlan封裝,同子網(node節點)之間進行三層路由轉發。

備注:

  1. 上面的配置為calico的默認配置,同子網(node節點)情況下,pod之間通信直接通過node節點的路由表進行轉發。這點和flannel的host-gw模式是類似的。只有在跨子網(node節點)時,才會走vxlan隧道封裝解封裝。

  2. calico 也支持同子網node之間pod通信走vxlan隧道的通信方式,將上面的參數修改,vxlanMode: Always,由于overlay封裝,性能會有損耗,這點和flannel的vxlan模式是類似的。

詳情參見:Overlay networking | Calico Documentation (tigera.io)

測試不同node節點pod之間的網絡性能:

# 部署測試用pod,分布于兩個node節點
[root@k8s-master ~]# cat test-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: test
spec:replicas: 3selector:matchLabels:app: testtemplate:metadata:labels:app: testspec:containers:- name: testimage: lldhsds/alpine:perf-20240717command: ["sleep", "3600"][root@master1 ~]# kubectl get pod -o wide
NAME               READY   STATUS    RESTARTS   AGE   IP             NODE         NOMINATED NODE   READINESS GATES
test-78bcb7b45d-mpfgn   1/1   Running     0     50s   10.244.44.136    node2     <none>           <none>
test-78bcb7b45d-t9mvw   1/1   Running     0     84m   10.244.154.221   node1     <none>           <none>
...# 在node2的pod中啟動iperf服務端
root@master1:~# kubectl exec -it test-78bcb7b45d-mpfgn -- /bin/bash
test-78bcb7b45d-mpfgn:/# iperf3 -s -p 12345 -i 1# 在node1的pod中啟動iperf客戶端測試
root@master1:~# kubectl exec -it test-78bcb7b45d-t9mvw -- /bin/bash
test-78bcb7b45d-t9mvw:/# iperf3 -c 10.244.44.136 -p 12345 -i 1 -t 60
Connecting to host 10.244.44.136, port 12345
[  5] local 10.244.154.221 port 39024 connected to 10.244.44.136 port 12345
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec   351 MBytes  2.94 Gbits/sec  1565   1.55 MBytes
...
[  5]  59.00-60.00  sec   347 MBytes  2.91 Gbits/sec   25   1.33 MBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-60.00  sec  19.2 GBytes  2.75 Gbits/sec  4355             sender
[  5]   0.00-60.01  sec  19.2 GBytes  2.75 Gbits/sec                  receiver

說明:

測試鏡像已經上傳值docker hub,可以通過命令拉取:docker pull lldhsds/alpine:perf-20240717

3.3 Node 與不同node的 Pod 之間(Native Routing-BGP模式)

# node1啟動iperf服務端
[root@node1 ~]# iperf3 -s -p 12345 -i 1
-----------------------------------------------------------
Server listening on 12345# 在node2的pod中啟動iperf客戶端測試
[root@k8s-master ~]# kubectl get pod -o wide
NAME                 READY   STATUS RESTARTS   AGE     IP             NODE         NOMINATED NODE   READINESS GATES
test-78bcb7b45d-mpfgn  1/1   Running    0    40m     10.244.44.136    node2     <none>           <none>
test-78bcb7b45d-t9mvw  1/1   Running    0    124m    10.244.154.221   node1     <none>           <none>
root@master1:~# kubectl exec -it test-78bcb7b45d-mpfgn -- /bin/bash
test-78bcb7b45d-mpfgn:/# iperf3 -c 192.168.0.62 -p 12345 -i 1 -t 60
Connecting to host 192.168.0.62, port 12345
[  5] local 10.244.44.136 port 32770 connected to 192.168.0.62 port 12345
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec   328 MBytes  2.75 Gbits/sec  771   1.48 MBytes
...
[  5]  59.00-60.00  sec   326 MBytes  2.73 Gbits/sec  191   1.14 MBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-60.00  sec  19.4 GBytes  2.78 Gbits/sec  4237             sender
[  5]   0.00-60.00  sec  19.4 GBytes  2.78 Gbits/sec                  receiver

3.4 不同node的 Pod 之間(VXLAN)

修改calico bgp的VXLANMODE為always,當pod跨節點(同子網)通信時,使用vxlan封裝解封裝。

# 查看calico的ipv4地址池
root@master1:~# calicoctl get ippool
NAME                  CIDR            SELECTOR
default-ipv4-ippool   10.244.0.0/16   all()# 到處默認ipv4地址池的配置
root@master1:~# calicoctl  get ippool default-ipv4-ippool -o yaml > ippool.yaml# 修改vxlanMode,默認為CrossSubnet
root@master1:~# vi ippool.yaml	# 
...vxlanMode: Always# 應用修改
root@master1:~# calicoctl apply -f ippool.yaml
Successfully applied 1 'IPPool' resource(s)root@master1:~# calicoctl  get ippool default-ipv4-ippool -o wide
NAME                  CIDR            NAT    IPIPMODE   VXLANMODE   DISABLED   DISABLEBGPEXPORT   SELECTOR
default-ipv4-ippool   10.244.0.0/16   true   Never      Always      false      false              all()# 這個時候查看node節點的路由表,當pod進行跨節點通信時,會走vxlan.calico進行封裝
root@master1:~#  ip route
default via 192.168.0.1 dev ens33 proto static
10.244.44.0/24 via 10.244.44.0 dev vxlan.calico onlink
10.244.154.0/24 via 10.244.154.0 dev vxlan.calico onlink
.。。

進行pod之間的帶寬測試:

# 在node1的pod中啟動iperf服務端
root@master1:~# kubectl exec -it test-78bcb7b45d-mpfgn -- /bin/bash
test-78bcb7b45d-mpfgn:/# iperf3 -s -p 12345 -i 1# 在node2的pod中啟動iperf客戶端測試
test-78bcb7b45d-t9mvw:/# iperf3 -c 10.244.44.136 -p 12345 -i 1 -t 60
Connecting to host 10.244.44.136, port 12345
[  5] local 10.244.154.221 port 59994 connected to 10.244.44.136 port 12345
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec   123 MBytes  1.03 Gbits/sec  196    793 KBytes
[  5]   1.00-2.00   sec   120 MBytes  1.00 Gbits/sec   73    896 KBytes
...
[  5]  59.00-60.00  sec   172 MBytes  1.45 Gbits/sec    0   2.30 MBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-60.00  sec  6.83 GBytes   978 Mbits/sec  1650             sender
[  5]   0.00-60.02  sec  6.83 GBytes   977 Mbits/sec                  receiver

3.5 Node 與不同node的 Pod 之間(VXLAN)

# node1啟動iperf服務端
[root@node1 ~]# iperf3 -s -p 12345 -i 1
-----------------------------------------------------------
Server listening on 12345# 在node2的pod中啟動iperf客戶端測試
[root@k8s-master ~]# kubectl get pod -o wide
NAME                 READY   STATUS RESTARTS   AGE     IP             NODE         NOMINATED NODE   READINESS GATES
test-78bcb7b45d-mpfgn  1/1   Running    0    40m     10.244.44.136    node2     <none>           <none>
test-78bcb7b45d-t9mvw  1/1   Running    0    124m    10.244.154.221   node1     <none>           <none>
root@master1:~# kubectl exec -it test-78bcb7b45d-mpfgn -- /bin/bash
test-78bcb7b45d-mpfgn:/# iperf3 -c 192.168.0.62 -p 12345 -i 1 -t 60
Connecting to host 192.168.0.62, port 12345
[  5] local 10.244.44.136 port 51004 connected to 192.168.0.62 port 12345
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec   346 MBytes  2.89 Gbits/sec  992   1.46 MBytes
[  5]   1.00-2.00   sec   350 MBytes  2.94 Gbits/sec  347   1.61 MBytes
...
[  5]  59.00-60.00  sec   314 MBytes  2.63 Gbits/sec    0   1.49 MBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-60.00  sec  18.6 GBytes  2.67 Gbits/sec  4278             sender
[  5]   0.00-60.01  sec  18.6 GBytes  2.67 Gbits/sec                  receiver

3.6 不同node的Pod之間(IP-IP模式)

修改為IP-IP模式:

root@master1:~# calicoctl  get ippool default-ipv4-ippool -o yaml > ippool.yaml# 修改ipipMode,同時刪除VXLANMode = 'CrossSubnet'
root@master1:~# vi ippool.yaml
...ipipMode: Always
...
# 應用修改
root@master1:~# calicoctl apply -f ippool.yaml
Successfully applied 1 'IPPool' resource(s)# 查看節點路由表此時流量轉發通過tunl0設備出去
root@master1:~# ip route
default via 192.168.0.1 dev ens33 proto static
10.244.44.0/24 via 192.168.0.63 dev tunl0 proto bird onlink
10.244.154.0/24 via 192.168.0.62 dev tunl0 proto bird onlink
blackhole 10.244.161.0/24 proto bird

進行pod之間的帶寬測試:

# 在node1的pod中啟動iperf服務端
root@master1:~# kubectl exec -it test-78bcb7b45d-mpfgn -- /bin/bash
test-78bcb7b45d-mpfgn:/# iperf3 -s -p 12345 -i 1# 在node2的pod中啟動iperf客戶端測試
test-78bcb7b45d-t9mvw:/# iperf3 -c 10.244.44.136 -p 12345 -i 1 -t 60
Connecting to host 10.244.44.136, port 12345
[  5] local 10.244.154.221 port 59994 connected to 10.244.44.136 port 12345
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec   163 MBytes  1.37 Gbits/sec  119   1.04 MBytes
[  5]   1.00-2.00   sec   129 MBytes  1.08 Gbits/sec  128   1.12 MBytes
...
[  5]  58.00-59.00  sec   172 MBytes  1.44 Gbits/sec    0   2.92 MBytes
[  5]  59.00-60.00  sec   161 MBytes  1.35 Gbits/sec    0   3.13 MBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-60.00  sec  8.60 GBytes  1.23 Gbits/sec  1256             sender
[  5]   0.00-60.02  sec  8.60 GBytes  1.23 Gbits/sec                  receiver

3. 7 Node 與不同node的 Pod 之間(IP-IP)

# node1啟動iperf服務端
[root@node1 ~]# iperf3 -s -p 12345 -i 1
-----------------------------------------------------------
Server listening on 12345# 在node2的pod中啟動iperf客戶端測試
[root@k8s-master ~]# kubectl get pod -o wide
NAME                 READY   STATUS RESTARTS   AGE     IP             NODE         NOMINATED NODE   READINESS GATES
test-78bcb7b45d-mpfgn  1/1   Running    0    40m     10.244.44.136    node2     <none>           <none>
test-78bcb7b45d-t9mvw  1/1   Running    0    124m    10.244.154.221   node1     <none>           <none>
root@master1:~# kubectl exec -it test-78bcb7b45d-mpfgn -- /bin/bash
test-78bcb7b45d-mpfgn:/# iperf3 -c 192.168.0.62 -p 12345 -i 1 -t 60
Connecting to host 192.168.0.62, port 12345
[  5] local 10.244.44.136 port 51004 connected to 192.168.0.62 port 12345
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec   407 MBytes  3.41 Gbits/sec  506    692 KBytes
[  5]   1.00-2.00   sec   336 MBytes  2.82 Gbits/sec  577    949 KBytes
[  5]   2.00-3.00   sec   310 MBytes  2.60 Gbits/sec   92   1.13 MBytes
...
[  5]  58.00-59.00  sec   323 MBytes  2.71 Gbits/sec    3   1.28 MBytes
[  5]  59.00-60.00  sec   329 MBytes  2.76 Gbits/sec    0   1.44 MBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-60.00  sec  19.4 GBytes  2.78 Gbits/sec  3960             sender
[  5]   0.00-60.00  sec  19.4 GBytes  2.77 Gbits/sec                  receiver

4. 總結

4.1 帶寬數據對比

場景calio網絡模式帶寬(Gbits/sec)
不同node之間不涉及2.85
不同node的pod之間Native Routing (BGP) 模式2.75
node與不同node的pod之間Native Routing (BGP) 模式2.78
不同node的pod之間VXLAN0.98
node與不同node的pod之間VXLAN2.67
不同node的pod之間IP-IP1.23
node與不同node的pod之間IP-IP2.77

從上述數據得出結論:

  1. calico的BGP模式網絡性能(pod之間)相比宿主機直接互聯的損耗在5%左右,基本接近與node節點之間的網絡性能,考慮浮動和誤差,基本可以認為網絡沒有損耗。從轉發路徑分析,相比于節點直接轉發,pod轉發只是多了連接pod和節點的veth-pair。
  2. VXLAN模式和IP-IP模式下,pod之間性能損耗高于50%,性能數據較差,這兩種模式下報文都經過了封裝、解封裝。相對來說,IP-IP模式下的性能要好與VXLAN模式,從底層報文封裝角度講,ip-ip要比vxlan開銷小,這樣也能解釋的通。
  3. Node與不同node的Pod之間測試來看,性能損耗比較少。

說明:

  1. 測試過程中也出現過pod之間帶寬高于node節點之間的情況,數據有一定的波動。本文使用的是筆記本下創建的虛擬機測試環境,虛擬機資源存在爭搶,對于測試結果有一定的影響。
  2. VXLAN、IP-IP模式下損耗大于50%,不代表一般的經驗數據,可能與具體的環境有關系,此處僅作參考。

關于calico網絡相關的進一步說明請參考:Overlay networking | Calico Documentation (tigera.io)。

4.2 綜合對比

本文使用的測試環境節點都在同子網下,只對比了有封裝和直接轉發兩種場景的性能數據。

關于跨子網的場景有待進一步摸索,下面是一些匯總的說明:

模式網絡模式描述性能適用場景
BGPunderlay使用 BGP 在節點間傳播路由,不進行任何封裝損耗最低物理網絡支持 BGP,節點可直接通信。首選該模式。
IPIP-CrossSubnetunderlay+overlay節點跨子網使用封裝,同子網內直接通信同子網內基本無損耗,跨子網損耗較多物理網絡不支持 BGP,節點大多在同子網下
IPIP-Alwaysoveraly不管節點是否跨子網,都使用 IPIP 封裝進行跨節點通信損耗較多,優于vxlan物理網絡不支持 BGP,節點跨多個子網的集群
VXLAN-CrossSubnetunderlay+overaly節點跨子網使用封裝,同子網內直接通信同子網內基本無損耗,跨子網損耗較多物理網絡不支持 BGP,節點大多在同子網下
VXLAN-Alwaysoveraly不管節點是否跨子網,都使用 VXLAN 封裝進行跨節點通信損耗較多物理網絡不支持 BGP,節點跨多個子網的集群

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

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

相關文章

6Python的Pandas:數據讀取與輸出

Pandas是一個強大的Python數據分析庫&#xff0c;提供了讀取和輸出數據的多種功能。以下是一些常見的數據讀取與輸出方法&#xff1a; 1. 讀取CSV 讀取數據 從CSV文件讀取數據 import pandas as pd# 讀取CSV文件 df pd.read_csv(file_path.csv) print(df.head())從Excel文…

Flutter 狀態管理調研總結

一, 候選狀態管理組件簡介 0. flutter_hooks 一個 React 鉤子在 Flutter 上的實現&#xff1a;Making Sense of React Hooks 鉤子是一種用來管理 Widget 生命周期的新對象&#xff0c;以減少重復代碼、增加組件間復用性&#xff0c;允許將視圖邏輯提取到通用的用例中并重用&…

思路|如何利用oneNote釣魚?

本文僅用于技術研究學習&#xff0c;請遵守相關法律&#xff0c;禁止使用本文所提及的相關技術開展非法攻擊行為&#xff0c;由于傳播、利用本文所提供的信息而造成任何不良后果及損失&#xff0c;與本賬號及作者無關。 本文來源無問社區&#xff0c;更多實戰內容&#xff0c;…

[python]pycharm設置清華源

國內鏡像源有以下幾個&#xff0c;因為都是國內的&#xff0c;基本速度差不了太多。 清華&#xff1a;https://pypi.tuna.tsinghua.edu.cn/simple 阿里云&#xff1a;http://mirrors.aliyun.com/pypi/simple/ 中國科技大學 https://pypi.mirrors.ustc.edu.cn/simple/ 豆瓣&…

針對【module_or_function】的單元測試,全面覆蓋可能的【edge_cases】

針對【module_or_function】的單元測試&#xff0c;全面覆蓋可能的【edge_cases】 編寫單元測試是為了驗證代碼模塊或函數的正確性和魯棒性。對于module_or_function&#xff0c;首先需要確定這個模塊或函數的具體功能和預期輸入范圍。一個好的單元測試應該包括以下幾個步驟&a…

高并發服務器-使用多線程(Multi-Thread)實現【C語言】

在上期的socket套接字的使用詳解中&#xff08;socket套接字的使用詳解&#xff09;最后實現的TCP服務器只能處理一個客戶端的請求發送&#xff0c;當有其他客戶端請求連接時會被阻塞。為了能同時處理多個客戶端的連接請求&#xff0c;本期使用多線程的方式來解決。 程序流程 …

爬蟲案例(讀書網)(下)

上篇鏈接&#xff1a; CSDN-讀書網https://mp.csdn.net/mp_blog/creation/editor/139306808 可以看見基本的全部信息&#xff1a;如(author、bookname、link.....) 寫下代碼如下&#xff1a; import requests from bs4 import BeautifulSoup from lxml import etreeheaders{…

scottplot5 中 使用signalXY圖,如何更新數據?

&#x1f3c6;本文收錄于《CSDN問答解答》專欄&#xff0c;主要記錄項目實戰過程中的Bug之前因后果及提供真實有效的解決方案&#xff0c;希望能夠助你一臂之力&#xff0c;幫你早日登頂實現財富自由&#x1f680;&#xff1b;同時&#xff0c;歡迎大家關注&&收藏&…

總部下達任務時,如何保證員工的執行力?

執行力是個體基于戰略目標&#xff0c;有效整合利用資源&#xff0c;保質保量完成預定目標的操作能力&#xff0c;員工執行力的高低是企業完成效益、成果轉化的關鍵。執行力包含完成任務的意愿、完成能力、完成程度三個維度&#xff0c;其中意愿是基礎和出發點&#xff0c;能力…

物聯網與通信技術

查了很多資料&#xff0c;也夾雜著一些自己的見解。此篇文章僅探討三個問題&#xff1a;物聯網與通信技術的關系&#xff1b;5G為物聯網帶來了什么&#xff0c;物聯網真的需要5G嗎&#xff1b;物聯網發展的現實問題。 1、物聯網與通信技術的關系 最近幾年&#xff0c;物聯網的…

Apache POI 使用Java處理Excel數據 進階

1.POI入門教程鏈接 http://t.csdnimg.cn/Axn4Phttp://t.csdnimg.cn/Axn4P建議&#xff1a;從入門看起會更好理解POI對Excel數據的使用和處理 記得引入依賴&#xff1a; <dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactI…

CentOS搭建 Mono 開發環境

Mono 是一個由 Xamarin 公司所主持的自由開放源代碼項目,該項目的目標是創建一系列匹配ECMA標準的.NET工具,包括 C# 編譯器和通用語言架構,Mono項目不僅可以運行于Windows系統上,還可以運行于Linux,FreeBSD,Unix,OS X和Solaris,甚至一些游戲平臺,本實驗帶您搭建 Mono …

Linux chmod 命令簡介

在Linux中&#xff0c;chmod 命令用于改變文件或文件夾的訪問權限。要改變一個文件夾及其內部所有文件和子文件夾的權限&#xff0c;您可以使用遞歸選項 -R。以下是一些常用的 chmod 命令示例&#xff1a; 給所有用戶讀、寫和執行權限&#xff1a; chmod -R 777 /path/to/direc…

JVM高頻面試點

文章目錄 JVM內存模型程序計數器Java虛擬機棧本地方法棧Java堆方法區運行時常量池 Java對象對象的創建如何為對象分配內存 對象的內存布局對象頭實例數據對齊填充 對象的訪問定位 垃圾收集器找到垃圾引用計數法可達性分析&#xff08;根搜索法&#xff09; 引用概念的擴充回收方…

【Socket套接字編程】(實現TCP和UDP的通信)

&#x1f387;&#x1f389;&#x1f389;&#x1f389;點進來你就是我的人了 博主主頁&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳&#xff0c;歡迎大佬指點&#xff01; 人生格言: 當你的才華撐不起你的野心的時候,你就應該靜下心來學習! 歡迎志同道合的朋友…

java序列化與反系列化,serializable原理,Parcelable接口原理解析,Json,XML

Java的序列化和反序列化是用于對象的持久化和傳輸的重要機制。以下是對相關概念的詳細解釋&#xff1a; Java 序列化與反序列化 序列化 (Serialization) 是將 Java 對象轉換為字節流的過程&#xff0c;這樣對象就可以通過網絡傳輸或者保存到文件中。反序列化 (Deserializatio…

創建通用JS公共模塊并發布至npm

title: 創建通用JS公共模塊并發布至npm tags: UMD rollup verdaccio npm categories: 模塊化 概要內容 創建&#xff1a;JS公共模塊 打包&#xff1a;使用rollup 打包公共模塊 發布&#xff1a;js公共模塊至verdaccio平臺 發布&#xff1a;js公共模塊至npm平臺 如何創建JS公共模…

【PostgreSQL】Windows 上安裝 PostgreSQL 16版本

博主介紹:?全網粉絲20W+,CSDN博客專家、Java領域優質創作者,掘金/華為云/阿里云/InfoQ等平臺優質作者、專注于Java技術領域? 技術范圍:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大數據、物聯網、機器學習等設計與開發。 感興趣的可…

二叉樹遍歷(C++)

題目描述 樹和二叉樹基本上都有先序、中序、后序、按層遍歷等遍歷順序&#xff0c; 給定中序和其它一種 遍歷的序列就可以確定一棵二叉樹的結構。 假定一棵二叉樹一個結點用一個字符描述&#xff0c;現在給出中序和按層遍歷的字符串&#xff0c;求該樹 的先序遍歷字符串。 輸…

【Python】TensorFlow介紹與實戰

TensorFlow介紹與使用 1. 前言 在人工智能領域的快速發展中&#xff0c;深度學習框架的選擇至關重要。TensorFlow 以其靈活性和強大的社區支持&#xff0c;成為了許多研究者和開發者的首選。本文將進一步擴展對 TensorFlow 的介紹&#xff0c;包括其優勢、應用場景以及在最新…