云原生之Dockerfile简介和基础实践

news2024/11/18 23:21:49

dockerfile简介和基础实践

  • 一、Dockerfile简介
    • 1.1、Dockerfile解决的问题
    • 1.2、docker build 构建流程
    • 1.3、关键字介绍
  • 二、Dockerfile 实践
    • 2.1、基本语法实践 --- golang
      • 问题检查
    • 2.2、基本语法实践 --- gcc
  • 总结
  • 后言

一、Dockerfile简介

Dockerfile是一个创建镜像所有命令的文本文件,,包含了一条条指令和说明,每条指令构建一层, 通过docker build命令,根据Dockerfile的内容构建镜像,因此每一条指令的内容,就是描述该层如何构建。有了Dockefile,就可以制定自己的docker镜像规则,只需要在Dockerfile上添加或者修改指令, 就可生成docker 镜像.。

1.1、Dockerfile解决的问题

  1. Dockerfile 包含了镜像制作的完整操作流程,其他开发者可以通过 Dockerfile 了解并复现制作过程。
  2. Dockerfile 中的每一条指令都会创建新的镜像层,这些镜像可以被 Docker Daemon 缓存。再次制作镜像时,Docker 会尽量复用缓存的镜像层(using cache),而不是重新逐层构建,这样可以节省时间和磁盘空间。
  3. Dockerfile 的操作流程可以通过docker image history [镜像名称]查询,方便开发者查看变更记录。

1.2、docker build 构建流程

docker build命令会读取Dockerfile的内容,并将Dockerfile的内容发送给 Docker 引擎,最终Docker引擎会解析Dockerfile中的每一条指令,构建出需要的镜像。
(1)docker build会将 context 中的文件打包传给 Docker daemon。如果 context 中 有.dockerignore文件,则会从上传列表中删除满足.dockerignore规则的文件。注意:如果上下文中有相当多的文件,可以明显感受到整个文件发送过程。这里有个例外,如果.dockerignore文件中有.dockerignore或者Dockerfile,docker build命令在排除文件时会忽略掉这两个文件。如果指定了镜像的 tag,还会对 repository 和 tag 进行验证。

(2)docker build命令向 Docker server 发送 HTTP 请求,请求 Docker server 构建镜像,请求中包含了需要的 context 信息。

(3)Docker server 接收到构建请求之后,会执行以下流程来构建镜像:

  1. 创建一个临时目录,并将 context 中的文件解压到该目录下。
  2. 读取并解析 Dockerfile,遍历其中的指令,根据命令类型分发到不同的模块去执行。
  3. Docker 构建引擎为每一条指令创建一个临时容器,在临时容器中执行指令,然后 commit 容器,生成一个新的镜像层。
  4. 最后,将所有指令构建出的镜像层合并,形成 build 的最后结果。最后一次 commit 生成的镜像 ID就是最终的镜像 ID。

为了提高构建效率,docker build默认会缓存已有的镜像层。如果构建镜像时发现某个镜像层已经被缓存,就会直接使用该缓存镜像,而不用重新构建。如果不希望使用缓存的镜像,可以在执行docker build命令时,指定–no-cache=true参数。

Docker 匹配缓存镜像的规则为:遍历缓存中的基础镜像及其子镜像,检查这些镜像的构建指令是否和当前指令完全一致,如果不一样,则说明缓存不匹配。对于ADD、COPY指令,还会根据文件的校验和(checksum)来判断添加到镜像中的文件是否相同,如果不相同,则说明缓存不匹配。

注意,缓存匹配检查不会检查容器中的文件。比如,当使用RUN apt-get -y update命令更新了容器中的文件时,缓存策略并不会检查这些文件,来判断缓存是否匹配。

最后,可以通过docker history命令来查看镜像的构建历史。

docker_build

1.3、关键字介绍

关键字含义
FROM设置镜像使用的基础镜像
MAINTAINER设置镜像的作者
RUN编译镜像时运行的脚步
CMD设置容器的启动命令
LABEL设置镜像标签
EXPOSE设置镜像暴露的端口
ENV设置容器的环境变量
ADD编译镜像时复制上下文中文件到镜像中
COPY编译镜像时复制上下文中文件到镜像中
ENTRYPOINT设置容器的入口程序
VOLUME设置容器的挂载卷
USER设置运行 RUN CMD ENTRYPOINT的用户名
WORKDIR设置 RUN CMD ENTRYPOINT COPY ADD 指令的工作目录
ARG设置编译镜像时加入的参数
ONBUILD设置镜像的ONBUILD 指令
STOPSIGNAL设置容器的退出信号量

二、Dockerfile 实践

2.1、基本语法实践 — golang

(1)创建文件夹,存放Dockerfile。注意,默认Dockerfile文件的首字母要大写,当不指定Dockerfile时docker会自动去匹配。

mkdir example1 
cd example1
vim Dockerfile

(2)Dockerfile输入如下内容:

FROM golang:1.18
MAINTAINER fly
ENV env1=v1
ENV env2=v2
LABEL myhello 1.0.0
LABEL env prod
RUN git clone https://gitee.com/nickdemo/helloworld.git
WORKDIR helloworld
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o app .
EXPOSE 80
CMD ["./app","--param1=p1","--param2=p2"]

说明:

  1. FROM golang:1.18 表示使用golang语言v1.18版本的基础镜像。
  2. ENV设置容器的环境变量,一般是v1和v2。
  3. LABEL 可以设置多个。
  4. RUN设置编译时运行的脚本,可以有多个。
  5. WORKDIR类似于cd命令,WORKDIR helloworld是进入helloworld目录。
  6. CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o app . 是golang编译命令,go可以和c语言配合使用,CGO_ENABLED=0表示不打开CGO功能;app是编译出来的文件名,后面的.表示编译到当前路径。

(3)执行docker build命令。要注意带有的“.” ,这是上下文,不可缺少

docker build -t hello:1.0.0 -f Dockerfile .

如果出现如下情况,编译不通过是因为没有设置golang的环境代理,因为golang服务器基本在国外,所以需要设置代理。

Sending build context to Docker daemon  2.048kB
Step 1/11 : FROM golang:1.18
1.18: Pulling from library/golang
32de3c850997: Pull complete 
fa1d4c8d85a4: Pull complete 
c796299bbbdd: Pull complete 
81283a9569ad: Pull complete 
c768848b86a2: Pull complete 
160a777925fe: Pull complete 
1be94824532a: Pull complete 
Digest: sha256:00d63686b480f6dc866e93ddc4b29efa2db03274a687e6495c2cfbfe615d638e
Status: Downloaded newer image for golang:1.18
 ---> fffd0d9a59da
Step 2/11 : MAINTAINER fly
 ---> Running in 115307734b60
Removing intermediate container 115307734b60
 ---> 563fafbaa215
Step 3/11 : ENV env1=v1
 ---> Running in cdc078b0e0f4
Removing intermediate container cdc078b0e0f4
 ---> 00cf872c162e
Step 4/11 : ENV env2=v2
 ---> Running in 9c5d21d9827a
Removing intermediate container 9c5d21d9827a
 ---> 675573fda93f
Step 5/11 : LABEL myhello 1.0.0
 ---> Running in 835edee10587
Removing intermediate container 835edee10587
 ---> 7fe90336bfc0
Step 6/11 : LABEL env prod
 ---> Running in 6b9a149d8760
Removing intermediate container 6b9a149d8760
 ---> 1f518a4de736
Step 7/11 : RUN git clone https://gitee.com/nickdemo/helloworld.git
 ---> Running in 3836f92a0cc1
Cloning into 'helloworld'...
Removing intermediate container 3836f92a0cc1
 ---> 497dfec57d8f
Step 8/11 : WORKDIR helloworld
 ---> Running in 8f33d51a24f9
Removing intermediate container 8f33d51a24f9
 ---> 581cbde35690
Step 9/11 : RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o app .
 ---> Running in ac2e563f44aa
go: downloading github.com/gomodule/redigo v1.8.9
go: downloading github.com/spf13/viper v1.12.0
hello/composeRedis.go:6:2: github.com/gomodule/redigo@v1.8.9: Get "https://proxy.golang.org/github.com/gomodule/redigo/@v/v1.8.9.zip": dial tcp 142.251.42.241:443: i/o timeout
hello/printConfig.go:5:2: github.com/spf13/viper@v1.12.0: Get "https://proxy.golang.org/github.com/spf13/viper/@v/v1.12.0.zip": dial tcp 142.251.42.241:443: i/o timeout
The command '/bin/sh -c CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o app .' returned a non-zero code: 1

(4)Dockerfile中设置代理:

FROM golang:1.18
MAINTAINER fly
ENV env1=v1
ENV env2=v2
LABEL myhello 1.0.0
LABEL env prod
RUN git clone https://gitee.com/nickdemo/helloworld.git
WORKDIR helloworld
RUN go env -w GOPROXY="https://proxy.golang.com.cn,https://goproxy.cn,direct"
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o app .
EXPOSE 80
CMD ["./app","--param1=p1","--param2=p2"]

(5)再次执行docker build命令。

docker build -t hello:1.0.0 -f Dockerfile .

成功结果:

Sending build context to Docker daemon  2.048kB
Step 1/12 : FROM golang:1.18
 ---> fffd0d9a59da
Step 2/12 : MAINTAINER fly
 ---> Using cache
 ---> 563fafbaa215
Step 3/12 : ENV env1=v1
 ---> Using cache
 ---> 00cf872c162e
Step 4/12 : ENV env2=v2
 ---> Using cache
 ---> 675573fda93f
Step 5/12 : LABEL myhello 1.0.0
 ---> Using cache
 ---> 7fe90336bfc0
Step 6/12 : LABEL env prod
 ---> Using cache
 ---> 1f518a4de736
Step 7/12 : RUN git clone https://gitee.com/nickdemo/helloworld.git
 ---> Using cache
 ---> 497dfec57d8f
Step 8/12 : WORKDIR helloworld
 ---> Using cache
 ---> 581cbde35690
Step 9/12 : RUN go env -w GOPROXY="https://proxy.golang.com.cn,https://goproxy.cn,direct"
 ---> Running in aa3d7b78e3ea
Removing intermediate container aa3d7b78e3ea
 ---> 228d20762041
Step 10/12 : RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o app .
 ---> Running in 0b4899bd2333
go: downloading github.com/gomodule/redigo v1.8.9
go: downloading github.com/spf13/viper v1.12.0
go: downloading github.com/fsnotify/fsnotify v1.5.4
go: downloading github.com/mitchellh/mapstructure v1.5.0
go: downloading github.com/spf13/afero v1.8.2
go: downloading github.com/spf13/cast v1.5.0
go: downloading github.com/spf13/jwalterweatherman v1.1.0
go: downloading github.com/spf13/pflag v1.0.5
go: downloading golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a
go: downloading golang.org/x/text v0.3.7
go: downloading github.com/subosito/gotenv v1.3.0
go: downloading github.com/hashicorp/hcl v1.0.0
go: downloading gopkg.in/ini.v1 v1.66.4
go: downloading github.com/magiconair/properties v1.8.6
go: downloading github.com/pelletier/go-toml/v2 v2.0.1
go: downloading gopkg.in/yaml.v3 v3.0.0
go: downloading github.com/pelletier/go-toml v1.9.5
Removing intermediate container 0b4899bd2333
 ---> 8a0543eb5966
Step 11/12 : EXPOSE 80
 ---> Running in 5de109cc2133
Removing intermediate container 5de109cc2133
 ---> 11f4f6f09a9e
Step 12/12 : CMD ["./app","--param1=p1","--param2=p2"]
 ---> Running in 49caece0cdf7
Removing intermediate container 49caece0cdf7
 ---> 308a6e93a8ff
Successfully built 308a6e93a8ff
Successfully tagged hello:1.0.0

(6)查看docker images。发现有了hello:1.0.0。

fly@fly:~/wokspace/example1$ docker images
REPOSITORY               TAG       IMAGE ID       CREATED              SIZE
hello                    1.0.0     308a6e93a8ff   About a minute ago   1.08GB
golang                   1.18      fffd0d9a59da   41 hours ago         965MB
nginx                    latest    ac8efec875ce   2 weeks ago          142MB
nongtengfei/mynginx      1.0.0     ac8efec875ce   2 weeks ago          142MB
localhost:5000/mynginx   1.0.0     ac8efec875ce   2 weeks ago          142MB
registry                 2         81c944c2288b   5 weeks ago          24.1MB

(7)运行镜像。

docker run -p 80:80 --name myhello hello:1.0.0

执行结果:

fly@fly:~/wokspace/example1$ docker run -p 80:80 --name myhello hello:1.0.0 
into main

也可以后台执行:

docker run -p 80:80 -d --name myhello hello:1.0.0

然后使用curl访问:

$ curl http://localhost:80/print/env
env list : env1 = v1 and env2 = v2

问题检查

上述制作的镜像有什么问题?

  1. 镜像非常大,什么都没做就是1.08GB。不方便传输。
  2. 使用了git软件,这个在golang的基础镜像默认有的,但是如果是是gcc环境,可能就没有这个git软件。
  3. 构建时传输了上下文,但是上下文基本没有用到。

2.2、基本语法实践 — gcc

(1)创建文件夹,存放Dockerfile。注意,默认Dockerfile文件的首字母要大写,当不指定Dockerfile时docker会自动去匹配。

mkdir example2
cd example2
vim Dockerfile

(2)Dockerfile输入如下内容:

FROM gcc
MAINTAINER fly
COPY ./hello.c ./
RUN pwd
LABEL myhello 1.0.0
LABEL env prod
RUN gcc hello.c -o hello
CMD ["./hello"]

(3)创建hello.c并输入内容:
(hello.c)

#include <stdio.h>
int main(int argc,char **argv)
{
	printf("hello world\n");
	return 0;
}

(4)构建镜像:

docker build -t myhelloc .

执行结果:

Sending build context to Docker daemon  3.072kB
Step 1/8 : FROM gcc
latest: Pulling from library/gcc
32de3c850997: Already exists 
fa1d4c8d85a4: Already exists 
c796299bbbdd: Already exists 
81283a9569ad: Already exists 
60b38700e7fb: Pull complete 
0db15631b022: Pull complete 
becc68bc09a5: Pull complete 
c369162968fc: Pull complete 
ce5ec26c51fc: Pull complete 
Digest: sha256:6c101c7698a6ebe5cd153182889ffc9ab2f7192bf96a06fe292806116fdaafba
Status: Downloaded newer image for gcc:latest
 ---> e94a76bddd72
Step 2/8 : MAINTAINER fly
 ---> Running in e193e6e7dac1
Removing intermediate container e193e6e7dac1
 ---> afa92db551f4
Step 3/8 : COPY ./hello.c ./
 ---> 87b51ccd7de3
Step 4/8 : RUN pwd
 ---> Running in 569f3ddfaf53
/
Removing intermediate container 569f3ddfaf53
 ---> 2ee756f47004
Step 5/8 : LABEL myhello 1.0.0
 ---> Running in 2deaebd60838
Removing intermediate container 2deaebd60838
 ---> 1610bf7d0792
Step 6/8 : LABEL env prod
 ---> Running in ce840c209a93
Removing intermediate container ce840c209a93
 ---> b6158d8d3aac
Step 7/8 : RUN gcc hello.c -o hello
 ---> Running in 6f01803e28b1
Removing intermediate container 6f01803e28b1
 ---> 6c9223360ad5
Step 8/8 : CMD ["./hello"]
 ---> Running in 9127f8f3e413
Removing intermediate container 9127f8f3e413
 ---> a88d99f3d8e8
Successfully built a88d99f3d8e8
Successfully tagged myhelloc:latest

(5)执行镜像:

docker run myhelloc

执行结果:

fly@fly:~/wokspace/example2$ docker run myhelloc
hello world

如果是后台执行,可以通过docker log 查询到输出的hello world。

总结

  1. 构建镜像时,选择上下文要注意,不要包含有不要用到的内容,通常使用项目的根目录作为上下文即可。
  2. COPY命令时,基本上是“./*”开始,没有绝对路径,因为构建的时候上下文已经发送到守护进程,不在宿主机了。
  3. go语言和c语言编译的区别,主要在FROM部分,依赖的基础环境;另外,编译命令也不一样。

后言

本专栏知识点是通过<零声教育>的系统学习,进行梳理总结写下文章,对c/c++linux系统提升感兴趣的读者,可以点击链接查看详细的服务:C/C++服务器开发 。

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

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

相关文章

为行业赋能 助力行业客户业务大放异彩

近日&#xff0c;2022亚马逊云科技re:Invent全球大会已完美落幕&#xff0c;在大会上发布了很多重磅新品&#xff0c;包括云原生数据战略、硬件创新、高性能计算等等在各行各业中的创新应用&#xff0c;下面就来看看医疗与生命科学、市场调研和数据分析、汽车行业&#xff0c;他…

如何理解UML2.5.1(04篇)

第一步&#xff1a; 这里发现UML2.5.1中的一处错误&#xff1a; 图四、Figure9.10中的一处错误。 错误就在于最下面一个关联右端点处的标记redefines&#xff0c;有了这个标记&#xff0c;就应该意味着此关联特化了某个关联&#xff0c;但是如果我们用“A_ownedAttribute_class…

在Android端集成OpenCV的三种方式

1.Opencv Android SDK 基于Opencv C本地代码&#xff0c;通过Java语言接口使用JNI技术调用C本地方法的SDK开发包。 &#xff08;1&#xff09;etc:各类模型文件存储地址 &#xff08;2&#xff09;java:Java版本的Android SDK相关文件 &#xff08;3&#xff09;native:JNI层…

【QGIS入门实战精品教程】3.4:QGIS创建GeoPackage地理数据库及数据入库案例详解

GeoPackage(以下简称gpkg),内部使用SQLite实现的一种单文件、与操作系统无关的地理数据库。在QGIS中可以很方便的实现GeoPackage的创建与连接等操作。 一、QGIS创建GeoPackage 1. 创建数据库 QGIS创建GeoPackage的方法与ArcGIS中创建File GDB的类似,选择一个目标文件夹,…

Adobe Acrobat XI 一进去就闪退;解决Acrobat的闪退问题

一、原因分析 闪退是因为网络中校验版权时出现问题 二、解决办法 域名欺骗&#xff0c;添加伪造的host条目 1. 进入C:\Windows\System32\drivers\etc 找到hosts文件 2. 右机hosts&#xff0c;选择属性&#xff0c;在安全选项里&#xff0c;点击高级&#xff1a; 3. 在ho…

Hive+Spark离线数仓工业项目实战--数仓设计及数据采集(1)

数仓设计及数据采集 1. **数据仓库设计** - 建模&#xff1a;维度建模&#xff1a;【事实表、维度表】 - 分层&#xff1a;ODS、DW【DWD、DWM、DWS】、APP - **掌握本次项目中数仓的分层** - ODS、DWD、DWB、DWS、ST、DM 2. 业务系统流程和数据来源 - 数据源…

Webpack5搭建Vue环境 | Webpack

文章目录webpack打包其他资源图片资源file-loader文件的命名规则url-loaderwebpack5 asset方式字体文件的打包PluginCleanWebpackPluginHtmlWebpackPluginDefinePluginCopyWebpackPluginmode配置webpack打包其他资源 图片资源 虽然此时我未安装file-loader 但是我正常显示了图片…

SHOP++ V9.1商城系统:可视化装修,0基础也能打造高颜值商城!

SHOP B2B2C商城系统新版本V9.1 新增的店铺装修功能是一款针对电商的DIY装修工具。可以快速装修店铺。能同时满足不同用户的使用需求。 一、页面可视化编辑组件 电商大潮异军突起的今天&#xff0c;如何让你的商品页面快速的抓住顾客的眼球&#xff0c;是促成订单转化的重要因素…

项目实战之旅游网(二)后台用户管理(上)

目录 一.管理员列表 二. 新增管理员 三.修改管理员 四.管理员详情 一.管理员列表 后台用户也称为管理员&#xff0c;每个管理员能在后台进行的操作不同,所以不同的管理员有不同的权限。在项目中&#xff0c;权限表的设计为用户-角色多对多&#xff0c;角色权限多对多&…

四、网络层(四)IPv6

目录 4.1 IPv6的主要特点 4.2 IPv6地址 4.3 从IPv4到IPv6过渡 4.1 IPv6的主要特点 解决IP地址耗尽问题的措施有以下3种 采用无分类域间路由&#xff0c;使IP地址的分配更加合理。采用网络地址转换NAT以节省全球IP地址。采用具有更大地址空间的新版本的IP协议IPv6。&am…

力扣(LeetCode)199. 二叉树的右视图(C++)

迭代 按照层序遍历&#xff0c;每一层最右边的元素就是二叉树右视图的元素。迭代算法需要队列保存二叉树每一层的所有结点&#xff0c;并且在遍历下一层时&#xff0c;上一层的所有结点已经出队。在遍历下一层之前&#xff0c;记录队列大小&#xff0c;即为二叉树当前层的结点…

三.keepalived介绍及工作原理

keepalived介绍及工作原理keepalived介绍及工作原理一、keepalived的介绍二、Keepalived服务的重要功能1、管理LVS负载均衡软件2、实现对LVS集群节点健康检查功能&#xff08;healthcheck&#xff09;3、作为系统网络服务的高可用功能&#xff08;failover&#xff09;三、Keep…

Redis 集合(Sorted Set)方法使用详解

目录一、简介二、常用方法2.1、ZADD2.2、ZREM2.3、ZSCORE2.4、ZINCRBY2.5、ZCARD2.6、ZRANK、ZREVRANK2.7、ZRANGE、ZREVRANGE2.8、ZRANGEBYSCORE、ZREVRANGEBYSCORE2.9、ZCOUNT2.10、ZREMRANGEBYRANK2.11、ZREMRANGEBYSCORE2.12、ZINTERSTORE、ZUNIONSTORE2.13、ZRANGEBYLEX、…

day 9 模拟和高精度

P4924 [1007]魔法少女小Scarlet 题目描述 Scarlet 最近学会了一个数组魔法&#xff0c;她会在 nn 二维数组上将一个奇数阶方阵按照顺时针或者逆时针旋转 90∘。 首先&#xff0c;Scarlet 会把 1 到 n^2 的正整数按照从左往右&#xff0c;从上至下的顺序填入初始的二维数组中…

带您认识spreadsheet专属的数据仓库,助力报表开发好帮手

业务主题是针对业务的一个概念&#xff0c;它将同一数据源中属于同一个分析主题的表或表中的字段组合在一起&#xff0c;为进一步的可视化数据集提供基本元素。 业务主题我们看作是 Smartbi 产品中的数据仓库&#xff0c;主要应用于可视化数据集等操作。 业务主题的应用场景有如…

佳缘线上超市网站

成品详细信息 开发工具(eclipse/idea/vscode等)&#xff1a; 数据库(sqlite/mysql/sqlserver等)&#xff1a; 功能模块(请用文字描述&#xff0c;至少200字)&#xff1a; 基于SPRINGBOOTE的佳源线上超市管理系统的设计与实现 模块划分&#xff1a;公告类型模块、公告信息模块…

【Pycharm教程】在 PyCharm 中使用 Emacs 作为外部编辑器

Emacs是一个高级的文本编辑器&#xff0c;可以让你全面地操作你的代码。使用 Emacs 意味着可以根据您用于编码的语言进行完全可调整的编辑。 本文介绍了如何将 Emacs 添加到 PyCharm 并使用它来修改您的代码。 最新版本的 Emacs 可以从官网下载安装。 将 Emacs 配置为外部编…

介绍在全志A40i Ubuntu系统上定制文件系统的操作过程

为了给客户的测试和开发提供便利&#xff0c;飞凌嵌入式的开发板产品一般都支持多种操作系统&#xff0c;以基于全志T507H处理器设计研发的OKT507-C开发板为例&#xff0c;它支持三种操作系统&#xff0c;分别是&#xff1a;Linux、Android 和 Forlinx Desktop&#xff08;Ubun…

stm32cubemx hal学习记录:电机控制

一、基础配置 1、配置RCC、SYS&#xff0c;SYS的Timebase Source选择TIM6 2、配置USART1、时钟84MHz 3、激活FreeRTOS&#xff0c;选择CMSIS_V1&#xff0c;Config parameters种USE_TIMERS选择ENABLE 二、编码器及电机驱动引脚配置 1、选用TIM3的编码器模式 2、驱动使用L2…

以数据赋能业务,qlik为企业搭建透明绩效管理平台

自从各类金融APP出现以来&#xff0c;分支机构网络的性质已经发生了巨大的变化。下一代分支机构通常是围绕着深化客户关系的愿景建立起来的&#xff0c;这些愿景包括理财方面的建议&#xff0c;以及企业和家庭贷款等更大的承诺&#xff0c;同时提供现金和交易设施。由于分支机构…