02_使用Docker在服务器上部署Jekins实现项目的自动化部署
02_使用Docker在服务器上部署jenkins实现项目的自动化部署
一、使用docker拉取阿里云容器私有镜像仓库内的jenkins镜像
- 登录阿里云Docker Registry
$ sudo docker login --username=wxxxo@1xxx registry.cn-shanghai.aliyuncs.com
用于登录的用户名为阿里云账号全名,密码为开通服务时设置的密码。
您可以在访问凭证页面修改凭证密码。
- 从Registry中拉取镜像
$ sudo docker pull registry.cn-shanghai.aliyuncs.com/xxx/jenkins:[镜像版本号]
二、创建jenkins容器并运行
$ sudo docker run -d -u root \
-p 8080:8080 \
-p 50000:50000 \
-v /home/docker/jenkins_home:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /usr/bin/docker:/usr/bin/docker \
-v /usr/bin/kubectl:/usr/bin/kubectl \
-v /root/.kube/config:/root/.kube/config \
--name jenkins \
registry.cn-shanghai.aliyuncs.com/xxx/jenkins:xxx
每个参数的含义:
-
docker run: 运行 Docker 容器的命令。
-
-d: 在后台运行容器,即“detached”模式。
-
-u root: 以 root 用户身份运行容器。这通常用于确保容器内的进程具有足够的权限执行需要的操作。
-
-p 8080:8080: 将容器内部的 8080 端口映射到宿主机的 8080 端口(宿主机端口:容器内部端口)。Jenkins 服务通常在 8080 端口上运行。
-
-p 50000:50000: 将容器内部的 50000 端口映射到宿主机的 50000 端口(宿主机端口:容器内部端口)。这是 Jenkins 使用的用于构建和执行任务的端口。
-
-v /home/docker/jenkins_home:/var/jenkins_home: 将宿主机上的目录(/home/docker/jenkins_home)挂载到容器内的 /var/jenkins_home 目录(宿主机目录:容器内部目录)。这样可以确保 Jenkins 数据和配置持久化,即使容器被删除,数据仍然保存在宿主机上。
注意:/home/docker/jenkins_home 为自己在Linux系统里创建的用来持久化jenkins数据的目录,而/var/jenkins_home是docker容器内的默认路径,即jenkins_home的路径在docker容器内的/var下。
-
-v /var/run/docker.sock:/var/run/docker.sock
宿主机上的目录(/var/run/docker.sock)挂载到容器内的 /var/run/docker.sock 目录(宿主机目录:容器内部目录)。挂载 宿主机的 Docker 套接字(socket)到容器内部,让容器能够控制使用宿主机上的 Docker。
-
-v /usr/bin/docker:/usr/bin/docker
宿主机上的目录( /usr/bin/docker)挂载到容器内的 /usr/bin/docker 目录(宿主机目录:容器内部目录)。将宿主机上的
docker命令二进制文件挂载到容器内,使容器内部可以直接调用 Docker 命令。 -
-v /usr/bin/kubectl:/usr/bin/kubectl
宿主机上的目录(/usr/bin/kubectl)挂载到容器内的 /usr/bin/kubectl 目录(宿主机目录:容器内部目录)。将宿主机的
kubectl命令挂载到容器内部,使 Jenkins 在容器中可以直接执行kubectl命令,管理 Kubernetes 集群。 -
-v /root/.kube/config:/root/.kube/config
宿主机上的目录(/root/.kube/config)挂载到容器内的 /root/.kube/config 目录(宿主机目录:容器内部目录)。将宿主机的 Kubernetes 配置文件挂载到容器内部,使 Jenkins 能够以ROOT权限访问 Kubernetes 集群。
-
–name jenkins: 为容器指定一个名称,即 “jenkins”。
-
registry.cn-shanghai.aliyuncs.com/xxx/jenkins:2.491-jdk17: 指定要运行的 Docker 镜像的名称和版本(镜像名称:版本号)。
三、登录jenkins
通过访问[服务器IP]:[jenkins端口]访问jenkins服务,刚使用jenkins服务时,需要使用jenkins提供的默认密码进行验证。
jenkins提供的默认密码路径(在docker容器内)为:
/var/jenkins_home/secrets/initialAdminPassword
(如果将宿主机的某个目录路径挂载到 /var/jenkins_home 路径):如将宿主机上的目录(/home/docker/jenkins_home)挂载到容器内的 /var/jenkins_home 目录,那么默认密码路径为
/home/docker/jenkins_home/secrets/initialAdminPassword
安装插件,当然也可以跳过,不过一般推荐按照jenkins的推荐的插件。安装完毕后,可以创建jenkins用户。
四、配置名为dockerhub的凭证
在Jenkins中配置名为dockerhub的凭证(实际上就是自己的账号密码),方便Jenkins在构建docker镜像过程中,可以登录阿里云私有仓库,并上传到阿里云私有仓库内。
-
点击 “Manage Jenkins”(管理 Jenkins)。
-
进入 “Manage Credentials”(管理凭证)。
-
点击 “Add Credentials”(添加凭证)。
-
Username(用户名): 阿里云账号
Password(密码): 阿里云密码
ID(唯一标识):
dockerhub(⚠️ 这个 ID 之后要在 Jenkinsfile 里用,也可以起其他ID名,但是需要和Jenkinsfile里的registryCredential保持一致)。
五、编写dockerfile、K8S/deployment.yaml、jenkinsfile文件
dockerfile文件:docker打包镜像时,可以读取该文件中的内容,依据文件中的命令进行打包。
dockerfile示例:
# FROM 指定使用哪个镜像作为基准
FROM docker.m.daocloud.io/openjdk:8u191-jdk-alpine# 创建目录, 并设置该目录为工作目录
RUN mkdir -p /aaa
WORKDIR /aaa# 复制文件到镜像中
# COPY target/aaa-1.0.jar aaa.jar
COPY aaa-1.0.jar ./# 设置时区
ENV TZ=Asia/Shanghai# 设置 JAVA_OPTS 环境变量,可通过 docker run -e "JAVA_OPTS=" 进行覆盖
ENV JAVA_OPTS="-Xms300m -Xmx300m -Djava.security.egd=file:/dev/./urandom"# 应用参数,可通过 docker run -e "ARGS=" 来设置,如 -e "ARGS=--spring.profiles.active=prod"
ENV ARGS=""# 暴露 8080 端口
EXPOSE 8080# 启动后端服务
CMD java ${JAVA_OPTS} -jar aaa-1.0.jar $ARGS
K8S/deployment.yaml文件:K8S创建应用时,可以通过该文件中的内容进行创建。
K8S/deployment.yaml文件:
apiVersion: v1 # apiVersion: v1:指定 Kubernetes API 版本,v1 适用于 Service 资源
kind: Service # 定义该资源的类型是一个 Service
metadata:name: aaa # 定义 Service 的名称
spec: # 定义 Service 的详细配置type: NodePort # 指定 Service 类型为 NodePort,即允许外部通过 NodeIP:nodePort 访问服务。selector:app: aaa # 表示该 Service 只会选择 app: aaa 这个标签的 Pod 作为后端服务。ports: # 定义 Service 的端口映射- protocol: TCP # 指定使用 TCP 作为通信协议port: 8080 # 这是 Service 内部的端口,其他 Pod 访问该 Service 时使用这个端口。 port 会转发流量到 targetPort,通常它们可以相同,但不强制相同nodePort: 31678 # Kubernetes 在每个节点上分配的端口号,用于外部访问targetPort: 8080 # 这是 Pod 内部运行的容器监听的端口,对应 Dockerfile 里 EXPOSE 的端口和后文的里的 containerPortname: http # 端口名称(可不写)---
apiVersion: apps/v1 # 指定 Kubernetes API 版本,apps/v1 适用于 Deployment 资源
kind: Deployment # 定义该资源的类型是一个 Deployment,用于管理 Pod 的创建和更新
metadata:name: aaa # Deployment 的名称annotations:kubernetes.io/change-cause: registry-vpc.cn-shanghai.aliyuncs.com/aaa/aaa:{{GIT_COMMIT}} # 用于记录该 Deployment 变更的原因,常用于回滚和版本管理,其中 {{GIT_COMMIT}} 是 Git 提交的版本号,通常在 CI/CD 过程中会被替换为实际值,例如Jenkinsfile文件中有一条命令便是查找{{GIT_COMMIT}}并将其替换为实际的版本号
spec: # 定义 Deployment 的详细配置replicas: 1 # 指定副本数,即 Pod 的数量为 1selector:matchLabels:app: aaa # 表示该 Deployment 只会管理 app: aaa 这个标签的 Podtemplate: # 定义 Pod 模板,所有由该 Deployment 创建的 Pod 都会遵循此模板metadata:labels:app: aaa # 给 Pod 打上 app: aaa 的标签,便于 Service 发现该 Podspec: # 定义 Pod 的详细配置 containers:- name: aaa # 容器名称image: registry-vpc.cn-shanghai.aliyuncs.com/aaa/aaa:{{GIT_COMMIT}} # 指定容器的镜像地址,{{GIT_COMMIT}} 代表 Git 版本号,CI/CD 过程中会被替换为实际值ports: - containerPort: 8080 # 定义容器内部监听的端口,应和dockerfile里EXPOSE暴露的端口保持一致# 下面是健康检查配置# livenessProbe: # (存活探针):检查容器是否存活,若失败 Kubernetes 会重启该容器# httpGet:# path: /user/health_check # 通过 HTTP GET 请求
Jenkinsfile文件:Jenkins全流程部署时,根据该文件中的内容,进行全流程部署。
Jenkinsfile文件:
pipeline { // 定义一个工作流environment { //定义环境变量//定义Docker镜像仓库地址registry = "registry-vpc.cn-shanghai.aliyuncs.com/aaa/aaa"registryCredential = "dockerhub" //docker登录阿里云的凭证,即配置的账号密码,存储在jekins的Credential里parentWorkspace = "$WORKSPACE" FAILED_STAGE=""CURRENT_ENVIRONMENT=""BLUE_OR_GREEN=""}agent any // 定义在哪个 agent 上运行,这里使用任意可用节点stages { // 定义流水线中各个阶段(stages)stage("Deply Parent") { // 项目构建阶段agent {docker { //指定使用 Docker 代理运行image 'registry.cn-hangzhou.aliyuncs.com/acs/maven:3-jdk-8'args '-v $HOME/.m2/repository:/root/.m2/repository -u root'}}steps { // 定义该阶段的步骤(steps),并使用 script 块以脚本形式执行命令script {FAILED_STAGE=env.STAGE_NAME //将当前阶段名称(env.STAGE_NAME)赋值给变量 FAILED_STAGE,以便在出错时记录是哪一阶段失败了。sh "mvn -Dmaven.repo.local=/var/jenkins_home/jenkins_m2_repo -U install -Dmaven.test.skip=true" // 执行一个 shell 命令,通过 Maven 进行项目构建:-Dmaven.repo.local=/var/jenkins_home/jenkins_m2_repo 指定 Maven 本地仓库路径,-U 表示强制更新 SNAPSHOT 依赖,install 命令用于构建并安装项目,-Dmaven.test.skip=true 则跳过测试执行。// 拷贝到容器外sh "cp target/analyzer-1.0.jar " + parentWorkspace +"/analyzer-1.0.jar" // 执行一个 shell 命令,将 target 目录下生成的 analyzer-1.0.jar 文件复制到外部的工作空间路径(由变量 parentWorkspace 指定)。}}}stage("Building image") { //构建镜像阶段steps {script {FAILED_STAGE=env.STAGE_NAME // 将当前阶段名称赋值给 FAILED_STAGE,docker.build(registry) // 调用 docker.build(registry) 方法,根据之前定义的 registry 变量构建 Docker 镜像。sh "docker rmi -f ${registry}:$GIT_COMMIT" // 强制删除本地镜像}}}stage("Deploy Image") { // 部署镜像阶段steps {script {FAILED_STAGE=env.STAGE_NAME // 将当前阶段名称赋值给 FAILED_STAGEdocker.withRegistry('https://registry-vpc.cn-shanghai.aliyuncs.com', registryCredential) { // 使用 docker.withRegistry 方法指定镜像仓库地址 https://registry-vpc.cn-shanghai.aliyuncs.com 和凭据 registryCredential,docker.image(registry).push("$GIT_COMMIT") //将构建的镜像以当前 Git 提交号($GIT_COMMIT)作为标签推送到仓库。}}}}stage("Update k8s cluster") { // 更新 Kubernetes 集群阶段options {timeout(time: 5, unit: 'MINUTES') // 本阶段超时时间限定为 5 分钟}steps {script {FAILED_STAGE=env.STAGE_NAME // 当前阶段名称赋值给 FAILED_STAGEif (env.GIT_BRANCH == "origin/test") { // 判断当前的 Git 分支是否为 "origin/test",分支需要按需选择,这里是在test分支下,使用使用test,也可以改为master等。sh "cat k8s/deployment.yml | sed 's/{{GIT_COMMIT}}/$GIT_COMMIT/g' | kubectl apply -n default -f -" // 使用 sed 命令将 k8s/deployment.yml 文件中的占位符 {{GIT_COMMIT}} 替换为实际的 Git 提交号,并通过管道传递给 kubectl apply 命令,应用于 default 命名空间sh "kubectl rollout status deployment/aaa -n default" // 使用 kubectl rollout status 命令检查部署状态,确保部署成功}else{sh "cat k8s/deployment-test.yml | sed 's/{{GIT_COMMIT}}/$GIT_COMMIT/g' | kubectl apply -n test -f -" // 对 k8s/deployment-test.yml 文件进行替换,并将其应用于 test 命名空间sh "kubectl rollout status deployment/aaa -n default" // 检查部署状态}}}}}post { // 流水线的后置操作(post)aborted { // 流水线被中止(aborted)时,执行以下 script 脚本script {if (FAILED_STAGE == "Update k8s cluster") { // 如果最后出错的阶段(FAILED_STAGE)是 "Update k8s cluster",则根据当前 Git 分支进行回滚操作if (env.GIT_BRANCH == "origin/test") { // 如果在 origin/test 分支下,分支需要按需选择,这里是在test分支下,使用使用test,也可以改为master等。sh "kubectl config use kubernetes" // 切换 kubectl 配置)sh "kubectl rollout undo deployment/aaa" // 回滚部署 aaa。}else{sh "kubectl config use kubernetes" 切换配置sh "kubectl rollout undo deployment/aaa-test" 回滚部署}}}}}
}
六、创建任务
创建一个任务(可以使用模板,如Freestyle project、Pipeline)。
- 如果使用的是Freestyle project
- 选择代码源管理(Source Code Management),项目如果在Coding、GitHub、Gitee等托管平台上,则选择Git。
- 填写仓库路径(Repository URL),HTTP的仓库路径。填写完路径以后,一般会报错。
- 如果没有Credentials,则需要添加一个新的Credentials。添加时,Username 填仓库所在平台的邮箱,密码填仓库所在平台的用户密码。完成以后,如果账号密码没问题,则此处不会报错。
- 有时还需要选择分支(Branch Specifier)。
- 处理构建流程(Steps),需要手动一个一个添加(Add build step)。
- 选择代码源管理(Source Code Management),项目如果在Coding、GitHub、Gitee等托管平台上,则选择Git。
- 如果使用的是Pipeline
- 一般选择Pipeline-Definition为Pipeline script from SCM。
- SCM (代码源)选择为 Git
- 填写仓库路径(Repository URL),HTTP的仓库路径。填写完路径以后,一般会报错。
- 如果没有Credentials,则需要添加一个新的Credentials。添加时,Username 填仓库所在平台的邮箱,密码填仓库所在平台的用户密码。完成以后,如果账号密码没问题,则此处不会报错。
- 有时还需要选择分支(Branch Specifier)。
- Script Path填写自己在项目根目录放置的用于jenkins读取的文件(自动化部署的命令),如jenkinsfile文件等。
相关文章:
02_使用Docker在服务器上部署Jekins实现项目的自动化部署
02_使用Docker在服务器上部署jenkins实现项目的自动化部署 一、使用docker拉取阿里云容器私有镜像仓库内的jenkins镜像 登录阿里云Docker Registry $ sudo docker login --usernamewxxxo1xxx registry.cn-shanghai.aliyuncs.com用于登录的用户名为阿里云账号全名,…...
Spring 执行流程(源码)
我们对SpringApplication中的run()方法内部进行一些简单的分析 1. //记录一下程序启动开始的事件,用于之后的统计耗时 long startTime System.nanoTime(); //通过调用SpringApplication的**createBootstrapContext()**方法,创建**bootstrapContext**…...
Python学习之numpy
Python学习之numpy 数组是Numpy库的核心数据结构。 NumPy 是一个 Python 包。 它代表 “Numeric Python”。 它是一个由多维数组对象和用于处理数组的例程集合组成的库。 Numeric,即 NumPy 的前身,是由 Jim Hugunin 开发的。 也开发了另一个包 Numarr…...
安装完 miniconda3 ,cmd无法执行 conda 命令
提示:安装 miniconda3 文章目录 前言一、安装二、安装完,cmd 无法执行 conda 前言 提示:版本 系统:win10 codna: miniconda3 安装完 miniconda3 ,cmd无法执行 conda 命令 提示:以下是本篇文章正文内容&am…...
PyTorch 实现图像版多头注意力(Multi-Head Attention)和自注意力(Self-Attention)
本文提供一个适用于图像输入的多头注意力机制(Multi-Head Attention)PyTorch 实现,适用于 ViT、MAE 等视觉 Transformer 中的注意力计算。 模块说明 输入支持图像格式 (B, C, H, W)内部转换为序列 (B, N, C),其中 N H * W多头注…...
从 Credit Metrics 到 CPV:现代信用风险模型的进化与挑战
文章目录 一、信用风险基础二、Credit Risk 模型核心思想关键假设模型框架实施步骤优缺点适用场景 三、Credit Metrics 模型核心思想关键假设模型框架实施步骤优缺点适用场景 四、Credit Portfolio View 模型核心思想关键假设模型框架实施步骤优缺点适用场景 五、总结 一、信用…...
Docker快速安装MongoDB并配置主从同步
目录 一、创建相关目录及授权 二、下载并运行MongoDB容器 三、配置主从复制 四、客户端远程连接 五、验证主从同步 六、停止和恢复复制集 七、常用命令 一、创建相关目录及授权 创建主节点mongodb数据及日志目录并授权 mkdir -p /usr/local/mongodb/mongodb1/data mkdir …...
Kafka 中的事务
Kafka 中的 事务(Transactions) 是为了解决 消息处理的原子性和幂等性问题,确保一组消息要么全部成功写入、要么全部失败,不出现中间状态或重复写入。事务机制尤其适合于 “精确一次(Exactly-Once)” 的处理…...
C++ 内存访问模式优化:从架构到实践
内存架构概览:CPU 与内存的 “速度博弈” 层级结构:从寄存器到主存 CPU 堪称计算的 “大脑”,然而它与内存之间的速度差距,宛如高速公路与乡间小路。现代计算机借助多级内存体系来缓和这一矛盾,其核心思路是…...
Golang系列 - 内存对齐
Golang系列-内存对齐 常见类型header的size大小内存对齐空结构体类型参考 摘要: 本文将围绕内存对齐展开, 包括字符串、数组、切片等类型header的size大小、内存对齐、空结构体类型的对齐等等内容. 关键词: Golang, 内存对齐, 字符串, 数组, 切片 常见类型header的size大小 首…...
SOMEIP通信矩阵解读
目录 1 摘要2 SOME/IP通信矩阵详细属性定义与示例2.1 服务基础属性2.2 数据类型定义2.3 服务实例与网络配置参数2.4 SOME/IP-SD Multicast 配置(SOME/IP服务发现组播配置)2.5 SOME/IP-SD Unicast 配置2.6 SOME/IP-SD ECU 配置参数详解 3 总结 1 摘要 本…...
Excel + VBA 实现“准实时“数据的方法
Excel 本身是静态数据处理工具,但结合 VBA(Visual Basic for Applications) 可以实现 准实时数据更新,不过严格意义上的 实时数据(如毫秒级刷新)仍然受限。以下是详细分析: 1. Excel + VBA 实现“准实时”数据的方法 (1) 定时刷新(Timer 或 Application.OnTime) Appl…...
网络原理 - HTTP/HTTPS
1. HTTP 1.1 HTTP是什么? HTTP (全称为 “超文本传输协议”) 是⼀种应用非常广泛的应用层协议. HTTP发展史: HTTP 诞生于1991年. 目前已经发展为最主流使用的⼀种应用层协议 最新的 HTTP 3 版本也正在完善中, 目前 Google / Facebook 等公司的产品已经…...
C++设计模式-解释器模式:从基本介绍,内部原理、应用场景、使用方法,常见问题和解决方案进行深度解析
一、解释器模式的基本介绍 1.1 模式定义与核心思想 解释器模式(Interpreter Pattern)是一种行为型设计模式,其核心思想是为特定领域语言(DSL)定义语法规则,并构建一个解释器来解析和执行该语言的句子。它…...
OCC Shape 操作
#pragma once #include <iostream> #include <string> #include <filesystem> #include <TopoDS_Shape.hxx> #include <string>class GeometryIO { public:// 加载几何模型:支持 .brep, .step/.stp, .iges/.igsstatic TopoDS_Shape L…...
深度学习入门(四):误差反向传播法
文章目录 前言链式法则什么是链式法则链式法则和计算图 反向传播加法节点的反向传播乘法节点的反向传播苹果的例子 简单层的实现乘法层的实现加法层的实现 激活函数层的实现ReLu层Sigmoid层 Affine层/SoftMax层的实现Affine层Softmax层 误差反向传播的实现参考资料 前言 上一篇…...
Linux:页表详解(虚拟地址到物理地址转换过程)
文章目录 前言一、分页式存储管理1.1 虚拟地址和页表的由来1.2 物理内存管理与页表的数据结构 二、 多级页表2.1 页表项2.2 多级页表的组成 总结 前言 在我们之前的学习中,我们对于页表的认识仅限于虚拟地址到物理地址转换的桥梁,然而对于具体的转换实现…...
AF3 OpenFoldDataLoader类解读
AlphaFold3 data_modules 模块的 OpenFoldDataLoader 类继承自 PyTorch 的 torch.utils.data.DataLoader。该类主要对原始 DataLoader 做了批数据增强与控制循环迭代次数(recycling)相关的处理。 源代码: class OpenFoldDataLoader(torch.utils.data.DataLoader):def __in…...
初见TypeScript
类型语言,在代码规模逐渐增大时,类型相关的错误难以排查。TypeScript 由微软开发,它本质上是 JavaScript 的超集,为 JavaScript 添加了静态类型系统,让开发者在编码阶段就能发现潜在类型错误,提升代码质量&…...
常见的 JavaScript 框架和库
在现代前端开发中,JavaScript框架和库成为了构建高效、可维护应用程序的关键工具。本文将介绍四个常见的JavaScript框架和库:React、Vue.js、Angular 和 Node.js,并探讨它们的特点、使用场景及适用场合。 1. React — 构建用户界面的JavaScri…...
机器学习代码基础——ML2 使用梯度下降的线性回归
ML2 使用梯度下降的线性回归 牛客网 描述 编写一个使用梯度下降执行线性回归的 Python 函数。该函数应将 NumPy 数组 X(具有一列截距的特征)和 y(目标)作为输入,以及学习率 alpha 和迭代次数,并返回一个…...
PostgreSQL 一文从安装到入门掌握基本应用开发能力!
本篇文章主要讲解 PostgreSQL 的安装及入门的基础开发能力,包括增删改查,建库建表等操作的说明。navcat 的日常管理方法等相关知识。 日期:2025年4月6日 作者:任聪聪 一、 PostgreSQL的介绍 特点:开源、免费、高性能、关系数据库、可靠性、稳定性。 官网地址:https://w…...
WEB安全--内网渗透--LMNTLM基础
一、前言 LM Hash和NTLM Hash是Windows系统中的两种加密算法,不过LM Hash加密算法存在缺陷,在Windows Vista 和 Windows Server 2008开始,默认情况下只存储NTLM Hash,LM Hash将不再存在。所以我们会着重分析NTLM Hash。 在我们内…...
查询条件与查询数据的ajax拼装
下面我将介绍如何使用 AJAX 动态拼装查询条件和获取查询数据,包括前端和后端的完整实现方案。 一、前端实现方案 1. 基础 HTML 结构 html 复制 <div class"query-container"><!-- 查询条件表单 --><form id"queryForm">…...
8.用户管理专栏主页面开发
用户管理专栏主页面开发 写在前面用户权限控制用户列表接口设计主页面开发前端account/Index.vuelangs/zh.jsstore.js 后端Paginator概述基本用法代码示例属性与方法 urls.pyviews.py 运行效果 总结 欢迎加入Gerapy二次开发教程专栏! 本专栏专为新手开发者精心策划了…...
室内指路机器人是否支持与第三方软件对接?
嘿,你知道吗?叁仟室内指路机器人可有个超厉害的技能,那就是能和第三方软件 “手牵手” 哦,接下来就带你一探究竟! 从技术魔法角度看哈:好多室内指路机器人都像拥有超能力的小魔法师,采用开放式…...
Apache BookKeeper Ledger 的底层存储机制解析
Apache BookKeeper 的 ledger(账本)是其核心数据存储单元,底层存储机制结合了日志追加(append-only)、分布式存储和容错设计。Ledger 的数据存储在 Bookie 节点的磁盘上,具体实现涉及 Journal(日…...
从代码上深入学习GraphRag
网上关于该算法的解析都停留在大概流程上,但是具体解析细节未知,由于代码是PipeLine形式因此阅读起来比较麻烦,本文希望通过阅读项目代码来解析其算法的具体实现细节,特别是如何利用大模型来完成图谱生成和检索增强的实现细节。 …...
通俗地讲述DDD的设计
通俗地讲述DDD的设计 前言为什么要使用DDDDDD架构分层重构实践关键问题解决方案通过领域事件机制解耦服务依赖:防止逻辑下沉 领域划分电商场景下的领域划分 结语完结撒花,如有需要收藏的看官,顺便也用发财的小手点点赞哈,…...
【Redis】通用命令
使用者通过redis-cli客户端和redis服务器交互,涉及到很多的redis命令,redis的命令非常多,我们需要多练习常用的命令,以及学会使用redis的文档。 一、get和set命令(最核心的命令) Redis中最核心的两个命令&…...
