当前位置: 首页 > news >正文

K8S存储总结持久化存储解决方案(以NFS为例)

目录

K8S存储

一、emptydir

1. emptydir是什么

2. emptydir例子

二、hostpath

hostpath 是什么

hostpath 例子

弊端

三、持久化存储

1.Persistent Volume(PV)

2.Persistent Volume Claim(PVC)

3.PV/PVC结合NFS使用实践(持久存储)

1. NFS服务器搭建

(1)搭建 NFS服务器

3. 验证PV-PVC-NFS存储结果

(1)pod中创建文件,NFS服务器查看文件

(2) NFS数据存储目录里创建文件,在Pod中查看文件

(3)删除Pod,NFS服务器查看文件

4.回收PV

4、StorageClass

1.1 什么是StorageClass

1.2 为什么需要StorageClass

1.3 运行原理

2. StorageClass 资源

2.1 存储制备器

3.NFS StorageClass 实战

3.1 部署流程

3.2 创建Service Account

3.3 创建StorageClass,指定provisioner

3.4 创建pod测试

K8S存储

一、emptydir

1. emptydir是什么

当pod的存储方案设定为emptydir的时候,pod启动时,就会在pod所在节点的磁盘空间开辟出一块空卷,最开始里面是什么都没有的,pod启动后容器产生的数据会存放到那个空卷中。

一旦pod容器消失,节点上开辟出的这个临时卷就会随着pod的销毁而销毁

一般来说emptydir的用途都是用来充当临时存储空间,例如一些不需要数据持久化的微服务,我们都可以用emptydir来当做微服务pod的存储方案

2. emptydir例子

# emptydir.yaml
---
apiVersion: v1
kind: Namespace
metadata:name: dev
---
apiVersion: v1
kind: Pod
metadata:name: test-emptydirnamespace: dev
spec:containers:- image: nginx:1.20.0name: test-emptydirvolumeMounts:- mountPath: /usr/share/nginx/html    #挂载到容器中的路径name: cache-volumevolumes:- name: cache-volumeemptyDir: {}   #指定存储方式为emptydir

验证emptydir

1.在调度节点g1-mix-online2-222上操作

docker ps -a | grep empty

2.查看容器详细信息

 docker inspect c3c0fa73aa9b

3.进入宿主机挂载路径并写入文件 

4.测试访问

curl 10.14.57.123

 5.删除pod,查看文件是否被删除

 emptydir是随pod创建而创建,然后再随pod删除而删除

二、hostpath

hostpath 是什么

hostPath类型是映射宿主机文件系统中的文件或者目录到pod里。但当pod漂移到其他node节点的时候,pod不会跨节点的去读取目录。所以hostpath只能算一种半持久化的存储方式

hostpath 例子

#  hostpath.yaml
apiVersion: v1
kind: Pod
metadata:name: test-hostpathnamespace: dev
spec:containers:- name: test-hostpathimage: nginx:1.20.0volumeMounts:- name: test-hostpath  # 取个名字mountPath: /usr/share/nginx/html   # 挂载到容器中的路径volumes:- name: test-hostpath    # 取个名字必须与上面volumeMounts中name的一致hostPath:# directory location on hostpath: /data            # node节点上宿主机的路径# this field is optionaltype: DirectoryOrCreate   # path的属性

接下来就是验证:g1-mix-online2-222节点和pod内目录是否进行了关联

宿主机

1.data目录已经自动创建

2.进入data文件夹,并写入测试文件

echo "cat" > /data/index.html 

 3.访问测试

查看 Pod内部:

1.查找容器

docker ps -a |  grep test-hostpath

2.查看容器详细信息

docker inspect 3e5431569426

3.进入容器查看文件是否存在

docker exec -it 3e5431569426  /bin/bash

 接下来,删除Pod,重新拉起一个Pod,看会不会还存在这个index.html文件

 此时,宿主机上的文件仍然存在

重新拉起pod,pod调度到g1-mix-online2-222节点

 进入容器查看文件是否存在,可见文件仍然存在

弊端

1.宿主机宕机会导致数据全部丢失

2.pod重新调度时,未调度到上次调度的节点,而是调度到新的节点,也会导致数据丢失

三、持久化存储

1.Persistent Volume(PV)

PV 描述的,是持久化存储数据卷。这个 API 对象主要定义的是一个持久化存储在宿主机上的目录,比如一个 NFS 的挂载目录。

通常情况下,PV 对象是由运维人员事先创建在 Kubernetes 集群里待用的。比如,运维人员可以定义这样一个 NFS 类型的 PV,如下所示:

apiVersion: v1
kind: PersistentVolume  # pv可以全局共享,不用指定命名空间
metadata:name: nfs
spec:storageClassName: manual capacity:   # 容量storage: 1Gi   # pv可用的大小   accessModes:   # 访问模式- ReadWriteMany  #读写权限nfs:server: 10.244.1.4 # NFS服务器地址path: "/" # NFS的路径  

2.Persistent Volume Claim(PVC)

PVC 描述的,则是 Pod 所希望使用的持久化存储的属性。比如,Volume 存储的大小、可读写权限等等。

PVC 对象通常由开发人员创建,比如,开发人员可以声明一个 1 GiB 大小的 PVC

apiVersion: v1
kind: PersistentVolumeClaim #需与使用pvc的pod在同一个namespace下
metadata:name: nfs
spec:accessModes: # 访问模式- ReadWriteMany   #读写权限storageClassName: manualresources:requests:storage: 1Gi # PVC允许申请的大小

而用户创建的 PVC 要真正被容器使用起来,就必须先和某个符合条件的 PV 进行绑定。

这里要检查的条件,包括两部分:

第一个条件,是 PV 和 PVC 的 spec 字段。比如,PV 的存储(storage)大小,就必须满足 PVC 的要求。

第二个条件,是 PV 和 PVC 的 storageClassName 字段需要相同。

PS: 也可以不使用storageClassName字段,通过PVC定义的 accessModes 读写权限,和storage定义的1G内存,PVC会自动找到符合这些配置的PV进行绑定。一个PV被PVC绑定后,不能被别的PVC绑定。

在成功地将 PVC 和 PV 进行绑定之后,Pod 就能够像使用 hostPath 等常规类型的 Volume 一样,在自己的 YAML 文件里声明使用这个 PVC 了,如下所示:

apiVersion: v1
kind: Pod   # 如果前面的PVC指定了命名空间这里必须指定与PVC一致的命名空间,否则PVC不可用
metadata:labels:role: web-frontend
spec:containers:- name: webimage: nginxports:- name: webcontainerPort: 80volumeMounts:- name: nfs  # 取个名字,与下面的volumes name 要一致mountPath: "/usr/share/nginx/html" # 容器中的路径volumes:- name: nfs #persistentVolumeClaim: claimName: nfs   # 引用前面声明的PVC

3.PV/PVC结合NFS使用实践(持久存储)

简单来说,要使用持久化存储,就需要使用pvc去跟pv去申请,然后pv查看自己有没有合适的存储空间卷,有合适的就与pvc进行绑定。pv与pvc是一一对应绑定的。

创建顺序:后端存储—pv—pvc—pod

1. NFS服务器搭建

NFS 是什么? nfs(network file system) 网络文件系统,是FreeBSD支持的文件系统中的一种,允许网络中的计算机之间通过TCP/IP网络共享资源

(1)搭建 NFS服务器

找一台centos 7机器,执行以下脚本,搭建 NFS服务器:

# 操作节点为NFS服务器# 安装nfs
yum -y install nfs-utils rpcbind# 创建nfs目录
mkdir -p /nfs/data/
mkdir -p /nfs/data/k8s# 授予权限
chmod -R 777 /nfs/data# 编辑export文件
vim /etc/exports
/nfs/data *(rw,no_root_squash,sync)  # 这里给的是root权限---生产环境不推荐
# 或者/nfs/data   0.0.0.0/0(rw,sync,all_squash)  # 所有用户权限被映射成服务端上的普通用户nobody,权限被压缩# 使得配置生效
exportfs -r# 查看生效
exportfs# 启动rpcbind、nfs服务
systemctl start rpcbind && systemctl enable rpcbind   #端口是111
systemctl start nfs && systemctl enable nfs           # 端口是 2049 # 查看rpc服务的注册情况
rpcinfo -p localhost# showmount测试
showmount -e ip(ip地址)

验证nfs是否启动

(2)在K8S集群所有node节点上安装NFS客户端

# 操作节点为k8s集群所有node节点
yum -y install nfs-utils  rpcbind
# systemctl start nfs && systemctl enable nfs

2. 创建pv、pvc、pod

# vim nginx-pv-demo.yaml 
# 定义PV
---
apiVersion: v1
kind: PersistentVolume
metadata:name: nginx-pv    # pv的名称
spec:accessModes:      # 访问模式- ReadWriteMany # PV以read-write挂载到多个节点capacity:  # 容量storage: 2Gi    # pv可用的大小   nfs:path: /nfs/data/     # NFS的挂载路径server: 10.16.216.221    # NFS服务器地址 
---
# 定义PVC,用于消费PV
# 通过PVC定义的 accessModes 读写权限,和storage定义的2G内存,PVC会自动找到符合这些配置的PV进行绑定。一个PV被PVC绑定后,不能被别的PVC绑定。
apiVersion: v1
kind: PersistentVolumeClaim  # 类型
metadata:name: nginx-pvc  # PVC 的名字namespace: dev   # 命名空间
spec:accessModes:    # 访问模式- ReadWriteMany   # PVC以read-write挂载到多个节点resources:requests:   storage: 2Gi    # PVC允许申请的大小
---
# 定义Pod,指定需要使用的PVC
apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-pvcnamespace: dev   # 如果前面的PVC指定了命名空间这里必须指定与PVC一致的命名空间,否则PVC不可用
spec:selector:matchLabels: app: nginx-pvctemplate:metadata:labels:app: nginx-pvcspec:containers:- name: nginx-test-pvcimage: nginx:1.20.0imagePullPolicy: IfNotPresentports:- name: web-portcontainerPort: 80protocol: TCPvolumeMounts:- name: nginx-persistent-storage    # 取个名字,与下面的volumes的名字要一致mountPath: /usr/share/nginx/html  # 容器中的路径volumes:- name: nginx-persistent-storage   persistentVolumeClaim:claimName: nginx-pvc  # 引用前面声明的PVC

注意:如果在NFS服务器上定义的路径是/nfs/data/nginx 首先我们需要去 /nfs/data下创建 nginx的文件夹,不然pod是启动不起来的 接下来,在master节点上启动。

3. 验证PV-PVC-NFS存储结果
(1)pod中创建文件,NFS服务器查看文件

pod中数据存储目录创建一个index.html,然后到nfs服务器上看有没有。

pod创建并写入文件

nfs服务器查看文件

(2) NFS数据存储目录里创建文件,在Pod中查看文件

nfs中数据存储目录创建一个文件,然后到pod中看有没有。

nfs中创建文件:

进入pod查看文件是否存在:

(3)删除Pod,NFS服务器查看文件

将pod删除,重新拉起之后进入pod查看文件是否存在

4.回收PV

当 PV 不再需要时,可通过删除 PVC 回收

必须先删除pod再删除pvc,因为pod绑定了pvc,如果先删pvc会出现pvc一直处于删除状态而无法删除

PV 生命周期总共四个阶段 :

Available(可用)—— 可用状态,尚未被 PVC 绑定。

Bound(已绑定)—— 绑定状态,已经与某个 PVC 绑定。

Released(已释放)—— 与之绑定的 PVC 已经被删除,但资源尚未被集群回收。

Failed(失败)—— 当删除 PVC 清理资源,自动回收卷时失败,所以处于故障状态

PV空间的回收策略:通过PV定义中的persistentVolumeReclaimPolicy字段进行设置,可选

  • Recycle:会清除数据,自动回收。

  • Retain(默认):需要手动清理回收。

  • Delete:云存储专用的回收空间使用命令。

4、StorageClass

1.StorageClass

1.1 什么是StorageClass

StorageClass 对象的作用,其实就是创建 PV 的模板,具体地说,StorageClass 对象会定义如下两个部分内容:

第一,PV 的属性。比如,存储类型、Volume 的大小等等。

第二,创建这种 PV 需要用到的存储插件。比如,Ceph 等等,即存储制备器。

有了这样两个信息之后,Kubernetes 就能够根据用户提交的 PVC,找到一个对应的 StorageClass 了。然后,Kubernetes 就会调用该 StorageClass 声明的存储插件,创建出需要的 PV。

StorageClass 对象的命名很重要,用户使用这个命名来请求生成一个特定的类。 当创建 StorageClass 对象时,管理员设置 StorageClass 对象的命名和其他参数,一旦创建了对象就不能再对其更新。

apiVersion: storage.k8s.io/v1
kind: StorageClass 
metadata:name: managed-nfs-storage #一旦创建,StorageClass名字不可更改
provisioner: nfs-storage   # 存储插件的名字,这里的名称要和provisioner配置文件中的环境变量PROVISIONER_NAME保持一致 # 若为公有云,此处填写公有云存储插件的名,例:provisioner: kubernetes.io/aws-ebs
parameters:   #具体存储插件相关信息server: "10.16.216.221 " path: "/nfs/data/k8s"readOnly: "false"
1.2 为什么需要StorageClass

1)在一个大规模的Kubernetes集群里,可能有成千上万个PVC,这就意味着运维人员必须实现创建出这个多个PV,此外,随着项目的需要,会有新的PVC不断被提交,那么运维人员就需要不断的添加新的,满足要求的PV,否则新的Pod就会因为PVC绑定不到PV而导致创建失败。

2)通过 StorageClass 的定义,管理员可以将存储资源定义为某种类型的资源,比如快速存储、慢速存储等,用户根据 StorageClass 的描述就可以非常直观的知道各种存储资源的具体特性了,这样就可以根据应用的特性去申请合适的存储资源了。

在动态资源供应模式下,通过StorageClass和PVC完成资源动态绑定(系统自动生成PV),并供Pod使用的存储管理机制

1.3 运行原理

要使用 StorageClass,我们就得安装对应的自动配置程序,比如我们这里存储后端使用的是 nfs,那么我们就需要使用到一个 nfs-client 的自动配置程序,我们也叫它 Provisioner(制备器),这个程序使用我们已经配置好的 nfs 服务器,来自动创建持久卷,也就是自动帮我们创建 PV。

  1. 自动创建的 PV 以${namespace}-${pvcName}-${pvName}这样的命名格式创建在 NFS 服务器上的共享数据目录中

  2. 而当这个 PV 被回收后会以archieved-${namespace}-${pvcName}-${pvName}这样的命名格式存在 NFS 服务器上。

2. StorageClass 资源

2.1 存储制备器

每个 StorageClass 都有一个制备器(Provisioner),用来决定使用哪个卷插件制备 PV。 该字段必须指定。

官方支持的StorageClass

 NFS 没有内部制备器,但可以使用外部制备器。 也有第三方存储供应商提供自己的外部制备器。

3.NFS StorageClass 实战

3.1 部署流程

搭建StorageClass + NFS,大致有以下几个步骤:

  • 创建一个可用的NFS Server

  • 创建Service Account,这是用来管控NFS Provisioner 在k8s集群中运行的权限

  • 创建StorageClass,负责建立PV并调用NFS provisioner进行工作,并让PV与PVC建立关联

  • 创建NFS provisioner

 NFS provisioner是一个provisioner相关的插件,需要从网络上下载,我们需要下载下来放到镜像库中 下载以后需要以pod方式运行通过deployment部署导入到本地环境中提前下载镜像(选择一个下载即可):镜像1  docker  pull   registry.cn-hangzhou.aliyuncs.com/open-ali/nfs-client-provisioner镜像2  docker  pull  lizhenliang/nfs-client-provisioner
3.2 创建Service Account
(1) 准备好NFS服务器

确保nfs可以正常工作,创建持久化需要的目录。

path: /nfs/data/class
server: 10.16.216.221 

(2)开启rbac权限

# rbac.yaml:#唯一需要修改的地方只有namespace,根据实际情况定义
apiVersion: v1
kind: ServiceAccount #  创建一个账户,主要用来管理NFS provisioner在k8s集群中运行的权限
metadata:name: nfs-client-provisionernamespace: default
---
kind: ClusterRole # 创建集群角色
apiVersion: rbac.authorization.k8s.io/v1
metadata:name: nfs-client-provisioner-runner # 角色名
rules: # 角色权限- apiGroups: [""]resources: ["persistentvolumes"] # 操作的资源 #pvverbs: ["get", "list", "watch", "create", "delete"] # 对该资源的操作权限- apiGroups: [""]resources: ["persistentvolumeclaims"] #pvcverbs: ["get", "list", "watch", "update"]- apiGroups: ["storage.k8s.io"]resources: ["storageclasses"] #storageclassesverbs: ["get", "list", "watch"]- apiGroups: [""]resources: ["events"]verbs: ["list", "watch", "create", "update","patch"]- apiGroups: [""]resources: ["endpoints"]verbs: ["create", "delete", "get", "list","watch", "patch", "update"]
---
kind: ClusterRoleBinding # 集群角色绑定
apiVersion: rbac.authorization.k8s.io/v1
metadata:name: run-nfs-client-provisioner
subjects: # 角色绑定对象- kind: ServiceAccountname: nfs-client-provisionernamespace: default
roleRef:kind: ClusterRole # 集群角色name: nfs-client-provisioner-runnerapiGroup: rbac.authorization.k8s.io
---
kind: Role # 创建角色
apiVersion: rbac.authorization.k8s.io/v1
metadata:name: leader-locking-nfs-client-provisioner # 角色名namespace: default # Role需要指定名称空间,ClusterRole全局可用不需要指定namespace
rules: # 角色权限- apiGroups: [""]resources: ["endpoints"]verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding # 角色绑定
apiVersion: rbac.authorization.k8s.io/v1
metadata:name: leader-locking-nfs-client-provisioner
subjects: # 角色绑定对象- kind: ServiceAccountname: nfs-client-provisionernamespace: default
roleRef: # 绑定哪个角色kind: Rolename: leader-locking-nfs-client-provisionerapiGroup: rbac.authorization.k8s.io

3.3 创建StorageClass,指定provisioner

创建nfs-client-provisioner.yaml文件

# 创建NFS资源的StorageClass
---
apiVersion: storage.k8s.io/v1
kind: StorageClass # 创建StorageClass
metadata:name: managed-nfs-storage
provisioner: nfs-storage   #这里的名称要和provisioner配置文件中的环境变量PROVISIONER_NAME保持一致
parameters:  server: "10.16.216.221 " path: "/nfs/data/k8s"readOnly: "false"
---
# 创建NFS provisioner
apiVersion: apps/v1
kind: Deployment # 部署nfs-client-provisioner
metadata:name: nfs-client-provisionerlabels:app: nfs-client-provisionernamespace: default #与RBAC文件中的namespace保持一致
spec:replicas: 1selector:matchLabels:app: nfs-client-provisionerstrategy:type: Recreatetemplate:metadata:labels:app: nfs-client-provisionerspec:serviceAccountName: nfs-client-provisioner # 指定serviceAccount!containers:- name: nfs-client-provisionerimage: registry.cn-hangzhou.aliyuncs.com/open-ali/nfs-client-provisioner #镜像地址volumeMounts: # 挂载数据卷到容器指定目录- name: nfs-client-rootmountPath: /persistentvolumesenv:- name: PROVISIONER_NAME # 配置provisioner的Namevalue: nfs-storage     # 确保该名称与 StorageClass 资源中的provisioner名称保持一致- name: NFS_SERVER       #绑定的nfs服务器value: 10.16.216.221 - name: NFS_PATH   #绑定的nfs服务器目录value: /nfs/data/k8svolumes: # 申明nfs数据卷- name: nfs-client-rootnfs:server: 10.16.216.221 path: /nfs/data/k8s

3.4 创建pod测试

创建pod,声明PVC进行测试

# 申明一个PVC,指定StorageClass
kind: PersistentVolumeClaim
apiVersion: v1
metadata:name: test-claim
spec:storageClassName: managed-nfs-storageaccessModes:- ReadWriteManyresources:requests:storage: 10Mi
---
# 创建测试pod,查看是否可以正常挂载    
kind: Pod
apiVersion: v1
metadata:name: test-pod
spec:containers:- name: test-podimage: nginx:1.20.0imagePullPolicy: IfNotPresentvolumeMounts:- name: nfs-pvc # 挂载数据卷mountPath: "/usr/share/nginx/html"restartPolicy: "Never"volumes:- name: nfs-pvcpersistentVolumeClaim: # 数据卷挂载的是pvcclaimName: test-claim  #与PVC名称保持一致

 

进入pod,向指定目录写文件

 验证成功

相关文章:

K8S存储总结持久化存储解决方案(以NFS为例)

目录 K8S存储 一、emptydir 1. emptydir是什么 2. emptydir例子 二、hostpath hostpath 是什么 hostpath 例子 弊端 三、持久化存储 1.Persistent Volume(PV) 2.Persistent Volume Claim(PVC) 3.PV/PVC结合NFS使用实践(持久存储) 1. NFS服务…...

vue3+ts项目02-安装eslint、prettier和sass

创建项目 项目创建 安装eslint yarn add eslint -D生成配置文件 npx eslint --init安装其他插件 yarn add -D eslint-plugin-import eslint-plugin-vue eslint-plugin-node eslint-plugin-prettier eslint-config-prettier eslint-plugin-node babel/eslint-parser vue-e…...

sface人脸相似度检测

sface人脸相似度检测,基于OPENCV,人脸检测采用yunet,人脸识别采用sface,支持PYTHON/C开发,图片来自网络,侵权请联系本人立即删除 yunet人脸检测sface人脸识别,检测两张图片的人脸相似度...

设计模式 - 行为型模式考点篇:模板方法模式(概念 | 案例实现 | 优缺点 | 使用场景)

目录 一、行为型模式 1.1、模板方法模式 1.1.1、概念 1.1.2、案例实现 1.1.3、优缺点 1.1.4、使用场景 一、行为型模式 一句话概括行为型模式 行为型模式:类或对象间如何交互、如何划分职责,从而更好的完成任务. 1.1、模板方法模式 1.1.1、概念 …...

因为计算机中找不到mfc140.dll无法启动修复步骤分享

mfc140.dll是Microsoft Foundation Class Library(微软基础类库)的一个组件,它是许多Windows应用程序(尤其是使用MFC编写的程序)所必需的动态链接库。MFC(Microsoft Foundation Classes)是一个用…...

【Python基础-Pandas】解决Pandas会自动把None转成NaN的问题

1. 背景 目前dataframe中的数据如下,power字段表示功率值,第一个值为20.0,第二个值为None。需要计算电量值,电量 功率 * 0.25,并保存到energy字段中,如果功率值为None,则电量值也为None。 pow…...

学习记忆——数学篇——案例——代数——方程——一元二次方程

重点记忆法 a x 2 b x c 0 ax^2bxc0 ax2bxc0 整体可以由: 根(多少,正负,区间) ⟹ \Longrightarrow ⟹ △ △ △ ⟹ \Longrightarrow ⟹ 求根公式 x 1 , 2 x_{1,2} x1,2​ − b △ 2 a \frac{-b\sqrt{△}}{2a} 2…...

接口测试及常用接口测试工具

首先,什么是接口呢? 接口一般来说有两种,一种是程序内部的接口,一种是系统对外的接口。 系统对外的接口:比如你要从别的网站或服务器上获取资源或信息,别人肯定不会把数据库共享给你,他只能给你…...

【java学习】数组中涉及的常见算法-含冒泡排序(11)

文章目录 1. 最大值、最小值、总和、平均数2. 数组的复制、反转3. 数组元素的排序3.1. 排序方式3.1.1. 冒泡排序 1. 最大值、最小值、总和、平均数 代码如下: public class Test1 {public static void main (String[] args) {int[] arr new int[] {4,2,7,1,3,5};/…...

useEffect Hook使用纠错

React的useEffect Hook是用于处理副作用操作的重要工具。副作用操作通常包括数据获取、订阅、手动DOM操作等。在使用useEffect时,有一些常见的错误和最佳实践需要注意。 以下是一些常见的useEffect使用错误以及如何解决它们的建议: 未清除订阅或定时器…...

LeetCode【739】每日温度

题目: 思路: https://www.bilibili.com/video/BV1PJ411H7P7/?spm_id_from333.337.search-card.all.click&vd_source2f682a60feabf0f730ad09e0f980ce83 单调栈 思考: 解决栈类问题,思考入栈,出栈条件;…...

核桃派walnutpi添加红外遥控器键盘映射(其他的linux板子同理)ir-keytable

01studio终于又发布新品了,全志h616 linux开发板核桃派,正好我也打算学习linux,做为我的启蒙公司,必须支持果断入了一个。 这个板子自带红外接收头,比较少见,一般都需要自己加,看官网文档&…...

cartographer(2)-launch-lua的配置

1.了解bag 1roscore2rosbag info rslidar-outdoor-gps.bag了解bag中topic的名称与类型duration: 3:33s types: geometry_msgs?QuaternionStamped nav_msgs_Odometry sensor_msgs/Imu sensor_msgs/IaserScan sensor_msgs/NavSatFix sensor_msgs/PointCloud2 tf2 msgs/TFMe…...

【C++设计模式之责任链模式:行为型】分析及示例

简介 责任链模式是一种行为型设计模式,它允许将请求沿着处理链传递,直到有一个处理器能够处理该请求。这种模式将请求的发送者和接收者解耦,同时提供了更高的灵活性和可扩展性。 描述 责任链模式由多个处理器组成一个处理链,每…...

如何选择编程语言Python Go还是Rust?

选择编程语言需要考虑多个方面,包括语言的特性、社区支持、工作机会、学习曲线等。下面是关于Python Go和Rust的一些介绍。 1.基本语法 1. Python: Python 是一种脚本语言,以简洁、易读的语法著称。以下是 Python 的基本语法示例: # Hello…...

CAN和CANFD通信介绍

CAN(Controller Area Network,控制器局域网)是一种串行通信技术,专门用于在汽车电子控制单元(ECU)之间实现可靠的数据交换。 CAN协议介绍 电子化 汽车近年来的发展呈现出以电子化为主的特点。电子化的主…...

解决网页 H5 对接微信 JSSDK 后自定义分享和跳转APP等没效果

导致的原因 在聊天窗口直接点击一个文本链接,现在微信JSSDK已经不支持这样使用。 解决办法1 将文本链接生成一个二维码,然后微信扫码进入这个链接。 解决办法2 将这个文本链接收藏,然后从收藏打开这个链接。...

基于DeOldify的给黑白照片、视频上色

老照片常常因为当时的技术限制而只有黑白版本。然而现代的 AI 技术,如 DeOldify,可以让这些照片重现色彩。 本教程将详细介绍如何使用 DeOldify 来给老照片上色。 文章目录 准备工作执行代码图片上色视频上色 总结 准备工作 这里用 git clone 命令克隆…...

腾讯云饥荒服务器配置选择和费用价格表

腾讯云饥荒服务器配置选择和费用价格表,腾讯云饥荒服务器配置怎么选择?CPU内存几核几G合适?饥荒服务器配置:建议2核4G起步,可以加载更多的MOD,不会太卡。因为15MOD启动后会占用1GB多内存,这是32…...

聊聊MySql索引的类型以及失效场景

文章目录 概念常见的索引1.B树索引2.哈希索引3.全文索引4.空间索引5.聚集索引 如何设计合理?1.明确索引需求2.选择索引列3.选择索引类型4.考虑索引维护开销5.设计联合索引6.删除不必要索引7.关注索引统计信息8.测试查询效果 常见不生效场景1.全表扫描2.索引列计算3.…...

零代码编程:用ChatGPT批量调整文件名称中的词汇顺序

文件夹里面很多文件,需要批量挑战标题中的一些词组顺序:“Peppa Pig - Kylie Kangaroo (14 episode _ 4 season) [HD].mp4”这个文件名改成“14 episode _ 4 season _ Peppa Pig - Kylie Kangaroo.mp4”,可以在ChatGPT中输入提示词&#xff1…...

stm32 hal库 st7789 1.54寸lcd

文章目录 前言一、软件spi1.cubemx配置2.源码文件 二、硬件spi1.cubemx配置2.源码文件3.小小修改 总结 前言 1.54寸lcd 240*240 一、软件spi 1.cubemx配置 一定要注意把这几个东西上拉。 使用c8 2.源码文件 我使用的是中景园的源码,他本来是是标准库的稍微修改…...

【arm实验1】GPIO实验-LED灯的流水亮灭

linuxlinux:~/study/01-asm$ cat asm-led.S .text .global _start _start: 1.设置GPIOE寄存器的时钟使能 RCC_MP_AHB4ENSETR[4]->1 0x50000a28 LDR R0,0X50000A28 LDR R1,[R0] 从r0为起始地址的4字节数据取出放在R1 ORR R1,R1,#(0x1<<4) 第4位设置为1 ORR R…...

MySQL关联数据表操作方式

1、准备工作&#xff08;创建数据表&#xff09; create table employee( emp_id int primary key, name varchar(20), birth_date date, sex varchar(1), salary int, branch_id int, sup_id int );create table client( client_id int primary key, client_name varchar(20)…...

SMOS数据处理,投影变换,‘EPSG:6933‘转为‘EPSG:4326‘

在处理SMOS数据时&#xff0c;遇到了读取nc数据并存为tif后&#xff0c;影像投影无法改变&#xff0c;因此全球数据无法重叠。源数据的投影为EPSG:6933&#xff0c;希望转为EPSG:4326。 解决代码。 python import os import netCDF4 as nc import numpy as np from osgeo impo…...

游戏服务端性能测试实战总结

导语&#xff1a;近期经历了一系列的性能测试&#xff0c;涵盖了Web服务器和游戏服务器的领域。在这篇文章中&#xff0c;我将会对游戏服务端所做的测试进行详细整理和记录。需要注意的是&#xff0c;本文着重于记录&#xff0c;而并非深入的编程讨论。在这里&#xff0c;我将与…...

塔望食观察 | 中国海参产业发展现状及挑战

海参&#xff0c;一个古老的物种&#xff0c;堪称海底活化石&#xff0c;据资料显示&#xff0c;海参在地球上存活超过6亿年&#xff0c;比恐龙还早。海参的药用、食疗和营养滋补价值极高&#xff0c;清朝学者赵学敏编的《本草纲目拾遗》有这样的叙述&#xff1a;“海参性温补&…...

springboot 捕获特点异常信息并处理

前端获取效果图 springboot 捕获特点异常信息并处理 import com.one.utils.JSONResult; //JSONResult定义处理结果对象 import org.springframework.web.bind.annotation.ExceptionHandler...

【Spring框架学习3】Spring Bean的作用域 及 生命周期

一、Spring Bean的作用域有哪些&#xff1f; Spring框架支持以下五种Bean的作用域&#xff1a; Singleton&#xff1a;这是默认的作用域&#xff0c;在每个Spring IoC容器中只有一个Bean的实例(IoC初始化后)。Spring 中的 bean 默认都是单例的&#xff0c;是对单例设计模式的…...

多线程并发篇---第四篇

系列文章目录 文章目录 系列文章目录一、Java中synchronized 和 ReentrantLock 有什么不同?二、有三个线程T1,T2,T3,如何保证顺序执行?三、SynchronizedMap和ConcurrentHashMap有什么区别?一、Java中synchronized 和 ReentrantLock 有什么不同? 相似点: 这两种同步方式有…...