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

在K8S上部署OceanBase的最佳实践

在K8S上部署OceanBase的最佳实践

目录

  • 1. 背景与选型
    • 1.1 为什么选择OB
    • 1.2 为什么选择ob-operator实现OB on K8S
  • 2. 部署实操
    • 2.1 环境准备
    • 2.2 安装 ob-operator
    • 2.3 配置 OB 集群
    • 2.4 配置 OBProxy 集群
    • 2.5 Headless Service 和 CoreDNS 配置
    • 2.6 监控与运维
      • 2.6.1 Promethues部署
      • 2.6.2 Grafana接入
  • 3. 部署中遇到的问题及解决方案
    • 3.1 ob-operator 的调度器问题
    • 3.2 网络配置问题

1. 背景与选型

OB(下称OB)是一款分布式关系型数据库,具有高性能、高可用性和弹性扩展等特点,其企业版已经在公司内部的"去Oracle"项目中进行了落地,并取得了不错的效果。此外,考虑到我们仍有许多业务在关系型数据库上有着需求,同时考虑到我们已经具备MySQL/MariaDB/MongoDB/PostgresSQL在公司内部的K8S集群上进行容器化部署经验,因此我们决定将OceanBase也进行容器化部署。

1.1 为什么选择OB

在选择数据库时,我们从以下几个维度进行了分析:

  • 高可用性:OB是基于Paxos算法的强一致性数据库,具备强大的容灾能力,支持多数据中心部署,同时单点故障并不影响业务连续性。
  • 弹性扩展:OB的租户特性,使得相比MySQL和TiDB等关系型数据库而言,OB提供了更灵活的扩展能力,能够根据业务需求动态调整资源。
  • 成本:OB内核天然自带数据压缩能力,相比MySQL/TiDB具备更低的存储成本,特别是在大规模部署时,能够有效降低硬件成本(实测重复性文本数据下,OB的存储成本仅为MySQL的1/4甚至更低)。
  • 兼容性:OB内核天然兼容MySQL协议,方便现有应用的迁移和集成。

1.2 为什么选择ob-operator实现OB on K8S

在将OB部署到K8S的过程中,我们选择了 ob-operator 作为核心组件。ob-operator 提供了自动化管理 OB集群的能力,能够简化部署、扩展和运维的复杂性。其主要优势包括:

  • 自动化管理:ob-operator 能够自动处理OB集群的生命周期管理,包括创建、更新和删除。
  • 灵活性:支持自定义OServer/OBTenant资源,支持快速扩展集群规模, 支持通过CR文件快速修改参数。
  • 高可用性:通过多实例部署和健康检查机制,确保集群的稳定运行。支持静态IP和OVN网络,确保POD重建后仍然使用原IP,避免了POD重建后IP变化带来的问题。

2 部署实操

对于希望将 OB 接入 K8S 但不知如何下手的用户,ob-operator 提供了一个方便快捷的起点。

2.1 环境准备

在开始之前,请确保已满足以下条件:

  • 有可用的 Kubernetes 集群,至少有 9 个可用 CPU,33 GB 可用内存和 360 GB 的可用存储空间。
  • ob-operator 依赖 cert-manager,请确保已安装 cert-manager。cert-manager 的安装方法如下。
  • 连接 OceanBase 集群时,需已安装 MySQL 客户端或 OBClient。
  • Kubernetes集群需要安装网络插件,例如OVN。2.3.1以上版本 ob-operator 支持OVN网络,并且能够做到pod重建后IP不变,进一步提高了 OB集群 的稳定性。

安装 cert-manager

# 检查是否已安装 cert-manager
kubectl get pod -n cert-manager# 若未安装,则执行以下命令
wget https://github.com/jetstack/cert-manager/releases/download/v1.5.3/cert-manager.yaml# 拉取镜像需要科学上网
# 我们使用的K8S的网络插件为OVN,节点需要调度到 OVN 网络的节点上,否则可能无法通过 cert-manager 的 service 访问后端 POD
kubectl apply -f cert-manager.yaml

2.2 安装 ob-operator

安装ob-operator的操作可参考ob-operator部署,如果手动通过CRD部署可以自行从github仓库中下载CRD和Operator的yaml文件,然后通过kubectl apply -f 命令进行安装。

2.3 配置 OB 集群

可参考官方文档进行集群创建

2.4 配置 OBProxy 集群

OBProxy(即odp,OceanBase Database Proxy) 是 OB集群 的代理组件,生产环境上建议使用 OBProxy 对OB集群进行访问。使用 OBProxy 的好处包括:

  • 连接管理:OBProxy 负责管理客户端的连接,维护与后端 OB集群 的会话,减少客户端与数据库之间的连接开销。
  • 负载均衡:OBProxy 能够智能地将客户端请求分发到不同的 OB 节点,优化资源使用,提升系统性能。
  • 高可用性:在后端 OB 节点发生故障时,OBProxy 能够自动剔除故障节点,确保请求的高可用性。
  • 安全性:通过 OBProxy,可以集中管理访问控制和安全策略,增强系统的安全性。

配置步骤

安装 OBProxy:直接应用 YAML 文件进行安装。

obproxy YAML文件地址:obproxy.yaml,但在部署 OBProxy 前需要创建一个用于 OBProxy 与 OB集群 通信的 Secret。

# 创建用于 OBProxy 与 OB集群 通信的 Secret
kubectl create secret -n oceanbase generic proxyro-password --from-literal=password='<proxyro_password>'# 部署 OBProxy
kubectl apply -f obproxy.yaml

基本内容如下

# 相比官方提供的 obproxy.yaml 文件,增加了 odp-headless 的无头服务配置,主要目的是用于 coreDNS 进行域名解析
apiVersion: v1
kind: Service
metadata:name: odp-headlessnamespace: oceanbase
spec:type: ClusterIPclusterIP: Noneselector:app: odpname: odpports:- name: "sql"port: 2883targetPort: 2883---
apiVersion: v1
kind: Service
metadata:name: odpnamespace: oceanbase
spec:type: ClusterIPselector:app: odpname: odpports:- name: "sql"port: 2883targetPort: 2883- name: "prometheus"port: 2884targetPort: 2884---
apiVersion: apps/v1
kind: Deployment
metadata:name: odp            # 生产环境下,不建议使用 odp 作为 Deployment 名称,建议使用 odp-${obcluster_name} 作为 Deployment 名称namespace: oceanbase
spec:selector:matchLabels:app: odpname: odp        # 生产环境下,不建议使用 odp 作为 Deployment 名称,建议使用 odp-${obcluster_name} 作为 Deployment 名称replicas: 3template:metadata:labels:app: odpname: odpspec:containers:- name: obproxyimage: oceanbase/obproxy-ce:4.2.1.0-11ports:- containerPort: 2883name: "sql"- containerPort: 2884name: "prometheus"env:- name: APP_NAMEvalue: helloworld # 用于 OBProxy 的名称- name: OB_CLUSTERvalue: obcluster # 此处填写OB集群的名称,其来源于 OB 部署YAML文件中的 clusterName 值- name: RS_LISTvalue: '******' # 格式为 ${OBServer1 POD_IP}:2881;${OBServer2 POD_IP}:2881;${OBServer3 POD_IP}:2881,需要根据实际OBSevrer PODIP来进行替换。- name: PROXYRO_PASSWORDvalueFrom: secretKeyRef:name: proxyro-password # 用于 OBProxy 与 OB集群 通信的 Secretkey: passwordresources:limits:memory: 2Gicpu: "1"requests: memory: 200Micpu: 200m

部署完成后,如下图所示:

在这里插入图片描述

通过 OBProxy 访问OB集群

此时,可以通过OBProxy的Service提供OB数据库的访问入口,如下(obmysql是我提前创建好的租户,testdb是提前在obmysql下创建的用户):

当然,在实际的生产中,我们采用的是域名访问的方式,而不是通过IP地址访问,因此需要进行域名重写,可看下一小节。

2.5 Headless Service 和 CoreDNS 配置

在我们的实践中,为了更好地管理 OBProxy 的访问,我们采用了 Headless Service 配合 CoreDNS 的方案:

  1. 为什么使用 Headless Service

    • Headless Service(无头服务)通过将 clusterIP: None 设置,使得 DNS 查询可以直接返回后端 Pod 的 IP 地址。
    • 这种方式避免了普通 Service 的 kube-proxy 转发,减少了网络跳转,提升了访问性能。
  2. CoreDNS 域名重写配置

    apiVersion: v1
    kind: ConfigMap
    metadata:name: corednsnamespace: kube-system
    data:Corefile: |.:3053 {errorsloghealth {lameduck 10s}rewrite stop {name regex ob-(.*).rds.com odp-headless-ob-{1}.oceanbase.svc.cluster.localanswer name odp-headless-ob-(.*).oceanbase.svc.cluster.local ob-{1}.rds.com}kubernetes cluster.local in-addr.arpa ip6.arpa {pods insecurefallthrough in-addr.arpa ip6.arpa}prometheus :9153ready :8153loopreloadcache 10loadbalance}
    
  3. 域名重写的优势

    • 简化访问:用户可以通过简单的域名格式(如 ob-test.rds.com)访问数据库,无需关心内部复杂的 K8S 域名。
    • 统一管理:通过规范的域名格式(ob-*.rds.com),便于管理和维护多个 OB 集群。
    • 透明代理:CoreDNS 自动完成域名转换,对应用层完全透明。
    • 灵活扩展:可以根据需求轻松添加新的 OB 集群,只需遵循命名规范即可。
  4. 访问流程

    • 应用通过 ob-{clustername}.rds.com 访问数据库
    • CoreDNS 将请求域名重写为 odp-headless-ob-{clustername}.oceanbase.svc.cluster.local
    • Headless Service 返回对应 OBProxy Pod 的 IP
    • CoreDNS 在响应中将域名重写回 ob-{clustername}.rds.com
    • 应用获得 Pod IP 并建立连接
  5. CoreDNS 主机模式部署

    • 将 CoreDNS 部署在主机网络模式 (即 hostNetwork: true),使 CoreDNS POD与主机共享网络。
    • 这样用,在其余K8S集群中的机器上,将 /etc/resolv.conf 配置为 CoreDNS 服务器ip后,即可通过 CoreDNS 进行域名解析。
    • 这种配置方式使得外部机器能够方便地通过 CoreDNS 进行域名解析,适合需要跨集群访问的场景。
  6. 如图所示

    • 直接通过域名即可访问,而不用关心 obproxy 的service ip,进一步加强了集群的高可用能力

2.6 监控与运维

2.6.1 Promethues部署
  • 应用ob-operator中的promethues.yaml文件进行部署,文件链接:promethues.yaml

执行以下命令部署

kubectl apply -f prometheus.yaml

执行以下命令检查是否部署完成

kubectl get pod -n oceanbase  | grep prometheus

执行以下命令获取SVC

kubectl get svc -n oceanbase  | grep prometheus

如下

root@(datamars)mhpl74334-10.20.248.59 ~$ kubectl get svc -n oceanbase  | grep pro
svc-prometheus    NodePort    12.80.144.38   <none>        9090:30090/TCP      7d15h
2.6.2 Grafana接入
  • 可以应用ob-operator中的grafana.yaml文件进行部署,文件链接:grafana.yaml
  • 也可以通过grafana的配置页面,添加prometheus数据源,然后通过prometheus的SVC地址进行接入。

因为我们本地已经有grafana,所以这里我们通过grafana的配置页面,添加prometheus数据源,然后通过prometheus的SVC地址进行接入。

2.6.2.1 配置Prometheus数据源
  1. 在Grafana左侧导航栏,单击 Configuration 按钮,然后单击 Add data source 按钮。
  2. Add data source 页面,选择 Prometheus 作为数据源类型。
  3. Prometheus 页面,填写 Nameob-prometheusURLhttp://12.80.144.38:9090(即上面的promethues对应的svc ip),然后单击 Save & Test 按钮。

2.6.2.2 配置Grafana Dashboard
  1. 新建一个名为OceanBase的文件夹

  1. 进入该文件夹,接着导入文件链接:grafana.yaml 中的grafana-dashboards-ob部分的json配置

  1. 监控展示如图

3. 部署中遇到的问题及解决方案

3.1 ob-operator 的调度器默认为K8S原生的 default-scheduler,而在我们环境中需要使用自定义的调度器

解决方案

  • 在 OBCluster的CRD中新增了 schedulerName 字段,用于指定调度器,具体修改可以参考 MR: Support Custom SchedulerName, 用法如下:
apiVersion: oceanbase.oceanbase.com/v1alpha1
kind: OBCluster
metadata:name: testnamespace: oceanbase
spec:observer:image: oceanbase/oceanbase-cloud-native:4.2.3.1-101000032024061316podFields:schedulerName: custom-scheduler # 指定调度器为 custom-schedulerresource:cpu: 8memory: 16Gi...

3.2 网络配置问题

问题描述:在使用 OVN 网络插件时,发现 Pod IP 在重启后发生变化,导致OBProxy无法正常访问OB集群。

解决方案
(1)使用ob-operator的service模式,即为每个OBServer Pod创建一个Service,通过service来做静态IP的绑定,从而解决IP变化的问题,用法如下:

apiVersion: oceanbase.oceanbase.com/v1alpha1
kind: OBCluster
metadata:name: testnamespace: oceanbaseannotations:"oceanbase.oceanbase.com/mode": "service" # 指定为service模式
spec:observer:image: oceanbase/oceanbase-cloud-native:4.2.3.1-101000032024061316podFields:schedulerName: custom-schedulerresource:cpu: 8memory: 16Gi...

但是链路上多一节service做静态IP的绑定,会增加网络的复杂度,而从生产角度和高可用shang因此我们采用了下面的方案。

(2)ob-operator更新到2.3.1,该版本支持OVN网络插件,并且能够做到Pod重建后IP不变。

(3)但仍存在潜在的IP冲突问题,即当一个 OB Pod 正在重建过程中时,如果此时有其他新的 Pod 被创建,这些新 Pod 可能会占用到正在重建的 OB Pod 原本使用的 IP 地址。这会导致该 OB Pod 重建完成后无法使用其原有的 IP 地址。

为了解决这个问题,我们采用了 OVN 的子网隔离方案:

  • 创建专用子网:为 OceanBase 的命名空间创建了一个专用的 subnet,将其与其他业务的 Pod 网络进行隔离。
  • 配置方式
    apiVersion: kubeovn.io/v1
    kind: Subnet
    metadata:name: ob-subnet
    spec:protocol: IPv4cidrBlock: 10.16.0.0/16  # 为 OB 集群预留足够大的网段namespaces:- oceanbase  # 将子网与 oceanbase 命名空间绑定gateway: 10.16.0.1excludeIps:- 10.16.0.1..10.16.0.10  # 排除网关等保留地址
    

这种配置的优势:

  • 网络隔离:OB 集群的 Pod 使用独立的 IP 地址段,避免与其他业务 Pod 发生 IP 冲突
  • 地址管理:可以更好地规划和管理 IP 地址资源
  • 安全性:通过网络隔离提升了系统安全性

相关文章:

在K8S上部署OceanBase的最佳实践

在K8S上部署OceanBase的最佳实践 目录 1. 背景与选型 1.1 为什么选择OB1.2 为什么选择ob-operator实现OB on K8S 2. 部署实操 2.1 环境准备2.2 安装 ob-operator2.3 配置 OB 集群2.4 配置 OBProxy 集群2.5 Headless Service 和 CoreDNS 配置2.6 监控与运维 2.6.1 Promethues部…...

IDEA中Maven依赖包导入失败报红的潜在原因

在上网试了别人的八个问题总结之后依然没有解决&#xff1a; IDEA中Maven依赖包导入失败报红问题总结最有效8种解决方案_idea导入依赖还是报红-CSDN博客https://blog.csdn.net/qq_43705131/article/details/106165960 江郎才尽之后突然想到一个原因&#xff1a;<dep…...

【计算机网络】课程 实验五 静态路由配置

实验五 静态路由配置 一、实验目的 理解静态路由的工作原理&#xff0c;掌握如何配置静态路由。 二、实验分析与设计 【背景描述】 假设校园网分为 2 个区域&#xff0c;每个区域内使用 1 台路由器连接 2 个子网&#xff0c; 现要在路由器上 做适当配置&#xff0c;实现校…...

基于单片机的数字气压计设计

摘要:在嵌入式技术快速发展过程中&#xff0c;智能测量仪器被广泛应用于工业生产以及人们日常生活领域。数字气压计在实际应用中&#xff0c;利用气压传感器检测环境中的压力大小&#xff0c;便于实现对设备进行智能化的控制操作。数字气压计在气象监测、矿产开采、科学实验等环…...

【Docker项目实战】使用Docker部署Typemill轻量级平面文件CMS

【Docker项目实战】使用Docker部署Typemill轻量级平面文件CMS 一、Typemill介绍1.1 Typemill简介1.2 主要特点1.3 主要使用场景二、本次实践规划2.1 本地环境规划2.2 本次实践介绍三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版本四、下载…...

react ts 定义基本类型,组件通过ref调用时类型提示

记录&#xff0c;以防忘记 子组件 import React, { forwardRef, Ref, useImperativeHandle, useState } from react;// 类型定义方式1 interface IProps {/**参数1 */params1: number | string | undefined/**参数2 */params2: number | string | undefined/**方法 */openDia…...

二十三种设计模式-原型模式

原型模式&#xff08;Prototype Pattern&#xff09;是一种创建型设计模式&#xff0c;它通过拷贝现有的实例来创建新的实例&#xff0c;而不是通过新建实例。这种方式可以避免复杂的构造过程&#xff0c;同时还能保持对象的创建和使用分离&#xff0c;提高系统的灵活性和扩展性…...

提升汽车金融租赁系统的效率与风险管理策略探讨

内容概要 在汽车金融租赁系统这个复杂的生态中&#xff0c;提升整体效率是每个企业都渴望达成的目标。首先&#xff0c;优化业务流程是实现高效运行的基础。通过分析目前的流程&#xff0c;找出冗余环节并进行简化&#xff0c;能够帮助企业缩短审批时间&#xff0c;提高客户满…...

Spring Framework 5.3.x源码构建 (jdk-1.8, gradle 7.5.1, idea2024.3)

1、下载jdk安装并配置环境变量&#xff08;自行百度&#xff09; https://www.oracle.com/java/technologies/downloads/#java8 2、下载spring-framework源码&#xff0c;切换分支到5.3.x https://github.com/spring-projects/spring-framework.git 备用地址 https://gitco…...

leetcode 2241. 设计一个 ATM 机器 中等

一个 ATM 机器&#xff0c;存有 5 种面值的钞票&#xff1a;20 &#xff0c;50 &#xff0c;100 &#xff0c;200 和 500 美元。初始时&#xff0c;ATM 机是空的。用户可以用它存或者取任意数目的钱。 取款时&#xff0c;机器会优先取 较大 数额的钱。 比方说&#xff0c;你想…...

IO模型与NIO基础

File类 File类主要是JAVA为文件这块的操作(如删除、新建等)而设计的相关类File类的包名是java.io&#xff0c;其实现了Serializable, Comparable两大接口以便于其对象可序列化和比较 创建一个文件/文件夹 删除文件/文件夹 获取文件/文件夹 判断文件/文件夹是否存在 对文件夹进…...

上门按摩系统架构与功能分析

一、系统架构 服务端&#xff1a;Java&#xff08;最低JDK1.8&#xff0c;支持JDK11以及JDK17&#xff09;数据库&#xff1a;MySQL数据库&#xff08;标配5.7版本&#xff0c;支持MySQL8&#xff09;ORM框架&#xff1a;Mybatis&#xff08;集成通用tk-mapper&#xff0c;支持…...

ubuntu安装ssh9.2

删除旧版本&#xff1a; dpkg --list|grep ssh apt remove sshwget https://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-9.2p1.tar.gz tar xzvf openssh-9.2p1.tar.gz cd openssh-9.2p1 #下载依赖#开始编译安装 ./configure && make && make inst…...

linux wsl配置 redis远程连接

✅ 1. 修改 Redis 配置文件 在 WSL 的 Redis 配置文件中&#xff0c;找到 redis.conf 或 /etc/redis/redis.conf 文件&#xff0c;编辑以下配置项&#xff1a; ➡️ 更新 bind 配置项 将 bind 127.0.0.1 ::1 修改为&#xff1a; bind 0.0.0.0这样&#xff0c;Redis 将监听所…...

JVM 优化指南

JVM 优化指南 1. JVM 参数配置 1.1 基础参数配置 设置堆内存大小 -Xms2048m -Xmx2048m 设置新生代大小 -Xmn1024m 设置元空间大小 -XX:MetaspaceSize256m -XX:MaxMetaspaceSize256m 设置线程栈大小 -Xss512k1.2 垃圾回收器配置 使用 G1 垃圾回收器 -XX:UseG1GC 设置期望停顿…...

关机重启后,GitLab服务异常

整理机房,关闭了所有主机重新上架。 上架后开机,所有主机硬件启动正常。 其中一台GitLab服务器启动正常,使用gitlab-ctl status查看服务业正常。 但使用web登陆却失败,如下图: 反复测试,发现无论使用正确密码还是错误密码都是同样的提示。很大可能是数据库的问题。 使…...

谷粒商城-高级篇完结-Sleuth+Zipkin 服务链路追踪

1、基本概念和整合 1.1、为什么用 微服务架构是一个分布式架构&#xff0c;它按业务划分服务单元&#xff0c;一个分布式系统往往有很多个服务单元。由于服务单元数量众多&#xff0c;业务的复杂性&#xff0c;如果出现了错误和异常&#xff0c;很难去定位 。主要体现在&#…...

C语言基本知识复习浓缩版:标识符、函数、进制、数据类型

C语言基本知识复习浓缩版&#xff1a;标识符、函数、进制、数据类型 【c语言期末复习3小时速成【完整全集】期末速成含考试题c语言期末速成突击复习C语言补考C语言期末大一】 B站看到的复习C语言视频&#xff0c;感觉非常棒&#xff0c;就跟着进行了一下学习。众所周知&#…...

selenium已经登陆了 我怎么查看 网页 在fRequest xhr 的数据呢

在使用 Selenium 登录网页后&#xff0c;查看网页的 XHR 请求数据可以通过以下几种方法&#xff1a; ### 1. 使用浏览器开发者工具 - **手动查看**&#xff1a; - 打开浏览器的开发者工具&#xff08;按 F12 或右键点击页面元素选择“检查”&#xff09;。 - 切换到“Netw…...

Bash语言的数据库编程

Bash语言的数据库编程 引言 在现代软件开发中&#xff0c;数据库编程是一个不可或缺的部分。从小型项目到大型系统&#xff0c;数据库通常是存储和管理数据的核心。然而&#xff0c;许多开发者往往将焦点放在高级编程语言如Python、Java或C#上&#xff0c;忽视了Shell脚本语言…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

C++:std::is_convertible

C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

Java 8 Stream API 入门到实践详解

一、告别 for 循环&#xff01; 传统痛点&#xff1a; Java 8 之前&#xff0c;集合操作离不开冗长的 for 循环和匿名类。例如&#xff0c;过滤列表中的偶数&#xff1a; List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录&#xff0c;但是由于这个树组件的节点越来越多&#xff0c;导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多&#xff0c;导致的浏览器卡顿&#xff0c;这里很明显就需要用到虚拟列表的技术&…...

管理学院权限管理系统开发总结

文章目录 &#x1f393; 管理学院权限管理系统开发总结 - 现代化Web应用实践之路&#x1f4dd; 项目概述&#x1f3d7;️ 技术架构设计后端技术栈前端技术栈 &#x1f4a1; 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 &#x1f5c4;️ 数据库设…...

【Go语言基础【12】】指针:声明、取地址、解引用

文章目录 零、概述&#xff1a;指针 vs. 引用&#xff08;类比其他语言&#xff09;一、指针基础概念二、指针声明与初始化三、指针操作符1. &&#xff1a;取地址&#xff08;拿到内存地址&#xff09;2. *&#xff1a;解引用&#xff08;拿到值&#xff09; 四、空指针&am…...

Linux 中如何提取压缩文件 ?

Linux 是一种流行的开源操作系统&#xff0c;它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间&#xff0c;使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的&#xff0c;要在 …...

LRU 缓存机制详解与实现(Java版) + 力扣解决

&#x1f4cc; LRU 缓存机制详解与实现&#xff08;Java版&#xff09; 一、&#x1f4d6; 问题背景 在日常开发中&#xff0c;我们经常会使用 缓存&#xff08;Cache&#xff09; 来提升性能。但由于内存有限&#xff0c;缓存不可能无限增长&#xff0c;于是需要策略决定&am…...