Kubernetes入门学习(下)

Kubernetes入门学习(下)

文章目录

  • Kubernetes入门学习(下)
    • 运行有状态的应用
    • ConfigMap与Secret
      • ConfigMap
      • Secret
    • 卷(Volume)
    • StatefulSet(有状态应用集)
    • Headless Service(无头服务)
    • Mysql主从复制
    • Port-forward端口转发
    • Helm
    • 参考

运行有状态的应用

我们以MySQL数据库为例,在kubernetes集群中运行一个有状态的应用。

部署数据库几乎覆盖了kubernetes中常见的对象和概念:

  • 配置文件–ConfigMap
  • 保存密码–Secret
  • 数据存储–持久卷(PV)和持久卷声明(PVC)
  • 动态创建卷–存储类(StorageClass)
  • 部署多个实例–StatefulSet
  • 数据库访问–Headless Service
  • 主从复制–初始化容器和sidecar
  • 数据库调试–port-forward
  • 部署Mysql集群–helm

ConfigMap与Secret

ConfigMap

在Docker中,我们一般通过绑定挂载的方式将配置文件挂载到容器里。

在Kubernetes集群中,容器可能被调度到任意节点,配置文件需要能在集群任意节点上访问、分发和更新。

  1. 概述

    ConfigMap 用来在键值对数据库(etcd)中保存非加密数据。一般用来保存配置文件。

    ConfigMap 可以用作环境变量、命令行参数或者存储卷。

    ConfigMap 将环境配置信息与 容器镜像 解耦,便于配置的修改。

    ConfigMap 在设计上不是用来保存大量数据的。

    在 ConfigMap 中保存的数据不可超过 1 MiB。

    超出此限制,需要考虑挂载存储卷或者访问文件存储服务。

  2. 用法

    • ConfigMap配置示例
    • Pod中使用ConfigMap
    apiVersion: v1
    kind: Pod
    metadata:
      name: mysql-pod
      labels:
        app: mysql
    spec:
      containers:
        - name: mysql
          image: mysql:5.7
          env:
            - name: MYSQL_ROOT_PASSWORD
              value: "123456"
          volumeMounts:
            - mountPath: /var/lib/mysql
              name: data-volume
            - mountPath: /etc/mysql/conf.d
              name: conf-volume
              readOnly: true
      volumes:
        - name: conf-volume
          configMap:
            name: mysql-config
        - name: data-volume
          hostPath:
            # directory location on host
            path: /home/mysql/data
            # this field is optional
            type: DirectoryOrCreate
    ---
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: mysql-config
    data:
      # 类属性键;每一个键都映射到一个简单的值
      # player_initial_lives: "3"
      # ui_properties_file_name: "user-interface.properties"
    
      # 类文件键
      mysql.cnf: |
        [mysqld]
        character-set-server=utf8mb4
        collation-server=utf8mb4_general_ci
        init-connect='SET NAMES utf8mb4'
    
        [client]
        default-character-set=utf8mb4
    
        [mysql]
        default-character-set=utf8mb4
    

    通过kubectl edit cm mysql-config更改相关配置,可以在mysql-pod中/etc/mysql/conf.d中查看变化

Secret

  1. 概述

    Secret 用于保存机密数据的对象。一般由于保存密码、令牌或密钥等。

    data字段用来存储 base64 编码数据。

    stringData存储未编码的字符串。

    Secret 意味着你不需要在应用程序代码中包含机密数据,减少机密数据(如密码)泄露的风险。

    Secret 可以用作环境变量、命令行参数或者存储卷文件。

  2. 用法

    • Secret配置示例
    • 将Secret用作环境变量
    echo -n '123456' | base64
    echo 'MTIzNDU2' | base64 --decode
    
    apiVersion: v1
    kind: Secret
    metadata:
      name: mysql-password
    type: Opaque
    data:
      PASSWORD: MTIzNDU2Cg==
    ---
    apiVersion: v1
    kind: Pod
    metadata:
      name: mysql-pod
    spec:
      containers:
        - name: mysql
          image: mysql:5.7
          env:
            - name: MYSQL_ROOT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-password
                  key: PASSWORD
                  optional: false # 此值为默认值;表示secret已经存在了
          volumeMounts:
            - mountPath: /var/lib/mysql
              name: data-volume
            - mountPath: /etc/mysql/conf.d
              name: conf-volume
              readOnly: true
      volumes:
        - name: conf-volume
          configMap:
            name: mysql-config
        - name: data-volume
          hostPath:
            # directory location on host
            path: /home/mysql/data
            # this field is optional
            type: DirectoryOrCreate
    ---
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: mysql-config
    data:
      mysql.cnf: |
        [mysqld]
        character-set-server=utf8mb4
        collation-server=utf8mb4_general_ci
        init-connect='SET NAMES utf8mb4'
    
        [client]
        default-character-set=utf8mb4
    
        [mysql]
        default-character-set=utf8mb4
    

卷(Volume)

  1. 概述

    将数据存储在容器中,一旦容器被删除,数据也会被删除。

    卷是独立于容器之外的一块存储区域,通过**挂载(Mount)**的方式供Pod中的容器使用。

    • 使用场景
      • 卷可以在多个容器之间共享数据。
      • 卷可以将容器数据存储在外部存储或云存储上。
      • 卷更容易备份或迁移。
  2. 常见卷类型

    • 临时卷(Ephemeral Volume):与 Pod 一起创建和删除,生命周期与 Pod 相同

      • emptyDir - 作为缓存或存储日志
      • configMap 、secret、 downwardAPI - 给Pod注入数据
    • 持久卷(Persistent Volume):删除Pod后,持久卷不会被删除

      • 本地存储 - hostPath、 local
      • 网络存储 - NFS
    • 分布式存储 - Ceph(cephfs文件存储、rbd块存储)

    • 投射卷(Projected Volumes):projected 卷可以将多个卷映射到同一个目录上

  3. 后端存储

    一个集群中可以包含多种存储(如localNFSCeph或云存储)。

    每种存储都对应一个存储类(StorageClass) ,存储类用来创建和管理持久卷,是集群与存储服务之间的桥梁。

    管理员创建持久卷(PV)时,通过设置不同的StorageClass来创建不同类型的持久卷。

  4. 临时卷(EV)

    与 Pod 一起创建和删除,生命周期与 Pod 相同

    • emptyDir - 初始内容为空的本地临时目录

      emptyDir会创建一个初始状态为空的目录,存储空间来自本地的 kubelet 根目录或内存(需要将emptyDir.medium设置为"Memory")。

      通常使用本地临时存储来设置缓存、保存日志等。

      例如,将redis的存储目录设置为emptyDir

      apiVersion: v1
      kind: Pod
      metadata:
        name: redis-pod
      spec:
        containers:
        - name: redis
          image: redis
          volumeMounts:
          - name: redis-storage
            mountPath: /data/redis
        volumes:
        - name: redis-storage
          emptyDir: {}
      
    • configMap - 为Pod注入配置文件

    • secret - 为Pod注入加密数据

      注意:这里的configMap和secret代表的是卷的类型,不是configMap和secret对象。

      删除Pod并不会删除ConfigMap对象和secret对象。

      image.png

      configMap卷和Secret卷是一种特殊类型的卷,kubelet引用configMap和Secret中定义的内容,在Pod所在节点上生成一个临时卷,将数据注入到Pod中。删除Pod,临时卷也会被删除。

      临时卷位于Pod所在节点的/var/lib/kubelet/pods目录下。

      image.png

  5. 持久卷(PV)与持久卷声明(PVC)

    持久卷(PV)

    持久卷(Persistent Volume):删除Pod后,卷不会被删除

    • 本地存储

    • hostPath - 节点主机上的目录或文件(仅供单节点测试使用;多节点集群请用 local 卷代替)

      挂载hostPath

      hostPath的type值:

      DirectoryOrCreate目录不存在则自动创建。
      Directory挂载已存在目录。不存在会报错。
      FileOrCreate文件不存在则自动创建。 不会自动创建文件的父目录,必须确保文件路径已经存在。
      File挂载已存在的文件。不存在会报错。
      Socket挂载 UNIX 套接字。例如挂载/var/run/docker.sock进程
      apiVersion: v1
      kind: Pod
      metadata:
        name: mysql-pod
      spec:
        containers:
          - name: mysql
            image: mysql:5.7
            env:
              - name: MYSQL_ROOT_PASSWORD
                value: "123456"
            ports:
              - containerPort: 3306
            volumeMounts:
              - mountPath: /var/lib/mysql #容器中的目录
                name: data-volume
        volumes:
          - name: data-volume
            hostPath:
              # 宿主机上目录位置
              path: /home/mysql/data
              type: DirectoryOrCreate
      
    • local - 节点上挂载的本地存储设备(不支持动态创建卷)

    • 网络存储:NFS - 网络文件系统 (NFS)

    • 分布式存储:Ceph(cephfs文件存储、rbd块存储)

    创建持久卷(PV)

    创建持久卷(PV)是服务端的行为,通常集群管理员会提前创建一些常用规格的持久卷以备使用。

    hostPath仅供单节点测试使用,当Pod被重新创建时,可能会被调度到与原先不同的节点上,导致新的Pod没有数据。多节点集群使用本地存储,可以使用local

    创建local类型的持久卷,需要先创建存储类(StorageClass)

    本地存储类示例

    # 创建本地存储类
    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: local-storage
    provisioner: kubernetes.io/no-provisioner
    volumeBindingMode: Immediate
    

    local卷不支持动态创建,必须手动创建持久卷(PV)。

    创建local类型的持久卷,必须设置nodeAffinity(节点亲和性)。

    调度器使用nodeAffinity信息来将使用local卷的 Pod 调度到持久卷所在的节点上,不会出现Pod被调度到别的节点上的情况。

    注意:local卷也存在自身的问题,当Pod所在节点上的存储出现故障或者整个节点不可用时,Pod和卷都会失效,仍然会丢失数据,因此最安全的做法还是将数据存储到集群之外的存储或云存储上。

    创建PV PV示例/local卷示例

    # local-storage.yaml
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: local-pv-1
    spec:
      capacity:
        storage: 4Gi
      volumeMode: Filesystem
      accessModes:
      - ReadWriteOnce
      persistentVolumeReclaimPolicy: Delete
      storageClassName: local-storage #通过指定存储类来设置卷的类型
      local:
        path: /mnt/disks/ssd1 #手动创建
      nodeAffinity:
        required:
          nodeSelectorTerms:
          - matchExpressions:
            - key: kubernetes.io/hostname
              operator: In
              values:
              - k8s-node1
    

    卷的状态

    • Available(可用)-- 卷是一个空闲资源,尚未绑定到任何;
    • Bound(已绑定)-- 该卷已经绑定到某个持久卷声明上;
    • Released(已释放)-- 所绑定的声明已被删除,但是资源尚未被集群回收;
    • Failed(失败)-- 卷的自动回收操作失败。

    卷模式

    卷模式(volumeMode)是一个可选参数。

    针对 PV 持久卷,Kubernetes 支持两种卷模式(volumeModes):

    • Filesystem(文件系统)

    默认的卷模式。

    • Block(块)

    ​ 将卷作为原始块设备来使用。

    创建持久卷声明(PVC)

    持久卷声明(PVC)是用户端的行为,用户在创建Pod时,无法知道集群中PV的状态(名称、容量、是否可用等),用户也无需关心这些内容,只需要在声明中提出申请,集群会自动匹配符合需求的持久卷(PV)。

    Pod使用持久卷声明(PVC)作为存储卷。

    PVC示例

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: local-pv-claim
    spec:
      storageClassName: local-storage # 与PV中的storageClassName一致
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 2Gi
    

    访问模式

    • ReadWriteOnce:卷可以被一个节点以读写方式挂载,并允许同一节点上的多个 Pod 访问。
    • ReadOnlyMany:卷可以被多个节点以只读方式挂载。
    • ReadWriteMany:卷可以被多个节点以读写方式挂载
    • ReadWriteOncePod:卷可以被单个 Pod 以读写方式挂载。 集群中只有一个 Pod 可以读取或写入该 PVC。

    使用PVC作为卷

    Pod 的配置文件指定了 PersistentVolumeClaim,但没有指定 PersistentVolume。

    对 Pod 而言,PersistentVolumeClaim 就是一个存储卷。

    PVC卷示例

    apiVersion: v1
    kind: Pod
    metadata:
      name: mysql-pod
    spec:
      containers:
        - name: mysql
          image: mysql:5.7
          env:
            - name: MYSQL_ROOT_PASSWORD
              value: "123456"
          ports:
            - containerPort: 3306
          volumeMounts:
            - mountPath: /var/lib/mysql #容器中的目录
              name: local-mysql-data
      volumes:
        - name: local-mysql-data
          persistentVolumeClaim:
            claimName: local-pv-claim
    

    持久卷(PV)持久卷声明(PVC)

    持久卷(PersistentVolume,PV) 是集群中的一块存储。可以理解为一块虚拟硬盘。

    持久卷可以由管理员事先创建, 或者使用存储类(Storage Class)根据用户请求来动态创建。

    持久卷属于集群的公共资源,并不属于某个namespace;


    持久卷声明(PersistentVolumeClaim,PVC) 表达的是用户对存储的请求。

    PVC声明好比申请单,它更贴近云服务的使用场景,使用资源先申请,便于统计和计费。

    Pod 将 PVC 声明当做存储卷来使用,PVC 可以请求指定容量的存储空间和访问模式 。PVC对象是带有namespace的。

    image.png

  6. 存储类(StorageClass)

    一个集群可以存在多个**存储类(StorageClass)**来创建和管理不同类型的存储。

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

    image.png

    卷绑定模式

    volumeBindingMode用于控制什么时候动态创建卷和绑定卷

    • Immediate立即创建:创建PVC后,立即创建PV并完成绑定
    • WaitForFirstConsumer 延迟创建:当使用该PVC的 Pod 被创建时,才会自动创建PV并完成绑定

    回收策略(Reclaim Policy)

    回收策略告诉集群,当用户删除PVC 对象时, 从PVC中释放出来的PV将被如何处理。

    • 删除(Delete)

      如果没有指定,默认为Delete

      当PVC被删除时,关联的PV 对象也会被自动删除。

    • 保留(Retain)

      当 PVC 对象被删除时,PV 卷仍然存在,数据卷状态变为"已释放(Released)"。

      此时卷上仍保留有数据,该卷还不能用于其他PVC。需要手动删除PV。

StatefulSet(有状态应用集)

StatefulSet 是用来管理有状态的应用。一般用于管理数据库、缓存等。

与 Deployment 类似, StatefulSet用来管理 Pod 集合的部署和扩缩。

Deployment用来部署无状态应用。StatefulSet用来有状态应用。

  1. 创建StatefulSet

    StatefulSet配置模版

    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: mysql
    spec:
      selector:
        matchLabels:
          app: mysql # 必须匹配 .spec.template.metadata.labels
      serviceName: db
      replicas: 3 # 默认值是 1
      minReadySeconds: 10 # 默认值是 0
      template:
        metadata:
          labels:
            app: mysql # 必须匹配 .spec.selector.matchLabels
        spec:
          terminationGracePeriodSeconds: 10
          containers:
            - name: mysql
              image: mysql:5.7
              env:
                - name: MYSQL_ROOT_PASSWORD
                  value: "123456"
              ports:
                - containerPort: 3306
              volumeMounts:
                - mountPath: /var/lib/mysql #容器中的目录
                  name: mysql-data
      volumeClaimTemplates:
        - metadata:
            name: mysql-data
          spec:
            accessModes:
              - ReadWriteOnce
            storageClassName: local-path
            resources:
              requests:
                storage: 2Gi
    
  2. 稳定的存储

    在 StatefulSet 中使用 VolumeClaimTemplate,为每个 Pod 创建持久卷声明(PVC)。
    每个 Pod 将会得到基于local-path 存储类动态创建的持久卷(PV)。 Pod 创建(或重新调度)时,会挂载与其声明相关联的持久卷。
    请注意,当 Pod 或者 StatefulSet 被删除时,持久卷声明和关联的持久卷不会被删除。

  3. Pod标识

    在具有 N 个副本的 StatefulSet中,每个 Pod 会被分配一个从 0 到 N-1 的整数序号,该序号在此 StatefulSet 上是唯一的。

    StatefulSet 中的每个 Pod 主机名的格式为StatefulSet名称-序号

    上例将会创建三个名称分别为 mysql-0、mysql-1、mysql-2 的 Pod。

Headless Service(无头服务)

之前我们创建了三个各自独立的数据库实例,mysql-0,mysql-1,mysql-2。

要想让别的容器访问数据库,我们需要将它发布为Service,但是Service带负载均衡功能,每次请求都会转发给不同的数据库,这样子使用过程中会有很大的问题。

无头服务(Headless Service)可以为 StatefulSet 成员提供稳定的 DNS 地址。

在不需要负载均衡的情况下,可以通过指定 Cluster IP的值为 “None” 来创建无头服务。

注意:StatefulSet中的ServiceName必须要跟Service中的metadata.name一致

# 为 StatefulSet 成员提供稳定的 DNS 表项的无头服务(Headless Service)
apiVersion: v1
kind: Service
metadata:
  #重要!这里的名字要跟后面StatefulSet里ServiceName一致
  name: db
  labels:
    app: database
spec:
  ports:
  - name: mysql
    port: 3306
  # 设置Headless Service
  clusterIP: None
  selector:
    app: mysql
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  selector:
    matchLabels:
      app: mysql # 必须匹配 .spec.template.metadata.labels
  serviceName: db  #重要!这里的名字要跟Service中metadata.name匹配
  replicas: 3 # 默认值是 1
  minReadySeconds: 10 # 默认值是 0
  template:
    metadata:
      labels:
        app: mysql # 必须匹配 .spec.selector.matchLabels
    spec:
      terminationGracePeriodSeconds: 10
      containers:
        - name: mysql
          image: mysql:5.7
          env:
            - name: MYSQL_ROOT_PASSWORD
              value: "123456"
          ports:
            - containerPort: 3306
          volumeMounts:
            - mountPath: /var/lib/mysql
              name: mysql-data
  volumeClaimTemplates:
    - metadata:
        name: mysql-data
      spec:
        accessModes:
          - ReadWriteOnce
        storageClassName: local-path
        resources:
          requests:
            storage: 2Gi

稳定的网络ID

StatefulSet 中的每个 Pod 都会被分配一个StatefulSet名称-序号格式的主机名。

集群内置的DNS会为Service分配一个内部域名db.default.svc.cluster.local,它的格式为 服务名称.命名空间.svc.cluster.local

Mysql主从复制

下面是部署一个读写分离Mysql数据库的示意图。

通过部署无头服务(Headless Service)将写操作指向固定的数据库。

部署一个Service用来做读操作的负载均衡。

数据库之间通过同步程序保持数据一致。

image.png

image.png

初始化容器(init containers)

初始化容器(Init Containers)是一种特殊容器,它在 Pod 内的应用容器启动之前运行。

初始化容器未执行完毕或以错误状态退出,Pod内的应用容器不会启动。

初始化容器需要在initContainers中定义,与containers同级。

基于上面的特性,初始化容器通常用于

  • 生成配置文件
  • 执行初始化命令或脚本
  • 执行健康检查(检查依赖的服务是否处于Ready或健康Health的状态)

在本例子中,有两个初始化容器。

  • init-mysql为MySQL实例分配server-id,并将mysql-0的配置文件设置为primary.cnf,其他副本设置为replica.cnf
  • clone-mysql从前一个Pod中获取备份的数据文件放到自己的数据目录下

边车Sidecar

Pod中运行了2个容器,MySQL 容器和一个充当辅助工具的 xtrabackup 容器,我们称之为边车(sidecar)。

image.png

sidecar容器负责将备份的数据文件发送给下一个Pod,并在副本服务器初次启动时,使用数据文件完成数据的导入。

MySQL使用bin-log同步数据,但是,当数据库运行一段时间后,产生了一些数据,这时候如果我们进行扩容,创建了一个新的副本,有可能追溯不到bin-log的源头(可能被手动清理或者过期自动删除),因此需要将现有的数据导入到副本之后,再开启数据同步,sidecar只负责数据库初次启动时完成历史数据导入,后续的数据MySQL会自动同步。

Port-forward端口转发

通常,集群中的数据库不直接对外访问。

但是,有时候我们需要图形化工具连接到数据库进行操作或者调试。

我们可以使用端口转发来访问集群中的应用。

kubectl port-forward可以将本地端口的连接转发给容器。

此命令在前台运行,命令终止后,转发会话将结束。

#主机端口在前,容器端口在后
#如果主机有多个IP,需要指定IP,如不指定IP,默认为127.0.0.1
kubectl port-forward pods/mysql-0 --address=192.168.56.109 33060:3306

img

Helm

Helm 是一个 Kubernetes 应用的包管理工具,类似于 Ubuntu 的 APT 和 CentOS 中的 YUM。

Helm使用chart 来封装kubernetes应用的 YAML 文件,我们只需要设置自己的参数,就可以实现自动化的快速部署应用。

  1. 安装Helm

    下载安装包:

    https://github.com/helm/helm/releases

    https://get.helm.sh/helm-v3.10.0-linux-amd64.tar.gz

    mv linux-amd64/helm /usr/local/bin/helm
    
  2. 三大概念

    • Chart 代表着 Helm 包。

      • 它包含运行应用程序需要的所有资源定义和依赖,相当于模版。
      • 类似于maven中的pom.xml、Apt中的dpkb或 Yum中的RPM
    • Repository(仓库) 用来存放和共享 charts。

      • 不用的应用放在不同的仓库中。
    • Release 是运行 chart 的实例。

    一个 chart 通常可以在同一个集群中安装多次。

    每一次安装都会创建一个新的 release,**release name**不能重复。

  3. Helm仓库

    Helm有一个跟docker Hub类似的应用中心(https://artifacthub.io/),我们可以在里面找到我们需要部署的应用。

  4. 安装单节点Mysql

    #添加仓库
    helm repo add bitnami https://charts.bitnami.com/bitnami
    #查看chart
    helm show chart bitnami/mysql 
    #查看默认值
    helm show values bitnami/mysql 
    
    #安装mysql
    helm install my-mysql \
    --set-string auth.rootPassword="123456" \
    --set primary.persistence.size=2Gi \
    bitnami/mysql
    
    #查看设置
    helm get values my-mysql
    #删除mysql
    helm delete my-release
    
  5. Helm部署MySQL集群

    安装过程中有两种方式传递配置数据:
    ●-f (或–values):使用 YAML 文件覆盖默认配置。可以指定多次,优先使用最右边的文件。
    ●–set:通过命令行的方式对指定项进行覆盖。
    如果同时使用两种方式,则 --set中的值会被合并到 -f中,但是 --set中的值优先级更高。

    # values.yaml
    auth:
      rootPassword: "123456"
    
    primary:
      persistence:
        size: 2Gi
        enabled: true
    
    secondary:
      replicaCount: 2
      persistence:
        size: 2Gi
        enabled: true
    
    architecture: replication
    
    helm install my-db -f values.yaml bitnami/mysql
    

参考

https://www.yuque.com/wukong-zorrm/qdoy5p/zrvene
https://kubernetes.io/zh-cn/docs/concepts

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/213013.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java中异常处理顺序和全局异常处理器

异常处理顺序 我们直接通过代码看下Java中异常的处理顺序。 数组越界异常属于运行时异常,被捕捉后就停止了,打印结果为数组越界了。 Test public void test2(){int[] arr new int[4];try{System.out.println(arr[5]);}catch (ArrayIndexOutOfBoundsE…

2023.12.2 关于 Spring AOP 详解

目录 Spring AOP Spring AOP 常见使用场景 AOP 组成 切面(类) 切点(方法) 通知 ​编辑 前置通知(Before) 后置通知(After) 返回通知(AfterReturning&#xff0…

【接口测试】Apifox实用技巧干货分享

前言 不知道有多少人和我有着这样相似的经历:从写程序只要不报错就不测试😊,到写了程序若是有bug就debug甚至写单元测试,然后到了真实开发场景,大哥和你说,你负责的功能模块的所有接口写完要测试一遍无误在…

C# 使用HtmlAgilityPack解析提取HTML内容

写在前面 HtmlAgilityPack是一个HTML解析类库,日常用法就是爬虫获取到内容后,先用XPath获取目标节点,再用正则进行匹配;使用XPath的目的主要是将目标节点或内容限定在一个较小的范围,如果一上来就用正则那效率肯定不…

python——进程常用功能

Python的multiprocessing模块提供了强大的并行处理能力,以下是几个功能的详细解释: join(): 在multiprocessing中,join方法用于阻塞主进程直到指定的进程终止。这对于确保所有子进程在程序结束前完成其工作是很有用的。deamon(): 在multipro…

讲一讲redis的使用

Redis(Remote Dictionary Server)是一个开源的内存数据库系统,它提供了高性能、支持多种数据结构的存储和操作,被广泛应用于缓存、消息队列、计数器、实时分析等场景。以下是Redis的使用详解,涵盖了基本概念、数据结构…

目标检测常用评价指标

1 基本概念 1.1 IOU(Intersection over Union) 1.2 TP TN FP FN 2. 各种率 3. PR曲线 4. mAP的计算 4.1 AP的计算 4.2 mAP 4.3 mAP0.5和mAP0.5:0.95 1.1 IOU(Intersection over Union) 1.2 TP TN FP FN TP(Truth Positive): 预测正类,实际正类&#x…

2022CVPR(PoseC3D):Revisiting Skeleton-based Action Recognition

Revisiting Skeleton-based Action Recognition 摘要1、引言2、相关工作3、框架3.1. 姿势提取的良好实践3.2.从2D姿势到3D热图体积3.3.基于骨架的动作识别的3D-CNN 4、实验4.2.姿势提取4.3. 3D热图体积的预处理4.4.与GCN的比较4.5. RGBPose-SlowFast4.6.与最先进的比较 5、结论…

糟了,数据库崩了,又好像没崩

前言 2023 年某一天周末,新手程序员小明因为领导安排的一个活来到公司加班,小明三下五除二,按照领导要求写了一个跑批的数据落库任务在测试环境执行 ,突然间公司停电了,小明大惊,“糟了,MySQL …

wordpress建站优化加速教程-Redis加速

这篇文章适合宝塔面板,在宝塔面板安装 Redis 实现网站加速( Redis是一个高性能的key-value数据库(PHP连接redis,需PHP设置中安装redis扩展) )。对在word press网站有着明显的加速效果。关于Redis具体说明请自己百度,…

30岁左右的简历模板精选7篇

30岁左右是职业发展的关键时期,一份出色的简历能带来更多机会。本文精选了7篇适合30岁左右求职者的专业简历案例,无论您是寻找晋升、转行还是新的职业挑战,都能从中借鉴灵感,打造一份令人印象深刻的简历。 30岁左右的简历模板下载…

Git 配置文件(.gitignore)

前言 在使用 Git 分布式版本控制系统的时候,有些文件如:数据库的一些配置文件,我们不想让这类文件在远程仓库让 Git 来管理,不想让别人看到,此时就可以自己在 Git 仓库目录下创建 / 在远程仓库创建的时候就配置好 .git…

队列顺序存储(详解)

队列是一种常见的数据结构,它是一种先进先出(First-In-First-Out, FIFO)的线性表。在队列中,数据元素按照插入的顺序排列,最先插入的元素在队列的前面,最后插入的元素在队列的后面。类比生活中排队购物的情…

调试GMS应用,报错“此设备未获得play保护机制认证”问题解决

不少同学在调试GMS相关应用时,需登录Google账号,有时会弹出如下通知。 Google登录界面也会出现如下提示 这个报错的原因是设备未通过Google认证,google服务器未配置荣耀设备的型号白名单导致 国内网页有一些指导方法在鸿蒙\荣耀的设备上消除这…

语言模型文本处理基石:Tokenizer简明概述

编者按:近年来,人工智能技术飞速发展,尤其是大型语言模型的问世,让 AI 写作、聊天等能力有了质的飞跃。如何更好地理解和利用这些生成式 AI,成为许多开发者和用户关心的问题。 今天,我们推出的这篇文章有助…

Linux环境下 make/makefile、文件时间属性 详解!!!

1.项目自动化构建工具make/makefile 1.为什么要有make/makefile 我们先写一个简单的代码,然后编译生成一个可执行程序,下面的内容我们需要知道gcc识和编译链接的一些知识,不清楚的朋友们可以点这里http://t.csdnimg.cn/0QvL8 我们知道要想生…

Python爬虫:通过js逆向分析某翻译网站的原理

Python爬虫:通过js逆向分析某翻译网站的原理 1. 网站实现原理2. 抓取接口3. 参考代码和运行结果 1. 网站实现原理 首先,说一下爬取的网站:百度翻译。网站实现翻译的效果是通过接口实现的,也就是各位听到的ajax技术(只需要更换对应…

Spring | Spring的基本应用

目录: 1.什么是Spring?2.Spring框架的优点3.Spring的体系结构 (重点★★★) :3.1 Core Container (核心容器) ★★★Beans模块 (★★★) : BeanFactoryCore核心模块 (★★★) : IOCContext上下文模块 (★★★) : ApplicationContextContext-support模块 (★★★)SpE…

Mongoose 开源库--http协议 header 报头解析

一、http 协议 header 报头相关 API 获取http header的值 struct mg_str *mg_http_get_header(struct mg_http_message *hm, const char *name);参数: hm - HTTP message to look for header name - Header name返回值: HTTP header value or NULL i…

Docker下安装MySQL

如果在Docker下直接拉取MySQL并运行镜像,由于没有指定字符编码集,可能会存在插入中文出现乱码的情况,并且当容器删除后,容器里面存在的数据会丢失,所以在运行容器时应该使用数据卷进行挂载,按照如下步骤操作…