K8s部署高可用Jenkins

小伙伴们大家好呀!断更了近一个月,XiXi去学习了一下K8sJenkins的相关技术。学习内容有些庞杂,近一个月的时间里我只学会了一些皮毛,更多的内容还需要后面不断学习,不断积累。最主要的是云主机真得很贵,为了写这篇文章,我花了近200块😭
491599167.jpg

回到正题,这里我分享的成果是:在K8s上部署一套Jenkins环境,可以基于Pod实现动态的Jenkins-Slave的扩展,下面记录着我的整个搭建过程。

环境介绍

  • K8s1.28.2集群
  • 一台可以连接外网的云主机:用于下载一些Docker镜像

准备NFS制备器

在创建Jenkins之前,我们需要先在K8s集群上创建一个NFS制备器。创建NFS制备器后,我们只需要声明PVC,NFS制备器便会自动地基于NFS文件系统创建相应的PV。

NFS文件系统搭建

我们需要先搭建起一个NFS文件系统,搭建流程相当简单

  1. 每台主机上执行安装
# 安装 nfs
yum install nfs-utils -y
# 启动 nfs
systemctl start nfs-server
# 查看 nfs 版本
cat /proc/fs/nfsd/versions
  1. 选择某一台主机创建共享目录

这里我选择了内网ip:172.24.12.240的一台云主机

# 创建共享目录
mkdir -p /data/nfs/jenkins
# 设置共享目录 export
vim /etc/exports
/data/nfs/jenkins *(rw,sync,no_subtree_check,no_root_squash)
# 重新加载
exportfs -f
systemctl reload nfs-server
# 查看
showmount -e 172.24.12.240
  1. 其他机器可以挂载共享目录
mkdir -p /data/nfs/jenkins
# 注意执行mount时的目录,不要是挂载目录
mount -t nfs 172.24.12.240:/data/nfs/jenkins /data/nfs/jenkins
  1. 最终效果

最终,可以实现,在任意一台主机的 /data/nfs/jenkins中操作,都会同步到其他主机上

image.png

NFS制备器

参考官方GitHub:https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner

官方为我们提供了3种NFS制备器的创建方式:

  • Helm
  • Kustomize
  • 手动方式

下面我采取手动的方式给大家做个演示

步骤一:克隆官方项目

# 不管用什么方式大家将项目克隆下来就好
git clone https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner.git

主要是需要使用项目中deploy文件夹中的yaml文件
image.png

步骤二:修改deploy目录中的yaml的内容
注:如果制备器想创建在default命名空间,配置文件中namespace的相关内容不用改

image.png

  • class.yaml:用于创建StorageClass
  • deployment.yaml:用于创建Deployment
  • rbac.yaml:创建ServiceAccount和绑定角色
  1. class.yaml文件
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: nfs-jenkins-client
provisioner: xixi.io/nfs-subdir-external-provisionerarchiveOnDelete: "false"

name:nfs-jenkins-client(可以保持原样)
provisioner: xixi.io/nfs-subdir-external-provisioner(可以保持原样,在下面的deployment.yaml文件中用到)

  1. deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: nfs-jenkins-client-provisionerlabels:app: nfs-jenkins-client-provisioner# replace with namespace where provisioner is deployednamespace: kube-system
spec:replicas: 1strategy:type: Recreateselector:matchLabels:app: nfs-jenkins-client-provisionertemplate:metadata:labels:app: nfs-jenkins-client-provisionerspec:serviceAccountName: nfs-client-provisionercontainers:- name: nfs-jenkins-client-provisionerimage: registry.k8s.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2volumeMounts:- name: nfs-client-rootmountPath: /persistentvolumesenv:- name: PROVISIONER_NAME# class.yaml 中的 provisioner保持一致value: xixi.io/nfs-subdir-external-provisioner- name: NFS_SERVERvalue: 172.24.12.240- name: NFS_PATHvalue: /data/nfs/jenkinsvolumes:- name: nfs-client-rootnfs:server: 172.24.12.240path: /data/nfs/jenkins
  • nfs的地址目录路径必改,其他的可以保持原样
  1. rbac.yaml文件
apiVersion: v1
kind: ServiceAccount
metadata:name: nfs-client-provisioner# replace with namespace where provisioner is deployednamespace: kube-system
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:name: nfs-client-provisioner-runner
rules:- apiGroups: [""]resources: ["nodes"]verbs: ["get", "list", "watch"]- apiGroups: [""]resources: ["persistentvolumes"]verbs: ["get", "list", "watch", "create", "delete"]- apiGroups: [""]resources: ["persistentvolumeclaims"]verbs: ["get", "list", "watch", "update"]- apiGroups: ["storage.k8s.io"]resources: ["storageclasses"]verbs: ["get", "list", "watch"]- apiGroups: [""]resources: ["events"]verbs: ["create", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:name: run-nfs-client-provisioner
subjects:- kind: ServiceAccountname: nfs-client-provisioner# replace with namespace where provisioner is deployednamespace: kube-system
roleRef:kind: ClusterRolename: nfs-client-provisioner-runnerapiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:name: leader-locking-nfs-client-provisioner# replace with namespace where provisioner is deployednamespace: kube-system
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# replace with namespace where provisioner is deployednamespace: kube-system
subjects:- kind: ServiceAccountname: nfs-client-provisioner# replace with namespace where provisioner is deployednamespace: kube-system
roleRef:kind: Rolename: leader-locking-nfs-client-provisionerapiGroup: rbac.authorization.k8s.io

步骤三:执行创建

kubectl apply -f ./rbac.yaml
kubectl apply -f ./class.yaml
kubectl apply -f ./deployment.yaml## 验证
kubectl get storageclass
kubectl get deploy -n kube-system
kubectl get sa -n kube-system | grep nfs

image.png
image.png
image.png

步骤四:测试

kind: PersistentVolumeClaim
apiVersion: v1
metadata:name: test-jenkins-claim
spec:storageClassName: nfs-jenkins-clientaccessModes:- ReadWriteManyresources:requests:storage: 1Mi
kubectl apply -f test-jenkins-claim.yaml
kubectl get pv,pvc

image.png
image.png

Jenkins-Master部署

GitHub供参考的Yaml:https://github.com/scriptcamp/kubernetes-jenkins
GitHub供参考的搭建流程:https://devopscube.com/setup-jenkins-on-kubernetes-cluster/
官方搭建流程:https://www.jenkins.io/doc/book/installing/kubernetes/

K8s上搭建Jenkins,官方提供的yaml比较老,里面的Jenkins镜像很老,所以得改。

步骤一:克隆官方的yaml

git clone https://github.com/scriptcamp/kubernetes-jenkins

image.png

步骤二:创建命名空间

kubectl create namespace devops-tools

步骤三:执行serviceAccount.yaml

kubectl apply -f serviceAccount.yaml
kubectl get sa -n devops-tools

image.png

步骤四:创建pvc(官方的volume.yaml就不用了)

apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: xixi-jenkins-pvcnamespace: devops-tools
spec:storageClassName: nfs-jenkins-clientaccessModes:- ReadWriteOnceresources:requests:storage: 10Gi
kubectl apply -f xixi-jenkins-pvc.yaml
kubectl get pv,pvc -n devops-tools

image.png
image.png

步骤五:修改deployment.yaml并执行

apiVersion: apps/v1
kind: Deployment
metadata:name: xixi-jenkinsnamespace: devops-tools
spec:replicas: 1selector:matchLabels:app: xixi-jenkins-servertemplate:metadata:labels:app: xixi-jenkins-serverspec:securityContext:fsGroup: 1000 runAsUser: 1000serviceAccountName: jenkins-admincontainers:- name: xixi-jenkinsimage: jenkins/jenkins:2.452.2-jdk17imagePullPolicy: IfNotPresentresources:limits:memory: "2Gi"cpu: "1000m"requests:memory: "500Mi"cpu: "500m"ports:- name: httpportcontainerPort: 8080- name: jnlpportcontainerPort: 50000livenessProbe:httpGet:path: "/login"port: 8080initialDelaySeconds: 125periodSeconds: 10timeoutSeconds: 5failureThreshold: 5readinessProbe:httpGet:path: "/login"port: 8080initialDelaySeconds: 120periodSeconds: 10timeoutSeconds: 5failureThreshold: 3volumeMounts:- name: xixi-jenkins-datamountPath: /var/jenkins_home         volumes:- name: xixi-jenkins-datapersistentVolumeClaim:claimName: xixi-jenkins-pvc

我这边把探针的时间放的久了一点,等待Jenkins启动,大家可以自己调整

kubectl apply -f deployment.yaml
kubectl get pods -n devops-tools -o wide

image.png

步骤六:暴露服务(这里直接用Service的NodePort方式)

apiVersion: v1
kind: Service
metadata:name: xixi-jenkins-servicenamespace: devops-toolsannotations:prometheus.io/scrape: 'true'prometheus.io/path:   /prometheus.io/port:   '8080'
spec:selector: app: xixi-jenkins-servertype: NodePort  ports:- name: httpport: 8080targetPort: 8080nodePort: 32001- name: channelport: 50000targetPort: 50000
kubectl apply -f service.yaml
kubectl get svc -n devops-tools

image.png

步骤六:获取秘钥,登录Jenkins

kubectl logs xixi-jenkins-c879b6b69-6s5pq -n devops-tools

image.png
访问:ip:32001(32001就是步骤六中service.yaml文件中指定暴露的端口)
image.png
输入pod日志打印的秘钥,安装插件,创建用户的过程就不贴图了,最后要设置一个Jenkins_URL需要注意下,需要设置成下图方式(如果设置错了,后面也可以改,不用担心)
image.png

Jenkins-Master测试

官方Jenkins镜像提供了OpenJDK17的环境、Git环境,但是没有安装Maven,大家如果有需要可以自己重新构建Jenkins镜像、或者Jenkins的UI界面的工具配置中可以选择自动安装Maven,再或者可以在Pod中配置另一个容器(容器配置好构建环境)用于构建代码。
这里我先简单展示下默认的情况

kubectl get pods -n devops-tools
kubectl exec -it  xixi-jenkins-c879b6b69-6s5pq -n devops-tools /bin/bash

image.png

测试一个简单的FreeStyle任务

  1. 配置Gitee仓库

image.png

  1. shell命令打印“hello world”

image.png

  1. 执行构建,查看结果

image.png

Jenkins-Slave部署

部署步骤

  1. Jenkins中安装K8s插件

image.png

  1. Jenkins中配置云服务

image.png

  1. 新建云

image.png
image.png

  1. 配置K8s地址

image.png

这里什么都不填也可以

  1. 配置Jenkins地址

image.png

http://svc名称.命名空间:8080/

  1. 添加一个Pod标签,并点击保存

image.png

  1. 再次进入配置的云

image.png

  1. 进入PodTemplate,新增Pod模版

image.png

  1. 配置PodTemplate并保存

image.png

PodTemplate后面还会更改

  1. 构建Jenkins任务测试

image.png

限制项目运行节点,填写在PodTemplate中标签列表的内容(见9

image.png
image.png

  1. 查看任务执行结果

image.png
image.png

  1. 查看Jenkins-Slave的Pod
kubectl get pods -n devops-tools
kubectl exec -it jnlp-q90n6 /bin/sh

image.png
image.png

自定义构建环境的镜像

Jenkins-Slave部署完成后,发现Pod中默认启动的容器jnlp,只能满足我们拉取代码的任务,我们要通过Maven构建项目,并且我们项目是JDK8的,需要一个JDK8的环境,因此,我们可以构建一个自己的用于代码打包的镜像,然后添加到Jenkins-Slave的Pod中
image.png

FROM centos:7
ADD ./apache-maven-3.9.0-bin.tar.gz /usr/local/
RUN yum -y update \&& yum -y install vim \&& yum -y install git \&& yum -y install java-1.8.0-openjdk-devel.x86_64
WORKDIR /usr/local/
ENV MAVEN_HOME=/usr/local/apache-maven-3.9.0
ENV PATH=$MAVEN_HOME/bin:$PATH
CMD ["/bin/bash","-c","while true; do echo hello world; sleep 1; done"]

解释下Dockerfile

  • maven的tar包中,我已经将settings.xml的中央仓库镜像换成了阿里云
  • 通过yum的方式安装了OpenJDK8和git
docker build -t my-env-build:2.0 .

修改PodTemplate,添加自定义构建环境容器

接下来我们需要将自己的镜像,也启动个容器放在Jenkins-Slave的Pod中

  1. 配置PodTemplate,添加容器

image.png

选择添加容器

image.png

输入自己构建环境的镜像名称:版本号。配置完成后,保存退出

  1. 构建一个pipeline项目
// Uses Declarative syntax to run commands inside a container.
pipeline {agent {label 'xixi-jnlp'}stages {stage('拉取代码') {steps {container('xixi-build') {// some blockgit credentialsId: '7e0d3d6a-2fd8-4f9e-b170-5dc351e3dc92', url: 'https://gitee.com/gao_xi/k8s-devops'sh "mvn clean install"}}}}
}

Pipeline脚本中,通过**container(‘容器名称’),**可以切换到指定容器中执行

  1. 执行构建

image.png
image.png

可以看到已经可以执行mvn了

  1. 查看Pod情况

image.png

kubectl get pod jnlp-l20bs -o=jsonpath='{.spec.containers[*].name}' -n devops-tools

image.png

可以看到此时Pod已经有两个容器了

  • jnlp:是默认启动的容器,里面运行Jenkins-Slave的agent程序
  • xixi-build:是我们自定义的构建环境容器

甚至我们可以继续向Pod中添加容器,比如可以将Docker放入

  1. jnlp容器xixi-build容器有共享目录

image.png
image.png

可以看到两个容器中的**/home/jenkins/agent**是共享的。具体原因是,在Pod模版中配置了Empty Dir
image.pngimage.png

修改PodTemplate,添加Docker容器

添加了自己的容器后,我们再向Pod中添加一个Docker容器,用于执行一些Docker命令

  1. 添加Docker容器

image.png
image.png

这里需要将宿主机的**/var/run/docker.sock**挂载进去

  1. pipeline脚本
// Uses Declarative syntax to run commands inside a container.
pipeline {agent {label 'xixi-jnlp'}stages {stage('拉取代码') {steps {container('xixi-build') {sh "echo hello world"}container('xixi-docker') {sh "docker ps"}}}}
}
  1. 结果

image.png

  1. 查看Pod情况

image.png
image.png

目录也是通过EmptyDir方式,实现Pod内3个容器jnlp、xixi-build、xixi-docker中目录共享

Jenkins-Slave创建的Pod原理图

image.png

部署一个微服务项目

基于前面的Pod模板,里面有自己构建的一套JDK8+Maven+Git环境、Docker环境(分别在xixi-build容器中和xixi-docker容器中),在构建项目前,我们在K8s中部署一套Nacos,并且Jenkins中再配置一些内容。

Nacos部署

这里由于仅仅是为了演示,我使用的是官方的quick-start

git clone https://github.com/nacos-group/nacos-k8s.git
cd nacos-k8s
sh quick-startup.sh

image.png
image.png

项目中的Nacos地址配置:nacos-headless.default:8848

修改PodTemplate,挂载kubectl

image.png

继续修改Jenkins中的Pod模板,增添kubectl挂载。
Maven仓库可以也挂载出来,最好是声明个PVC,这里我就直接挂载到HostPath上

Jenkins-配置K8s凭证

image.png

将K8s集群Master节点的/root/.kube/config上传这里

Jenkins-安装K8s CLI插件

image.png

安装此插件后,可以通过Pipeline,执行kubectl命令

pipeline {agent {label 'xixi-jnlp'}stages {stage('测试kubectl'){steps{withKubeConfig(caCertificate: '', clusterName: '', contextName: '', credentialsId: 'k8s-config', namespace: 'default', restrictKubeConfigAccess: false, serverUrl: '') {sh "kubectl get pods"}}}}
}

项目结构和Pipeline脚本

image.png

引入了dockerfile-maven-plugin插件,自动为我们打包镜像

<plugin><groupId>com.spotify</groupId><artifactId>dockerfile-maven-plugin</artifactId><version>1.3.6</version><configuration><repository>${project.artifactId}</repository><buildArgs><JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE></buildArgs></configuration>
</plugin>

pipeline

pipeline {agent {label 'xixi-jnlp'}environment {harbor_url = "registry.cn-hangzhou.aliyuncs.com"harbor_namespace = "aliyun_gx"gateway_project_name = "xixi-mall-gateway"}parameters {extendedChoice multiSelectDelimiter: ',', name: 'selectedProjects', quoteValue: false, saveJSONParameterToFile: false, type: 'PT_CHECKBOX', value: 'mall-order-service,mall-product-service,xixi-mall-gateway', visibleItemCount: 3}stages {stage('环境准备'){steps{script{selectedProjects = selectedProjects.split(',')}}}stage('拉取代码'){steps{checkout scmGit(branches: [[name: '*/k8s-devops']], extensions: [], userRemoteConfigs: [[credentialsId: '7e0d3d6a-2fd8-4f9e-b170-5dc351e3dc92', url: 'https://gitee.com/gao_xi/xixi-mall-devops.git']])}}stage('构建整体'){steps{container('xixi-build'){sh "mvn clean install"}}}stage('构建项目镜像'){steps{script{for(int i=0;i<selectedProjects.size();i++){def currentProject = selectedProjects[i];echo "项目名称: ${currentProject}"if( gateway_project_name == currentProject){echo "发布网关"container("xixi-build"){sh "mvn -f ${currentProject} dockerfile:build"}} else {container("xixi-build"){sh "mvn -f xixi-mall-service/${currentProject} dockerfile:build"}}//上传镜像container("xixi-docker"){sh "docker tag ${currentProject}:latest ${harbor_url}/${harbor_namespace}/${currentProject}:latest"withCredentials([usernamePassword(credentialsId: 'aliyun-image-repo', passwordVariable: 'password', usernameVariable: 'username')]) {sh "docker login -u ${username} -p ${password} ${harbor_url}"sh "docker push ${harbor_url}/${harbor_namespace}/${currentProject}:latest"sh "docker rm -f ${currentProject}:latest"sh "docker rm -f ${harbor_url}/${harbor_namespace}/${currentProject}:latest"}}}}}}stage('项目发布'){steps{script{for(int i=0;i<selectedProjects.size();i++){def currentProject = selectedProjects[i];echo "发布项目: ${currentProject}"withKubeConfig(caCertificate: '', clusterName: '', contextName: '', credentialsId: 'k8s-config', namespace: 'default', restrictKubeConfigAccess: false, serverUrl: '') {sh "kubectl apply -f deploy/${currentProject}-deploy.yaml"}}}}}}
}

成果展示

image.png
image.png
image.png

通过网关访问服务
curl 10.102.58.6:18000/order/getOrder

image.png

可以为Gateway配置一个Ingress,这里就不演示了。

总结

好了,兄弟们,这就是XiXi最近探索的内容,中间过程相当曲折,镜像下载问题就把整个人整崩溃了,还好在水群的时候以前同学给了方案,阿里云租台美国主机,通过docker save 和 docker load -i的方式下载镜像。
如果大家想要我文档中一些配置的yaml和项目源码,可以私信,我尽量给到大家。

参考资料

  • 【完整版Kubernetes(K8S)全套入门+微服务实战项目,带你一站式深入掌握K8S核心能力】 https://www.bilibili.com/video/BV1MT411x7GH/?share_source=copy_web&vd_source=48905e7be046ec712a8d80b099294b80
  • 《Jenkins持续集成从入门到精通》(需要公众号推的,阿里的)

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

注意 llamaIndex 中 Chroma 的坑!

llamaIndex 做索引是默认存在内存中&#xff0c;由于索引需要通过网络调用 API&#xff0c;而且索引是比较耗时的操作&#xff0c;为了避免每次都进行索引&#xff0c;使用向量数据库进行 Embedding 存储以提高效率。首先将 Document 解析成 Node&#xff0c;索引时调用 Embedd…

一、系统学习微服务遇到的问题集合

1、启动了nacos服务&#xff0c;没有在注册列表 应该是版本问题 Alibaba-nacos版本 nacos-文档 Spring Cloud Alibaba-中文 Spring-Cloud-Alibaba-英文 Spring-Cloud-Gateway 写的很好的一篇文章 在Spring initial上面配置 start.aliyun.com 重新下载 < 2、 No Feign…

力扣SQL50 求关注者的数量 分组计数

Problem: 1729. 求关注者的数量 Code select user_id, count(1) followers_count from Followers group by user_id order by user_id;

运算放大器(运放)低通滤波反相放大器电路和积分器电路

低通滤波反相放大器电路 运放积分器电路请访问下行链接 运算放大器(运放)积分器电路 设计目标 输入ViMin输入ViMax输出VoMin输出VoMaxBW&#xff1a;fp电源Vee电源Vcc–0.1V0.1V–2V2V2kHz–2.5V2.5V 设计说明 这款可调式低通反相放大器电路可将信号电平放大 26dB 或 20V/…

全面理解-Flutter(万字长文,深度解析)

1、Web 性能差&#xff0c;跟原生 App 存在肉眼可见的差距&#xff1b; 2、React Native 跟 Web 相比&#xff0c;支持的能力非常有限&#xff0c;特定长场景问题&#xff0c;需要三端团队一个一个处理&#xff1b; 3、Web 浏览器的安卓碎片化严重&#xff08;感谢 X5&#x…

【C++算法】——高精度(加,减,乘,除)

前言 高精度算法就是为了去解决一些比较大的数&#xff0c;这些数大到long long都存不下。&#xff0c;这里的主要思想就是用字符串来存。 下面的内容有很多用到c的容器&#xff0c;不明白的可以先去学习stl。 一 高精度加法 首先第一步就是去模拟我们自己写的加法&#xff…

Nikto一键扫描Web服务器(KALI工具系列三十)

目录 1、KALI LINUX 简介 2、Nikto工具简介 3、信息收集 3.1 目标IP&#xff08;服务器) 3.2kali的IP 4、操作实例 4.1 基本扫描 4.2 扫描特定端口 4.3 保存扫描结果 4.4 指定保存格式 4.5 连接尝试 4.6 仅扫描文件上传 5、总结 1、KALI LINUX 简介 Kali Linux 是一…

2024最新版:C++用Vcpkg搭配VS2022安装matplotlib-cpp库

matplotlib-cpp是一个用于在C中使用matplotlib绘图库的头文件库。它提供了一个简单的接口&#xff0c;使得在C中创建和显示图形变得更加容易。这个库的灵感来自于Python的matplotlib库&#xff0c;它使得在C中进行数据可视化变得更加便捷。 matplotlib-cpp允许在C中使用类似Py…

CTFHUB-SSRF-端口扫描

已经提示我们需要扫描8000~9000的端口 ?urlhttp://127.0.0.1:8000/flag.php 访问用burp抓包爆破 通过Burp扫描8000-9000端口开放的web服务&#xff0c;发现8718开放web服务

QML 列表,图片展示(一)

文章目录 1.QML 列表&#xff0c;图片展示效果图2.项目基本说明3.项目详解3.1界面显示部分3.2 网络部分 4.源代码5.flickr图片查询链接&#xff0c;后面我们将调整代码&#xff0c;获取更多图片 1.QML 列表&#xff0c;图片展示效果图 2.项目基本说明 该项目来自Qt示例程序 Ph…

MySQL数据库(一):数据库介绍与安装

在嵌入式开发中&#xff0c;数据库的重要性体现在高效的数据存储和管理、数据持久化、复杂查询和处理、数据同步和共享、安全性和可扩展性。常见嵌入式数据库包括SQLite、MySQL、LevelDB等&#xff0c;应用于智能家居、工业控制、车载系统和物联网设备&#xff0c;提升了系统功…

关于 pnpm monorepo 项目中 TS2742 Error 的 workaround

最近我在使用 pnpm 作为包管理器开发一个 monorepo 项目&#xff0c;从个人体验来说&#xff0c;在 monorepo 项目中&#xff0c;pnpm 确实要比 yarn classic 用得舒心&#xff0c;最让我欣喜的是 pnpm 对 workspace 协议的支持度很好&#xff1b;另外感受比较明显的一点就是&a…

Nginx+Lua+Redis 实现Nginx301跳转配置管理

业务场景需求 long long ago&#xff1a; 在项目的运维过程中有一次SEO团队提出 网页的URL 中如果可以带上关键字&#xff0c;那么网页在各大搜索引擎中收录和排名有非常重大的突出优势&#xff08;~~SEO团队到底专不专业 ~~&#xff0c;此处不做置评&#xff09;&#xff0c;…

超详细!想进华为od的请疯狂看我!

三分钟带你全面了解华为OD 【合同及管理】签约方为科锐国际/外企德科&#xff08;人力服务公司&#xff09;&#xff0c;劳动合同期为4年&#xff0c;试用期6个月。员工关系合同管理、五险一金、考勤发薪由科锐国际/外企德科负责&#xff1b;定级定薪、员工培训、工作安排、绩…

学生课程信息管理系统

摘 要 目前&#xff0c;随着科学经济的不断发展&#xff0c;高校规模不断扩大&#xff0c;所招收的学生人数越来越 多&#xff1b;所开设的课程也越来越多。随之而来的是高校需要管理更多的事务。对于日益增 长的学生相关专业的课程也在不断增多&#xff0c;高校对其管理具有一…

计算机网络:应用层 - 万维网 HTTP协议

计算机网络&#xff1a;应用层 - 万维网 & HTTP协议 万维网 WWW统一资源定位符 URL 超文本传输协议 HTTP非持续连接持续连接非流水线流水线 代理服务器HTTP报文 万维网 WWW 万维网是一个大规模的、联机式的信息储藏所。万维网用链接的方法能非常方便地从互联网上的一个站点…

路由

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 客户端&#xff08;例如浏览器&#xff09;把请求发送给 Web 服务器&#xff0c;Web 服务器再把请求发送给 Flask程序实例。程序实例需要知道对每个U…

昇思25天学习打卡营第5天|网络构建

一、简介&#xff1a; 神经网络模型是由神经网络层和Tensor操作构成的&#xff0c;mindspore.nn提供了常见神经网络层的实现&#xff0c;在MindSpore中&#xff0c;Cell类是构建所有网络的基类&#xff08;这个类和pytorch中的modul类是一样的作用&#xff09;&#xff0c;也是…

std::bind与std::ref配合使用时要注意的几个问题

目录 1 假如输入函数的变量是左值非常量引用&#xff0c;则该变量在std::bind中只能用std::ref修饰&#xff0c;不能用cref&#xff0c;否则编译失败&#xff1a; 2 假如输入函数的变量是左值常量引用&#xff0c;则该变量在std::bind中既可以用std::ref修饰&#xff0c;也可…

Mathtype7在Word2016中闪退(安装过6)

安装教程&#xff1a;https://blog.csdn.net/Little_pudding10/article/details/135465291 Mathtype7在Word2016中闪退是因为安装过Mathtype6&#xff0c;MathPage.wll和MathType Comm***.dotm)&#xff0c;不会随着Mathtype的删除自动删除&#xff0c;而新版的Mathtype中的文件…