local-path-provisioner的使用(hostPath、local、local-path-provisioner三者对比)
前言
环境:k8s 1.22.17 、centos7.9
有时候,为了使用本地服务器上的磁盘存储资源,我们会使用hostPath这种方式来为k8s提供本地存储,本篇就来对比一下hostPath、local这两种使用本地服务器储存的方案,从而引出第三种local-path本地储存。
hostPath卷
hostPath 卷能将主机节点文件系统上的文件或目录挂载到你的 Pod 中,但是我们知道,pod重启后会随机调度,所以就需要为pod固定主机节点。下面仅演示hostPath的使用方法,挂载一个宿主机上的目录到pod中:
#hostPath示例一
#pod中直接使用hostPath卷
[root@matser data]# vim nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-179namespace: default
spec:replicas: 1selector:matchLabels:app: nginx-179template:metadata:labels:app: nginx-179spec:nodeName: master #固定pod能调度的节点,确保pod重启后仍能访问之前的数据containers:- image: nginx:1.7.9imagePullPolicy: IfNotPresentname: nginx-containerports:- containerPort: 80name: httpprotocol: TCPvolumeMounts:- mountPath: /var/log/nginx #持久化日志name: hostpath-volumerestartPolicy: Alwaysvolumes:- name: hostpath-volumehostPath: #hostPath卷path: /data/nginx #使用宿主机上的/data/nginx目录type: DirectoryOrCreatekubectl apply -f nginx.yaml
kubectl delete -f nginx.yaml
#hostPath示例二
#pod中使用pvc,pvc与pv关联,pv中定义hostPath,pod固定调度节点
[root@matser data]# cat hostPath.yaml
apiVersion: v1
kind: PersistentVolume
metadata:name: hostpath-pvlabels:type: local
spec:storageClassName: ""capacity:storage: 10GiaccessModes:- ReadWriteManyhostPath:path: "/data/nginx"type: DirectoryOrCreate
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: hostpath-pvc
spec:accessModes:- ReadWriteManyresources:requests:storage: 10Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-179namespace: default
spec:replicas: 1selector:matchLabels:app: nginx-179template:metadata:labels:app: nginx-179spec:nodeName: master #固定pod能调度的节点,确保pod重启后仍能访问之前的数据containers:- image: nginx:1.7.9imagePullPolicy: IfNotPresentname: nginx-containerports:- containerPort: 80name: httpprotocol: TCPvolumeMounts:- mountPath: /var/log/nginxname: hostpath-volumerestartPolicy: Alwaysvolumes:- name: hostpath-volumepersistentVolumeClaim: #使用pvcclaimName: hostpath-pvc
[root@matser data]#
#创建完成pv和pvc,当pvc与pv绑定之后发现并没有创建hostPath目录,只有当pod调度到节点上时才会真正创建hostPath目录。
#当pod重启之后,如果pod没有指定调度的节点,则仍然会在其他节点创建hostPath目录,所以为了使pod能访问之前的数据,都要把pod固定调度到指定节点。
#hostPath示例三
#pod中使用pvc,pvc与pv关联,pv中定义hostPath且定义节点亲和性#为节点打标签,只打了一个节点,如果是多个节点,那么pod会随机调度到这些节点数据就没有唯一性而言。
[root@matser data]# kubectl label nodes node2 storage=true
[root@matser data]# cat hostPath.yaml
apiVersion: v1
kind: PersistentVolume
metadata:name: hostpath-pvlabels:type: local
spec:storageClassName: ""capacity:storage: 10GiaccessModes:- ReadWriteManyhostPath:path: "/data/nginx"type: DirectoryOrCreatenodeAffinity: #定义了节点亲和性required:nodeSelectorTerms:- matchExpressions: - key: storageoperator: Invalues:- "true"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: hostpath-pvc
spec:accessModes:- ReadWriteManyresources:requests:storage: 10Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-179namespace: default
spec:replicas: 1selector:matchLabels:app: nginx-179template:metadata:labels:app: nginx-179spec: #pod中不在指定调度节点而是有pv中定义了节点亲和性,k8s会根据pv的节点亲和性来判断pod要调度到哪些节点containers:- image: nginx:1.7.9imagePullPolicy: IfNotPresentname: nginx-containerports:- containerPort: 80name: httpprotocol: TCPvolumeMounts:- mountPath: /var/log/nginxname: hostpath-volumerestartPolicy: Alwaysvolumes:- name: hostpath-volumepersistentVolumeClaim:claimName: hostpath-pvc
[root@matser data]#
hostPath卷总结:我们发现,无论是pod中直接使用hostPath,还是pod调用pvc,pvc调用pv,pv中使用hostPath,两者本质上没啥区别,示例1和实例2中都在pod中固定了调度节点,而实例3是在pv中定义了节点亲和性。
local卷
local 卷所代表的是某个被挂载的本地存储设备,例如磁盘、分区或者目录。
local 卷只能用作静态创建的持久卷。不支持动态配置。
与 hostPath 卷相比,local 卷能够以持久和可移植的方式使用,而无需手动将 Pod 调度到节点。系统通过查看 PersistentVolume 的节点亲和性配置,就能了解卷的节点约束。然而,local 卷仍然取决于底层节点的可用性,并不适合所有应用程序。 如果节点变得不健康,那么 local 卷也将变得不可被 Pod 访问。使用它的 Pod 将不能运行。 使用 local 卷的应用程序必须能够容忍这种可用性的降低,以及因底层磁盘的耐用性特征而带来的潜在的数据丢失风险。
下面是一个使用 local 卷和 nodeAffinity 的持久卷示例:
#local的使用和上面示例三hostPath卷的使用没多大区别,如下
[root@matser data]# cat local.yaml
apiVersion: v1
kind: PersistentVolume
metadata:name: local-pv
spec:capacity:storage: 10GivolumeMode: FilesystemaccessModes:- ReadWriteManypersistentVolumeReclaimPolicy: Retainlocal: #这里定义的是local卷,path字段定义的是目录,这个目录必须先创建path: /data/nginxnodeAffinity: #节点亲和性required:nodeSelectorTerms:- matchExpressions:- key: storageoperator: Invalues:- "true"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: local-pvc
spec:accessModes:- ReadWriteManyresources:requests:storage: 10Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-179namespace: default
spec:replicas: 1selector:matchLabels:app: nginx-179template:metadata:labels:app: nginx-179spec:containers: #没有定义节点选择器,k8s会根据pv定义的节点亲和性来调度pod- image: nginx:1.7.9imagePullPolicy: IfNotPresentname: nginx-containerports:- containerPort: 80name: httpprotocol: TCPvolumeMounts:- mountPath: /var/log/nginxname: local-volumerestartPolicy: Alwaysvolumes:- name: local-volumepersistentVolumeClaim:claimName: local-pvc
[root@matser data]#
使用 local 卷时,你需要设置 PersistentVolume 对象的 nodeAffinity 字段。 Kubernetes 调度器使用 PersistentVolume 的 nodeAffinity 信息来将使用 local 卷的 Pod 调度到正确的节点。
PersistentVolume 对象的 volumeMode 字段可被设置为 "Block" (而不是默认值 "Filesystem"),以将 local 卷作为原始块设备暴露出来。
使用 local 卷时,建议创建一个 StorageClass 并将其 volumeBindingMode 设置为 WaitForFirstConsumer。要了解更多详细信息,请参考 local StorageClass 示例。 延迟卷绑定的操作可以确保 Kubernetes 在为 PersistentVolumeClaim 作出绑定决策时,会评估 Pod 可能具有的其他节点约束,例如:如节点资源需求、节点选择器、Pod 亲和性和 Pod 反亲和性。
总结:local卷和hostPath没啥区别,都可以通过在pv中定义节点亲和性,这样使用该pv的pod就会被k8s调度到指定的节点。唯一区别的是,local可以使用裸设备磁盘、分区、目录,而hostPath只能是文件或目录。
local-path-provisioner动态供给localPath或local卷
无论是hostPath卷还是local 卷,他们都不支持动态扩容,而local-path-provisioner很好的弥补了这一缺陷。
kubernetes-sigs版:https://github.com/kubernetes-sigs/sig-storage-local-static-provisioner
注意kubernetes-sigs版不支持动态扩容/动态供给dynamically provisioning,所以建议使用rancher版。这里介绍的都是rancher版。
rancher版:https://github.com/rancher/local-path-provisioner
下载local-path-provisioner yml文件
# 进入https://github.com/rancher/local-path-provisioner,里面有很详细的安装教程
#安装local-path-provisioner
wget https://raw.githubusercontent.com/rancher/local-path-provisioner/v0.0.24/deploy/local-path-storage.yaml
查看官方configmap解析
#local-path-storage.yaml中定义了一个configmap,我们先来看下官方样例中对这个cm的介绍.
provisioner的配置存储在一个configmap中,configmap包含1个json文件配置即config.json、1个Pod模板即helperPod.yaml、两个bash脚本即setup和teardown,如下所示:kind: ConfigMap
apiVersion: v1
metadata:name: local-path-confignamespace: local-path-storage
data:config.json: |-{"nodePathMap":[{"node":"DEFAULT_PATH_FOR_NON_LISTED_NODES","paths":["/opt/local-path-provisioner"]},{"node":"yasker-lp-dev1","paths":["/opt/local-path-provisioner", "/data1"]},{"node":"yasker-lp-dev3","paths":[]}]}setup: |-#!/bin/shset -eumkdir -m 0777 -p "$VOL_DIR"teardown: |-#!/bin/shset -eurm -rf "$VOL_DIR"helperPod.yaml: |-apiVersion: v1kind: Podmetadata:name: helper-podspec:containers:- name: helper-podimage: busyboxnodePathMap字段是一个数组,用于自定义在每个节点上存储数据的位置。
如果一个节点没有在nodePathMap上列出,而Kubernetes想要在它上面创建卷,那么default_path_for_non_listd_nodes中指定的路径将被用于分配。
如果nodePathMap上列出了一个节点,则将使用paths中指定的路径进行发放。
如果仅列出了节点,但路径设置为[],则提供程序将拒绝在该节点上提供服务。
如果节点上指定了多个路径,则在provision供给时将随机选择路径。
规则:路径必须是绝对路径,路径不能是根/,一个节点可以有多个不同的路径,不能重复列出节点,一个节点不能列出相同的路径。sharedFileSystemPath允许提供者使用同时挂载在所有节点上的文件系统。在这种情况下,支持所有访问模式:ReadWriteOnce, ReadOnlyMany和ReadWriteMany存储声明。
另外,volumeBindingMode: Immediate可以在StorageClass定义中使用。
请注意nodePathMap和sharedFileSystemPath是互斥的。如果使用sharedFileSystemPath,则nodePathMap必须设置为[]。setup脚本:在创建卷之前运行setup脚本来在节点上准备卷目录。
teardown脚本:删除卷后运行teardown脚本,清理节点上的卷目录。
helperPod.yaml模板:用于创建一个helper pod,用这个helper pod来执行setup和teardown脚本。provisioner支持自动热重载,即可以在线修改local-path-config配置,provisioner会自动生效配置,从local-path-provisioner pod中可以查看日志,如果provisioner生效失败,则provisioner仍然会保持上一个有效的local-path-config配置。
#指定local-path-provisioner创建的卷类型,可以通过以下2种方式指定local-path-provisioner要给你创建什么类型的卷
当你手动创建PVC时,在pvc的中添加以下注解:
annotations:volumeType: <local or hostPath>亦可以在存储类的定义中添加以下注解:
StorageClass:
annotations:defaultVolumeType: <local or hostPath>需要注意的是:StorageClass的注释将应用于使用它的所有卷,如果PVC提供了注释,则覆盖SC上的注释。如果这两个注解都没有提供,那么默认使用hostPath。
开始安装local-path-provisioner
#查看修改local-path-storage.yaml内容
[root@matser data]# cat local-path-storage.yaml
apiVersion: v1
kind: Namespace
metadata:name: local-path-storage
---
apiVersion: v1
kind: ServiceAccount
metadata:name: local-path-provisioner-service-accountnamespace: local-path-storage
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:name: local-path-provisioner-role
rules:- apiGroups: [ "" ]resources: [ "nodes", "persistentvolumeclaims", "configmaps" ]verbs: [ "get", "list", "watch" ]- apiGroups: [ "" ]resources: [ "endpoints", "persistentvolumes", "pods" ]verbs: [ "*" ]- apiGroups: [ "" ]resources: [ "events" ]verbs: [ "create", "patch" ]- apiGroups: [ "storage.k8s.io" ]resources: [ "storageclasses" ]verbs: [ "get", "list", "watch" ]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:name: local-path-provisioner-bind
roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: local-path-provisioner-role
subjects:- kind: ServiceAccountname: local-path-provisioner-service-accountnamespace: local-path-storage
---
apiVersion: apps/v1
kind: Deployment
metadata:name: local-path-provisionernamespace: local-path-storage
spec:replicas: 1selector:matchLabels:app: local-path-provisionertemplate:metadata:labels:app: local-path-provisionerspec:serviceAccountName: local-path-provisioner-service-accountcontainers:- name: local-path-provisionerimage: rancher/local-path-provisioner:v0.0.24imagePullPolicy: IfNotPresentcommand:- local-path-provisioner- --debug- start- --config- /etc/config/config.jsonvolumeMounts:- name: config-volumemountPath: /etc/config/env:- name: POD_NAMESPACEvalueFrom:fieldRef:fieldPath: metadata.namespacevolumes:- name: config-volumeconfigMap:name: local-path-config
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: local-pathannotations: #添加了注释,表示StorageClass提供哪些卷类型,可以是hostPath和local,默认值为hostPathvolumeType: hostPath
provisioner: rancher.io/local-path
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Retain #修改为Retain,原来默认是Delete
allowVolumeExpansion: true #允许扩容
---
kind: ConfigMap
apiVersion: v1
metadata:name: local-path-confignamespace: local-path-storage
data:config.json: |-{"nodePathMap":[{"node":"DEFAULT_PATH_FOR_NON_LISTED_NODES", #指定其它节点使用/data/local-path-provisioner目录作为存储"paths":["/data/local-path-provisioner"] #存储目录,会自动创建},{"node":"master", #指定使用master节点的/opt/local-path-provisioner目录作为存储"paths":["/opt/local-path-provisioner"] #存储目录,会自动创建} #如果不想让指定节点作为存储节点,则需显示的列出来,并且将该节点的path设置[]]}setup: |-#!/bin/shset -eumkdir -m 0777 -p "$VOL_DIR"teardown: |-#!/bin/shset -eurm -rf "$VOL_DIR"helperPod.yaml: |-apiVersion: v1kind: Podmetadata:name: helper-podspec:containers:- name: helper-podimage: busyboximagePullPolicy: IfNotPresent
[root@matser data]# kubectl apply -f local-path-storage.yaml
创建pod、pvc进行验证
[root@matser data]# cat local-path.yaml
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: local-path-pvc
spec:storageClassName: local-pathaccessModes:- ReadWriteOnceresources:requests:storage: 10Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-179namespace: default
spec:replicas: 1selector:matchLabels:app: nginx-179template:metadata:labels:app: nginx-179spec:containers:- image: nginx:1.7.9imagePullPolicy: IfNotPresentname: nginx-containerports:- containerPort: 80name: httpprotocol: TCPvolumeMounts:- mountPath: /usr/share/nginx/htmlname: local-path-volumerestartPolicy: Alwaysvolumes:- name: local-path-volumepersistentVolumeClaim:claimName: local-path-pvc
[root@matser data]# kubectl apply -f local-path.yaml#验证发现,pod随机调度到node2节点,并且已经自动创建了/data/local-path-provisioner/目录,并且存在权限是777的pvc-e04ceb06-1a30-4b83-8215-7786850f3d93_default_local-path-pvc目录,所有动态分配pv验证成功了。
#验证过程中发现,pv其实还是具有节点亲和性的,这说明,当节点挂掉的时候,pod无法重新调度到其他节点,因为pod使用的pv定义节点亲和性,
#这也难怪,provisioner创建的卷类型本身就是hostPath或local卷。
[root@matser data]# kubectl get pv pvc-0926a91c-854a-400f-be54-ad3fdd5e0051 -oyaml
apiVersion: v1
kind: PersistentVolume
metadata:........hostPath: #其实卷的类型仍是hostPathpath: /opt/local-path-provisioner/pvc-0926a91c-854a-400f-be54-ad3fdd5e0051_default_local-path-pvctype: DirectoryOrCreatenodeAffinity: #具有节点亲和性required:nodeSelectorTerms:- matchExpressions:- key: kubernetes.io/hostnameoperator: Invalues:- master
........
存在的问题
#发现如果在pod中定义nodeName想让pod调度到某台节点,pod会无法调度,pod的events报错如下:
[root@matser data]# kubectl describe pod nginx-1791-5d444554cb-b2mvq
Events:Type Reason Age From Message---- ------ ---- ---- -------Warning FailedMount 6s kubelet Unable to attach or mount volumes: unmounted volumes=[local-path-volume], unattached volumes=[local-path-volume kube-api-access-c7h9m]: error processing PVC default/local-path-pvc1: PVC is not bound
查看pvc的报错如下:
[root@matser data]# kubectl describe pvc local-path-pvc1
Events:Type Reason Age From Message---- ------ ---- ---- -------Normal WaitForFirstConsumer 5s (x2 over 15s) persistentvolume-controller waiting for first consumer to be created before binding这是怎么回事呢?pod显示pvc没有绑定,pvc又在等待pod来消费,这不是死循环吗。如果pod中不指定nodeName,让pod随机调度,是能正常创建的,但是一旦定义了nodeName就不能正常了,这是什么回事呢?
local-path-provisioner仅支持ReadWriteOnce访问模式
在写pvc的时候,如果将accessModes写成 ReadWriteMany,则pvc将一直处于penging状态,查看local-path-provisioner pod的日志或kubectl describe pvc local-path-pvc 发现了以下报错:
Type Reason Age From Message---- ------ ---- ---- -------Normal WaitForFirstConsumer 11m persistentvolume-controller waiting for first consumer to be created before bindingNormal ExternalProvisioning 102s (x42 over 11m) persistentvolume-controller waiting for a volume to be created, either by external provisioner "rancher.io/local-path" or manually created by system administratorNormal Provisioning 52s (x7 over 11m) rancher.io/local-path_local-path-provisioner-6464fcbd8b-bhmqs_d68778ed-2a18-4f48-9788-1b2dc0f2b88f External provisioner is provisioning volume for claim "default/local-path-pvc"Warning ProvisioningFailed 52s (x7 over 11m) rancher.io/local-path_local-path-provisioner-6464fcbd8b-bhmqs_d68778ed-2a18-4f48-9788-1b2dc0f2b88f failed to provision volume with StorageClass "local-path": Only support ReadWriteOnce access mode
[root@matser data]# kubectl describe pvc local-path-pvc
#怎么local-path-provisioner创建的pv仅支持ReadWriteOnce访问模式而已的呢?
卸载local-path-provisioner
#1、手动删除pv,确保已经没有pv是使用local-path 这个存储类的
#2、kubectl delete -f local-path-storage.yaml
#3、手动删除节点上的目录
总结
1、pod中直接使用hostPath来挂载宿主机的指定目录,但是为了防止pod重启后没有调度到上一次调度的宿主机节点,所以pod中需要定义nodeName指定调度主机。
2、可以在pv中使用hostPath,然后创建pvc与pv进行绑定,然后pod中使用pvc即可,pod中仍需要定义nodeName指定调度主机。
3、可以在pv中使用hostPath并且pv中定义节点亲和性,然后创建pvc与pv进行绑定,然后pod中使用pvc即可,此时pod中不需要定义nodeName指定调度主机,k8s会根据pv中定义的节点亲和性来选择调度pod,这样其实也是间接的指定了pod要调度的主机。
4、local的使用和上面第3点相同,都是在pv中定义节点亲和性,local与hostPath的区别在于,local可以使用裸设备、目录、分区,而hostPath只能是目录或文件。
5、local和hostPath都没有动态供给,都是手动的。
6、引入local-path-provisioner只是为了实现local或hostPath的动态供给。
7、创建一个local-path-provisioner 的pod、存储类、cm、服务账号等资源对象来实现动态供给。
8、本质上local-path-provisioner提供的卷仍是hostPath或local,所以local-path-provisioner提供的pv仍是具有节点亲和性的,这就说明当宿主机挂机了的时候,由于pod绑定的pv具有节点亲和性,所以pod无法在其他节点重新调度,pod就会存在故障。这其实就是hostPath、local卷的劣势。
9、使用local-path-provisioner动态供给pv,发现pod无法使用nodeName节点选择器,这一点有待研究。
10、使用local-path-provisioner动态供给pv,pvc只能是ReadWriteOnce,因为local-path-provisioner pod显示StorageClass "local-path": Only support ReadWriteOnce access mode
相关文章:
local-path-provisioner的使用(hostPath、local、local-path-provisioner三者对比)
前言 环境:k8s 1.22.17 、centos7.9 有时候,为了使用本地服务器上的磁盘存储资源,我们会使用hostPath这种方式来为k8s提供本地存储,本篇就来对比一下hostPath、local这两种使用本地服务器储存的方案,从而引出第三种lo…...
命令行快捷键Mac Iterm2
原文:Jump forwards, backwards and delete a word in iTerm2 on Mac OS iTerm2并不允许你使用 ⌥← 或 ⌥→ 来跳过单词。 你也不能使用 ⌥backspace 来删除整个单词。 下面是在Mac OS上如何配置iTerm2以便能做到这一点的方法。 退格键 首先,你需要将你的左侧 ⌥…...
无涯教程-Lua - Modules(模块)
模块就像可以使用 require 加载的库,并且具有包含Table的单个全局名称,该模块可以包含许多函数和变量。 Lua 模块 其中一些模块示例如下。 -- Assuming we have a module printFormatter -- Also printFormatter has a funtion simpleFormat(arg) -- …...
url重定向
不安全的url跳转 不安全的url跳转问题可能发生在一切执行了url地址跳转的地方。 如果后端采用了前端传进来的(可能是用户传参,或者之前预埋在前端页面的url地址)参数作为了跳转的目的地,而又没有做判断的话 就可能发生"跳错对象"的问题。 url跳转比较直接的危害是…...
Linux 查看IP地址、子网掩码和网关的配置信息
使用以下命令来查看IP地址、子网掩码和网关的配置信息: 1,使用ifconfig命令: ifconfig 在输出中,找到你正在使用的网络接口的配置信息。你将看到类似以下的内容: eth0: flags4163<UP,BROADCAST,RUNNING,MULTICA…...
token
token验证流程: ①客户端使用用户名和密码请求登录。 ②服务端收到请求,验证用户名和密码。 ③验证成功后,服务端会生成一个token,然后把这个token发送给客户端。 ④客户端收到token后把它存储起来,可以放在cookie…...
利用awk筛选给定时间范围内的日志
文章目录 筛选给定时间范围内的日志时间时间戳什么是时间戳? 系统时间 筛选日志时间示例简单示例mktime()函数是什么 进阶示例 筛选给定时间范围内的日志 时间 时间的表示方法: 时间戳系统时间(年月日时间) 时间戳 什么是时间…...
ORACLE字符集概念学习
1、字符集的一些基本知识 字符集有很多种,最初的字符集是ASCII,由于ASCII支持的字符很有限,因此随后又出现了很多的编码方案,这些编码方案大部分都是包括了ASCII 的。EBCDIC编码是另一个比较基本的编码,它的部分字符采…...
时间复杂度、空间复杂度实践练习(力扣OJ)
目录 文章目录 前言 题目一:轮转数组 思路一: 思路二: 思路三: 题目二:消失的数字 思路一: 思路二: 思路三: 题目三:移除元素 思路: 总结 前言 想要编写高效的…...
JMeter(二十四)、使用吞吐量控制器实现不同的用户操纵不同的业务
一、需求 需求:博客系统,模拟用户真实行为,80%的用户阅读文章,20%的用户创建文章,创建文章的用户随机的删除或者修改文章。 二、脚本实现 80%的用户查看文章 20%用户创建文章 根据post_id是否能整除2,决…...
8.1Jmeter5.1:Jmeter SSL
Jmeter配置证书请求双向认证SSL的web接口 需求:需要通过Jmeter配置证书请求双向认证SSL的web接口 提供的证书:P12格式 备注:Jmeter需要导入的证书是keystore证书 那么要先把P12转成keystore文件 1、使用p12生成keystore文件 keytool介绍 这里需要提到提到jdk自带的key…...
7-7 找最小的字符串 (15 分)
7-7 找最小的字符串 (15 分) 本题要求编写程序,针对输入的N个字符串,输出其中最小的字符串。 输入格式: 输入第一行给出正整数N;随后N行,每行给出一个长度小于80的非空字符串,其中不会出现换行…...
Red Hat 安装MySQL 8.0与 Navicat
目录 Red Hat 安装 MySQL 8.0 1、更新软件包列表 2、安装MySQL服务器和客户端 3、启动MySQL服务 4、确保MySQL服务器正在运行 5、root 用户的密码 6、登录MySQL,输入mysql密码 7、MySQL默认位置 Red Hat 安装 Navicat 1、下载 Navicat 2、执行命令 Red H…...
17游刃有余:动手实现自己的RPC框架(三)
这篇文章我们来实现跨语言的网络通信。 跨语言RPC框架的必要性主要体现在以下几个方面: 解决不同语言之间的互操作性。不同语言使用的数据类型和序列化方式可能不同,跨语言 RPC 框架可以提供通用的编解码库和语言适配器,以便将不同语言的数据转换为通用的格式进行通信。实现…...
c语言——求n之内的素数和
//求n之内的素数和 //列如:2、3、5等 #include<stdio.h> #include<math.h> int main() {int i,j,k,n0;scanf("%d",&n);for(i2;i<n;i){k(int)sqrt(i);for(j2;j<k;j)if(i%j0)break;if(j>k){printf("%d,",i);n;if(n%50)p…...
【M波段2D双树(希尔伯特)小波多分量图像去噪】基于定向M波段双树(希尔伯特)小波对多分量/彩色图像进行降噪研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
unity TextMeshPro 富文本
<b>粗体标签</b> <i>斜体标签</i> <u>下划线标签</u> <s>删除线标签</s> <sup>上标标签</sup>前面后边上标签 5<sup>。</sup>C <sub>下标标签,如:</sub>H<sub&…...
【PyTorch】PyTorch、Cuda 的安装和使用
原文作者:我辈李想 版权声明:文章原创,转载时请务必加上原文超链接、作者信息和本声明。 文章目录 前言一、Anaconda 中安装 PyTorch 和 CUDA二、检查PyTorch和CUDA版本三、PyTorch的基本使用四、PyTorch调用cuda五、Matplotlib绘制Pytorch损…...
1.初识typescript
在很多地方的示例代码中使用的都是ts而不是js,为了使用那些示例,学习ts还是有必要的 JS有的TS都有,JS与TS的关系很像css与less ts在运行前需要先编译为js,浏览器不能直接运行ts 目录 1 编译TS的工具包 1.1 安装 1.2 基本…...
iPhone 6透明屏是什么?原理、特点、优势
iPhone 6透明屏是一种特殊的屏幕技术,它能够使手机屏幕变得透明,让用户能够透过屏幕看到手机背后的物体。 这种技术在科幻电影中经常出现,给人一种未来科技的感觉。下面将介绍iPhone 6透明屏的原理、特点以及可能的应用。 iPhone 6透明屏的原…...
Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
cf2117E
原题链接:https://codeforces.com/contest/2117/problem/E 题目背景: 给定两个数组a,b,可以执行多次以下操作:选择 i (1 < i < n - 1),并设置 或,也可以在执行上述操作前执行一次删除任意 和 。求…...
第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...
ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)
前言: 最近在做行为检测相关的模型,用的是时空图卷积网络(STGCN),但原有kinetic-400数据集数据质量较低,需要进行细粒度的标注,同时粗略搜了下已有开源工具基本都集中于图像分割这块,…...
【7色560页】职场可视化逻辑图高级数据分析PPT模版
7种色调职场工作汇报PPT,橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版:职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...
站群服务器的应用场景都有哪些?
站群服务器主要是为了多个网站的托管和管理所设计的,可以通过集中管理和高效资源的分配,来支持多个独立的网站同时运行,让每一个网站都可以分配到独立的IP地址,避免出现IP关联的风险,用户还可以通过控制面板进行管理功…...
NPOI操作EXCEL文件 ——CAD C# 二次开发
缺点:dll.版本容易加载错误。CAD加载插件时,没有加载所有类库。插件运行过程中用到某个类库,会从CAD的安装目录找,找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库,就用插件程序加载进…...
