案例:Docker 镜像的创建及使用(commit与dockerfile方式)

文章目录

  • 1、commit方式创建镜像
    • 1.1、前期准备
    • 1.2、制成镜像
    • 1.3、启动镜像
      • 1.3.1、启动镜像+启动nginx
      • 1.3.2、一个命令直接全部启动
      • 1.3.3、两种方式区别
    • 1.4、commit创建镜像方式的本质
  • 2、Dockerfile的使用
    • 2.1、Dockerfile指令
    • 2.2、nginx镜像制作案例
    • 2.3、查看构建历史:
      • 为镜像指定环境变量,挂载目录,默认启动命令
    • 2.4、run VS cmd VS entrypoint
      • docker容器的主业
    • 推荐的ENTRYPOINT 方式
  • 3、commit和Dockerfile的区别

1、commit方式创建镜像

我要将一个包含nginx的容器做成一个镜像,供其他人使用,这样其他人就不必再执行nginx安装等操作。

1.1、前期准备

首先,还是启动一个容器:

docker run -it --name n1 centos /bin/bash

命名为n1。

然后在容器内部安装nginx:

yum install nginx -y

这里yum源出现问题:
在这里插入图片描述
解决看这里

安装成功并启动运行:

whereis nginx/usr/sbin/nginx

在这里插入图片描述

在另一个终端,查看nginx情况:

docker inspect n1  # n1是该容器的name
[{"Id": "704c3c99bc66f5e22ee47be1a989701986a48aae1ad6d69b2abba2e017842fc9","Created": "2023-08-06T12:27:49.98892154Z","Path": "/bin/bash","Args": [],"State": {"Status": "running","Running": true,"Paused": false,"Restarting": false,"OOMKilled": false,"Dead": false,"Pid": 16981,"ExitCode": 0,"Error": "","StartedAt": "2023-08-06T12:27:50.31650392Z","FinishedAt": "0001-01-01T00:00:00Z"},"Image": "sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6","ResolvConfPath": "/var/lib/docker/containers/704c3c99bc66f5e22ee47be1a989701986a48aae1ad6d69b2abba2e017842fc9/resolv.conf","HostnamePath": "/var/lib/docker/containers/704c3c99bc66f5e22ee47be1a989701986a48aae1ad6d69b2abba2e017842fc9/hostname","HostsPath": "/var/lib/docker/containers/704c3c99bc66f5e22ee47be1a989701986a48aae1ad6d69b2abba2e017842fc9/hosts","LogPath": "/var/lib/docker/containers/704c3c99bc66f5e22ee47be1a989701986a48aae1ad6d69b2abba2e017842fc9/704c3c99bc66f5e22ee47be1a989701986a48aae1ad6d69b2abba2e017842fc9-json.log","Name": "/n1","RestartCount": 0,"Driver": "overlay2","Platform": "linux","MountLabel": "","ProcessLabel": "","AppArmorProfile": "","ExecIDs": null,"HostConfig": {"Binds": null,"ContainerIDFile": "","LogConfig": {"Type": "json-file","Config": {}},"NetworkMode": "default","PortBindings": {},"RestartPolicy": {"Name": "no","MaximumRetryCount": 0},"AutoRemove": false,"VolumeDriver": "","VolumesFrom": null,"ConsoleSize": [50,180],"CapAdd": null,"CapDrop": null,"CgroupnsMode": "host","Dns": [],"DnsOptions": [],"DnsSearch": [],"ExtraHosts": null,"GroupAdd": null,"IpcMode": "private","Cgroup": "","Links": null,"OomScoreAdj": 0,"PidMode": "","Privileged": false,"PublishAllPorts": false,"ReadonlyRootfs": false,"SecurityOpt": null,"UTSMode": "","UsernsMode": "","ShmSize": 67108864,"Runtime": "runc","Isolation": "","CpuShares": 0,"Memory": 0,"NanoCpus": 0,"CgroupParent": "","BlkioWeight": 0,"BlkioWeightDevice": [],"BlkioDeviceReadBps": [],"BlkioDeviceWriteBps": [],"BlkioDeviceReadIOps": [],"BlkioDeviceWriteIOps": [],"CpuPeriod": 0,"CpuQuota": 0,"CpuRealtimePeriod": 0,"CpuRealtimeRuntime": 0,"CpusetCpus": "","CpusetMems": "","Devices": [],"DeviceCgroupRules": null,"DeviceRequests": null,"MemoryReservation": 0,"MemorySwap": 0,"MemorySwappiness": null,"OomKillDisable": false,"PidsLimit": null,"Ulimits": null,"CpuCount": 0,"CpuPercent": 0,"IOMaximumIOps": 0,"IOMaximumBandwidth": 0,"MaskedPaths": ["/proc/asound","/proc/acpi","/proc/kcore","/proc/keys","/proc/latency_stats","/proc/timer_list","/proc/timer_stats","/proc/sched_debug","/proc/scsi","/sys/firmware"],"ReadonlyPaths": ["/proc/bus","/proc/fs","/proc/irq","/proc/sys","/proc/sysrq-trigger"]},"GraphDriver": {"Data": {"LowerDir": "/var/lib/docker/overlay2/e256f9203c6a18429e19e0d9458494cf25de028eeb086697f77f6f12bb2bb82e-init/diff:/var/lib/docker/overlay2/0351cac31df5ec6bd716f7dd314842417100097dcad45cdbf3b2b602df85ac0d/diff","MergedDir": "/var/lib/docker/overlay2/e256f9203c6a18429e19e0d9458494cf25de028eeb086697f77f6f12bb2bb82e/merged","UpperDir": "/var/lib/docker/overlay2/e256f9203c6a18429e19e0d9458494cf25de028eeb086697f77f6f12bb2bb82e/diff","WorkDir": "/var/lib/docker/overlay2/e256f9203c6a18429e19e0d9458494cf25de028eeb086697f77f6f12bb2bb82e/work"},"Name": "overlay2"},"Mounts": [],"Config": {"Hostname": "704c3c99bc66","Domainname": "","User": "","AttachStdin": true,"AttachStdout": true,"AttachStderr": true,"Tty": true,"OpenStdin": true,"StdinOnce": true,"Env": ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd": ["/bin/bash"],"Image": "centos","Volumes": null,"WorkingDir": "","Entrypoint": null,"OnBuild": null,"Labels": {"org.label-schema.build-date": "20210915","org.label-schema.license": "GPLv2","org.label-schema.name": "CentOS Base Image","org.label-schema.schema-version": "1.0","org.label-schema.vendor": "CentOS"}},"NetworkSettings": {"Bridge": "","SandboxID": "7ff17da73c9e66bbfbd41b199708eda43a0755d1e2719ef4e07234f4d241e385","HairpinMode": false,"LinkLocalIPv6Address": "","LinkLocalIPv6PrefixLen": 0,"Ports": {},"SandboxKey": "/var/run/docker/netns/7ff17da73c9e","SecondaryIPAddresses": null,"SecondaryIPv6Addresses": null,"EndpointID": "3674d5008409dc73853dc14b6c7627ab5d5bcaf2786df5f12c43a966613256e6","Gateway": "172.17.0.1","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"IPAddress": "172.17.0.2","IPPrefixLen": 16,"IPv6Gateway": "","MacAddress": "02:42:ac:11:00:02","Networks": {"bridge": {"IPAMConfig": null,"Links": null,"Aliases": null,"NetworkID": "348aaaac8b83d35b8f2b750e66eefa696566a774d5791710e2b15e0e3d101332","EndpointID": "3674d5008409dc73853dc14b6c7627ab5d5bcaf2786df5f12c43a966613256e6","Gateway": "172.17.0.1","IPAddress": "172.17.0.2","IPPrefixLen": 16,"IPv6Gateway": "","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"MacAddress": "02:42:ac:11:00:02","DriverOpts": null}}}}
]

然后看到 ip是 172.17.0.2,访问nginx指令:

curl  172.17.0.2

访问成功!

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><head><title>Test Page for the Nginx HTTP Server on Red Hat Enterprise Linux</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><style type="text/css">/*<![CDATA[*/body {background-color: #fff;color: #000;font-size: 0.9em;font-family: sans-serif,helvetica;margin: 0;padding: 0;}:link {color: #c00;}:visited {color: #c00;}a:hover {color: #f50;}h1 {text-align: center;margin: 0;padding: 0.6em 2em 0.4em;background-color: #900;color: #fff;font-weight: normal;font-size: 1.75em;border-bottom: 2px solid #000;}h1 strong {font-weight: bold;font-size: 1.5em;}h2 {text-align: center;background-color: #900;font-size: 1.1em;font-weight: bold;color: #fff;margin: 0;padding: 0.5em;border-bottom: 2px solid #000;}hr {display: none;}.content {padding: 1em 5em;}.alert {border: 2px solid #000;}img {border: 2px solid #fff;padding: 2px;margin: 2px;}a:hover img {border: 2px solid #294172;}.logos {margin: 1em;text-align: center;}/*]]>*/</style></head><body><h1>Welcome to <strong>nginx</strong> on Red Hat Enterprise Linux!</h1><div class="content"><p>This page is used to test the proper operation of the<strong>nginx</strong> HTTP server after it has beeninstalled. If you can read this page, it means that theweb server installed at this site is workingproperly.</p><div class="alert"><h2>Website Administrator</h2><div class="content"><p>This is the default <tt>index.html</tt> page thatis distributed with <strong>nginx</strong> onRed Hat Enterprise Linux.  It is located in<tt>/usr/share/nginx/html</tt>.</p><p>You should now put your content in a location ofyour choice and edit the <tt>root</tt> configurationdirective in the <strong>nginx</strong>configuration file<tt>/etc/nginx/nginx.conf</tt>.</p><p>For information on Red Hat Enterprise Linux, please visit the <a href="http://www.redhat.com/">Red Hat, Inc. website</a>. The documentation for Red Hat Enterprise Linux is <a href="http://www.redhat.com/docs/manuals/enterprise/">available on the Red Hat, Inc. website</a>.</p></div></div><div class="logos"><a href="http://nginx.net/"><imgsrc="nginx-logo.png" alt="[ Powered by nginx ]"width="121" height="32" /></a><a href="http://www.redhat.com/"><imgsrc="poweredby.png"alt="[ Powered by Red Hat Enterprise Linux ]"width="88" height="31" /></a></div></div></body>
</html>

1.2、制成镜像

将刚才的bash退回到宿主机:
注意!如果使用exit指令,退出容器时容器包括内部的镜像都停止了,我们要后台运行退出,使用如下指令:

Ctrl+P+Q

在这里插入图片描述
然后制作镜像:
docker commit 容器名 自定义镜像名

docker commit n1 cent-nginx:v1

在这里插入图片描述
提交成功,查看一下镜像列表:

docker images

可以看到我们制作好的镜像~
在这里插入图片描述

1.3、启动镜像

1.3.1、启动镜像+启动nginx

docker run -it --name nginx1 cent-nginx:v1 /bin/bash

然后在nginx1容器里查看,nginx此时是没有启动的:
在这里插入图片描述

在外部,查看容器启动情况:

在这里插入图片描述
可以看到nginx1确实在运行中。

那么想要运行nginx,则还是手动启动:
在这里插入图片描述
然后另一边再访问nginx,访问成功~

docker inspect nginx1  # 查看ipcurl 172.17.0.3

启动容器还得再进入内部启动nginx,很麻烦~

1.3.2、一个命令直接全部启动

docker run -d --name nginx2 cent-nginx:v1 /usr/sbin/nginx -g "daemon off;"

解释: 这里指定了nginx要做的事情
在这里插入图片描述
在这里插入图片描述

1.3.3、两种方式区别

1、nginx 启动服务: /usr/sbin/nginx (不会结束一直前台跑)
2、/usr/sbin/nginx -g “daemon off;”

后面运行的命令都是容器命令,由于nginx命令没有设置到path中,所以全路径启动,
而nginx -g这个参数是指可以在外面添加指令到nginx的配置文件中,
daemon off是指nginx服务不运行在后端,而是在前台运行(container中的服务必须运行在前台)

1.4、commit创建镜像方式的本质

在这里插入图片描述
原容器与commit后的镜像,在文件系统上并无区别。只是把容器层原来的可写属性,置成了只读。于是变成了一个不可改的镜像。

2、Dockerfile的使用

在这里插入图片描述
在这里插入图片描述

2.1、Dockerfile指令

先看这个表格:

关键字作用备注
FROM指定父镜像指定dockerfile基于那个image构建
MAINTAINER作者信息用来标明这个dockerfile谁写的
LABEL标签用来标明dockerfile的标签 可以使用Label代替Maintainer 最终都是在docker image基本信息中可以查看
RUN执行命令执行一段命令 默认是/bin/sh 格式: RUN command 或者 RUN [“command” , “param1”,“param2”]
CMD容器启动命令提供启动容器时候的默认命令 和ENTRYPOINT配合使用.格式 CMD command param1 param2 或者 CMD [“command” , “param1”,“param2”]
ENTRYPOINT入口一般在制作一些执行就关闭的容器中会使用
COPY复制文件build的时候复制文件到image中
ADD添加文件build的时候添加文件到image中 不仅仅局限于当前build上下文 可以来源于远程服务
ENV环境变量指定build时候的环境变量 可以在启动的容器的时候 通过-e覆盖 格式ENV name=value
ARG构建参数构建参数 只在构建的时候使用的参数 如果有ENV 那么ENV的相同名字的值始终覆盖arg的参数
VOLUME定义外部可以挂载的数据卷指定build的image那些目录可以启动的时候挂载到文件系统中 启动容器的时候使用 -v 绑定 格式 VOLUME [“目录”]
EXPOSE暴露端口定义容器运行的时候监听的端口 启动容器的使用-p来绑定暴露端口 格式: EXPOSE 8080 或者 EXPOSE 8080/udp
WORKDIR工作目录指定容器内部的工作目录 如果没有创建则自动创建 如果指定/ 使用的是绝对地址 如果不是/开头那么是在上一条workdir的路径的相对路径
USER指定执行用户指定build或者启动的时候 用户 在RUN CMD ENTRYPONT执行的时候的用户
HEALTHCHECK健康检查指定监测当前容器的健康监测的命令 基本上没用 因为很多时候 应用本身有健康监测机制
ONBUILD触发器当存在ONBUILD关键字的镜像作为基础镜像的时候 当执行FROM完成之后 会执行 ONBUILD的命令 但是不影响当前镜像 用处也不怎么大
STOPSIGNAL发送信号量到宿主机该STOPSIGNAL指令设置将发送到容器的系统调用信号以退出。
SHELL指定执行脚本的shell指定RUN CMD ENTRYPOINT 执行命令的时候 使用的shell

以下是重点指令的解读~

  • FROM
      FROM {base镜像}
      必须放在DOckerfile的第一行,表示从哪个baseimage开始构建
  • MAINTAINER
    可选的,用来标识image作者的地方
  • RUN
    RUN都是启动一个容器、执行命令、然后提交存储层文件变更。
    第一层 RUN command1 的执行仅仅是当前进程,一个内存上的变化而已,其结果不会造成任何文件。
    而到第二层的时候,启动的是一个全新的容器,跟第一层的容器更完全没关系,自然不可能继承前一层构建过程中的内存变化。
    而如果需要将两条命令或者多条命令联合起来执行需要加上&&。
    如:cd /usr/local/src && wget xxxxxxx
  • CMD
      CMD的作用是作为执行container时候的默认行为(容器默认的启动命令)
      当运行container的时候声明了command,则不再用image中的CMD默认所定义的命令
    一个Dockerfile中只能有一个有效的CMD,当定义多个CMD的时候,只有最后一个才会起作用
  • EXPOSE
    EXPOSE 指令是声明运行时容器提供服务端口,这只是一个声明,在运行时并不会因为这个声明应用就会开启这个端口的服务。在 Dockerfile 中写入这样的声明有两个好处,一个是帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射;另一个用处则是在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。
  • entrypoint
    entrypoint的作用是,把整个container变成可执行的文件,且不能够通过替换CMD的方法来改变创建container的方式。但是可以通过参数传递的方法影响到container内部
    每个Dockerfile只能够包含一个entrypoint,多个entrypoint只有最后一个有效
    当定义了entrypoint以后,CMD只能够作为参数进行传递
  • ADD & COPY
      把host上的文件或者目录复制到image中(能够进行自动解压压缩包)
  • ENV
      用来设置环境变量,后续的RUN可以使用它所创建的环境变量
  • WORKDIR
      用来指定当前工作目录(或者称为当前目录)
  • USER
      运行RUN指令的用户
  • VOLUME
      用来创建一个在image之外的mount point

2.2、nginx镜像制作案例

首先,创建一个新目录,在该目录下制作:

mkdir dockerfile-nginx
cd dockerfile-nginx

在这里插入图片描述
然后创建并编辑Dockerfile文件:

vi Dcokerfile

文件内容如下:

# Base image
FROM centos:7# MAINTAINER
MAINTAINER cyl# 将nginx以及pcre源代码加入镜像
ADD nginx-1.20.1.tar.gz /usr/local/src/
ADD pcre-8.45.tar.gz /usr/local/src/# 安装编译器
RUN yum install -y gcc gcc-c++ make openssl-devel lsof
RUN useradd -s /sbin/nologin -M nginx# 指定工作目录
WORKDIR /usr/local/src/nginx-1.20.1/# 编译nginx
RUN ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_stub_status_module --with-pcre=/usr/local/src/pcre-8.45 && make && make install
RUN echo "daemon off;" >> /usr/local/nginx/conf/nginx.conf# 设置环境变量
ENV PATH /usr/local/nginx/sbin:$PATH# 暴露80端口
EXPOSE 80# 容器默认启动命令
ENTRYPOINT ["nginx"]

然后保存退出,wget下载这两个源码包:

wget http://nginx.org/download/nginx-1.13.2.tar.gz
wget http://downloads.sourceforge.net/project/pcre/pcre/8.45/pcre-8.45.tar.gz

然后开始build构建:

docker build -t cent-ngx2 .   # . 表示在当前目录下构建

在这里插入图片描述
这里奇怪的是,我构建完毕,没有出现successfully的提示(但是nginx依然构建成功可以正常运行):
在这里插入图片描述

然后,run运行并指定端口映射:

docker run -d --name ngx2 -p 80:80 cent-ngx2

运行成功,浏览器访问(linux宿主机ip+端口80):
在这里插入图片描述

2.3、查看构建历史:

docker history 镜像id

在这里插入图片描述
此镜像层基本与dockerfile文件的RUN是一一对应的。
注:missing表示无法获取image id,通常从docker hub下载的镜像会有这个问题

以上dockerfile中指定了启动命令(前台启动),假如未指定,构建成功后,又想要制定怎么办?

为镜像指定环境变量,挂载目录,默认启动命令

在上一版镜像的基础上,新加配置:
在这里插入图片描述
执行:

docker build -t cent-ngx3

查看镜像的历史,可看到比ngx2的镜像多了几个层。
在这里插入图片描述
镜像的缓存特性

docker会缓存已有的镜像层,构建镜像时,如果某镜像层已经存在,就直接使用,无需创建,如果不希望在构建镜像时使用缓存,可以在docker build命令中加上–no-cache参数。dockerfile中每一个指令都会创建一个镜像层,上层依赖于下层的。无论什么时候,只要某一层发生变化,其上面所有层的缓存都会失效。除了构建时使用缓存,docker在下载镜像时也会使用

调试dockerfile

在执行dockerfile时,如果因为某种原因执行到某个指令失败了,也能够得到前一个指令成功执行构建出的容器,可以运行新的镜像,手动运行那条失败的指令,从而定位失败的原因

2.4、run VS cmd VS entrypoint

  • RUN:执行命令并创建新的镜像层,常用于安装软件包;
  • CMD:设置容器启动后默认执行的命令及其参数,但 docker run 后跟参数时会替换(忽略) CMD
  • ENTRYPOINT:配置容器启动时运行的命令。

在这里插入图片描述

docker容器的主业

docker理念里,容器启动时,应当为它指定主业是什么,如nginx容器主业就是nginx代理服务,tomcat容器就是web服务等等
1、容器创建时,必须指定主业任务,如不指定,则容器无事可干立即退出。
2、在dockerfile打包镜像时,可以使用cmd命令来指定一个默认的主业,如下:
在这里插入图片描述
3、既然镜像里是默认主业,即意味着创建容器时,可以覆盖此默认命令,如下
在这里插入图片描述

推荐的ENTRYPOINT 方式

1、镜像本身应该有稳定的主业,应当指定后即不能更改用途,于是引入ENTRYPOINT
2、使用ENTRYPOINT字义即容器入口,它不能被run中cmd覆盖,如下例:
在这里插入图片描述
执行:docker build -t nginxx:v3 .
在这里插入图片描述
以后使用nginxx:v3这个镜像时,只能做nginx服务来使用。

更详细用法看这里

3、commit和Dockerfile的区别

Commit生成的镜像和Dockerfile有以下几点区别:

  1. Commit生成的镜像是一个完整的镜像,而Dockerfile只是一个构建镜像的指令文件,它只能用于构建镜像,而不能用于运行容器。
  2. Commit生成的镜像可以直接运行容器,而Dockerfile只能用于构建镜像,不能直接运行容器。
  3. Commit生成的镜像可以直接推送到远程仓库,而Dockerfile不能直接推送到远程仓库,必须先构建镜像,然后再推送到远程仓库。

Docker commit的缺点如下:

  1. 需要在容器内操作麻烦,效率低。
  2. 这一点也是最重要的,使用docker commit 意味着所有对镜像的操作都是黑箱操作,生成的镜像也被称为黑箱镜像。其他人或者过一段时间后自己也不知道这个镜像是怎么做出来的,都安装了什么。但是使用Dockerfile构建的镜像,我们可以通过构建历史查看每一层做了什么。
  3. 而且,commit任何修改的结果仅仅是在当前层进行标记,添加,修改,而不会改动上一层。如果使用docker commit制作镜像,以及后期修改的话,每一次修改都会让镜像更加臃肿一次,所删除的上一层的东西并不会丢失,会一直如影随形的跟着这个镜像,即使根本无法访问到,这会使镜像更加臃肿。

那么为什么还要学习这种方式?

  1. docker commit有一些特殊的应用场合,比如被入侵后保存现场等。但是,不要使用docker commmit定制镜像,定制行为应该使用Dockerfile来完成
  2. Dockerfille每一步build出来的镜像正是通过docker commit 构建出来的。学习commit可以有助于我们理解dockerfile。

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

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

相关文章

wordpress 打开缓慢处理

gravatar.com 头像网站被墙 追踪发现请求头像时长为21秒 解决方案一 不推荐&#xff0c;容易失效&#xff0c;网址要是要稳定为主&#xff0c;宁愿头像显示异常&#xff0c;也不能网址打不开 网上大部分搜索到的替换的CDN网址都过期了&#xff0c;例如&#xff1a;gravatar.du…

37.利用linprog解 有约束条件多元变量函数最小值(matlab程序)

1.简述 linprog函数主要用来求线型规划中的最小值问题&#xff08;最大值的镜像问题&#xff0c;求最大值只需要加个“-”&#xff09; 2. 算法结构及使用方法 针对约束条件为Axb或Ax≤b的问题 2.1 linprog函数 xlinprog(f,A,b) xlinprog(f,A,b,Aeq,beq) xlinprog(f,A,b,Aeq,…

5.PyCharm基础使用及快捷键

在前几篇文章中介绍了PyCharm的安装和汉化,本篇文章一起来看一下PyCharm的基本用法和一些快捷键的使用方法。 本篇文章PyCharm的版本为PyCharm2023.2 新建项目和运行 打开工具,在菜单中——文件——新建项目 选择项目的创建位置(注意最好不要使用中文路径和中文名项目名称…

如何查询多级菜单(采用递归的方法)

应用场景 1.京东 京东的页面就是这么显示的在家用电器下面有电视.空调.洗衣机然后再电视下面又有全面屏电视.教育电视等等 2.我们的后端管理系统 我们后端在页面上显示的很多也是通过层级目录的显示出来。 如何实现 1.准备数据库 我们这里parent_id为0的为我们的一级菜单 …

自己实现Linux 的 cp指令

cp指令 Linux的cp指令就是复制文件&#xff1a; cp: 拷贝(cp 拷贝的文件 要拷贝到的地址或文件)&#xff0c;cp b.c test.c 将b.c拷成test.c的一个新文件 Linux 系统初识_mjmmm的博客-CSDN博客 实现思路 打开源文件读文件内容到缓冲区创建新文件将读到的文件内容全部写入新文…

Apache+Tomcat 整合

目录 方式一&#xff1a;JK 1、下载安装包 2、添加依赖 3、启动服务&#xff0c;检查端口是否监听 4、提供apxs命令 5、检查是否确实依赖 6、编译安装 7、重要配置文件 方式二&#xff1a;http_proxy 方式三&#xff1a;ajp_proxy 方式一&#xff1a;JK 1、下载安装…

windows环境下如何更改pip安装的默认位置

1.查看配置信息 python -m site2.查看配置文件位置 python -m site -help3.修改配置文件 USER_SITE "D:\\soft\\Anaconda\\Lib\\site-packages" USER_BASE "D:\\soft\\Anaconda\\Scripts"如果遇到文件无法保存情况&#xff0c;请给用户增加权限。 4.…

微信如何多号定时群发?

微信作为国内最大的网络社交平台&#xff0c;目前用户已超过11亿。 掐点给朋友送生日祝福,给领导同事送新年祝福&#xff0c;提醒朋友的待办事项等等&#xff0c;这些定时发送功能一直都是微博 QQ&#xff0c;邮箱的专属&#xff0c;如果微信也能定时发送该多好&#xff1f;其…

Qt实现可伸缩的侧边工具栏(鼠标悬浮控制伸缩栏)

Qt实现可伸缩的侧边工具栏 一直在网上找&#xff0c;发现大多的实现方案都是用一个按钮&#xff0c;按下控制侧边栏的伸缩&#xff0c;但是我想要实现鼠标悬浮在侧边栏的时候就伸出&#xff0c;移开就收缩的功能&#xff0c;也没找到好的参考&#xff0c;所以决定自己实现一个…

人工智能的未来:探索下一代生成模型

推荐&#xff1a;使用 NSDT场景编辑器 助你快速搭建可编辑的3D应用场景 生成式 AI 目前能够做什么&#xff0c;以及探索下一波生成式 AI 模型需要克服的当前挑战&#xff1f; 如果你跟上科技世界的步伐&#xff0c;你就会知道生成式人工智能是最热门的话题。我们听到了很多关于…

Kafka-消费者组消费流程

消费者向kafka集群发送消费请求&#xff0c;消费者客户端默认每次从kafka集群拉取50M数据&#xff0c;放到缓冲队列中&#xff0c;消费者从缓冲队列中每次拉取500条数据进行消费。

JVM面试突击班2

JVM面试突击班2 对象被判定为不可达对象之后就“死”了吗 对象的生命周期 创建阶段 &#xff08;1&#xff09;为对象分配存储空间 &#xff08;2&#xff09;开始构造对象 &#xff08;3&#xff09;从超类到子类对static成员进行初始化 &#xff08;4&#xff09;超类成…

数学建模学习(10):遗传算法

遗传算法简介 • 遗传算法&#xff08;Genetic Algorithms&#xff09;是基于生物进化理论的原理发展起来的一种广为 应用的、高效的随机搜索与优化的方法。其主要特点是群体搜索策略和群体中个体之 间的信息交换&#xff0c;搜索不依赖于梯度信息。它是20世纪70年代初期由美国…

铸铝齿轮泵比例流量阀放大器

液压齿轮泵是一种常用的液压泵&#xff0c;被广泛应用于各种低压系统中&#xff0c;如采矿、冶金、建筑、航空、航海、农林等机械的中、高压液压系统中。 液压齿轮泵的特点是结构简单&#xff0c;制造方便&#xff0c;价格低廉&#xff0c;体积小&#xff0c;重量轻&#xff0…

机器学习深度学习——循环神经网络RNN

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位即将上大四&#xff0c;正专攻机器学习的保研er &#x1f30c;上期文章&#xff1a;机器学习&&深度学习—语言模型和数据集 &#x1f4da;订阅专栏&#xff1a;机器学习&&深度学习 希望文章对你们有所帮助…

vs code remote ssh: Resolver error: Error: Got bad result from install script

今天像往常一样&#xff0c;打开 windows 11&#xff0c;使用 vs code 远程连接服务器 ubuntu 20&#xff0c;但是遇到了一个错误&#xff1a;Resolver error: Error: Got bad result from install script。 ok&#xff01;&#xff01;&#xff01;开始 Bing &#xff01;&…

利用abapGit的离线模式导出、导入开发对象

1. 背景 abapGit是为ABAP服务器开发的开源Git客户端&#xff0c;用于在ABAP系统之间导入和导出ABAP对象。 使用abapGit&#xff0c;可以将ABAP对象从任何系统导出到另一个系统&#xff0c;通常是从本地系统导出到云&#xff0c;或者从一个云系统导出到另一个云系统。 当然从…

Redis——特性介绍与应用场景

Redis特性介绍 In-memory data structrues 众所周知&#xff0c;MySQL是一种关系型数据库&#xff0c;其通过表的结构存储数据&#xff0c;就类似于建立了一个excel表格来存储数据。但是像视频这类数据并不适合存储在关系型数据库中&#xff0c;因此存在非关系型数据库——通…

【Linux命令行与Shell脚本编程】第十六章 Shell函数

Linux命令行与Shell脚本编程 第一章 文章目录 Linux命令行与Shell脚本编程六.函数6.1.脚本函数基础6.1.1.创建函数6.1.2.使用函数 6.2.函数返回值6.2.1.默认的退出状态码6.2.2.使用return命令6.2.3.使用函数输出 6.3.函数中使用变量6.3.1.向函数传递参数6.3.2.在函数中处理变量…

python爬虫2:requests库-原理

python爬虫2&#xff1a;requests库-原理 前言 ​ python实现网络爬虫非常简单&#xff0c;只需要掌握一定的基础知识和一定的库使用技巧即可。本系列目标旨在梳理相关知识点&#xff0c;方便以后复习。 目录结构 文章目录 python爬虫2&#xff1a;requests库-原理1. 概述2. re…