docker(4): 把容器变成镜像(docker容器更换镜像)
wptr33 2025-07-06 17:18 27 浏览
在docker中,我们可以基于镜像创建容器,也可以基于容器创建镜像,镜像和容器之间是可以互相转化的。
在之前的实验中,我们使用的镜像是官方的nginx镜像,如果我们想要自己制作一个nginx镜像,该怎么办呢?我通常会使用如下两种方法:
方法一:下载官方的nginx镜像,基于官方nginx镜像启动一个容器,把需要的文件拷贝到容器中,把配置文件改成自己想要的样子,把收拾好的容器变成镜像。
方法二:下载一个基础系统的镜像,比如centos、debian或者alpine镜像,然后基于这些系统镜像启动一个容器,在这个容器中安装nginx,然后把需要的文件拷贝到容器中,修改配置文件,最后把收拾好的容器变成镜像。
其实这两种方法没有本质区别,整体思路都是基于某个镜像,启动成容器,把容器改成自己想要的样子,然后把改好的容器变成镜像。由于方法一中基于的镜像是别人已经安装好软件的镜像,所以省去了安装软件的步骤,如果是想把自己公司开发的软件容器化,则只能使用方法二了,因为只有咱们自己有公司开发的软件,安装配置过程也只有自己最清楚。
使用方法二时,需要用到一些基础的系统镜像,咱们先下载一些基础镜像,熟悉熟悉它们
docker pull debian:11.2docker pull ubuntu:18.04docker pull centos:7.9.2009docker pull alpine:latest
拉取上述基础镜像后,可以发现,centos的体积较大,alpine的体积最小
[root@kvm32docker2 ~]# docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEalpine latest 9c842ac49a39 18 hours ago 5.57MBdebian 11.2 6f4986d78878 3 months ago 124MBubuntu 18.04 5a214d77f5d7 5 months ago 63.1MBcentos 7.9.2009 eeb6ee3f44bd 6 months ago 204MB
alpine是一个基于musl libc和busybox的Linux操作系统,体积非常小,所以在容器化时有先天优势,musl libc与常用的glibc基本兼容,musl libc更加轻量,但是可能缺少一些扩展,或者存在一些其他问题,在使用alpine作为基础系统时,需要进行充分的测试。
在选择基于哪个镜像容器化自己的软件时,在保证正常运行的前提下,如果最终的运行效果没有区别,优先选择体积较小的镜像。
此处使用debian和ubuntu的镜像创建两个容器,容器名为debian-test和ubuntu-test。
docker run -td --name debian-test debian:11.2docker run -td --name ubuntu-test ubuntu:18.04
上述命令的-td选项是两个短选项的合并写法,-t表示为容器分配伪终端(和前文中的docker exec命令中的-t选项作用一样),-d表示让容器在后台运行。
上例中,如果只使用-d选项,不使用-t选项,会无法正常运行容器,原因是pid为1的主进程结束时,容器也会自动停止,具体情况是这样的,这些操作系统类的基础镜像默认运行的程序通常都是shell,比如bash,也就是说,bash是容器中的主进程,pid是1,如果不使用-t选项为bash分配伪终端,单独执行bash命令后,bash进程就直接结束了(没有绑定任何终端,相当于执行bash命令后一闪而过,没有任何输入输出,直接结束进程),而前文中做过实验,当pid为1的主进程结束时,容器就会停止,所以,我们需要让bash持续运行,从而实现持续运行容器的目的,使用-t选项就是为了给bash分配伪终端,让其可以通过终端占用前台,从而达到持续运行pid1进程的目的。
上例中,如果只是用-t选项,不使用-d选项,为容器分配的伪终端会直接占用host的命令行,所以,-t选项配合-d选项,让容器在后台运行,可以避免容器一直占用host的命令行窗口,并持续运行容器。
前文中,启动nginx-demo容器的命令如下
docker run --name nginx-demo -d -p 80:80 nginx:latest
上述命令并没有使用-t选项,这是因为nginx镜像默认运行的程序是nginx(其实默认运行的是脚本,在脚本中通过exec命令调用nginx,让nginx的pid为1,具体过程以后再聊),nginx程序的运行不需要使用终端,所以无需使用-t选项。
通过上述对比可以说明,在使用docker run命令启动容器时,具体使用哪些选项取决于容器中运行程序的方式以及具体运行的是哪个程序,大部分容器在启动时使用-d、-t、-i选项中的一个或几个都可以满足正常持续运行容器的需求。
使用如下命令可以查看镜像或容器的默认运行程序。
docker inspect -f '{{.Config.Cmd}}' 容器名或镜像名docker inspect -f '{{.Config.Entrypoint}}' 容器名或镜像名
我在host主机上又打开了两个shell,通过两个shell分别进入刚才创建的两个容器
[root@kvm32docker2 ~]# docker exec -it ubuntu-test bashroot@92c0833b1889:/# [root@kvm32docker2 ~]# docker exec -it debian-test bashroot@b5b41ca43b68:/#
然后分别在host、ubuntu-test、debian-test中执行uname -r命令,查看内核版本,输出信息如下
[root@kvm32docker2 ~]# uname -r3.10.0-1160.el7.x86_64root@92c0833b1889:/# uname -r3.10.0-1160.el7.x86_64root@b5b41ca43b68:/# uname -r3.10.0-1160.el7.x86_64
很明显,它们输出的内核信息是完全一样的,因为在前文中说过,容器都是共享host的内核的,无论是debian镜像,还是ubuntu镜像,它们都只是打包了对应系统发行版的类库环境和命令工具,镜像中不包含内核,它们共享使用了宿主机的内核,只要宿主机的内核能够兼容对应的系统发行版,那么系统镜像就能够在host上正常运行。
为了方便后面实验,这里选择alpine镜像创建容器
[root@kvm32docker2 ~]# docker run -td --name alpine-test alpine06e550f1f88d0d9ac1e988cf50fd19b7c11d5f544027200f8296e19f7f9c86b6
启动容器后,我们可以按照方法二中的思路,进入容器,把公司开发的软件服务部署到容器中,此处为了方便演示,假设nginx就是我们要部署的服务,在docker hub中,很多官方仓库直接提供了基于alpine系统的软件镜像,比如redis、nginx等,直接pull下来就可以使用,不过话说回来,此处还是为了模拟实验,所以,咱们自己安装nginx,在alpine中,可以使用apk命令安装软件,apk是一个包管理工具,就像centos中的yum一样,只需在alpine容器中执行如下命令,即可安装nginx
apk add nginx
但是默认的软件源比较慢,我们可以把默认的软件源换成阿里或科大的镜像源,提升安装速度
换成阿里镜像源sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories换成科大镜像源sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories
通过apk安装nginx后,默认的nginx配置文件路径是/etc/nginx/nginx.conf,默认的server配置文件是
/etc/nginx/http.d/default.conf,这里修改一下默认server的配置,修改后配置如下
~ # cat /etc/nginx/http.d/default.conf # This is a default site configuration which will simply return 404, preventing# chance access to any other virtualhost.server { listen 80 default_server; listen [::]:80 default_server; # Everything is a 404 location / { #return 404; return 200 https://www.zsythink.net; } # You may need this to prevent return 404 recursion. location = /404.html { internal; }}
默认配置是访问根时返回404,这里改成返回200,并返回博客我的博客地址。
启动nginx,用自带的wget命令访问一下默认页面
~ # nginx~ # ~ # wget -q --header="Accept: text/html" http://127.0.0.1 -O-https://www.zsythink.net~ #
返回的信息正是我设置的网址,可见nginx已经正常工作了。
假设,我对现在的状态很满意,我想要基于当前容器,创建一个镜像,方便以后使用,则可以执行如下命令
docker commit -p -c 'CMD ["nginx","-g","daemon off;"]' alpine-test zsythink/nginx:test1
如上所示,docker commit命令可以将容器提交为镜像,上述命令表示基于alpine-test容器创建tag为zsythink/nginx:test1的镜像,前文已经说过tag(标签)的命名规则,上例标签中的zsythink是我在docker hub上注册的账号ID,zsythink/nginx表示zsythink账号下名为nginx的仓库,完整的写法应该是
docker.io/zsythink/nginx:test1,表示docker hub上zsythink账户下nginx仓库中的tag为test1的镜像,但是由于是docker hub上的仓库,所以可以省略registry地址,于是就写成了zsythink/nginx:test1,聪明如你一定已经看出来了,我之所以把创建的镜像的标签写成上面的样子,是因为在后面的实验中,我要把这个创建的镜像推送到docker hub上,所以标签要和真实的仓库地址对应上,如果只是在本地做实验,不推送镜像到任何仓库,那么标签可以随便写。上例中,-p选项表示在基于容器创建镜像的过程中,暂停容器的运行。-c选项用于设定镜像的各种参数,上例-c选项的值为'CMD ["nginx","-g","daemon off;"]',表示将镜像的默认运行的程序设置为nginx,执行如下命令,可见alpine镜像默认运行的命令是sh
[root@kvm32docker2 ~]# docker inspect -f '{{.Config.Cmd}}' alpine[/bin/sh]
所以,基于alpine镜像启动的容器alpine-test默认运行的程序也是sh,当我们基于alpine-test容器创建自己的镜像时,如果不修改默认运行的程序,创建出的镜像将仍然默认运行sh,但是我创建这个镜像的目的是使用里面的nginx,让基于这个镜像启动的容器可以默认提供我定制好的nginx服务,所以需要通过上述方式将nginx设置为默认运行的程序,上例'CMD ["nginx","-g","daemon off;"]'中的CMD是专门用来设置默认运行程序的一个指令,在后面的文章中会总结各种设置指令的用法,此处不用纠结,上例将默认运行的程序指令设置为nginx -g 'daemon off;',表示设置nginx以非守护进程的方式运行,这么做是为了防止容器自动停止,原因仍然与pid为1的进程有关,当我们设置nginx为默认运行的程序时,nginx进程就是容器中pid为1的主进程,如果nginx以daemon的方式运行,当守护进程被fork以后,发起守护进程的源nginx进程就会结束,而源nginx进程的pid为1,这就会导致容器也随之停止,所以,我们需要阻止nginx以daemon的方式在后台运行,通过-g 'daemon off;'可以让nginx在前台保持运行,最终实现持续运行容器的目的。
当执行了docker commit命令以后,即可在镜像列表中查看到我们创建的镜像
[root@kvm32docker2 ~]# docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEzsythink/nginx test1 9fbed7b04dc0 17 hours ago 9.45MBalpine latest 9c842ac49a39 5 days ago 5.57MBdebian 11.2 6f4986d78878 3 months ago 124MBubuntu 18.04 5a214d77f5d7 5 months ago 63.1MBcentos 7.9.2009 eeb6ee3f44bd 6 months ago 204MB
现在,我们就可以基于自己创建的这个镜像,启动新的容器了。
比如,创建一个名为nginx-alpine的容器
[root@kvm32docker2 ~]# docker run --name nginx-alpine -d zsythink/nginx:test1cf759b1bb597694ba55c567949f56e439a6be07775f4b05794dc64f9f1eb6434[root@kvm32docker2 ~]# [root@kvm32docker2 ~]# [root@kvm32docker2 ~]# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMEScf759b1bb597 zsythink/nginx:test1 "nginx -g 'daemon of…" 4 seconds ago Up 3 seconds nginx-alpine06e550f1f88d alpine "/bin/sh" 3 days ago Up 3 days alpine-test
容器启动后,执行如下命令,可以查看到容器在docker默认网络下分配到的内网IP,在host主机上通过这个IP地址即可访问到容器内部的nginx,容器网络的相关话题咱们后面再聊,此处先略过。
[root@kvm32docker2 ~]# docker inspect nginx-alpine -f '{{.NetworkSettings.IPAddress}}'172.17.0.3
在host中访问容器对应的IP地址,可以看到我们预设的内容,证明容器已经正常运行了。
[root@kvm32docker2 ~]# curl 172.17.0.3https://www.zsythink.net[root@kvm32docker2 ~]#
到此,我们已经完成了基于容器制作镜像的全部过程,还是很简单的,起到关键作用的其实只是一条docker commit命令罢了,只是我说的比较啰嗦而已,除了通过docker commit可以创建镜像,还有另一种方法也可以创建镜像,这种方法需要我们编写一个叫Dockerfile的配置文件,通过Dockerfile去创建镜像,之后的文章会总结Dockerfile的用法,这里我们先使用docker commit
我们可以把自己制作好的镜像推送到远程的仓库中,分享给别人使用,在推送镜像之前,需要先确保已经登录了对应的registry
#使用docker login命令可以登录对应的registry,语法如下docker login registryURL#假设,我们在内网中建立了一个私有镜像仓库,私有仓库地址为192.168.1.100,那么使用如下命令即可登录私有仓库docker login http://192.168.1.100#当没有指定registryURL时,默认登录的registry为docker hub,如下docker login
执行docker login命令后,根据提示输入用户名和密码,即可登录docker hub,登录成功后,执行docker push命令,可以将本地镜像推送到对应的仓库中
#先查看一下镜像,此处我们要推送的镜像是zsythink/nginx:test1[root@kvm32docker2 ~]# docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEzsythink/nginx test1 9fbed7b04dc0 19 hours ago 9.45MBalpine latest 9c842ac49a39 5 days ago 5.57MBdebian 11.2 6f4986d78878 3 months ago 124MBubuntu 18.04 5a214d77f5d7 5 months ago 63.1MBcentos 7.9.2009 eeb6ee3f44bd 6 months ago 204MB#在已经登录docker hub的前提下,直接执行push命令,docker会按照完整的标签地址将镜像推送到对应的仓库中。#所以,如果想要正常推送镜像,需要确保镜像的tag地址对应的仓库是真实存在的。#zsythink/nginx是我提前创建好的仓库,注册docker hub账号后,通过https://hub.docker.com/repositories地址即可创建自己的仓库[root@kvm32docker2 ~]# docker push zsythink/nginx:test1The push refers to repository [docker.io/zsythink/nginx]e68e457d8858: Pushed ff768a1413ba: Mounted from library/alpine test1: digest: sha256:f49ad91ac5c9a80c2330d9644935b72cba9bcc43754419de6873c62e4c664974 size: 739
推送完成后,登录docker hub的网页,在repositories中即可看到自己推送的镜像。
除了能将镜像推送到远程仓库,我们还可以直接将镜像从本地导出,使用docker save命令即可将镜像导出成文件。
#如下命令表示将本地的nginx:latest镜像和busybox:latest镜像导出到一个名为test.images的文件中,-o参数用于指定导出镜像时输出的文件名docker save -o test.images nginx:latest busybox:latest
如你所见,我们可以一次性导出一个或多个镜像到一个文件,上例中导出的文件名为test.images,我们可以把test.images文件拷贝到其他docker主机上,然后通过docker load命令即可把这个文件中包含的所有镜像导入到其他docker主机上,导入命令如下
docker load -i test.images
在使用docker commit命令时,如果没有指定标签,创建的镜像则不会有任何标签,只会有一个镜像ID,我们可以使用docker tag命令,为没有标签的镜像添加标签,具体过程如下
#如下命令表示基于alpine-test容器创建镜像,但是没有为创建的镜像指定标签,创建出的镜像的id为2e16a148800c......[root@kvm32docker2 ~]# docker commit -p alpine-testsha256:2e16a148800cb90394e53746b50e8944868782998e75bd13facce5b53cc146a1#通过命令查看镜像列表,可见刚才创建的id为2e16a148800c...的镜像没有任何标签信息[root@kvm32docker2 ~]# docker imagesREPOSITORY TAG IMAGE ID CREATED SIZE<none> <none> 2e16a148800c 4 seconds ago 9.45MBzsythink/nginx test1 9fbed7b04dc0 20 hours ago 9.45MBalpine latest 9c842ac49a39 5 days ago 5.57MBdebian 11.2 6f4986d78878 3 months ago 124MBubuntu 18.04 5a214d77f5d7 5 months ago 63.1MBcentos 7.9.2009 eeb6ee3f44bd 6 months ago 204MB#使用docker tag命令,可为id为2e16a148800c的镜像添加标签#此处执行了两次docker tag命令,给id为2e16a148800c的镜像添加了两个标签#一个标签为zsythink/nginx:test2,另一个标签为test-nginx:1[root@kvm32docker2 ~]# docker tag 2e16a148800c zsythink/nginx:test2[root@kvm32docker2 ~]# [root@kvm32docker2 ~]# docker tag 2e16a148800c test-nginx:1#再次查看镜像列表,可以发现,id为2e16a148800c的镜像已经有两个标签了#这两个标签在镜像列表中就好像两个镜像一样,其实它们是一个镜像,只是使用了不同的标签而已。[root@kvm32docker2 ~]# docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEtest-nginx 1 2e16a148800c 6 minutes ago 9.45MBzsythink/nginx test2 2e16a148800c 6 minutes ago 9.45MBzsythink/nginx test1 9fbed7b04dc0 20 hours ago 9.45MBalpine latest 9c842ac49a39 5 days ago 5.57MBdebian 11.2 6f4986d78878 3 months ago 124MBubuntu 18.04 5a214d77f5d7 5 months ago 63.1MBcentos 7.9.2009 eeb6ee3f44bd 6 months ago 204MB
我们可以根据自己的需求,为同一个镜像,添加上很多个不同的标签,以便区分一个镜像在不同场景下所扮演的角色。
在同一个镜像ID有多个标签的情况下,如果想要删除某一个标签,只需要执行docker rmi命令即可,示例如下
#查看镜像列表,可见ID为2e16a148800c的镜像有两个条目[root@kvm32docker2 ~]# docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEtest-nginx 1 2e16a148800c 6 minutes ago 9.45MBzsythink/nginx test2 2e16a148800c 6 minutes ago 9.45MBzsythink/nginx test1 9fbed7b04dc0 20 hours ago 9.45MBalpine latest 9c842ac49a39 5 days ago 5.57MBdebian 11.2 6f4986d78878 3 months ago 124MBubuntu 18.04 5a214d77f5d7 5 months ago 63.1MBcentos 7.9.2009 eeb6ee3f44bd 6 months ago 204MB#首先,删除标签为test-nginx:1的镜像,执行如下命令,注意命令的返回结果[root@kvm32docker2 ~]# docker rmi test-nginx:1Untagged: test-nginx:1#此时查看镜像列表,发现对应标签为test-nginx:1的条目已经不在了[root@kvm32docker2 ~]# docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEzsythink/nginx test2 2e16a148800c 24 minutes ago 9.45MBzsythink/nginx test1 9fbed7b04dc0 21 hours ago 9.45MBalpine latest 9c842ac49a39 5 days ago 5.57MBdebian 11.2 6f4986d78878 3 months ago 124MBubuntu 18.04 5a214d77f5d7 5 months ago 63.1MBcentos 7.9.2009 eeb6ee3f44bd 6 months ago 204MB#再次执行docker rmi命令,删除标签为zsythink/nginx:test2的镜像,注意命令的返回结果[root@kvm32docker2 ~]# docker rmi zsythink/nginx:test2Untagged: zsythink/nginx:test2Deleted: sha256:2e16a148800cb90394e53746b50e8944868782998e75bd13facce5b53cc146a1#再次查看镜像列表,发现ID为2e16a148800c的镜像已经不存在了[root@kvm32docker2 ~]# docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEzsythink/nginx test1 9fbed7b04dc0 21 hours ago 9.45MBalpine latest 9c842ac49a39 5 days ago 5.57MBdebian 11.2 6f4986d78878 3 months ago 124MBubuntu 18.04 5a214d77f5d7 5 months ago 63.1MBcentos 7.9.2009 eeb6ee3f44bd 6 months ago 204MB
通过上述实验可知,当一个镜像有多个标签时,在执行docker rmi 标签名删除镜像时,其实只是删除了对应镜像的某一个标签而已,当一个镜像只有唯一一个标签时,docker rmi 标签名才会删除对应的镜像。
这篇文章总结了如何基于容器创建镜像以及一些常用的命令,没有什么难点,只是需要孰能生巧啊,今天先总结到这里,下次见啦~
相关推荐
- MySQL进阶五之自动读写分离mysql-proxy
-
自动读写分离目前,大量现网用户的业务场景中存在读多写少、业务负载无法预测等情况,在有大量读请求的应用场景下,单个实例可能无法承受读取压力,甚至会对业务产生影响。为了实现读取能力的弹性扩展,分担数据库压...
- 3分钟短文 | Laravel SQL筛选两个日期之间的记录,怎么写?
-
引言今天说一个细分的需求,在模型中,或者使用laravel提供的EloquentORM功能,构造查询语句时,返回位于两个指定的日期之间的条目。应该怎么写?本文通过几个例子,为大家梳理一下。学习时...
- 一文由浅入深带你完全掌握MySQL的锁机制原理与应用
-
本文将跟大家聊聊InnoDB的锁。本文比较长,包括一条SQL是如何加锁的,一些加锁规则、如何分析和解决死锁问题等内容,建议耐心读完,肯定对大家有帮助的。为什么需要加锁呢?...
- 验证Mysql中联合索引的最左匹配原则
-
后端面试中一定是必问mysql的,在以往的面试中好几个面试官都反馈我Mysql基础不行,今天来着重复习一下自己的弱点知识。在Mysql调优中索引优化又是非常重要的方法,不管公司的大小只要后端项目中用到...
- MySQL索引解析(联合索引/最左前缀/覆盖索引/索引下推)
-
目录1.索引基础...
- 你会看 MySQL 的执行计划(EXPLAIN)吗?
-
SQL执行太慢怎么办?我们通常会使用EXPLAIN命令来查看SQL的执行计划,然后根据执行计划找出问题所在并进行优化。用法简介...
- MySQL 从入门到精通(四)之索引结构
-
索引概述索引(index),是帮助MySQL高效获取数据的数据结构(有序),在数据之外,数据库系统还维护者满足特定查询算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构...
- mysql总结——面试中最常问到的知识点
-
mysql作为开源数据库中的榜一大哥,一直是面试官们考察的重中之重。今天,我们来总结一下mysql的知识点,供大家复习参照,看完这些知识点,再加上一些边角细节,基本上能够应付大多mysql相关面试了(...
- mysql总结——面试中最常问到的知识点(2)
-
首先我们回顾一下上篇内容,主要复习了索引,事务,锁,以及SQL优化的工具。本篇文章接着写后面的内容。性能优化索引优化,SQL中索引的相关优化主要有以下几个方面:最好是全匹配。如果是联合索引的话,遵循最...
- MySQL基础全知全解!超详细无废话!轻松上手~
-
本期内容提醒:全篇2300+字,篇幅较长,可搭配饭菜一同“食”用,全篇无废话(除了这句),干货满满,可收藏供后期反复观看。注:MySQL中语法不区分大小写,本篇中...
- 深入剖析 MySQL 中的锁机制原理_mysql 锁详解
-
在互联网软件开发领域,MySQL作为一款广泛应用的关系型数据库管理系统,其锁机制在保障数据一致性和实现并发控制方面扮演着举足轻重的角色。对于互联网软件开发人员而言,深入理解MySQL的锁机制原理...
- Java 与 MySQL 性能优化:MySQL分区表设计与性能优化全解析
-
引言在数据库管理领域,随着数据量的不断增长,如何高效地管理和操作数据成为了一个关键问题。MySQL分区表作为一种有效的数据管理技术,能够将大型表划分为多个更小、更易管理的分区,从而提升数据库的性能和可...
- MySQL基础篇:DQL数据查询操作_mysql 查
-
一、基础查询DQL基础查询语法SELECT字段列表FROM表名列表WHERE条件列表GROUPBY分组字段列表HAVING分组后条件列表ORDERBY排序字段列表LIMIT...
- MySql:索引的基本使用_mysql索引的使用和原理
-
一、索引基础概念1.什么是索引?索引是数据库表的特殊数据结构(通常是B+树),用于...
- 一周热门
-
-
C# 13 和 .NET 9 全知道 :13 使用 ASP.NET Core 构建网站 (1)
-
程序员的开源月刊《HelloGitHub》第 71 期
-
详细介绍一下Redis的Watch机制,可以利用Watch机制来做什么?
-
假如有100W个用户抢一张票,除了负载均衡办法,怎么支持高并发?
-
Java面试必考问题:什么是乐观锁与悲观锁
-
如何将AI助手接入微信(打开ai手机助手)
-
redission YYDS spring boot redission 使用
-
SparkSQL——DataFrame的创建与使用
-
一文带你了解Redis与Memcached? redis与memcached的区别
-
如何利用Redis进行事务处理呢? 如何利用redis进行事务处理呢英文
-
- 最近发表
- 标签列表
-
- git pull (33)
- git fetch (35)
- mysql insert (35)
- mysql distinct (37)
- concat_ws (36)
- java continue (36)
- jenkins官网 (37)
- mysql 子查询 (37)
- python元组 (33)
- mybatis 分页 (35)
- vba split (37)
- redis watch (34)
- python list sort (37)
- nvarchar2 (34)
- mysql not null (36)
- hmset (35)
- python telnet (35)
- python readlines() 方法 (36)
- munmap (35)
- docker network create (35)
- redis 集合 (37)
- python sftp (37)
- setpriority (34)
- c语言 switch (34)
- git commit (34)