使用Buildpacks构建Docker镜像

## 使用Buildpacks构建Docker镜像

![](../assets/运维手册-Buildpacks-Buildpacks.io.png)

### Buildpacks简介

与Dockerfile相比,Buildpacks为构建应用程序提供了更高层次的抽象。具体来说,Buildpacks:

* 提供一个平衡的控制,减少开发人员的操作负担,并支持企业运营商在规模上管理应用程序。

* 确保应用程序满足安全性和法规遵从性要求,而无需开发人员干预。

* 提供操作系统级和应用程序级依赖项升级的自动交付,有效地处理第二天的应用程序操作,这些操作通常很难用Dockerfile进行管理。

* 依赖兼容性保证安全地应用补丁,而不必重建工件,也不必意外地更改应用程序行为。

Buildpacks是可插入的、模块化的工具,通过提供比Dockerfile更高级别的抽象,将源代码转换为容器就绪的构件。通过这样做,他们提供了一种控制的平衡,最小化了最初的生产时间,减少了开发者的操作负担,并支持大规模管理应用程序的企业运营商。

Cloud Native Buildpacks

2018年10月云原生Buildpacks项目加入CNCF沙箱

CNB流程分为四个步骤,每个步骤都有各自的重要目标,最终产出就是 OCI 镜像。CNB让开发和运维人员能够把创建各种软件的过程中所需的构建、补丁和重新打包的工作自动化成适合机器执行的重复任务。

![](../assets/运维手册-Buildpacks-CNB流程.png)

检测:对源码以及其它内容进行检测,查找与其匹配的可用 Buildpacks。假设提供一套Go源文件,就会检测到Go Buildpack适用于这一输入。

分析:CNB 会在应用的生命周期中运行多次,在这一步骤里会对前一次的打包内容进行分析,分析过程会对文件的变更进行优化,从而减少构建时间和文件传输。这里会使用多个镜像层来对内容进行组织。

构建:如果镜像层或者目录需要进行替换,构建过程就会生成新的层。这里会提供缓存来加速构建过程。

导出:这个步骤中会生成最终镜像并推送到镜像仓库之中。传输、磁盘使用和更新时间都会用镜像层的更新操作来完成。另外 CVE 补丁也可以同时应用到多个镜像之中。

所以还等什么?现在开始使用Buildpacks尝尝鲜吧。

### 应用程序从源代码到镜像的短暂之旅

#### 构建Go Web应用Docker镜像

使用pack和buildpacks从源代码创建可运行的应用程序镜像。这意味着需要确保安装了pack程序包,注意:pack只是Cloud Native Buildpacks平台规范的一个实现。

先决条件:

安装Docker

安装pack

#### 构建一个app

将应用程序从源代码转换为可运行镜像的基础知识。

1.选择builder

2.构建app

3.运行app

环境变量

环境变量是在构建时配置各种构建包的常用方法。

指定构建包

指定构建过程中使用的构建包。

在我们开始之前,您需要了解buildpacks的基本知识以及它们是如何工作的。

buildpack的工作是收集应用程序构建和运行所需的所有信息,它通常会快速而安静地完成这项工作。

当平台针对您的应用程序的源代码依次测试buildpacks组时,就会发生自动检测。第一个认为自己适合您的源代码的组将成为应用程序选定的buildpacks。

检测标准对每个buildpack是特定的 -例如,一个Go buildpack可能会寻找Go的源文件。

#### 创建buildpack

这是一个使用简单bash脚本创建云原生构建包的逐步教程。

设置本地环境

构建云原生Buildpack的块

检测应用程序:

下一步,您将需要实际检测您正在构建的应用程序是一个GO应用程序。为了做到这一点,你需要检查一个go.mod文件。

构建应用程序

使应用程序可运行

通过缓存提高性能:

我们可以通过缓存构建之间的依赖关系来提高性能,只在必要时重新下载。

使您的构建包可配置

#### 打包buildpack

了解如何使用标准的OCI注册表打包buildpack以进行发布。

0.获取样本代码仓

1.创建package.toml:

我们需要创造一个package.toml文件,以便告诉pack在何处查找要打包的buildpack的依赖项。

2.指定您的构建包:

让我们从指定要打包的buildpack的位置开始。

3.指定依赖的构建包

4.打包您的构建包

#### 什么是builder?

builder是一个镜像,它打包了有关如何构建应用程序的所有bits和信息,例如buildpacks和build-time镜像,

并针对应用程序源代码执行buildpacks。

#### 构建Go应用程序

在shell中运行以下命令来克隆和构建一个简单的Go应用程序。

```shell

# clone the repo

git clone http://gitlab.ebcpaas.com/buildpacks/samples.git

# go to the app directory

cd samples/apps/cnb-go

# build the app

pack build cnb-go --builder cnbs/sample-builder:bionic \

--buildpack ../../buildpacks/cnb-go

```

注意:这是您第一次为应用程序cnb-go运行pack build,因此您会注意到该生成可能需要比平时更长的时间。后续的构建将利用各种形式的缓存。

展示Terminal日志信息:

```

bionic: Pulling from cnbs/sample-builder

...

Status: Downloaded newer image for cnbs/sample-builder:bionic

bionic: Pulling from cnbs/sample-stack-run

...

Status: Image is up to date for cnbs/sample-stack-run:bionic

===> DETECTING

[detector] samples/cnb-go 0.0.1

===> ANALYZING

[analyzer] Previous image with name "index.docker.io/library/cnb-go:latest" not found

[analyzer] Restoring metadata for "samples/cnb-go:golang" from cache

===> RESTORING

[restorer] Restoring data for "samples/cnb-go:golang" from cache

===> BUILDING

[builder] ---> Golang buildpack

[builder] + env_dir=/platform/env

[builder] + layers_dir=/layers/samples_cnb-go

[builder] + plan_path=/tmp/plan.387032741/samples_cnb-go/plan.toml

[builder] + git_version=2.10.1

[builder] + git_url=https://github.com/git/git/archive/v2.10.1.tar.gz

[builder] + golang_version=1.13

[builder] ---> Installing golang

[builder] + golang_url=http://25.38.21.19:8080/go1.13.linux-amd64.tar.gz

[builder] + compgen -G '/platform/env/*'

[builder] + export PATH=/layers/samples_cnb-go/git/git/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

[builder] + PATH=/layers/samples_cnb-go/git/git/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

[builder] + echo '---> Installing golang'

[builder] + [[ -f /layers/samples_cnb-go/golang.toml ]]

[builder] ++ yj -t

[builder] ++ jq -r .metadata.url

[builder] ++ cat /layers/samples_cnb-go/golang.toml

[builder] + cached_golang_url=http://25.38.21.19:8080/go1.13.linux-amd64.tar.gz

[builder] + [[ http://25.38.21.19:8080/go1.13.linux-amd64.tar.gz != '' ]]

[builder] + rm -rf /layers/samples_cnb-go/golang

[builder] + mkdir -p /layers/samples_cnb-go/golang/gopath

[builder] + wget -qO go.tgz http://25.38.21.19:8080/go1.13.linux-amd64.tar.gz

[builder] + tar -C /layers/samples_cnb-go/golang -xzf go.tgz

[builder] + rm go.tgz

[builder] + ls -la /layers/samples_cnb-go/golang/go/bin/

[builder] total 18196

[builder] drwxr-xr-x 2 cnb cnb 4096 Sep 3 2019 .

[builder] drwxr-xr-x 10 cnb cnb 4096 Sep 3 2019 ..

[builder] -rwxr-xr-x 1 cnb cnb 15075523 Sep 3 2019 go

[builder] -rwxr-xr-x 1 cnb cnb 3543823 Sep 3 2019 gofmt

[builder] + /layers/samples_cnb-go/golang/go/bin/go version

[builder] go version go1.13 linux/amd64

[builder] + echo 'launch = false'

[builder] + echo 'build = true'

[builder] + echo 'cache = true'

[builder] + echo -e '[metadata]\n version = "1.13"\n url = "http://25.38.21.19:8080/go1.13.linux-amd64.tar.gz"'

[builder] + export PATH=/layers/samples_cnb-go/golang/go/bin:/layers/samples_cnb-go/git/git/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

[builder] + PATH=/layers/samples_cnb-go/golang/go/bin:/layers/samples_cnb-go/git/git/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

[builder] + export GOROOT=/layers/samples_cnb-go/golang/go

[builder] + GOROOT=/layers/samples_cnb-go/golang/go

[builder] + ln -s /layers/samples_cnb-go/golang /home/cnb/go

[builder] + export GOPATH=/home/cnb/go

[builder] + GOPATH=/home/cnb/go

[builder] + GOPACKAGENAME=workspace

[builder] + mkdir -p /home/cnb/go/src /home/cnb/go/bin

[builder] + chmod -R 777 /home/cnb/go

[builder] + ln -s /workspace /home/cnb/go/src/workspace

[builder] + env

[builder] HOSTNAME=54425b122133

[builder] CNB_STACK_ID=io.buildpacks.samples.stacks.bionic

[builder] GOPATH=/home/cnb/go

[builder] PWD=/workspace

[builder] HOME=/home/cnb

[builder] GOROOT=/layers/samples_cnb-go/golang/go

[builder] SHLVL=1

[builder] PATH=/layers/samples_cnb-go/golang/go/bin:/layers/samples_cnb-go/git/git/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

[builder] _=/usr/bin/env

[builder] + cd /home/cnb/go/src/workspace

[builder] + go build -o workspace

[builder] + echo 'processes = [{ type = "web", command = "./workspace"}]'

===> EXPORTING

[exporter] Adding layer 'launcher'

[exporter] Adding 1/1 app layer(s)

[exporter] Adding layer 'config'

[exporter] *** Images (edd743e6c495):

[exporter] index.docker.io/library/cnb-go:latest

[exporter] Adding cache layer 'samples/cnb-go:golang'

Successfully built image cnb-go

```

就这样!您的本地Docker守护进程上现在有一个名为cnb-go的可运行应用程序镜像。我们说过这毕竟是一次短暂的旅行。请注意,您的应用程序是在不需要额外安装Go语言包或配置构建环境的情况下构建的。pack和buildpacks帮你搞定了。

要在本地测试您的新应用程序映像,您可以使用Docker运行它:

```shell

docker run --rm -p 8089:8080 cnb-go

```

现在通过浏览器访问localhost:8089查看应用

![](../assets/运维手册-Buildpacks-通过浏览器查看应用.png)

### Buildpacks组件

Buildpacks组件:

Builder

Buildpack

Lifecycle

Stack

#### Builder

Builder由以下组件组成:

Buildpacks

Lifecycle

Stack’s build image

![](../assets/运维手册-Buildpacks-Builder-Image.png)

创建builder

创建自定义builder允许您控制使用哪些buildpacks以及应用程序基于哪些镜像。

0.获取样本代码仓

1.Builder配置

2.创建builder

3.使用你的builder

4.运行app

#### 什么是Buildpack?

buildpack是一个工作单元,它检查你的应用程序源代码并制定一个计划来构建和运行你的应用程序。

它们是将源代码转换为可运行的应用程序镜像的核心。

有两个基本阶段允许buildpack创建可运行镜像:

检测

构建

典型的构buildpack至少由三个文件组成:

buildpack.toml–提供有关buildpack的元数据

bin/detect –确定是否应该应用buildpack

bin/build – 执行buildpack(构建包)逻辑

buildpack.toml

```

# Buildpack API version

api = "0.2"

# Buildpack ID and metadata

[buildpack]

id = "samples/cnb-go"

name = "Sample cnb-go Buildpack"

version = "0.0.1"

# Stacks that the buildpack will work with

[[stacks]]

id = "io.buildpacks.samples.stacks.bionic"

[[stacks]]

id = "io.buildpacks.samples.stacks.alpine"

```

bin/detect

```

#!/usr/bin/env bash

set -eo pipefail

if test -f "go.mod" ||

test -f "main.go" ||

test -f "./vendor"

then

exit 0

fi

exit 1

```

bin/build

```

#!/usr/bin/env bash

echo "---> Golang buildpack"

set -eo pipefail

set -x

env_dir="$2/env"

layers_dir="$1"

plan_path="$3"

git_version="2.10.1"

git_url="https://github.com/git/git/archive/v${git_version}.tar.gz"

golang_version=1.13

#golang_url="https://golang.google.cn/dl/go${golang_version}.linux-amd64.tar.gz"

golang_url="http://25.38.21.19:8080/go1.13.linux-amd64.tar.gz"

# Load user-provided build-time environment variables

if compgen -G "$env_dir/*" > /dev/null; then

for var in "$env_dir"/*; do

declare "$(basename "$var")=$(<"$var")"

done

fi

# echo "---> Installing git"

#

# if [[ -f $layers_dir/git.toml ]]; then

# cached_git_url=$(cat "$layers_dir/git.toml" | yj -t | jq -r .metadata.url 2>/dev/null || echo 'Golang TOML parsing failed')

# fi

# if [[ $git_url != $cache_git_url ]] ; then

# rm -rf "$layers_dir/git"

# mkdir -p "$layers_dir/git"

# wget -qO git.tgz "$git_url";

# tar -C "$layers_dir/git" -xzf git.tgz

# pushd "${layers_dir}/git/git-${git_version}"

# make configure

# ./configure --prefix "${layers_dir}/git"

# make all

# make install

# popd

# rm git.tgz

# ls -la $layers_dir/git

# echo "launch = false" > "$layers_dir"/git.toml

# echo "build = true" >> "$layers_dir"/git.toml

# echo "cache = true" >> "$layers_dir"/git.toml

# echo -e "[metadata]\n version = \"$git_version\"\n url = \"$git_url\"" >> "$layers_dir"/git.toml

# fi

export PATH=$layers_dir/git/git/bin:$PATH

echo "---> Installing golang"

if [[ -f $layers_dir/golang.toml ]]; then

cached_golang_url=$(cat "$layers_dir/golang.toml" | yj -t | jq -r .metadata.url 2>/dev/null || echo 'Golang TOML parsing failed')

fi

if [[ $golang_url != $cache_golang_url ]] ; then

rm -rf "$layers_dir/golang"

mkdir -p "$layers_dir/golang/gopath"

wget -qO go.tgz "$golang_url";

tar -C "$layers_dir/golang" -xzf go.tgz

rm go.tgz

ls -la $layers_dir/golang/go/bin/

"$layers_dir"/golang/go/bin/go version

echo "launch = false" > "$layers_dir"/golang.toml

echo "build = true" >> "$layers_dir"/golang.toml

echo "cache = true" >> "$layers_dir"/golang.toml

echo -e "[metadata]\n version = \"$golang_version\"\n url = \"$golang_url\"" >> "$layers_dir"/golang.toml

fi

export PATH=$layers_dir/golang/go/bin:$PATH

export GOROOT=$layers_dir/golang/go

ln -s $layers_dir/golang $HOME/go

export GOPATH="$HOME/go"

GOPACKAGENAME=${PWD##*/}

mkdir -p "$GOPATH/src" "$GOPATH/bin" && chmod -R 777 "$GOPATH"

ln -s "$PWD" "$GOPATH/src/$GOPACKAGENAME"

env

cd "$GOPATH/src/$GOPACKAGENAME"

go build -o $GOPACKAGENAME

#go_binary=${PWD##*/}

echo "processes = [{ type = \"web\", command = \"./$GOPACKAGENAME\"}]" > "$layers_dir/launch.toml"

```

#### Lifecycle

lifecycle安排buildpack的执行,后将生成的构件组装到最终的应用程序镜像中。

阶段

检测:查找要在构建阶段使用的有序buildpacks构建包组。

分析:可用于优化构建和导出阶段的buildpacks构建包还原文件。

构建:将应用程序源代码转换为可运行的构件,这些构件可以打包到容器中。

导出:创建最终的OCI镜像。

#### 什么是Stack?

Stack以镜像的形式为buildpack生命周期提供构建时和运行时环境。

Stacks的使用

栈由builders使用,并通过builders的配置文件进行配置:

```

[[buildpacks]]

# ...

[[order]]

# ...

[stack]

id = "com.example.stack"

build-image = "example/build"

run-image = "example/run"

run-image-mirrors = ["gcr.io/example/run", "registry.example.com/example/run"]

```

通过提供所需的[stack]部分,builder作者可以配置stack的ID、构建映像和运行映像(包括任何镜像)。

### Buildpacks操作

Build

Rebase

#### Build构建

构建说明

![](../assets/运维手册-Buildpacks-Build构建.png)

构建是对应用程序的源代码执行一个或多个buildpacks构建包以生成可运行的OCI镜像的过程。每个构建包都检查源代码并提供相关的依赖项。然后从应用程序的源代码和这些依赖项生成一个镜像。

Buildpack与一个或多个stacks兼容。stack指定构建镜像和运行镜像。在构建过程中,stacks的构建镜像成为执行Buildpack的环境,其运行镜像成为最终应用程序镜像的基础。

Buildpack可以与特定stack的构建镜像绑定,从而生成builder镜像(请注意“er”结尾)。builder为给定stack发布构建包提供了最方便的方法。

#### Rebase变基

Rebase允许应用程序开发或运维人员在应用程序stack的运行镜像发生更改时快速更新应用程序映像。通过使用image层变基,此命令避免了完全重建应用程序的需要。

 

![](../assets/运维手册-Buildpacks-Rebase变基.png)

从根本上讲,image变基是一个简单的过程。通过检查应用程序镜像,rebase可以确定应用程序的基本镜像是否存在较新版本(本地或注册表中)。如果是,rebase将更新应用程序image的层元数据以引用较新的基本image版本。

示例:变基应用程序image

考虑一个应用程序image my-app:my-tag最初是使用默认builder生成的。该builder栈有一个名为pack/run的运行镜像。运行以下命令将更新带最新版本pack/run的my-app:my-tag基础镜像 。

```shell

pack rebase my-app:my-tag

```

https://github.com/paketo-buildpacks/go-mod/blob/master/buildpack.toml

https://paketo.io/docs/create-paketo-buildpack/

Go buildpack | Cloud Foundry Docs

https://buildpacks.io/docs/reference/spec/buildpack-api/

https://github.com/buildpacks/samples

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

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

相关文章

大佬,简单解释下“嵌入式软件开发”和“嵌入式硬件开发”的区别

在开始前刚好我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「嵌入式的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xff01;首先&#xff0c;嵌入式硬…

【AIGC半月报】AIGC大模型启元:2024.10(上)

【AIGC半月报】AIGC大模型启元&#xff1a;2024.10&#xff08;上&#xff09; (1) YOLO11&#xff08;Ultralytics新作&#xff09; (1) YOLO11&#xff08;Ultralytics新作&#xff09; 2024.10.01 Ultralytics在 YOLO Vision 2024 活动上宣布发布其新的计算机视觉模型 YOLO…

无人机电力巡检:点亮电力巡检新视野!

一、无人机电力巡查的优势 提高巡检效率&#xff1a;无人机可以搭载高清摄像头、红外热像仪等先进设备&#xff0c;实时拍摄和传输图像&#xff0c;帮助巡检人员快速发现潜在问题&#xff0c;如电线破损、绝缘子污损、设备过热等&#xff0c;从而大大缩短了巡检周期。 降低人…

Vue+NestJS项目实操(图书管理后台)

一、项目搭建 前端基于vben进行二次开发 在Github下载vben框架&#xff0c;搜索vben即可 下载地址&#xff1a;https://github.com/vbenjs/vue-vben-admin 下载完成后&#xff0c;进行安装依赖&#xff0c;使用命令&#xff1a; // 下载依赖 pnpm install// 运行项目 pnpm …

开源的云平台有哪些?

开源云平台为用户提供了构建、管理和运行云基础设施及应用的能力&#xff0c;同时允许社区参与开发和改进。以下是一些知名的开源云平台&#xff1a; 1. OpenStack 简介&#xff1a;OpenStack&#xff1a;一个广泛使用的开源云平台&#xff0c;它由多个组件组成&#xff0c;提…

HTML+CSS - 表单交互(一)

1. 前言 ​​​​​​​ Web 表单是用于和用户交互的强大工具——其常用于收集用户数据和控制用户界面。 web 表单是用户和 web 站点或应用程序之间交互的主要内容之一。它们允许用户输入数据&#xff0c;大多数情况下会将数据发送到 web 服务器进行处理和存储 2. form标签 …

Redis篇(Redis原理 - RESP协议)

目录 一、简介 二、Redis通信协议 基于Socket自定义Redis的客户端 三、Redis内存回收 1. 过期key处理 1.1. 惰性删除 1.2. 周期删除 1.3. 知识小结 2. 内存淘汰策略 一、简介 Redis是一个CS架构的软件&#xff0c;通信一般分两步&#xff08;不包括pipeline和PubSub&a…

AI不可尽信

看到某项目有类似这样的一段代码 leaves : make([]int, 10) leaves leaves[:0]没理解这样的连续两行,有何作用? 初始化一个长度和容量都为10的切片,接着把切片长度设置为0 即如下demo: (在线地址) package mainimport "fmt"func main() {leaves : make([]int, 1…

M3u8视频由手机拷贝到电脑之后,通过potplayer播放报错找不到文件地址怎么解决?

该文章前面三节主要介绍M3u8视频是什么&#xff0c;视频播放错误(找不到地址)的解决方法在后面 M3U8是一种多媒体播放列表文件格式&#xff0c;主要用于流媒体播放。 一、文件格式特点 1. 文本文件&#xff1a;M3U8是一个采用 UTF-8 编码的文本文件&#xff0c;这意味着它可…

【STM32开发之寄存器版】(三)-详解NVIC中断

一、前言 STM32F103ZET6具备强大的中断控制能力&#xff0c;其嵌套向量中断控制器(NVIC)和处理器核的接口紧密相连&#xff0c;可以实现低延迟的中断处理和高效地处理晚到的中断。NVIC主要具备以下特性&#xff1a; 68个可屏蔽中断通道(不包含16个Cortex™-M3的中断线)&#xf…

经典文献阅读之--WiROS(用于机器人的WiFi感知工具箱)

0. 简介 近期的许多研究探索了使用基于WiFi的感知技术来改善SLAM&#xff08;同时定位与地图构建&#xff09;、机器人操控或探索。此外&#xff0c;WiFi的广泛可用性使其成为最具优势的射频信号。但WiFi传感器缺乏一个准确、易处理、多功能的工具箱&#xff0c;这限制了它们与…

VUE2常见问题以及解决方案汇总(不断更新中)

解决vue项目中 el-table 的 row-click 事件与行内点击事件冲突&#xff0c;点击事件不生效&#xff08;表格行点击事件和行内元素点击事件冲突&#xff09;需要阻止事件冒泡 问题描述 1.点击列的编辑按钮&#xff0c;会触发按钮本身事件&#xff0c;同时会触发行点击事件 2.点…

SaaS 应用如何助长网络犯罪

过去十年&#xff0c;软件即服务 (SaaS)的采用呈爆炸式增长&#xff0c;彻底改变了我们的工作方式。 从电子邮件平台到通信和协作应用程序&#xff0c;再到文件存储和共享服务&#xff0c;这些工具有望为我们的日常工作生活带来更大的灵活性和效率&#xff0c;尤其是在当今的远…

Linux环境基础开发工具使用(2)

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 Linux环境基础开发工具使用(2) 收录于专栏[Linux学习] 本专栏旨在分享学习Linux的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目录 1. Li…

VS开发 - 静态编译和动态编译的基础实践与混用

目录 1. 基础概念 2. 直观感受一下静态编译和动态编译的体积与依赖项目 3. VS运行时库包含哪些主要文件&#xff08;从VS2015起&#xff09; 4. 动态库和静态库混用的情况 5. 感谢清单 1. 基础概念 所谓的运行时库&#xff08;Runtime Library&#xff09;就是WINDOWS系统…

防反接电路设计

方案1 串联二极管&#xff0c; 优点&#xff1a;成本低、设计简单 缺点&#xff1a;损耗大&#xff0c;P ui 方案2 串联自恢复保险丝 当电源反接的时候&#xff0c;D4导通&#xff0c;F2超过跳闸带你留&#xff0c;就会断开&#xff0c;从而保护了后级电路 方案3 H桥电路…

解决DHCP服务异常导致设备无法获取IP地址的方法

DHCP在网络环境中会自动为网络中的设备分配IP地址和其他关键网络参数&#xff0c;可以简化网络配置过程。但是&#xff0c;如果DHCP服务出现异常时&#xff0c;设备可能无法正常获取IP地址&#xff0c;会影响到网络通信。 本文讲述一些办法可以有效解决DHCP服务异常导致设备无法…

No.2 笔记 | 网络安全攻防:PC、CS工具与移动应用分析

引言 在当今数字化时代,网络安全已成为每个人都应该关注的重要话题。本文将总结一次关于网络安全攻防技术的学习内容,涵盖PC端和移动端的恶意程序利用,以及强大的渗透测试工具Cobalt Strike的使用。通过学习这些内容,我们不仅能够了解攻击者的手法,更能提高自身的安全意识和防…

Java编码方式:Base64编码与解码

1、Base64 算法介绍 Base64 是一种基于 64 个可打印字符来表示二进制数据的表示方法。它主要用于在不支持二进制数据的场合&#xff08;如电子邮件、URL、文件系统名等&#xff09;传输二进制数据。严格来说 Base64 并不是一种加密/解密算法&#xff0c;而是一种编码方式。Bas…

基于Springboot+Android的的电子书阅读器系统的设计与实现(含源码+数据库)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 该系统…