【狂神说Java】Docker最新超详细版教程通俗易懂 - 学习笔记

传送门:官方参考文档 | Docker Hub镜像仓库 | 【狂神说Java】Docker视频教程

Docker概述

Docker 是一个便携的应用容器,基于 Go 语言开发的。它可以让开发者打包应用以及应用的依赖到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上。容器是完全使用沙箱机制,相互之间不会有任何接口,非常适合于高密度环境以及中小型部署,而且可以用更少的资源做更多的事情。
Docker 从 17.03 版本之后分为 CE(Community Edition: 社区版) 和 EE(Enterprise Edition: 企业版),我们用社区版就可以了。

Docker可以干什么?

Docker 提供了一个基础系统镜像作为运行应用的基础。Docker 并不在乎你的应用程序是什么、做什么,也就是说,只要是 Linux 系统上的应用都可以运行在 Docker 容器中。这是因为 Docker 提供了一组应用打包、传输和部署的方法,以便你能更好地在容器内运行任何应用。
例如:Docker 只需要一条命令便可以运行 MySQL 数据库:

[root@localhost ~]# docker run -d -p 3306:3306 tutum/mysql

比较Docker和虚拟机的不同

  1. 传统虚拟机,虚拟出硬件,运行一个完整的操作系统,然后在这个系统上安装和运行软件。
  2. Docker利用 Linux 原生支持的容器方式实现资源和环境的隔离,直接利用宿主内核,性能接近原生。
  3. 每个容器都是相互隔离的,每个容器都有属于自己的文件系统,互不影响。
    【狂神说Java】Docker最新超详细版教程通俗易懂 - 学习笔记_第1张图片

Docker容器化带来的好处

DevOps思想:它涵盖开发、测试、运维的整个过程,其核心就是流程的统一和自动化。

  1. 系统应用可以更快速的交付和部署
    传统方式:部署前需要写一堆的文档,安装程序;使用Docker:打包镜像发布,一键运行
  2. 更便捷的升级和扩容
    使用Docker后,我们部署系统应用就像搭积木一样。项目打包为一个镜像,在服务器A部署后,一键扩容到服务器B!
  3. 更简单的系统运维
    在容器化以后,我们的开发、测试环境可以做到高度一致。
  4. 更高效的计算资源利用
    Docker 是内核级别的虚拟化,可以在一个物理机上运行很多的容器实例,服务器的性能可以被压榨到极致。

Docker的基本组成部分

镜像(Image): Docker镜像就好比是一个模板,可以通过这个模板来创建容器服务。一个镜像可以创建多个容器。比如,Tomcat镜像 ===> Run ===> Tomcat容器(可以提供服务)

容器(Containers): Docker利用容器技术,可以独立运行一个或一组应用,它是通过镜像来创建的。我们可以把容器理解为就是一个微型的Linux系统。它包括启动、停止、删除等基本命令。

仓库(Repository): 就是存放镜像的地方,一个Docker Registry中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。官方默认的Registry是 Docker Hub,在国内使用时一般需要配置镜像加速。

【狂神说Java】Docker最新超详细版教程通俗易懂 - 学习笔记_第2张图片

安装Docker环境

注意:在CentOS系统上安装Docker引擎时,要求操作系统是CentOS 7以上版本。可以通过如下命令查看系统内核与系统版本。

# 系统内核版本
[root@localhost ~]# uname -r 
# 查看系统版本
[root@localhost ~]# cat /etc/os-release 
  1. 卸载旧版本
    如果安装了这些,请卸载它们以及相关的依赖项

    [root@localhost ~]# yum remove docker \
                      docker-client \
                      docker-client-latest \
                      docker-common \
                      docker-latest \
                      docker-latest-logrotate \
                      docker-logrotate \
                      docker-engine
    
  2. 添加Docker的yum源信息

    # 安装 yum-utils
    [root@localhost ~]# yum install -y yum-utils
    # (推荐)使用阿里云的软件源地址
    [root@localhost ~]# yum-config-manager \
        --add-repo \
        https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    # (不推荐)国外地址
    [root@localhost ~]# yum-config-manager \
        --add-repo \
        https://download.docker.com/linux/centos/docker-ce.repo
    

    小贴士: yum-utils 提供了 yum-config-manager 的实用程序

  3. 安装前建议更新 yum 软件包索引

    [root@localhost ~]# yum makecache fast
    

    小贴士:该操作的目的就是将软件包信息提前在本地缓存一份,用来提高搜索安装软件的速度。如果觉得 yum 下载的软件包占用磁盘空间,可以使用 yum clean [all / 软件包] 指令清除缓存。

  4. 安装docker相关的配置

    [root@localhost ~]# yum install docker-ce docker-ce-cli containerd.io
    

    小贴士:docker-ce 是社区版,docker-ee 企业版

  5. 启动 Docker 并设置开机启动

    # 启动 Docker
    [root@localhost ~]# systemctl start docker 
    # 查看当前版本号,是否启动成功 
    [root@localhost ~]# docker version 
    # 设置开机自启动 
    [root@localhost ~]# systemctl enable docker
    
  6. 运行 hello-world 看看效果

    # 运行hello-world
    [root@localhost ~]# docker run hello-world
    # 查看下载的 hello-world 镜像
    [root@localhost ~]# docker images
    
  7. Docker卸载

    # 1. 卸载依赖 
    [root@localhost ~]# yum remove docker-ce docker-ce-cli containerd.io 
    # 2. 删除资源  /var/lib/docker 是 Docker 的默认工作路径
    [root@localhost ~]# rm -rf /var/lib/docker
    

    小贴士:Docker官方的安装文档也比较详细,有需要的小伙伴可以查阅 官方安装文档(CentOS)

Docker 配置阿里云镜像加速

使用加速器可以提升获取Docker官方镜像的速度,在不同的操作系统下,配置加速器的方式略有不同,下文将介绍主要操作系统的配置方法。

  1. 获取加速器的地址
    您登录容器镜像服务控制台后,在左侧导航栏选择镜像工具 > 镜像加速器,在镜像加速器页面就会显示为您独立分配的加速器地址。

    例如:
    加速器地址:[系统分配前缀].mirror.aliyuncs.com
    
  2. 配置加速器
    当您安装的Docker Version不低于1.10时,建议直接通过daemon config进行配置。使用配置文件 /etc/docker/daemon.json (没有时新建该文件)。

    {
         "registry-mirrors": [""]
    }    
    
  3. 重启Docker Daemon即可

    [root@localhost ~]# sudo systemctl daemon-reload 
    [root@localhost ~]# sudo systemctl restart docker
    

    小贴士:阿里云官方也提供了更加详细的说明文档,有需要的小伙伴可以查阅 阿里云官方帮助文档

Docker常用命令汇总

Docker是一个 Client - Server 结构的系统,因此它提供了在客户端 - 服务器环境中进行交互和工作的命令。在这里,我们列出了一些重要和常用的 Docker 命令进行学习。

基础命令

  1. 查看Docker的版本信息

    [root@localhost ~]# docker version
    
  2. 查看Docker的系统信息,包括镜像和容器的数量

    [root@localhost ~]# docker info
    
  3. 帮助命令(可查看可选的参数)

    [root@localhost ~]# docker 命令 --help
    

镜像命令

  1. docker images 查看本地主机的所有镜像

    [root@localhost ~]# docker images
    REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
    hello-world   latest    feb5d9fea6a5   2 months ago   13.3kB
    
    # 可选参数
    -a,--all       # 列出所有镜像
    -q,--quiet     # 只显示镜像的id
    
  2. docker search 搜索镜像
    搜索镜像时建议优先使用 官网镜像仓库 ,那里有完善的文档信息。

    [root@localhost ~]# docker search mysql          
    NAME                              DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
    mysql                             MySQL is a widely used, open-source relation…   11833     [OK]       
    mariadb                           MariaDB Server is a high performing open sou…   4505      [OK]       
    mysql/mysql-server                Optimized MySQL Server Docker images. Create…   887                  [OK]
    centos/mysql-57-centos7           MySQL 5.7 SQL database server                   92                   
    mysql/mysql-cluster               Experimental MySQL Cluster Docker images. Cr…   90                   
    
    # 可选参数
      -f, --filter filter   # 根据所提供的条件过滤输出 如:docker search mysql --filter STARS=5000
          --format string   # 输出打印模板,如:docker search --format "{{.Name}}: {{.StarCount}}" nginx
          --limit int       # 最大搜索结果数(默认为25)
          --no-trunc        # 不截断输出
    
  3. docker pull 镜像名[:tag] 下载镜像

    [root@localhost ~]# docker pull mysql
    Using default tag: latest            # 如果下载命令中部指定tag,则默认下载latest
    latest: Pulling from library/mysql
    ffbb094f4f9e: Pull complete          # 分层下载,docker image的核心-联合文件系统
    df186527fc46: Pull complete 
    fa362a6aa7bd: Pull complete 
    5af7cb1a200e: Pull complete 
    949da226cc6d: Pull complete 
    bce007079ee9: Pull complete 
    eab9f076e5a3: Pull complete 
    8a57a7529e8d: Pull complete 
    b1ccc6ed6fc7: Pull complete 
    b4af75e64169: Pull complete 
    3aed6a9cd681: Pull complete 
    23390142f76f: Pull complete 
    Digest: sha256:ff9a288d1ecf4397967989b5d1ec269f7d9042a46fc8bc2c3ae35458c1a26727
    Status: Downloaded newer image for mysql:latest
    docker.io/library/mysql:latest         # 下载来源的真实地址  
    
    # 如下两个命令是等价的
    [root@localhost ~]# docker pull mysql
    [root@localhost ~]# docker pull docker.io/library/mysql:latest
    # 下载指定版本试一试
    [root@localhost ~]# docker pull mysql:5.7
    
  4. docker rmi 删除镜像

    # 删除指定的镜像
    [root@localhost ~]# docker rmi -f 镜像id
    # 删除多个镜像
    [root@localhost ~]# docker rmi -f  镜像id 镜像id 镜像id
    # 删除全部的镜像
    [root@localhost ~]# docker rmi -f  $(docker images -aq)
    
    # 可选参数
      -f, --force      # 强制移除
          --no-prune   # 不移除该镜像的过程镜像,默认移除
    

容器命令

  1. 如拉取一个 centos 镜像

    [root@localhost ~]# docker pull centos
    
  2. 运行容器并进入容器

    [root@localhost ~]# docker run --name CentOS -it centos /bin/bash
    [root@d6cbf0e93a8b /]# ls   # 进入到centos容器中,展示根目录下的文件
    bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
    
    # 重要参数说明
    --name string          # 指定容器名字
    -d                     # 后台方式运行
    -it                    # 使用交互方式运行,进入容器查看内容
    -p                     # 指定容器的端口及主机端口映射,三种示例如下
        -p ip:主机端口:容器端口 
        -p 主机端口:容器端口    # 推荐
        -p 容器端口
    -P                      # 随机指定端口(大写的P)
    

    小贴士: docker run -it centos /bin/bash 命令后面的 bin/bash 的作用,表示载入容器后运行bash ,Docker中必须要保持一个进程的运行,要不然整个容器启动后就会马上停止,这个 /bin/bash 就表示启动容器后启动 bash。

  3. 后台方式运行容器

    # 后台方式运行 centos 容器,因为没有前台进程使用,会马上停止运行
    [root@localhost ~]# docker run --name CentOS_01 -d centos
    ecbc3e9d773d120ba0cc14ba064cc9eeb843cd23bab81b1fb9724f045319874d
    [root@localhost ~]# docker ps -n 1   
    CONTAINER ID   IMAGE     COMMAND       CREATED              STATUS                          PORTS     NAMES
    ecbc3e9d773d   centos    "/bin/bash"   About a minute ago   Exited (0) About a minute ago             CentOS_01
    
    # 运行一个脚本,使得 centos 容器保持运行状态
    [root@localhost ~]# docker run --name CentOS_02 -d centos /bin/sh -c "while true;do echo hi;sleep 5;done"
    [root@localhost ~]# docker ps -n 1
    CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS     NAMES
    67a894effbcf   centos    "/bin/sh -c 'while t…"   4 seconds ago   Up 3 seconds             CentOS_02
    
    # 查看容器的日志信息
    [root@localhost ~]# docker logs -tf --tail 3  67a894effbcf  
    2021-12-17T15:03:36.016984749Z hi
    2021-12-17T15:03:41.030581591Z hi
    2021-12-17T15:03:46.037004793Z hi
    2021-12-17T15:03:51.045708743Z hi
    

    小贴士:Docker容器后台运行时,必须要有一个前台的进程,否则会自动停止。

  4. 退出容器

    # exit 停止并退出容器(以后台方式运行时,则仅退出容器)
    # Ctrl+P+Q  不停止容器退出
    
    [root@d6cbf0e93a8b /]# exit
    exit
    [root@localhost ~]#
    
  5. 列出系统中的容器

    [root@localhost ~]# docker ps
    CONTAINER ID   IMAGE     COMMAND       CREATED          STATUS          PORTS     NAMES
    d6cbf0e93a8b   centos    "/bin/bash"   30 seconds ago   Up 28 seconds             CentOS
    [root@localhost ~]# docker ps -a
    CONTAINER ID   IMAGE          COMMAND       CREATED          STATUS                   PORTS     NAMES
    d6cbf0e93a8b   centos         "/bin/bash"   34 seconds ago   Up 32 seconds                      CentOS
    54f01f55548d   feb5d9fea6a5   "/hello"      7 hours ago      Exited (0) 7 hours ago             friendly_chandrasekhar
    
    # 可选参数,不带参数默认列出当前正在运行的容器
    -a           # 列出所有容器的运行记录 
    -n=?         # 显示最近创建的n个容器 
    -q           # 只显示容器的编号
    
  6. 删除容器

    [root@localhost ~]# docker rm 容器id                 # 删除指定的容器,不能删除正在运行的容器,强制删除使用 rm -f
    [root@localhost ~]# docker rm -f $(docker ps -aq)    # 删除所有的容器
    [root@localhost ~]# docker ps -a -q|xargs docker rm  # 删除所有的容器
    
  7. 启动和停止容器

    [root@localhost ~]# docker start 容器id          # 启动容器
    [root@localhost ~]# docker restart 容器id        # 重启容器
    [root@localhost ~]# docker stop 容器id           # 停止当前运行的容器
    [root@localhost ~]# docker kill 容器id           # 强制停止当前容器
    

其他常用命令

  1. 日志的查看

    [root@localhost ~]# docker logs -tf 容器id 
    [root@localhost ~]# docker logs --tail number 容器id         # 注意:number为要显示的日志条数
    
  2. 查看容器中进程信息

    [root@localhost ~]# docker top d6cbf0e93a8b
    UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
    root                3825                3806                0                   22:43               pts/0               00:00:00            /bin/bash
    
  3. 查看容器的元数据

    [root@localhost ~]# docker inspect d6cbf0e93a8b
    
  4. 进入当前正在运行的容器
    因为通常我们的容器都是使用后台方式来运行的,有时需要进入容器修改配置信息
    方式一(推荐): docker exec 进入容器后开启一个新的终端,可以在里面操作,使用 exit 退出时,不会停止容器运行

    [root@localhost ~]# docker exec -it d6cbf0e93a8b /bin/bash
    [root@d6cbf0e93a8b /]# ls
    bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
    [root@d6cbf0e93a8b /]# ps -ef
    UID         PID   PPID  C STIME TTY          TIME CMD
    root          1      0  0 14:43 pts/0    00:00:00 /bin/bash
    root         23      0  0 15:12 pts/1    00:00:00 /bin/bash
    root         38     23  0 15:12 pts/1    00:00:00 ps -ef
    [root@d6cbf0e93a8b /]# exit
    exit
    [root@localhost ~]# docker ps
    CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS     NAMES
    d6cbf0e93a8b   centos    "/bin/bash"              31 minutes ago   Up 31 minutes             CentOS
    

    方式二(不推荐): docker attach 进入容器正在执行的终端,不会启动新的进程,使用 exit 退出时,会停止容器运行

    [root@localhost ~]# docker attach d6cbf0e93a8b
    [root@d6cbf0e93a8b /]# exit
    exit
    [root@localhost ~]# docker ps
    CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS     NAMES
    
  5. 拷贝操作

    # 拷贝容器的文件到主机中
    docker cp 容器id:容器内路径  目的主机路径
    # 拷贝宿主机的文件到容器中
    docker cp 目的主机路径 容器id:容器内路径
    

操作命令小结

Docker有很多操作(Docker CLI 的基础命令),我们没必要记住所有命令的具体使用方法。学习方法,我们可以通过命令 docker command --help 更深入的了解指定的 Docker 命令使用方法。例如:我们要查看 docker images 指令的具体使用方法:

[root@localhost ~]# docker images --help

【狂神说Java】Docker最新超详细版教程通俗易懂 - 学习笔记_第3张图片

Docker数据卷技术

为什么需要数据卷?什么是数据卷?

利用前面学习到的技术部署容器,容器运行所需的配置信息和数据文件都是保存在该容器中的。这就会导致容器被删除后,容器中产生的数据也就没有了。那怎么才能做到容器数据的持久化呢?
使用下面介绍的数据卷技术就可以做到容器之间数据的共享和容器与本地之间的持久化存储。

使用数据卷

  • 方式一:直接使用命令参数来挂载
    命令: docker run -it -v 宿主机目录:容器目录
    实战:安装MySQL

    # 安装MySQL数据库,设置密码为123456,并挂载两个数据卷用于存储配置和数据信息
    [root@localhost ~]# docker run --name MySQL -d -p 3306:3306 \
                        -e MYSQL_ROOT_PASSWORD=123456 \
                        -v /home/mysql/conf:/etc/mysql/conf \
                        -v /home/mysql/data:/var/lib/mysql \
                        mysql:5.7
    # 此时可以通过数据库可视化工具连接到MySQL,并尝试创建一下数据表
    # 删除MySQL容器
    [root@localhost ~]# docker rm -f MySQL
    # 执行执行数据库安装后,之前MySQL中的创建的数据表依然存在
    

    执行数据卷挂载以后,我们可以通过 docker inspect 容器名 命令,在元数据信息中查看数据卷情况,结果如下:
    【狂神说Java】Docker最新超详细版教程通俗易懂 - 学习笔记_第4张图片
    当然也可以通过 docker volume inspect 数据卷名 命令,查看数据卷挂载情况。如下:
    【狂神说Java】Docker最新超详细版教程通俗易懂 - 学习笔记_第5张图片

  • 方式二:使用Dockerfile脚本挂载数据卷
    初识 Dockerfile ,使用 Dockerfile 中的 VOLUME 指令来给镜像添加一个或多个数据卷。 Dockerfile 脚本比较简单,按照如下步骤操作即可:

    # 编写 Dockerfile 脚本
    [root@localhost home]# vi dockerfile01
    
    # 脚本内容
    # 每个指令必须是大写字母,一个指令代表一个新的镜像层
    FROM centos                         # FROM:基础镜像,一切基于这个开始构建
    VOLUME ["volume01","volume02"]      # VOLUME:挂载的目录
    CMD echo "----end----"              # CMD:容器启动时要运行的命令
    CMD /bin/bash
    
    # 执行构建镜像
    [root@localhost home]# docker build -f dockerfile01 -t wangxf/centos:1.0 .
    # 查看镜像
    [root@localhost home]# docker images
    REPOSITORY            TAG       IMAGE ID       CREATED          SIZE
    wangxf/centos         1.0       af2f08491630   22 seconds ago   231MB
    # 启动自己生成的容器
    [root@localhost home]# docker run -it af2f08491630 /bin/bash
    [root@c60faa5b4dea /]# ls v
    var/      volume01/ volume02/ 
    
    # 解析:上面的volume01  volume02两个目录就是刚刚通过Dockerfile挂载的数据卷,自己动手找一下他们分别挂载到宿主机的什么位置呢?
    

匿名挂载和具名挂载

  • 匿名挂载

    # 匿名挂载:-v 容器内路径
    [root@localhost data]# docker run -d -p 80:80 --name Nginx -v /ect/nginx nginx
    
  • 具名挂载

    # 具名挂载:-v 卷名:容器内路径
    [root@localhost data]# docker run -d -p 80:80 --name Nginx_JM -v juming-nginx:/ect/nginx nginx
    # 查看卷情况
    [root@localhost data]# docker volume ls    
    DRIVER    VOLUME NAME
    local     40104546065ec402615d03842c6b7d6cbdb8e43413666c697ea4980baaa36477
    local     cd637459e5acab02e1935d098a916d873727f0f83d0377dc7caf17be5c170fb0
    local     juming-nginx
    # 查看具名卷在配置路径
    [root@localhost data]# docker volume inspect juming-nginx
    [
        {
            "CreatedAt": "2021-12-18T18:45:24+08:00",
            "Driver": "local",
            "Labels": null,
            "Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",
            "Name": "juming-nginx",
            "Options": null,
            "Scope": "local"
        }
    ]
    

    小贴士:所有的Docker容器内的卷,在没有指定目录的情况下都是在 /var/lib/docker/volumes/卷名称/_data/ 路径下

只读和可读可写权限

在 -v 可选参数后面追加 :ro / :rw ,可以改变读写权限。
:ro,readonly即只读权限,说明这个路径只能通过宿主机来操作,容器内部是无法操作的
:rw,readwrite即可读可写权限,默认就是它

# 一旦设置了容器权限,容器对我们挂载出来的内容就是限定的了
[root@localhost data]# docker run -d -p 80:80 --name Nginx_JM -v juming-nginx:/ect/nginx:ro nginx
[root@localhost data]# docker run -d -p 80:80 --name Nginx_JM -v juming-nginx:/ect/nginx:rw nginx

多个容器间数据如何同步?

通过容器数据卷就可以实现同步多个容器间的数据。
【狂神说Java】Docker最新超详细版教程通俗易懂 - 学习笔记_第6张图片
实操示例:下面我们在创建两个 centos 容器,并对两个容器建立数据卷共享关系。

  1. 新创建一个 centos_01 容器,并进行指定路径挂载

    [root@localhost ~]# docker run -it --name centos_01 -v /webapp:/webapp centos
    # 此时在 centos_01 容器或者宿主机容器的 /webapp 目录新建文件,两者都会自动同步
    
  2. 通过 --volumes-from 可选参数,与 centos_01 容器建立容器数据卷挂载关系

    [root@localhost ~]# docker run -it --name centos_02 --volumes-from centos_01 centos
    # 创建好 centos_02 容器以后,发现 /webapp 目录中的内容与 centos_01 容器、宿主机容器中的 /webapp 目录的内容相同
    
  3. 删除 centos_01 容器,然后进入 centos_02 看看数据卷中的内容还是否存在

    [root@localhost volumes]# docker rm -f centos_01
    [root@localhost volumes]# docker exec -it centos_02 /bin/bash
    [root@3c9e9153aa30 /]# cd /webapp/ && ls
    wangxf.java
    

数据卷小结

容器之间数据卷的生命周期一直持续到没有容器使用为止。但是如果你的数据卷中的数据持久化到本地后,本地数据是不会删除的。

Dockerfile

什么是Dockerfile?

Dockerfile就是用来构建Docker镜像的脚本文件,实际上就是一个命令脚本。通过这个脚本就可以生成镜像,镜像是一层一层的,那么脚本中的每个命令都是一层。
【狂神说Java】Docker最新超详细版教程通俗易懂 - 学习笔记_第7张图片
Dockerfile是面向开发者的,发布项目时需要做成镜像,那么就需要编写 Dockerfile 脚本文件。涉及如下几个关键点:

  1. Dockerfile:构建文件,定义了一切的构建步骤,源代码。—— 开发
  2. DockerImages:通过 Dockerfile 构建生成的镜像,最终发布和运行的产品。—— 部署
  3. Docker容器:就是运行起来的镜像,对外提供服务。—— 运维

Dockerfile的基本语法

  1. 每个指令(保留关键字)都必须是大写字母
  2. 指令从上到下顺序执行
  3. # 表示注释
  4. 每个指令都会创建提交一个新的镜像层

通过 Dockerfile 构建 Docker 镜像的步骤

  1. 编写一个 Dockerfile 脚本
  2. 使用 docker build 命令构建成一个镜像
  3. 使用 docker run 命令运行镜像
  4. 使用 docker push 发布镜像到镜像仓库(DockerHub、阿里云镜像仓库)

Dockerfile的指令

  • 指令说明

    FROM			# 指定基础镜像,一切都要基于这个开始
    MAINTAINER		# 镜像是谁写的,姓名+邮箱(通用标准)
    RUN				# 镜像构建时需要运行的命令
    ADD				# 将本地文件添加到容器中,tar类型文件会自动解压(网络压缩资源不会被解压),可以访问网络资源
    WORKDIR			# 镜像的工作目录
    VOLUME			# 挂载的目录
    EXPOSE			# 对外暴露的端口
    CMD				# 指定这个容器启动的时候要运行的命令(只有最后一个会生效)
    ENTRYPOINT		# 指定这个容器启动的时候要运行的命令,可以追加命令
    ONBUILD			# 当构建一个被继承DockerFile,这个时候就会运行ONBUILD的指令,触发指令
    COPY			# 功能类似ADD,但是是不会自动解压文件,也不能访问网络资源
    ENV				# 构建的时候设置环境变量 
    
  • 实操练习,实现一个自己的 centos 容器

  1. 首先编写一个 Dockerfile 脚本文件,内容如下:

    [root@localhost dockerfile]# vim mydockerfile-centos
    FROM centos
    MAINTAINER wangxf<912309845@qq.com>
    
    ENV MYPATH /usr/local
    WORKDIR $MYPATH 
    
    RUN yum -y install vim            # 安装vim工具
    RUN yum -y install net-tools      # 安装网络基础包
    
    EXPOSE 80
    
    CMD echo $MYPATH
    CMD echo "--- END ---"
    CMD /bin/bash
    
  2. 通过 Dockerfile 脚本构建镜像文件
    命令: docker build -f dockerfile文件路径 -t 镜像名:[TAG] . ,注意最后的点

    [root@localhost dockerfile]# docker build -f mydockerfile-centos -t mycentos:0.1 .
    [root@localhost dockerfile]# docker images
    REPOSITORY            TAG       IMAGE ID       CREATED          SIZE
    mycentos              0.1       9f12990cd386   20 seconds ago   322MB
    

    修改镜像TAG

    [root@localhost dockerfile]# docker tag 9f12990cd386 mycentos:0.2
    
  3. 测试运行

    # 运行容器
    [root@localhost dockerfile]# docker run -it mycentos:0.1
    # 运行容器后,自动进入到 /usr/local 目录
    [root@6eb7f871b213 local]# pwd
    /usr/local
    # 看看我们安装的网络基础包是否生效了
    [root@6eb7f871b213 local]# ifconfig
    eth0: flags=4163,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        其他内容省略……
    
  4. 查看镜像的变更历史

    [root@localhost dockerfile]# docker history 9f12990cd386
    IMAGE          CREATED          CREATED BY                                      SIZE      COMMENT
    9f12990cd386   14 minutes ago   /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "/bin…   0B        
    7e99c710a5d5   14 minutes ago   /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "echo…   0B        
    ae48ddb633e8   14 minutes ago   /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "echo…   0B        
    7079d2482219   14 minutes ago   /bin/sh -c #(nop)  EXPOSE 80                    0B        
    5e2d68b08b92   14 minutes ago   /bin/sh -c yum -y install net-tools             27MB      
    ecf92b08e7bf   14 minutes ago   /bin/sh -c yum -y install vim                   64.1MB    
    63e10164af59   15 minutes ago   /bin/sh -c #(nop) WORKDIR /usr/local            0B        
    1910d234fba0   15 minutes ago   /bin/sh -c #(nop)  ENV MYPATH=/usr/local        0B        
    a7f48ed49a91   15 minutes ago   /bin/sh -c #(nop)  MAINTAINER wangxf<9123098…   0B        
    5d0da3dc9764   3 months ago     /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B        
          3 months ago     /bin/sh -c #(nop)  LABEL org.label-schema.sc…   0B        
          3 months ago     /bin/sh -c #(nop) ADD file:805cb5e15fb6e0bb0…   231MB    
    
  • 实操练习,实现一个Tomcat镜像
  1. 准备镜像文件,Tomcat压缩包,JDK压缩包

    # 为了跳过Oracle对其资源的下载限制,JDK下载需要设置请求头信息
    [root@localhost dockerfile]# wget --no-check-certificate -c --header="Cookie: oraclelicense=accept-securebackup-cookie" \
                                    http://download.oracle.com/otn-pub/java/jdk/8u131-b11/d54c1d3a095b4ff2b6607d096fa80163/jdk-8u131-linux-x64.tar.gz
    # Tomcat下载
    [root@localhost dockerfile]# wget https://archive.apache.org/dist/tomcat/tomcat-8/v8.0.23/bin/apache-tomcat-8.0.23.tar.gz
    [root@localhost dockerfile]# ls
    apache-tomcat-8.0.23.tar.gz  jdk-8u131-linux-x64.tar.gz
    
  2. 编写 Dockerfile 脚本文件,文件名建议使用官方命名:Dockerfile ,这样在 docker build 时会默认寻找当前目录下的文件,不需要使用 -f 参数进行指定了。

    FROM centos
    MAINTAINER wangxf<912309845@qq.com>
    
    COPY readme.txt /usr/local/readme.txt
    
    ADD jdk-8u311-linux-x64.tar.gz /usr/local/
    ADD apache-tomcat-8.0.23.tar.gz /usr/local/
    
    RUN yum -y install vim
    
    ENV MYPATH /usr/local
    WORKDIR $MYPATH
    
    ENV JAVA_HOME /usr/local/jdk1.8.0_311
    ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
    ENV CATALINA_HOME /usr/local/apache-tomcat-8.0.23
    ENV CATALINA_BASH /usr/local/apache-tomcat-8.0.23
    ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
    
    EXPOSE 8080
    
    CMD /usr/local/apache-tomcat-8.0.23/bin/startup.sh && tail -F /usr/local/apache-tomcat-8.0.23/logs/catalina.out
    
  3. 构建镜像

    [root@localhost dockerfile]# docker build -t diytomcat:1.0 .
    
  4. 启动镜像

    [root@localhost dockerfile]# docker run -d -p 9090:8080 --name diytomcat \
        -v /home/dockerfile/tomcat/webapps/test:/usr/local/apache-tomcat-8.0.23/webapps/test \
        -v /home/dockerfile/tomcat/logs:/usr/local/apache-tomcat-8.0.23/logs \
        diytomcat:1.0
    
  5. 测试访问:http://your_ip:9090/

  6. 发布项目,我们在本地挂载的数据卷中进行项目发布,发布后访问http://your_ip:9090/test

    [root@localhost dockerfile]# cd /home/dockerfile/tomcat/webapps/test
    [root@localhost test]# cat index.jsp 
    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    
    
    "utf-8">
    Hello World<<span class="token operator">/</span>title>
    <<span class="token operator">/</span>head>
    <body>
    Hello World!<br/>
    <<span class="token operator">%</span> out<span class="token punctuation">.</span>println<span class="token punctuation">(</span><span class="token string">"你的 IP 地址 "</span> <span class="token operator">+</span> request<span class="token punctuation">.</span>getRemoteAddr<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token operator">%</span>>
    <<span class="token operator">/</span>body>
    <<span class="token operator">/</span>html>
    </code></pre> </li> 
      </ol> 
      <h3>发布自己的镜像</h3> 
      <p>参考官方文档:容器镜像服务</p> 
      <h3>Dockerfile小结</h3> 
      <p><a href="http://img.e-com-net.com/image/info8/2ed79210976047e0be1505260226c5e0.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/2ed79210976047e0be1505260226c5e0.jpg" alt="【狂神说Java】Docker最新超详细版教程通俗易懂 - 学习笔记_第8张图片" width="650" height="389" style="border:1px solid black;"></a></p> 
      <h2>Docker网络原理</h2> 
      <h3>Docker的网络模式</h3> 
      <p>安装Docker的时候,它会自动创建四个网络:bridge(创建容器默认连接到此网络),host,container,none。在Docker 1.9版本以后新增了用户自定义网络模式</p> 
      <ul> 
       <li>bridge模式(即 <code>--net=bridge</code>),这是Dokcer网络的默认设置,为容器创建独立的网络命名空间,容器具有独立的网卡等所有单独的网络栈,是最常用的使用方式。 在 docker run 启动容器的时候,如果不加 --net 参数,就默认采用这种网络模式。安装完 Docker,系统会自动添加一个供 Docker 使用的网桥 docker0,我们创建一个新的容器时, 容器通过 DHCP 获取一个与 docker0 同网段的IP地址,并默认连接到 docker0 网桥,以此实现容器与宿主机的网络互通。</li> 
       <li>host模式(即 <code>--net=host</code>), 这个模式下创建出来的容器,直接使用容器宿主机的网络命名空间。 将不拥有自己独立的 Network Namespace,即没有独立的网络环境。它使用宿主机的ip和端口。</li> 
       <li>container模式(即 <code>--net=container:name OR id</code>), 与host模式类似,只是容器将与指定的容器共享网络命名空间。 这个模式就是指定一个已有的容器,共享该容器的IP和端口。除了网络方面两个容器共享,其他的如文件系统,进程等还是隔离开的。</li> 
       <li>none模式(即 <code>--net=none</code>), 为容器创建独立网络命名空间,但不为它做任何网络配置,容器中只有lo,用户可以在此基础上,对容器网络做任意定制。 这个模式下,Dokcer不为容器进行任何网络配置。需要我们自己为容器添加网卡,配置IP。</li> 
       <li>自定义模式:允许容器使用第三方的网络实现或者创建单独的 bridge 网络,提供网络隔离能力。</li> 
      </ul> 
      <h3>理解Docker网络(docker0)</h3> 
      <p>安装 Docker 以后,宿主机会自动配置一个虚拟的网桥叫 docker0,并且 Docker 会在私有 IP 网段中,选择一个和宿主机不同的IP地址和子网分配给 docker0,例如将 172.17.0.1/16 分配给 docker0 网桥 。<br> 一般情况下,使用 Docker 创建一个容器的时候,都会自动创建一对虚拟的网络接口(叫做veth-pair),分别放在宿主机和新容器中,这就是连接各种虚拟网络设备的桥梁。宿主机一端的虚拟接口(即veth)会连接到 docker0 网桥上;而容器一端的虚拟接口(即eth0)只能在该容器内可见,并且会从网桥可用地址段中获取一个空闲地址分配给该容器(例如172.17.0.2/16)。通过这种方式,宿主机可以跟容器通信,容器之间也可以相互通信。Docker 就创建了在宿主机和所有容器之间一个虚拟共享网络。当然用户也可以通过 docker network 命令来手动管理网络。<br> <a href="http://img.e-com-net.com/image/info8/5b5ef91427a24bf9a1069c68ed47b384.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/5b5ef91427a24bf9a1069c68ed47b384.jpg" alt="【狂神说Java】Docker最新超详细版教程通俗易懂 - 学习笔记_第9张图片" width="650" height="511" style="border:1px solid black;"></a></p> 
      <p>docker0 可以通过宿主机的 <code>ip addr</code> 命令进行查看:<br> <a href="http://img.e-com-net.com/image/info8/cf6f30892f194236a9a668f4fe295fe6.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/cf6f30892f194236a9a668f4fe295fe6.jpg" alt="【狂神说Java】Docker最新超详细版教程通俗易懂 - 学习笔记_第10张图片" width="650" height="188" style="border:1px solid black;"></a><br> Docker中的网络接口默认都是虚拟的接口。虚拟接口的最大优势就是转发效率极高。这是因为Linux在内核中通过数据复制实现虚拟接口之间的数据转发,即发送接口的发送缓存中的数据包将被直接复制到接收接口的接收缓存中,而无需通过外部物理网络设备进行交换。需要注意的是,当我们删除一个容器后,该容器对应的虚拟网络接口也会随之删除。</p> 
      <h3>容器互联</h3> 
      <p>在微服务部署的场景下,注册中心是使用服务名来唯一识别微服务的,而我们上线部署的时候微服务对应的IP地址可能会改动,所以我们需要使用容器名来配置容器间的网络连接。使用 --link 可以实现这个功能。</p> 
      <ul> 
       <li> <p>–link<br> 使用 --link 实现容器互联</p> <pre><code class="prism language-powershell"><span class="token comment"># 启动 tomcat01</span>
    <span class="token namespace">[root@localhost ~]</span><span class="token comment"># docker run -d -P --name tomcat01 tomcat:8.0.20</span>
    <span class="token comment"># 启动 tomcat02,通过 --link 连接到 tomcat01</span>
    <span class="token namespace">[root@localhost ~]</span><span class="token comment"># docker run -d -P --name tomcat02 --link tomcat01 tomcat:8.0.20</span>
    <span class="token comment"># 进入tomcat02,ping tomcat01</span>
    <span class="token namespace">[root@localhost ~]</span><span class="token comment"># docker exec -it tomcat02 ping tomcat01</span>
    PING tomcat01 <span class="token punctuation">(</span>172<span class="token punctuation">.</span>17<span class="token punctuation">.</span>0<span class="token punctuation">.</span>1<span class="token punctuation">)</span> 56<span class="token punctuation">(</span>84<span class="token punctuation">)</span> bytes of <span class="token keyword">data</span><span class="token punctuation">.</span>
    64 bytes <span class="token keyword">from</span> tomcat01 <span class="token punctuation">(</span>172<span class="token punctuation">.</span>17<span class="token punctuation">.</span>0<span class="token punctuation">.</span>1<span class="token punctuation">)</span> : icmp_seq=1 ttl=64 time=0<span class="token punctuation">.</span>037 ms
    64 bytes <span class="token keyword">from</span> tomcat01 <span class="token punctuation">(</span>172<span class="token punctuation">.</span>17<span class="token punctuation">.</span>0<span class="token punctuation">.</span>1<span class="token punctuation">)</span> : icmp_seq=2 ttl=64 time=0<span class="token punctuation">.</span>037 ms
    64 bytes <span class="token keyword">from</span> tomcat01 <span class="token punctuation">(</span>172<span class="token punctuation">.</span>17<span class="token punctuation">.</span>0<span class="token punctuation">.</span>1<span class="token punctuation">)</span> : icmp_seq=3 ttl=64 time=0<span class="token punctuation">.</span>039 ms
    </code></pre> 
        <blockquote> 
         <p>–link 的网络原理<br> 其网络通信原理是在容器中配置 host,即在指定容器的 /etc/hosts 文件中添加容器名和 IP 地址映射。所以通过 --link 建立的网络连接是单向的,若容器 A 与容器 B 建立了一条网络连接,只能从 A 向 B 通信,反之则不可。<br> 目前 --link 设置容器互连的方式已经不推荐使用。更多地选择自定义网络。</p> 
        </blockquote> </li> 
       <li> <p>自定义网络<br> 我们可以通过 <code>docker network create <Option> <NetworkName></code> 命令来创建一个自定义网络。命令说明:</p> <pre><code class="prism language-powershell">docker network create <Option> <NetworkName>
    <span class="token comment"># 可选参数</span>
    <span class="token operator">--</span>config-<span class="token keyword">from</span> 复制其他网络配置
    <span class="token operator">--</span>driver 指定网络模式
    <span class="token operator">--</span>gateway 指定网关,所有的请求都要经过它
    <span class="token operator">--</span>internal 限制只能内部访问
    <span class="token operator">--</span>ip-range 从子网范围分配容器IP
    <span class="token operator">--</span>ipv6 启用IPv6网络
    <span class="token operator">--</span>subnet 指定网段
    </code></pre> </li> 
      </ul> 
      <ol> 
       <li> <p>创建一个自定义网络</p> <pre><code class="prism language-powershell"><span class="token comment"># 创建一个名叫 mynet 的网络,它的网络模式是 桥接(bridge),网段是 192.168.0.0/16,网关是 192.168.0.1</span>
    <span class="token namespace">[root@localhost ~]</span><span class="token comment"># docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet</span>
    <span class="token comment"># 网络列表</span>
    <span class="token namespace">[root@localhost ~]</span><span class="token comment"># docker network ls</span>
    NETWORK ID     NAME      DRIVER    SCOPE
    51604e1eac75   bridge    bridge    local
    9182708c0a34   host      host      local
    2c61a06248d3   mynet     bridge    local
    895dbec7357c   none      null      local
    </code></pre> </li> 
       <li> <p>查看自定义的网络信息</p> <pre><code class="prism language-powershell"><span class="token namespace">[root@localhost ~]</span><span class="token comment"># docker network inspect mynet</span>
    </code></pre> <p>网络创建好以后,我们就可以把创建的服务放到自己创建的网络当中。</p> </li> 
       <li> <p>使用自定义网络<br> 现在我们就可以启动容器,并让他们使用自定义网络了。如下,我启动两个Tomcat容器。</p> <pre><code class="prism language-powershell"><span class="token namespace">[root@localhost ~]</span><span class="token comment"># docker run -it --name tomcat-net-01 --net mynet tomcat:8.0.20 </span>
    <span class="token namespace">[root@localhost ~]</span><span class="token comment"># docker run -it --name tomcat-net-01 --net mynet tomcat:8.0.20 </span>
    </code></pre> <p>此时,再看看我们的自定义网络,会发现网络中多了两个容器信息。<br> <a href="http://img.e-com-net.com/image/info8/80e0e9414229451bbad6e8fc488f48d2.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/80e0e9414229451bbad6e8fc488f48d2.jpg" alt="【狂神说Java】Docker最新超详细版教程通俗易懂 - 学习笔记_第11张图片" width="650" height="499" style="border:1px solid black;"></a><br> 现在我们在 tomcat-net-01 中直接 <code>ping tomcat-net-02</code> 就可以直接连通。</p> </li> 
       <li> <p>自定义网络的好处<br> ✓ 自定义网络默认支持 ping 容器名<br> ✓ 可以使不同的集群使用不同的网络,保证集群是安全健康的</p> </li> 
      </ol> 
      <ul> 
       <li> <p>网络连通<br> 完成自定义网络后,我们如何实现不同网络间的容器网络连接呢?也就是说,在两个不同的网络间实现网络互通,即 docker0 和 mynet自定义网络 建立网络连接。<br> <a href="http://img.e-com-net.com/image/info8/c06fe4a8f1aa45e79eb154040582535d.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/c06fe4a8f1aa45e79eb154040582535d.jpg" alt="【狂神说Java】Docker最新超详细版教程通俗易懂 - 学习笔记_第12张图片" width="523" height="256" style="border:1px solid black;"></a><br> 这时我们可以通过 <code>docker network connect [Options] NetworkName ContainerName</code> 命令打通不同网络之间的容器连接。</p> <pre><code class="prism language-powershell"><span class="token comment"># 建立网络连接</span>
    <span class="token namespace">[root@localhost ~]</span><span class="token comment"># docker network connect mynet tomcat01</span>
    <span class="token comment"># 查看网络信息</span>
    <span class="token namespace">[root@localhost ~]</span><span class="token comment"># docker network inspect mynet</span>
    <span class="token comment"># 验证网络是否打通了</span>
    <span class="token namespace">[root@localhost ~]</span><span class="token comment"># docker exec -it tomcat01 ping tomcat-net-01</span>
    PING centos-net-01 <span class="token punctuation">(</span>192<span class="token punctuation">.</span>168<span class="token punctuation">.</span>0<span class="token punctuation">.</span>3<span class="token punctuation">)</span>: 56 <span class="token keyword">data</span> bytes
    64 bytes <span class="token keyword">from</span> 192<span class="token punctuation">.</span>168<span class="token punctuation">.</span>0<span class="token punctuation">.</span>3: icmp_seq=0 ttl=64 time=0<span class="token punctuation">.</span>086 ms
    64 bytes <span class="token keyword">from</span> 192<span class="token punctuation">.</span>168<span class="token punctuation">.</span>0<span class="token punctuation">.</span>3: icmp_seq=1 ttl=64 time=0<span class="token punctuation">.</span>205 ms
    64 bytes <span class="token keyword">from</span> 192<span class="token punctuation">.</span>168<span class="token punctuation">.</span>0<span class="token punctuation">.</span>3: icmp_seq=2 ttl=64 time=0<span class="token punctuation">.</span>242 ms
    64 bytes <span class="token keyword">from</span> 192<span class="token punctuation">.</span>168<span class="token punctuation">.</span>0<span class="token punctuation">.</span>3: icmp_seq=3 ttl=64 time=0<span class="token punctuation">.</span>086 ms
    <span class="token comment"># 但是此时 tomcat02 是连不通的,因为 tomcat02 与 mynet 还没有建立网络连接</span>
    <span class="token namespace">[root@localhost ~]</span><span class="token comment"># docker exec -it tomcat02 ping centos-net-01 </span>
    ping: unknown host
    </code></pre> <p>结论:假设要跨网络操作别人,首先需要使用 <code>docker network connect</code> 来实现网络连通!</p> </li> 
      </ul> 
      <h2>Docker Compose</h2> 
      <h3>Docker Compose是什么?</h3> 
      <p>Docker Compose 是对 Docker 容器进行编排的工具,定义和运行多容器的应用,可以一条命令启动多个容器。<br> 使用三部曲:</p> 
      <ol> 
       <li>Dockerfile 定义应用的运行环境</li> 
       <li>docker-compose.yml 定义组成应用的各服务,服务编排</li> 
       <li><code>docker-compose up</code> 启动整个应用</li> 
      </ol> 
      <h3>安装 Docker Compose</h3> 
      <pre><code class="prism language-powershell"><span class="token comment"># 下载 docker-compose,你可以通过修改URL中的版本,可以自定义您的需要的版本</span>
    <span class="token namespace">[root@localhost ~]</span><span class="token comment"># curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.5/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose </span>
    <span class="token comment"># 修改可执行权限</span>
    <span class="token namespace">[root@localhost ~]</span><span class="token comment"># chmod +x /usr/local/bin/docker-compose</span>
    <span class="token comment"># 查看版本,安装成功</span>
    <span class="token namespace">[root@localhost bin]</span><span class="token comment"># docker-compose -version </span>
    docker-compose version 1<span class="token punctuation">.</span>25<span class="token punctuation">.</span>5<span class="token punctuation">,</span> build 8a1c60f6
    </code></pre> 
      <h3>Docker Compose 常用命令</h3> 
      <pre><code class="prism language-powershell"><span class="token comment"># 默认使用docker-compose.yml构建镜像</span>
    <span class="token namespace">[root@localhost ~]</span><span class="token comment"># docker-compose build</span>
    <span class="token namespace">[root@localhost ~]</span><span class="token comment"># docker-compose build --no-cache</span>
    <span class="token comment"># 指定不同yml文件模板用于构建镜像</span>
    <span class="token namespace">[root@localhost ~]</span><span class="token comment"># docker-compose build -f docker-compose-1.yml</span>
    
    <span class="token comment"># 列出Compose文件构建的镜像</span>
    <span class="token namespace">[root@localhost ~]</span><span class="token comment"># docker-compose images                          </span>
    
    <span class="token comment"># 启动所有编排容器服务,该命令十分强大,它将尝试自动完成包括构建镜像,(重新)创建服务,启动服务,并关联服务相关容器的一系列操作。</span>
    <span class="token namespace">[root@localhost ~]</span><span class="token comment"># docker-compose up -d</span>
    
    <span class="token comment"># 查看正在运行中的容器</span>
    <span class="token namespace">[root@localhost ~]</span><span class="token comment"># docker-compose ps </span>
    <span class="token comment"># 查看所有编排容器,包括已停止的容器</span>
    <span class="token namespace">[root@localhost ~]</span><span class="token comment"># docker-compose ps -a</span>
    <span class="token comment"># 停止 up 命令所启动的容器,并移除网络</span>
    <span class="token namespace">[root@localhost ~]</span><span class="token comment"># docker-compose down</span>
    
    <span class="token comment"># 进入指定容器执行命令</span>
    <span class="token namespace">[root@localhost ~]</span><span class="token comment"># docker-compose exec nginx bash </span>
    <span class="token namespace">[root@localhost ~]</span><span class="token comment"># docker-compose exec web python manage.py migrate --noinput</span>
    
    <span class="token comment"># 查看web容器的实时日志</span>
    <span class="token namespace">[root@localhost ~]</span><span class="token comment"># docker-compose logs -f web</span>
     
    <span class="token comment"># 启动已经存在的服务容器</span>
    <span class="token namespace">[root@localhost ~]</span><span class="token comment"># docker-compose start</span>
    <span class="token comment"># 停止已经处于运行状态的容器,但不删除它,可以再次重启</span>
    <span class="token namespace">[root@localhost ~]</span><span class="token comment"># docker-compose stop</span>
    <span class="token comment"># 重新启动停止服务的容器</span>
    <span class="token namespace">[root@localhost ~]</span><span class="token comment"># docker-compose restart web</span>
    
    <span class="token comment"># 暂停web容器</span>
    <span class="token namespace">[root@localhost ~]</span><span class="token comment"># docker-compose pause web</span>
    <span class="token comment"># 恢复web容器</span>
    <span class="token namespace">[root@localhost ~]</span><span class="token comment"># docker-compose unpause web</span>
    
    <span class="token comment"># 删除web容器,删除前必需停止stop web容器服务</span>
    <span class="token namespace">[root@localhost ~]</span><span class="token comment"># docker-compose rm web  </span>
    
    <span class="token comment"># 查看各个服务容器内运行的进程 </span>
    <span class="token namespace">[root@localhost ~]</span><span class="token comment"># docker-compose top  </span>
    </code></pre> 
      <h3>Docker Compose 配置编写规则</h3> 
      <pre><code class="prism language-powershell"><span class="token comment"># 版本号</span>
    version: <span class="token string">"3"</span>
    <span class="token comment"># 服务</span>
    services:
     <span class="token comment"># 服务名称</span>
      redis:
       <span class="token comment"># 镜像名: 仓库/标签:版本</span>
        image: redis:alpine
       <span class="token comment"># 暴露端口信息</span>
        ports:
          <span class="token operator">-</span> <span class="token string">"6379"</span>
       <span class="token comment"># 添加环境变量.可以使用数组或字典两种形式</span>
       <span class="token comment"># 任何布尔值:true, false, yes, no 需要用引号括起来,以确保它们不被YAML解析器转换为True或False </span>
        environment:
      db:
        image: postgres:9<span class="token punctuation">.</span>4
        <span class="token comment"># 定义全局挂载卷</span>
        volumes:
          <span class="token operator">-</span> db-<span class="token keyword">data</span>:<span class="token operator">/</span><span class="token keyword">var</span><span class="token operator">/</span>lib/postgresql/<span class="token keyword">data</span>
        networks:
          <span class="token operator">-</span> backend
        deploy:
          placement:
            constraints: <span class="token namespace">[node.role == manager]</span>
    </code></pre> 
      <h3>使用 Docker Compose 一键部署WordPress博客</h3> 
      <pre><code class="prism language-powershell"><span class="token comment"># 创建一个新的项目目录</span>
    <span class="token namespace">[root@localhost home]</span><span class="token comment"># mkdir wp_compose</span>
    <span class="token comment"># 进入到项目目录</span>
    <span class="token namespace">[root@localhost home]</span><span class="token comment"># cd wp_compose</span>
    <span class="token comment"># 创建 docker-compose.yml 文件,编排你的服务,主要内容包括WordPress博客和一个单独的MySQL实例卷挂载数据持久化</span>
    <span class="token namespace">[root@localhost wp_compose]</span><span class="token comment"># vim docker-compose.yml</span>
    version: <span class="token string">"3.3"</span>
    services:
      db:
        image: mysql:5<span class="token punctuation">.</span>7
        volumes:
          <span class="token operator">-</span> db_data:<span class="token operator">/</span><span class="token keyword">var</span><span class="token operator">/</span>lib/mysql
        restart: always
        environment:
          MYSQL_ROOT_PASSWORD: somewordpress
          MYSQL_DATABASE: wordpress
          MYSQL_USER: wordpress
          MYSQL_PASSWORD: wordpress
      wordpress:
        depends_on:
          <span class="token operator">-</span> db
        image: wordpress:latest
        volumes:
          <span class="token operator">-</span> wordpress_data:<span class="token operator">/</span><span class="token keyword">var</span><span class="token operator">/</span>www/html
        ports:
          <span class="token operator">-</span> <span class="token string">"8000:80"</span>
        restart: always
        environment:
          WORDPRESS_DB_HOST: db
          WORDPRESS_DB_USER: wordpress
          WORDPRESS_DB_PASSWORD: wordpress
          WORDPRESS_DB_NAME: wordpress
    volumes:
      db_data: <span class="token punctuation">{</span><span class="token punctuation">}</span>
      wordpress_data: <span class="token punctuation">{</span><span class="token punctuation">}</span>
    
    <span class="token comment"># 启动博客项目</span>
    <span class="token namespace">[root@localhost home]</span><span class="token comment"># docker-compose up -d</span>
    <span class="token comment"># 预览效果</span>
    http:<span class="token operator">/</span><span class="token operator">/</span>your_ip:8000/
    </code></pre> 
      <hr> 
      <p><a href="http://img.e-com-net.com/image/info8/df619e7868e64204b5bf06752e380860.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/df619e7868e64204b5bf06752e380860.jpg" alt="在这里插入图片描述" width="371" height="95"></a><br> 欢迎关注我的个人公众号:小瓦匠学编程,优质好文不错过!扫描二维码或微信搜索 “小瓦匠学编程” 即可关注。</p> 
      <p>(本文完)</p> 
     </div> 
    </div>
                                </div>
                            </div>
                        </div>
                        <!--PC和WAP自适应版-->
                        <div id="SOHUCS" sid="1752517920442826752"></div>
                        <script type="text/javascript" src="/views/front/js/chanyan.js"></script>
                        <!-- 文章页-底部 动态广告位 -->
                        <div class="youdao-fixed-ad" id="detail_ad_bottom"></div>
                    </div>
                    <div class="col-md-3">
                        <div class="row" id="ad">
                            <!-- 文章页-右侧1 动态广告位 -->
                            <div id="right-1" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad">
                                <div class="youdao-fixed-ad" id="detail_ad_1"> </div>
                            </div>
                            <!-- 文章页-右侧2 动态广告位 -->
                            <div id="right-2" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad">
                                <div class="youdao-fixed-ad" id="detail_ad_2"></div>
                            </div>
                            <!-- 文章页-右侧3 动态广告位 -->
                            <div id="right-3" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad">
                                <div class="youdao-fixed-ad" id="detail_ad_3"></div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <div class="container">
            <h4 class="pt20 mb15 mt0 border-top">你可能感兴趣的:(Docker,docker,容器,java)</h4>
            <div id="paradigm-article-related">
                <div class="recommend-post mb30">
                    <ul class="widget-links">
                        <li><a href="/article/1943993659481452544.htm"
                               title="guava loadingCache代码示例" target="_blank">guava loadingCache代码示例</a>
                            <span class="text-muted">IM 胡鹏飞</span>
    <a class="tag" taget="_blank" href="/search/Java/1.htm">Java</a><a class="tag" taget="_blank" href="/search/%E5%B7%A5%E5%85%B7%E7%B1%BB%E4%BB%8B%E7%BB%8D/1.htm">工具类介绍</a>
                            <div>publicclassTest2{publicstaticvoidmain(String[]args)throwsException{LoadingCachecache=CacheBuilder.newBuilder()//设置并发级别为8,并发级别是指可以同时写缓存的线程数.concurrencyLevel(8)//设置缓存容器的初始容量为10.initialCapacity(10)//设置缓存</div>
                        </li>
                        <li><a href="/article/1943992018892025856.htm"
                               title="JSON 与 AJAX" target="_blank">JSON 与 AJAX</a>
                            <span class="text-muted">Auscy</span>
    <a class="tag" taget="_blank" href="/search/json/1.htm">json</a><a class="tag" taget="_blank" href="/search/ajax/1.htm">ajax</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a>
                            <div>一、JSON(JavaScriptObjectNotation)1.数据类型与语法细节支持的数据类型:基本类型:字符串(需用双引号)、数字、布尔值(true/false)、null。复杂类型:数组([])、对象({})。严格语法规范:键名必须用双引号包裹(如"name":"张三")。数组元素用逗号分隔,最后一个元素后不能有多余逗号。数字不能以0开头(如012会被解析为12),不支持八进制/十六进制</div>
                        </li>
                        <li><a href="/article/1943990125864218624.htm"
                               title="JavaScript 树形菜单总结" target="_blank">JavaScript 树形菜单总结</a>
                            <span class="text-muted">Auscy</span>
    <a class="tag" taget="_blank" href="/search/microsoft/1.htm">microsoft</a>
                            <div>树形菜单是前端开发中常见的交互组件,用于展示具有层级关系的数据(如文件目录、分类列表、组织架构等)。以下从核心概念、实现方式、常见功能及优化方向等方面进行总结。一、核心概念层级结构:数据以父子嵌套形式存在,如{id:1,children:[{id:2}]}。节点:树形结构的基本单元,包含自身信息及子节点(若有)。展开/折叠:子节点的显示与隐藏切换,是树形菜单的核心交互。递归渲染:因数据层级不固定,</div>
                        </li>
                        <li><a href="/article/1943987101301272576.htm"
                               title="精通Canvas:15款时钟特效代码实现指南" target="_blank">精通Canvas:15款时钟特效代码实现指南</a>
                            <span class="text-muted">烟幕缭绕</span>
    
                            <div>本文还有配套的精品资源,点击获取简介:HTML5的Canvas是一个用于绘制矢量图形的API,通过JavaScript实现动态效果。本项目集合了15种不同的时钟特效代码,帮助开发者通过学习绘制圆形、线条、时间更新、旋转、颜色样式设置及动画效果等概念,深化对Canvas的理解和应用。项目中的CSS文件负责时钟的样式设定,而JS文件则包含实现各种特效的逻辑,通过不同的函数或类处理时间更新和动画绘制,提</div>
                        </li>
                        <li><a href="/article/1943986344934043648.htm"
                               title="深入剖析OpenJDK 18 GA源码:Java平台最新发展" target="_blank">深入剖析OpenJDK 18 GA源码:Java平台最新发展</a>
                            <span class="text-muted">想法臃肿</span>
    
                            <div>本文还有配套的精品资源,点击获取简介:OpenJDK18GA作为Java开发的关键里程碑,提供了诸多新特性和改进。本文章深入探讨了OpenJDK18GA源码,揭示其内部机制,帮助开发者更好地理解和利用这个版本。文章还涵盖了PatternMatching、SealedClasses、Records、JEP395、JEP406和JEP407等特性,以及HotSpot虚拟机、编译器、垃圾收集器、内存模型</div>
                        </li>
                        <li><a href="/article/1943985462716723200.htm"
                               title="docker-compose方式搭建lnmp环境——筑梦之路" target="_blank">docker-compose方式搭建lnmp环境——筑梦之路</a>
                            <span class="text-muted">筑梦之路</span>
    <a class="tag" taget="_blank" href="/search/linux%E7%B3%BB%E7%BB%9F%E8%BF%90%E7%BB%B4/1.htm">linux系统运维</a><a class="tag" taget="_blank" href="/search/%E5%9B%BD%E4%BA%A7%E5%8C%96/1.htm">国产化</a><a class="tag" taget="_blank" href="/search/docker/1.htm">docker</a><a class="tag" taget="_blank" href="/search/android/1.htm">android</a><a class="tag" taget="_blank" href="/search/adb/1.htm">adb</a>
                            <div>docker-compose.yml文件#生成docker-compose.ymlcat>docker-compose.ymlnginx/conf.d/default.conf">www/index.phpecho"开始启动服务..."docker-composeup-d#获取本机ipip_addr=$(hostname-I|awk'{print$1}')echo"部署完成!"echo"访问测试页</div>
                        </li>
                        <li><a href="/article/1943983444027568128.htm"
                               title="Java大厂面试实录:谢飞机的电商场景技术问答(Spring Cloud、MyBatis、Redis、Kafka、AI等)" target="_blank">Java大厂面试实录:谢飞机的电商场景技术问答(Spring Cloud、MyBatis、Redis、Kafka、AI等)</a>
                            <span class="text-muted"></span>
    
                            <div>Java大厂面试实录:谢飞机的电商场景技术问答(SpringCloud、MyBatis、Redis、Kafka、AI等)本文模拟知名互联网大厂Java后端岗位面试流程,以电商业务为主线,由严肃面试官与“水货”程序员谢飞机展开有趣的对话,涵盖SpringCloud、MyBatis、Redis、Kafka、SpringSecurity、AI等热门技术栈,并附详细解析,助力求职者备战大厂面试。故事设定谢</div>
                        </li>
                        <li><a href="/article/1943983191836651520.htm"
                               title="【超硬核】JVM源码解读:Java方法main在虚拟机上解释执行" target="_blank">【超硬核】JVM源码解读:Java方法main在虚拟机上解释执行</a>
                            <span class="text-muted">HeapDump性能社区</span>
    <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a><a class="tag" taget="_blank" href="/search/%E5%90%8E%E7%AB%AF/1.htm">后端</a><a class="tag" taget="_blank" href="/search/jvm/1.htm">jvm</a>
                            <div>本文由HeapDump性能社区首席讲师鸠摩(马智)授权整理发布第1篇-关于Java虚拟机HotSpot,开篇说的简单点开讲Java运行时,这一篇讲一些简单的内容。我们写的主类中的main()方法是如何被Java虚拟机调用到的?在Java类中的一些方法会被由C/C++编写的HotSpot虚拟机的C/C++函数调用,不过由于Java方法与C/C++函数的调用约定不同,所以并不能直接调用,需要JavaC</div>
                        </li>
                        <li><a href="/article/1943983064304644096.htm"
                               title="算法学习笔记:17.蒙特卡洛算法 ——从原理到实战,涵盖 LeetCode 与考研 408 例题" target="_blank">算法学习笔记:17.蒙特卡洛算法 ——从原理到实战,涵盖 LeetCode 与考研 408 例题</a>
                            <span class="text-muted"></span>
    
                            <div>在计算机科学和数学领域,蒙特卡洛算法(MonteCarloAlgorithm)以其独特的随机抽样思想,成为解决复杂问题的有力工具。从圆周率的计算到金融风险评估,从物理模拟到人工智能,蒙特卡洛算法都发挥着不可替代的作用。本文将深入剖析蒙特卡洛算法的思想、解题思路,结合实际应用场景与Java代码实现,并融入考研408的相关考点,穿插图片辅助理解,帮助你全面掌握这一重要算法。蒙特卡洛算法的基本概念蒙特卡</div>
                        </li>
                        <li><a href="/article/1943981422331097088.htm"
                               title="Java大厂面试故事:谢飞机的互联网音视频场景技术面试全纪录(Spring Boot、MyBatis、Kafka、Redis、AI等)" target="_blank">Java大厂面试故事:谢飞机的互联网音视频场景技术面试全纪录(Spring Boot、MyBatis、Kafka、Redis、AI等)</a>
                            <span class="text-muted">来旺</span>
    <a class="tag" taget="_blank" href="/search/Java%E5%9C%BA%E6%99%AF%E9%9D%A2%E8%AF%95%E5%AE%9D%E5%85%B8/1.htm">Java场景面试宝典</a><a class="tag" taget="_blank" href="/search/Java/1.htm">Java</a><a class="tag" taget="_blank" href="/search/Spring/1.htm">Spring</a><a class="tag" taget="_blank" href="/search/Boot/1.htm">Boot</a><a class="tag" taget="_blank" href="/search/MyBatis/1.htm">MyBatis</a><a class="tag" taget="_blank" href="/search/Kafka/1.htm">Kafka</a><a class="tag" taget="_blank" href="/search/Redis/1.htm">Redis</a><a class="tag" taget="_blank" href="/search/%E5%BE%AE%E6%9C%8D%E5%8A%A1/1.htm">微服务</a><a class="tag" taget="_blank" href="/search/AI/1.htm">AI</a>
                            <div>Java大厂面试故事:谢飞机的互联网音视频场景技术面试全纪录(SpringBoot、MyBatis、Kafka、Redis、AI等)互联网大厂技术面试不仅考察技术深度,更注重业务场景与系统设计能力。本篇以严肃面试官与“水货”程序员谢飞机的对话,带你体验音视频业务场景下的Java面试全过程,涵盖主流技术栈,并附详细答案解析,助你面试无忧。故事场景设定谢飞机是一名有趣但技术基础略显薄弱的程序员,这次应</div>
                        </li>
                        <li><a href="/article/1943979785097113600.htm"
                               title="【前端】jQuery数组合并去重方法总结" target="_blank">【前端】jQuery数组合并去重方法总结</a>
                            <span class="text-muted"></span>
    
                            <div>在jQuery中合并多个数组并去重,推荐使用原生JavaScript的Set对象(高效简单)或$.unique()(仅适用于DOM元素,不适用于普通数组)。以下是完整解决方案:方法1:使用ES6Set(推荐)//定义多个数组constarr1=[1,2,3];constarr2=[2,3,4];constarr3=[3,4,5];//合并数组并用Set去重constmergedArray=[...</div>
                        </li>
                        <li><a href="/article/1943975122729758720.htm"
                               title="EMQX 社区版单机和集群部署" target="_blank">EMQX 社区版单机和集群部署</a>
                            <span class="text-muted">pcj_888</span>
    <a class="tag" taget="_blank" href="/search/MQTT/1.htm">MQTT</a><a class="tag" taget="_blank" href="/search/MQTT/1.htm">MQTT</a><a class="tag" taget="_blank" href="/search/EMQ/1.htm">EMQ</a>
                            <div>EMQ支持Docker,宿主机,k8s部署;支持单机或集群部署。以下给出EMQX社区版单机和集群部署方法1.Docker单机部署官方推荐最小配置:2核4G下载容器镜像dockerpullemqx/emqx:5.3.2启动容器dockerrun-d--nameemqx\-p1883:1883\-p8083:8083\-p8883:8883\-p8084:8084\-p18083:18083\emqx</div>
                        </li>
                        <li><a href="/article/1943973357707915264.htm"
                               title="MySQL Explain 详解:从入门到精通,让你的 SQL 飞起来" target="_blank">MySQL Explain 详解:从入门到精通,让你的 SQL 飞起来</a>
                            <span class="text-muted"></span>
    
                            <div>引言:为什么Explain是SQL优化的“照妖镜”?在Java开发中,我们常常会遇到数据库性能瓶颈的问题。一条看似简单的SQL语句,在数据量增长到一定规模后,可能会从毫秒级响应变成秒级甚至分钟级响应,直接拖慢整个应用的性能。此时,你是否曾困惑于:为什么这条SQL突然变慢了?索引明明建了,为什么没生效?到底是哪里出了问题?答案就藏在MySQL的EXPLAIN命令里。EXPLAIN就像一面“照妖镜”,</div>
                        </li>
                        <li><a href="/article/1943972599365169152.htm"
                               title="docker安装node部分问题" target="_blank">docker安装node部分问题</a>
                            <span class="text-muted">自律的蜗牛</span>
    <a class="tag" taget="_blank" href="/search/docker/1.htm">docker</a><a class="tag" taget="_blank" href="/search/%E5%AE%B9%E5%99%A8/1.htm">容器</a><a class="tag" taget="_blank" href="/search/node.js/1.htm">node.js</a>
                            <div>sudonlatestsudo:n:commandnotfound如果运行sudonlatest时出现:sudo:n:commandnotfound说明n版本管理工具未安装或未添加到PATH环境变量。解决方案1️⃣先检查n是否已安装运行:whichn或者:command-vn如果有输出/usr/local/bin/n,说明n已安装,但可能需要sudo访问。如果没有任何输出,说明n没有安装,跳到方法</div>
                        </li>
                        <li><a href="/article/1943972220988616704.htm"
                               title="Java特性之设计模式【责任链模式】" target="_blank">Java特性之设计模式【责任链模式】</a>
                            <span class="text-muted">Naijia_OvO</span>
    <a class="tag" taget="_blank" href="/search/Java%E7%89%B9%E6%80%A7/1.htm">Java特性</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/1.htm">设计模式</a><a class="tag" taget="_blank" href="/search/%E8%B4%A3%E4%BB%BB%E9%93%BE%E6%A8%A1%E5%BC%8F/1.htm">责任链模式</a>
                            <div>一、责任链模式概述顾名思义,责任链模式(ChainofResponsibilityPattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推主要解决:职责链上的处理者负责处理请求,客户只需要将</div>
                        </li>
                        <li><a href="/article/1943969321717919744.htm"
                               title="日历插件-FullCalendar的详细使用" target="_blank">日历插件-FullCalendar的详细使用</a>
                            <span class="text-muted">老马聊技术</span>
    <a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/javascript/1.htm">javascript</a>
                            <div>一、介绍FullCalendar是一个功能强大、高度可定制的JavaScript日历组件,用于在网页中显示和管理日历事件。它支持多种视图(月、周、日等),可以轻松集成各种框架,并提供丰富的事件处理功能。二、实操案例具体代码如下:FullCalendar日期选择body{font-family:Arial,sans-serif;margin:20px;}#calendar{max-width:900</div>
                        </li>
                        <li><a href="/article/1943963649831923712.htm"
                               title="玩转Docker | 使用Docker部署gopeed下载工具" target="_blank">玩转Docker | 使用Docker部署gopeed下载工具</a>
                            <span class="text-muted">心随_风动</span>
    <a class="tag" taget="_blank" href="/search/%E7%8E%A9%E8%BD%ACDocker/1.htm">玩转Docker</a><a class="tag" taget="_blank" href="/search/docker/1.htm">docker</a><a class="tag" taget="_blank" href="/search/%E5%AE%B9%E5%99%A8/1.htm">容器</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a>
                            <div>玩转Docker|使用Docker部署gopeed下载工具前言一、gopeed介绍Gopeed简介主要特点二、系统要求环境要求环境检查Docker版本检查检查操作系统版本三、部署gopeed服务下载镜像创建容器检查容器状态检查服务端口安全设置四、访问gopeed应用五、测试与下载六、总结前言在当今信息爆炸的时代,高效地获取和管理网络资源变得尤为重要。无论是下载大型文件还是进行日常的数据传输,一个稳</div>
                        </li>
                        <li><a href="/article/1943963145055825920.htm"
                               title="react-native android 环境搭建" target="_blank">react-native android 环境搭建</a>
                            <span class="text-muted"></span>
    
                            <div>环境:macjava版本:Java11最重要:一定要一定要一定要react涉及到很多的依赖下载,gradle和react相关的,第一次安装环境时有外网环境会快速很多。安装nodejs安装react-nativenpminstallreact-native-clinpminstallreact-native创建一个新项目react-nativeinitfirstReact替换gradle下载源rep</div>
                        </li>
                        <li><a href="/article/1943962515373355008.htm"
                               title="Docker指定网桥和指定网桥IP" target="_blank">Docker指定网桥和指定网桥IP</a>
                            <span class="text-muted"></span>
    
                            <div>$dockernetworklsNETWORKIDNAMEDRIVER7fca4eb8c647bridgebridge9f904ee27bf5nonenullcf03ee007fb4hosthostBridge默认bridge网络,我们可以使用dockernetworkinspect命令查看返回的网络信息,我们使用dockerrun命令是将网络自动应用到新的容器Host如果是hosts模式,启动容</div>
                        </li>
                        <li><a href="/article/1943962387782627328.htm"
                               title="Java 调用 HTTP 接口的 7 种方式:全网最全指南" target="_blank">Java 调用 HTTP 接口的 7 种方式:全网最全指南</a>
                            <span class="text-muted"></span>
    
                            <div>Java调用HTTP接口的7种方式:全网最全指南在开发过程中,调用HTTP接口是最常见的需求之一。本文将详细介绍Java中7种主流的调用HTTP接口的方式,包括每种工具的优缺点和完整代码实现。1.使用RestTemplateRestTemplate是Spring提供的同步HTTP客户端,适用于传统项目。尽管从Spring5开始被标记为过时,它仍然是许多开发者的首选。示例代码importorg.sp</div>
                        </li>
                        <li><a href="/article/1943960369345130496.htm"
                               title="Java三年经验程序员技术栈全景指南:从前端到架构,对标阿里美团全栈要求" target="_blank">Java三年经验程序员技术栈全景指南:从前端到架构,对标阿里美团全栈要求</a>
                            <span class="text-muted">可曾去过倒悬山</span>
    <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/%E6%9E%B6%E6%9E%84/1.htm">架构</a>
                            <div>Java三年经验程序员技术栈全景指南:从前端到架构,对标阿里美团全栈要求三年经验是Java程序员的分水岭,技术栈深度决定你成为“业务码农”还是“架构师候选人”。本文整合阿里、美团、滴滴等大厂招聘要求,为你绘制可落地的进阶路线。一、Java核心:从语法糖到JVM底层三年经验与初级的核心差异在于系统级理解,大厂面试常考以下能力:JVM与性能调优内存模型(堆外内存、元空间)、GC算法(G1/ZGC适用场</div>
                        </li>
                        <li><a href="/article/1943957596671111168.htm"
                               title="docker0网卡没有ip一步解决" target="_blank">docker0网卡没有ip一步解决</a>
                            <span class="text-muted">ξ流ぁ星ぷ132</span>
    <a class="tag" taget="_blank" href="/search/tcp%2Fip/1.htm">tcp/ip</a><a class="tag" taget="_blank" href="/search/%E7%BD%91%E7%BB%9C/1.htm">网络</a><a class="tag" taget="_blank" href="/search/%E6%9C%8D%E5%8A%A1%E5%99%A8/1.htm">服务器</a>
                            <div>正常查看ip的时候一直显示没有ip这里先删除docker0网卡iplinkdeletedocker0然后重启服务systemctlrestartdocker再次查看显示有ip了并且查看配置文件也是正常的cat/etc/docker/daemon.json{"registry-mirrors":["https://docker.m.daocloud.io","https://docker.imgdb</div>
                        </li>
                        <li><a href="/article/1943954447797383168.htm"
                               title="javascript高级程序设计第3版——第12章 DOM2与DOM3" target="_blank">javascript高级程序设计第3版——第12章 DOM2与DOM3</a>
                            <span class="text-muted">weixin_30687587</span>
    <a class="tag" taget="_blank" href="/search/javascript/1.htm">javascript</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B8%8E%E7%AE%97%E6%B3%95/1.htm">数据结构与算法</a><a class="tag" taget="_blank" href="/search/ViewUI/1.htm">ViewUI</a>
                            <div>12章——DOM2与DOM3为了增强D0M1,DOM级规范定义了一些模块。DOM2核心:为不同的DOM类型引入了一些与XML命名空间有关的方法,还定义了以编程方式创建Document实例的方法;DOM2级样式:针对操作元素的样式而开发;其特性总结:1.每个元素都有一个关联的style对象,可用来确定和修改行内样式;2.要确定某个元素的计算样式,可使用getComgetComputedStyle()</div>
                        </li>
                        <li><a href="/article/1943951046015512576.htm"
                               title="Java设计模式实战:高频场景解析与避坑指南" target="_blank">Java设计模式实战:高频场景解析与避坑指南</a>
                            <span class="text-muted">mckim_</span>
    <a class="tag" taget="_blank" href="/search/%E7%AC%94%E8%AE%B0/1.htm">笔记</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/1.htm">设计模式</a>
                            <div>引言设计模式是软件开发的基石,但许多开发者面对23种模式时容易陷入“学完就忘”或“滥用模式”的困境。本文从工业级项目视角出发,精选10种高频设计模式,结合真实代码案例与主流框架应用,帮你建立模式思维,拒绝纸上谈兵。一、创建型模式:告别new的暴力美学1.工厂方法模式(FactoryMethod)核心痛点:对象创建逻辑散落各处,难以统一管理。场景案例:电商平台需要支持多种支付方式(支付宝、微信、银联</div>
                        </li>
                        <li><a href="/article/1943950163496202240.htm"
                               title="JavaScript 基础09:Web APIs——日期对象、DOM节点" target="_blank">JavaScript 基础09:Web APIs——日期对象、DOM节点</a>
                            <span class="text-muted">梦想当全栈</span>
    <a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a><a class="tag" taget="_blank" href="/search/javascript/1.htm">javascript</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a>
                            <div>JavaScript基础09:WebAPIs——日期对象、DOM节点进一步学习DOM相关知识,实现可交互的网页特效能够插入、删除和替换元素节点。能够依据元素节点关系查找节点。一、日期对象掌握Date日期对象的使用,动态获取当前计算机的时间。ECMAScript中内置了获取系统时间的对象Date,使用Date时与之前学习的内置对象console和Math不同,它需要借助new关键字才能使用。1.实例</div>
                        </li>
                        <li><a href="/article/1943949028848889856.htm"
                               title="系统迁移从CentOS7.9到Rocky8.9" target="_blank">系统迁移从CentOS7.9到Rocky8.9</a>
                            <span class="text-muted"></span>
    
                            <div>我有两台阿里云上的服务器是CentOS7.9,由于CentOS7已经停止支持,后续使用的话会有安全漏洞,所以需要尽快迁移,个人使用的话目前兼容性好的还是RockyLinux8,很多脚本改改就能用了。一、盘点系统和迁移应用查看当前系统发行版版本cat/etc/os-release盘点迁移清单服务器应用部署方式docker镜像来源v1wordpressdockerdockerhubv1zdirdock</div>
                        </li>
                        <li><a href="/article/1943946255763828736.htm"
                               title="《Java前端开发全栈指南:从Servlet到现代框架实战》" target="_blank">《Java前端开发全栈指南:从Servlet到现代框架实战》</a>
                            <span class="text-muted"></span>
    
                            <div>前言在当今Web开发领域,Java依然是后端开发的主力语言,而随着前后端分离架构的普及,Java开发者也需要掌握前端技术栈。本文将全面介绍JavaWeb前端开发的核心技术,包括传统Servlet/JSP体系、现代前端框架集成方案,以及全栈开发的最佳实践。通过本文,您将了解如何构建现代化的JavaWeb应用前端界面。一、JavaWeb前端技术演进1.1传统技术栈Servlet:JavaWeb基础,处</div>
                        </li>
                        <li><a href="/article/1943943735733710848.htm"
                               title="javaSE面试题---语法基础、面向对象、常用类、集合、多线程、文件和IO" target="_blank">javaSE面试题---语法基础、面向对象、常用类、集合、多线程、文件和IO</a>
                            <span class="text-muted">yang_xiao_wu_</span>
    <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E9%9D%A2%E8%AF%95/1.htm">面试</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a><a class="tag" taget="_blank" href="/search/javase/1.htm">javase</a><a class="tag" taget="_blank" href="/search/java%E5%9F%BA%E7%A1%80/1.htm">java基础</a><a class="tag" taget="_blank" href="/search/%E5%A4%9A%E7%BA%BF%E7%A8%8B/1.htm">多线程</a><a class="tag" taget="_blank" href="/search/%E6%96%87%E4%BB%B6%E5%92%8CIO/1.htm">文件和IO</a>
                            <div>目录语法基础1.jdkjrejvm区别2.基本数据类型3.引用数据类型4.自动类型转换、强制类型转换5.常见的运算符6.&和&&区别7.++--在前和在后的区别8.+=有什么作用9.switch..case中switch支持哪些数据类型10.break和continue区别11.while和dowhile区别12.如何生成一个取值范围在[min,max]之间的随机数13.数组的长度如何获取?数组下</div>
                        </li>
                        <li><a href="/article/1943943105145270272.htm"
                               title="JAVA 高频八股文 Day03" target="_blank">JAVA 高频八股文 Day03</a>
                            <span class="text-muted">Conqueror675</span>
    <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a>
                            <div>12.TCP和Http的区别是什么TCP是传输层协议,负责建立可靠的点对点连接,确保数据有序、完整地传输(如铁路轨道);HTTP是应用层协议,基于TCP构建,定义了Web服务交互的报文格式和规则(如货运订单)。TCP关注数据如何可靠送达,通过三次握手建立连接、流量控制等机制保证传输;HTTP关注传输内容的意义,提供请求/响应语义(GET/POST等)和无状态通信。补充:说一下什么是三次握手四次挥手</div>
                        </li>
                        <li><a href="/article/1943932394662850560.htm"
                               title="Docker容器底层原理详解:从零理解容器化技术" target="_blank">Docker容器底层原理详解:从零理解容器化技术</a>
                            <span class="text-muted">Debug Your Career</span>
    <a class="tag" taget="_blank" href="/search/%E9%9D%A2%E8%AF%95/1.htm">面试</a><a class="tag" taget="_blank" href="/search/docker/1.htm">docker</a><a class="tag" taget="_blank" href="/search/%E5%AE%B9%E5%99%A8/1.htm">容器</a><a class="tag" taget="_blank" href="/search/docker/1.htm">docker</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a>
                            <div>一、容器本质:一个“隔离的进程”关键认知:Docker容器并不是一个完整的操作系统,而是一个被严格隔离的进程。这个进程拥有独立的文件系统、网络、进程视图等资源,但它直接运行在宿主机内核上(而虚拟机需要模拟硬件和操作系统)。类比理解:想象你在一个办公楼里租了一间独立办公室(容器)。你有自己的桌椅(文件系统)、电话分机(网络)、门牌号(主机名),但共享整栋楼的水电(宿主机内核)和电梯(硬件资源)。办公</div>
                        </li>
                                    <li><a href="/article/50.htm"
                                           title="java封装继承多态等" target="_blank">java封装继承多态等</a>
                                        <span class="text-muted">麦田的设计者</span>
    <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/eclipse/1.htm">eclipse</a><a class="tag" taget="_blank" href="/search/jvm/1.htm">jvm</a><a class="tag" taget="_blank" href="/search/c/1.htm">c</a><a class="tag" taget="_blank" href="/search/encapsulatopn/1.htm">encapsulatopn</a>
                                        <div>       最近一段时间看了很多的视频却忘记总结了,现在只能想到什么写什么了,希望能起到一个回忆巩固的作用。 
        1、final关键字 
          译为:最终的 
           &</div>
                                    </li>
                                    <li><a href="/article/177.htm"
                                           title="F5与集群的区别" target="_blank">F5与集群的区别</a>
                                        <span class="text-muted">bijian1013</span>
    <a class="tag" taget="_blank" href="/search/weblogic/1.htm">weblogic</a><a class="tag" taget="_blank" href="/search/%E9%9B%86%E7%BE%A4/1.htm">集群</a><a class="tag" taget="_blank" href="/search/F5/1.htm">F5</a>
                                        <div>        http请求配置不是通过集群,而是F5;集群是weblogic容器的,如果是ejb接口是通过集群。 
            F5同集群的差别,主要还是会话复制的问题,F5一把是分发http请求用的,因为http都是无状态的服务,无需关注会话问题,类似</div>
                                    </li>
                                    <li><a href="/article/304.htm"
                                           title="LeetCode[Math] - #7 Reverse Integer" target="_blank">LeetCode[Math] - #7 Reverse Integer</a>
                                        <span class="text-muted">Cwind</span>
    <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E9%A2%98%E8%A7%A3/1.htm">题解</a><a class="tag" taget="_blank" href="/search/Math/1.htm">Math</a><a class="tag" taget="_blank" href="/search/LeetCode/1.htm">LeetCode</a><a class="tag" taget="_blank" href="/search/Algorithm/1.htm">Algorithm</a>
                                        <div>原题链接:#7 Reverse Integer 
      
    要求: 
    按位反转输入的数字 
    例1: 输入 x = 123, 返回 321 
    例2: 输入 x = -123, 返回 -321 
      
    难度:简单 
      
    分析: 
    对于一般情况,首先保存输入数字的符号,然后每次取输入的末位(x%10)作为输出的高位(result = result*10 + x%10)即可。但</div>
                                    </li>
                                    <li><a href="/article/431.htm"
                                           title="BufferedOutputStream" target="_blank">BufferedOutputStream</a>
                                        <span class="text-muted">周凡杨</span>
    
                                        <div>     首先说一下这个大批量,是指有上千万的数据量。 
         例子: 
         有一张短信历史表,其数据有上千万条数据,要进行数据备份到文本文件,就是执行如下SQL然后将结果集写入到文件中! 
         select t.msisd</div>
                                    </li>
                                    <li><a href="/article/558.htm"
                                           title="linux下模拟按键输入和鼠标" target="_blank">linux下模拟按键输入和鼠标</a>
                                        <span class="text-muted">被触发</span>
    <a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a>
                                        <div>查看/dev/input/eventX是什么类型的事件, cat /proc/bus/input/devices 
    设备有着自己特殊的按键键码,我需要将一些标准的按键,比如0-9,X-Z等模拟成标准按键,比如KEY_0,KEY-Z等,所以需要用到按键 模拟,具体方法就是操作/dev/input/event1文件,向它写入个input_event结构体就可以模拟按键的输入了。 
     
    linux/in</div>
                                    </li>
                                    <li><a href="/article/685.htm"
                                           title="ContentProvider初体验" target="_blank">ContentProvider初体验</a>
                                        <span class="text-muted">肆无忌惮_</span>
    <a class="tag" taget="_blank" href="/search/ContentProvider/1.htm">ContentProvider</a>
                                        <div>ContentProvider在安卓开发中非常重要。与Activity,Service,BroadcastReceiver并称安卓组件四大天王。 
    在android中的作用是用来对外共享数据。因为安卓程序的数据库文件存放在data/data/packagename里面,这里面的文件默认都是私有的,别的程序无法访问。 
    如果QQ游戏想访问手机QQ的帐号信息一键登录,那么就需要使用内容提供者COnte</div>
                                    </li>
                                    <li><a href="/article/812.htm"
                                           title="关于Spring MVC项目(maven)中通过fileupload上传文件" target="_blank">关于Spring MVC项目(maven)中通过fileupload上传文件</a>
                                        <span class="text-muted">843977358</span>
    <a class="tag" taget="_blank" href="/search/mybatis/1.htm">mybatis</a><a class="tag" taget="_blank" href="/search/spring+mvc/1.htm">spring mvc</a><a class="tag" taget="_blank" href="/search/%E4%BF%AE%E6%94%B9%E5%A4%B4%E5%83%8F/1.htm">修改头像</a><a class="tag" taget="_blank" href="/search/%E4%B8%8A%E4%BC%A0%E6%96%87%E4%BB%B6/1.htm">上传文件</a><a class="tag" taget="_blank" href="/search/upload/1.htm">upload</a>
                                        <div>Spring MVC 中通过fileupload上传文件,其中项目使用maven管理。 
      
    1.上传文件首先需要的是导入相关支持jar包:commons-fileupload.jar,commons-io.jar 
    因为我是用的maven管理项目,所以要在pom文件中配置(每个人的jar包位置根据实际情况定) 
    <!-- 文件上传 start by zhangyd-c --&g</div>
                                    </li>
                                    <li><a href="/article/939.htm"
                                           title="使用svnkit api,纯java操作svn,实现svn提交,更新等操作" target="_blank">使用svnkit api,纯java操作svn,实现svn提交,更新等操作</a>
                                        <span class="text-muted">aigo</span>
    <a class="tag" taget="_blank" href="/search/svnkit/1.htm">svnkit</a>
                                        <div> 原文:http://blog.csdn.net/hardwin/article/details/7963318 
      
    import java.io.File;  
      
    import org.apache.log4j.Logger;  
    import org.tmatesoft.svn.core.SVNCommitInfo;  
    import org.tmateso</div>
                                    </li>
                                    <li><a href="/article/1066.htm"
                                           title="对比浏览器,casperjs,httpclient的Header信息" target="_blank">对比浏览器,casperjs,httpclient的Header信息</a>
                                        <span class="text-muted">alleni123</span>
    <a class="tag" taget="_blank" href="/search/%E7%88%AC%E8%99%AB/1.htm">爬虫</a><a class="tag" taget="_blank" href="/search/crawler/1.htm">crawler</a><a class="tag" taget="_blank" href="/search/header/1.htm">header</a>
                                        <div>		@Override
    		protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
    		{
    			String type=req.getParameter("type");
    			Enumeration es=re</div>
                                    </li>
                                    <li><a href="/article/1193.htm"
                                           title="java.io操作 DataInputStream和DataOutputStream基本数据流" target="_blank">java.io操作 DataInputStream和DataOutputStream基本数据流</a>
                                        <span class="text-muted">百合不是茶</span>
    <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E6%B5%81/1.htm">流</a>
                                        <div>1,java中如果不保存整个对象,只保存类中的属性,那么我们可以使用本篇文章中的方法,如果要保存整个对象  先将类实例化  后面的文章将详细写到 
      
      
    2,DataInputStream 是java.io包中一个数据输入流允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型。应用程序可以使用数据输出流写入稍后由数据输入流读取的数据。</div>
                                    </li>
                                    <li><a href="/article/1320.htm"
                                           title="车辆保险理赔案例" target="_blank">车辆保险理赔案例</a>
                                        <span class="text-muted">bijian1013</span>
    <a class="tag" taget="_blank" href="/search/%E8%BD%A6%E9%99%A9/1.htm">车险</a>
                                        <div>理赔案例: 
    一货运车,运输公司为车辆购买了机动车商业险和交强险,也买了安全生产责任险,运输一车烟花爆竹,在行驶途中发生爆炸,出现车毁、货损、司机亡、炸死一路人、炸毁一间民宅等惨剧,针对这几种情况,该如何赔付。 
    赔付建议和方案: 
    客户所买交强险在这里不起作用,因为交强险的赔付前提是:“机动车发生道路交通意外事故”; 
    如果是交通意外事故引发的爆炸,则优先适用交强险条款进行赔付,不足的部分由商业</div>
                                    </li>
                                    <li><a href="/article/1447.htm"
                                           title="学习Spring必学的Java基础知识(5)—注解" target="_blank">学习Spring必学的Java基础知识(5)—注解</a>
                                        <span class="text-muted">bijian1013</span>
    <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a>
                                        <div>        文章来源:http://www.iteye.com/topic/1123823,整理在我的博客有两个目的:一个是原文确实很不错,通俗易懂,督促自已将博主的这一系列关于Spring文章都学完;另一个原因是为免原文被博主删除,在此记录,方便以后查找阅读。 
      
            有必要对</div>
                                    </li>
                                    <li><a href="/article/1574.htm"
                                           title="【Struts2一】Struts2 Hello World" target="_blank">【Struts2一】Struts2 Hello World</a>
                                        <span class="text-muted">bit1129</span>
    <a class="tag" taget="_blank" href="/search/Hello+world/1.htm">Hello world</a>
                                        <div>Struts2 Hello World应用的基本步骤 
    创建Struts2的Hello World应用,包括如下几步: 
    1.配置web.xml 
    2.创建Action 
    3.创建struts.xml,配置Action 
    4.启动web server,通过浏览器访问 
      配置web.xml 
    <?xml version="1.0" encoding="</div>
                                    </li>
                                    <li><a href="/article/1701.htm"
                                           title="【Avro二】Avro RPC框架" target="_blank">【Avro二】Avro RPC框架</a>
                                        <span class="text-muted">bit1129</span>
    <a class="tag" taget="_blank" href="/search/rpc/1.htm">rpc</a>
                                        <div>1. Avro RPC简介 1.1. RPC 
     
     RPC逻辑上分为二层,一是传输层,负责网络通信;二是协议层,将数据按照一定协议格式打包和解包 
     从序列化方式来看,Apache Thrift 和Google的Protocol Buffers和Avro应该是属于同一个级别的框架,都能跨语言,性能优秀,数据精简,但是Avro的动态模式(不用生成代码,而且性能很好)这个特点让人非常喜欢,比较适合R</div>
                                    </li>
                                    <li><a href="/article/1828.htm"
                                           title="lua set get cookie" target="_blank">lua set get cookie</a>
                                        <span class="text-muted">ronin47</span>
    <a class="tag" taget="_blank" href="/search/lua+cookie/1.htm">lua cookie</a>
                                        <div>lua:
    local access_token = ngx.var.cookie_SGAccessToken
    if access_token then
        ngx.header["Set-Cookie"] = "SGAccessToken="..access_token.."; path=/;Max-Age=3000"
    end</div>
                                    </li>
                                    <li><a href="/article/1955.htm"
                                           title="java-打印不大于N的质数" target="_blank">java-打印不大于N的质数</a>
                                        <span class="text-muted">bylijinnan</span>
    <a class="tag" taget="_blank" href="/search/java/1.htm">java</a>
                                        <div>
    
    public class PrimeNumber {
    
    	/**
    	 * 寻找不大于N的质数
    	 */
    	public static void main(String[] args) {
    		int n=100;
    		PrimeNumber pn=new PrimeNumber();
    		pn.printPrimeNumber(n);
    		System.out.print</div>
                                    </li>
                                    <li><a href="/article/2082.htm"
                                           title="Spring源码学习-PropertyPlaceholderHelper" target="_blank">Spring源码学习-PropertyPlaceholderHelper</a>
                                        <span class="text-muted">bylijinnan</span>
    <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a>
                                        <div>今天在看Spring 3.0.0.RELEASE的源码,发现PropertyPlaceholderHelper的一个bug 
    当时觉得奇怪,上网一搜,果然是个bug,不过早就有人发现了,且已经修复: 
    详见: 
    http://forum.spring.io/forum/spring-projects/container/88107-propertyplaceholderhelper-bug 
     
    </div>
                                    </li>
                                    <li><a href="/article/2209.htm"
                                           title="[逻辑与拓扑]布尔逻辑与拓扑结构的结合会产生什么?" target="_blank">[逻辑与拓扑]布尔逻辑与拓扑结构的结合会产生什么?</a>
                                        <span class="text-muted">comsci</span>
    <a class="tag" taget="_blank" href="/search/%E6%8B%93%E6%89%91/1.htm">拓扑</a>
                                        <div> 
       如果我们已经在一个工作流的节点中嵌入了可以进行逻辑推理的代码,那么成百上千个这样的节点如果组成一个拓扑网络,而这个网络是可以自动遍历的,非线性的拓扑计算模型和节点内部的布尔逻辑处理的结合,会产生什么样的结果呢? 
     
       是否可以形成一种新的模糊语言识别和处理模型呢?  大家有兴趣可以试试,用软件搞这些有个好处,就是花钱比较少,就算不成</div>
                                    </li>
                                    <li><a href="/article/2336.htm"
                                           title="ITEYE 都换百度推广了" target="_blank">ITEYE 都换百度推广了</a>
                                        <span class="text-muted">cuisuqiang</span>
    <a class="tag" taget="_blank" href="/search/Google/1.htm">Google</a><a class="tag" taget="_blank" href="/search/AdSense/1.htm">AdSense</a><a class="tag" taget="_blank" href="/search/%E7%99%BE%E5%BA%A6%E6%8E%A8%E5%B9%BF/1.htm">百度推广</a><a class="tag" taget="_blank" href="/search/%E5%B9%BF%E5%91%8A/1.htm">广告</a><a class="tag" taget="_blank" href="/search/%E5%A4%96%E5%BF%AB/1.htm">外快</a>
                                        <div>以前ITEYE的广告都是谷歌的Google AdSense,现在都换成百度推广了。 
      
    为什么个人博客设置里面还是Google AdSense呢? 
      
    都知道Google AdSense不好申请,这在ITEYE上也不是讨论了一两天了,强烈建议ITEYE换掉Google AdSense。至少,用一个好申请的吧。 
      
    什么时候能从ITEYE上来点外快,哪怕少点</div>
                                    </li>
                                    <li><a href="/article/2463.htm"
                                           title="新浪微博技术架构分析" target="_blank">新浪微博技术架构分析</a>
                                        <span class="text-muted">dalan_123</span>
    <a class="tag" taget="_blank" href="/search/%E6%96%B0%E6%B5%AA%E5%BE%AE%E5%8D%9A/1.htm">新浪微博</a><a class="tag" taget="_blank" href="/search/%E6%9E%B6%E6%9E%84/1.htm">架构</a>
                                        <div>新浪微博在短短一年时间内从零发展到五千万用户,我们的基层架构也发展了几个版本。第一版就是是非常快的,我们可以非常快的实现我们的模块。我们看一下技术特点,微博这个产品从架构上来分析,它需要解决的是发表和订阅的问题。我们第一版采用的是推的消息模式,假如说我们一个明星用户他有10万个粉丝,那就是说用户发表一条微博的时候,我们把这个微博消息攒成10万份,这样就是很简单了,第一版的架构实际上就是这两行字。第</div>
                                    </li>
                                    <li><a href="/article/2590.htm"
                                           title="玩转ARP攻击" target="_blank">玩转ARP攻击</a>
                                        <span class="text-muted">dcj3sjt126com</span>
    <a class="tag" taget="_blank" href="/search/r/1.htm">r</a>
                                        <div>我写这片文章只是想让你明白深刻理解某一协议的好处。高手免看。如果有人利用这片文章所做的一切事情,盖不负责。 网上关于ARP的资料已经很多了,就不用我都说了。 用某一位高手的话来说,“我们能做的事情很多,唯一受限制的是我们的创造力和想象力”。 ARP也是如此。 以下讨论的机子有 一个要攻击的机子:10.5.4.178 硬件地址:52:54:4C:98</div>
                                    </li>
                                    <li><a href="/article/2717.htm"
                                           title="PHP编码规范" target="_blank">PHP编码规范</a>
                                        <span class="text-muted">dcj3sjt126com</span>
    <a class="tag" taget="_blank" href="/search/%E7%BC%96%E7%A0%81%E8%A7%84%E8%8C%83/1.htm">编码规范</a>
                                        <div>一、文件格式 
    1. 对于只含有 php 代码的文件,我们将在文件结尾处忽略掉 "?>" 。这是为了防止多余的空格或者其它字符影响到代码。例如:<?php$foo = 'foo';2. 缩进应该能够反映出代码的逻辑结果,尽量使用四个空格,禁止使用制表符TAB,因为这样能够保证有跨客户端编程器软件的灵活性。例</div>
                                    </li>
                                    <li><a href="/article/2844.htm"
                                           title="linux 脱机管理(nohup)" target="_blank">linux 脱机管理(nohup)</a>
                                        <span class="text-muted">eksliang</span>
    <a class="tag" taget="_blank" href="/search/linux+nohup/1.htm">linux nohup</a><a class="tag" taget="_blank" href="/search/nohup/1.htm">nohup</a>
                                        <div>脱机管理 nohup 
    转载请出自出处:http://eksliang.iteye.com/blog/2166699 
    nohup可以让你在脱机或者注销系统后,还能够让工作继续进行。他的语法如下 
    nohup [命令与参数]   --在终端机前台工作
    nohup [命令与参数] & --在终端机后台工作 
      
    但是这个命令需要注意的是,nohup并不支持bash的内置命令,所</div>
                                    </li>
                                    <li><a href="/article/2971.htm"
                                           title="BusinessObjects Enterprise Java SDK" target="_blank">BusinessObjects Enterprise Java SDK</a>
                                        <span class="text-muted">greemranqq</span>
    <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/BO/1.htm">BO</a><a class="tag" taget="_blank" href="/search/SAP/1.htm">SAP</a><a class="tag" taget="_blank" href="/search/Crystal+Reports/1.htm">Crystal Reports</a>
                                        <div>最近项目用到oracle_ADF  从SAP/BO 上调用 水晶报表,资料比较少,我做一个简单的分享,给和我一样的新手 提供更多的便利。 
      
    首先,我是尝试用JAVA JSP 去访问的。 
      
    官方API:http://devlibrary.businessobjects.com/BusinessObjectsxi/en/en/BOE_SDK/boesdk_ja</div>
                                    </li>
                                    <li><a href="/article/3098.htm"
                                           title="系统负载剧变下的管控策略" target="_blank">系统负载剧变下的管控策略</a>
                                        <span class="text-muted">iamzhongyong</span>
    <a class="tag" taget="_blank" href="/search/%E9%AB%98%E5%B9%B6%E5%8F%91/1.htm">高并发</a>
                                        <div>假如目前的系统有100台机器,能够支撑每天1亿的点击量(这个就简单比喻一下),然后系统流量剧变了要,我如何应对,系统有那些策略可以处理,这里总结了一下之前的一些做法。 
    1、水平扩展 
    这个最容易理解,加机器,这样的话对于系统刚刚开始的伸缩性设计要求比较高,能够非常灵活的添加机器,来应对流量的变化。 
    2、系统分组 
    假如系统服务的业务不同,有优先级高的,有优先级低的,那就让不同的业务调用提前分组</div>
                                    </li>
                                    <li><a href="/article/3225.htm"
                                           title="BitTorrent DHT 协议中文翻译" target="_blank">BitTorrent DHT 协议中文翻译</a>
                                        <span class="text-muted">justjavac</span>
    <a class="tag" taget="_blank" href="/search/bit/1.htm">bit</a>
                                        <div>前言 
    做了一个磁力链接和BT种子的搜索引擎 {Magnet & Torrent},因此把 DHT 协议重新看了一遍。 
     
     BEP: 5Title: DHT ProtocolVersion: 3dec52cb3ae103ce22358e3894b31cad47a6f22bLast-Modified: Tue Apr 2 16:51:45 2013 -070</div>
                                    </li>
                                    <li><a href="/article/3352.htm"
                                           title="Ubuntu下Java环境的搭建" target="_blank">Ubuntu下Java环境的搭建</a>
                                        <span class="text-muted">macroli</span>
    <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E5%B7%A5%E4%BD%9C/1.htm">工作</a><a class="tag" taget="_blank" href="/search/ubuntu/1.htm">ubuntu</a>
                                        <div>配置命令: 
      $sudo apt-get install ubuntu-restricted-extras 
      再运行如下命令: 
      $sudo apt-get install sun-java6-jdk 
      待安装完毕后选择默认Java. 
      $sudo update- alternatives --config java 
      安装过程提示选择,输入“2”即可,然后按回车键确定。 </div>
                                    </li>
                                    <li><a href="/article/3479.htm"
                                           title="js字符串转日期(兼容IE所有版本)" target="_blank">js字符串转日期(兼容IE所有版本)</a>
                                        <span class="text-muted">qiaolevip</span>
    <a class="tag" taget="_blank" href="/search/TO/1.htm">TO</a><a class="tag" taget="_blank" href="/search/Date/1.htm">Date</a><a class="tag" taget="_blank" href="/search/String/1.htm">String</a><a class="tag" taget="_blank" href="/search/IE/1.htm">IE</a>
                                        <div>	/**
    	 * 字符串转时间(yyyy-MM-dd HH:mm:ss)
    	 * result (分钟)
    	 */
    	stringToDate : function(fDate){
    		var fullDate = fDate.split(" ")[0].split("-");
    		var fullTime = fDate.split("</div>
                                    </li>
                                    <li><a href="/article/3606.htm"
                                           title="【数据挖掘学习】关联规则算法Apriori的学习与SQL简单实现购物篮分析" target="_blank">【数据挖掘学习】关联规则算法Apriori的学习与SQL简单实现购物篮分析</a>
                                        <span class="text-muted">superlxw1234</span>
    <a class="tag" taget="_blank" href="/search/sql/1.htm">sql</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E6%8C%96%E6%8E%98/1.htm">数据挖掘</a><a class="tag" taget="_blank" href="/search/%E5%85%B3%E8%81%94%E8%A7%84%E5%88%99/1.htm">关联规则</a>
                                        <div>关联规则挖掘用于寻找给定数据集中项之间的有趣的关联或相关关系。 
    关联规则揭示了数据项间的未知的依赖关系,根据所挖掘的关联关系,可以从一个数据对象的信息来推断另一个数据对象的信息。 
    例如购物篮分析。牛奶 ⇒ 面包 [支持度:3%,置信度:40%]  支持度3%:意味3%顾客同时购买牛奶和面包。   置信度40%:意味购买牛奶的顾客40%也购买面包。   规则的支持度和置信度是两个规则兴</div>
                                    </li>
                                    <li><a href="/article/3733.htm"
                                           title="Spring 5.0 的系统需求,期待你的反馈" target="_blank">Spring 5.0 的系统需求,期待你的反馈</a>
                                        <span class="text-muted">wiselyman</span>
    <a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a>
                                        <div>        
           Spring 5.0将在2016年发布。Spring5.0将支持JDK 9。 
      
           Spring 5.0的特性计划还在工作中,请保持关注,所以作者希望从使用者得到关于Spring 5.0系统需求方面的反馈。 
     </div>
                                    </li>
                    </ul>
                </div>
            </div>
        </div>
    
    <div>
        <div class="container">
            <div class="indexes">
                <strong>按字母分类:</strong>
                <a href="/tags/A/1.htm" target="_blank">A</a><a href="/tags/B/1.htm" target="_blank">B</a><a href="/tags/C/1.htm" target="_blank">C</a><a
                    href="/tags/D/1.htm" target="_blank">D</a><a href="/tags/E/1.htm" target="_blank">E</a><a href="/tags/F/1.htm" target="_blank">F</a><a
                    href="/tags/G/1.htm" target="_blank">G</a><a href="/tags/H/1.htm" target="_blank">H</a><a href="/tags/I/1.htm" target="_blank">I</a><a
                    href="/tags/J/1.htm" target="_blank">J</a><a href="/tags/K/1.htm" target="_blank">K</a><a href="/tags/L/1.htm" target="_blank">L</a><a
                    href="/tags/M/1.htm" target="_blank">M</a><a href="/tags/N/1.htm" target="_blank">N</a><a href="/tags/O/1.htm" target="_blank">O</a><a
                    href="/tags/P/1.htm" target="_blank">P</a><a href="/tags/Q/1.htm" target="_blank">Q</a><a href="/tags/R/1.htm" target="_blank">R</a><a
                    href="/tags/S/1.htm" target="_blank">S</a><a href="/tags/T/1.htm" target="_blank">T</a><a href="/tags/U/1.htm" target="_blank">U</a><a
                    href="/tags/V/1.htm" target="_blank">V</a><a href="/tags/W/1.htm" target="_blank">W</a><a href="/tags/X/1.htm" target="_blank">X</a><a
                    href="/tags/Y/1.htm" target="_blank">Y</a><a href="/tags/Z/1.htm" target="_blank">Z</a><a href="/tags/0/1.htm" target="_blank">其他</a>
            </div>
        </div>
    </div>
    <footer id="footer" class="mb30 mt30">
        <div class="container">
            <div class="footBglm">
                <a target="_blank" href="/">首页</a> -
                <a target="_blank" href="/custom/about.htm">关于我们</a> -
                <a target="_blank" href="/search/Java/1.htm">站内搜索</a> -
                <a target="_blank" href="/sitemap.txt">Sitemap</a> -
                <a target="_blank" href="/custom/delete.htm">侵权投诉</a>
            </div>
            <div class="copyright">版权所有 IT知识库 CopyRight © 2000-2050 E-COM-NET.COM , All Rights Reserved.
    <!--            <a href="https://beian.miit.gov.cn/" rel="nofollow" target="_blank">京ICP备09083238号</a><br>-->
            </div>
        </div>
    </footer>
    <!-- 代码高亮 -->
    <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shCore.js"></script>
    <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shLegacy.js"></script>
    <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shAutoloader.js"></script>
    <link type="text/css" rel="stylesheet" href="/static/syntaxhighlighter/styles/shCoreDefault.css"/>
    <script type="text/javascript" src="/static/syntaxhighlighter/src/my_start_1.js"></script>
    
    
    
    
    
    </body>
    
    </html>