【狂神说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/1835509897106649088.htm"
                               title="Long类型前后端数据不一致" target="_blank">Long类型前后端数据不一致</a>
                            <span class="text-muted">igotyback</span>
    <a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a>
                            <div>响应给前端的数据浏览器控制台中response中看到的Long类型的数据是正常的到前端数据不一致前后端数据类型不匹配是一个常见问题,尤其是当后端使用Java的Long类型(64位)与前端JavaScript的Number类型(最大安全整数为2^53-1,即16位)进行数据交互时,很容易出现精度丢失的问题。这是因为JavaScript中的Number类型无法安全地表示超过16位的整数。为了解决这个问</div>
                        </li>
                        <li><a href="/article/1835509769822105600.htm"
                               title="LocalDateTime 转 String" target="_blank">LocalDateTime 转 String</a>
                            <span class="text-muted">igotyback</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>importjava.time.LocalDateTime;importjava.time.format.DateTimeFormatter;publicclassMain{publicstaticvoidmain(String[]args){//获取当前时间LocalDateTimenow=LocalDateTime.now();//定义日期格式化器DateTimeFormatterformat</div>
                        </li>
                        <li><a href="/article/1835509391361667072.htm"
                               title="Linux下QT开发的动态库界面弹出操作(SDL2)" target="_blank">Linux下QT开发的动态库界面弹出操作(SDL2)</a>
                            <span class="text-muted">13jjyao</span>
    <a class="tag" taget="_blank" href="/search/QT%E7%B1%BB/1.htm">QT类</a><a class="tag" taget="_blank" href="/search/qt/1.htm">qt</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/sdl2/1.htm">sdl2</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a>
                            <div>需求:操作系统为linux,开发框架为qt,做成需带界面的qt动态库,调用方为java等非qt程序难点:调用方为java等非qt程序,也就是说调用方肯定不带QApplication::exec(),缺少了这个,QTimer等事件和QT创建的窗口将不能弹出(包括opencv也是不能弹出);这与qt调用本身qt库是有本质的区别的思路:1.调用方缺QApplication::exec(),那么我们在接口</div>
                        </li>
                        <li><a href="/article/1835502578050363392.htm"
                               title="PHP环境搭建详细教程" target="_blank">PHP环境搭建详细教程</a>
                            <span class="text-muted">好看资源平台</span>
    <a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/php/1.htm">php</a>
                            <div>PHP是一个流行的服务器端脚本语言,广泛用于Web开发。为了使PHP能够在本地或服务器上运行,我们需要搭建一个合适的PHP环境。本教程将结合最新资料,介绍在不同操作系统上搭建PHP开发环境的多种方法,包括Windows、macOS和Linux系统的安装步骤,以及本地和Docker环境的配置。1.PHP环境搭建概述PHP环境的搭建主要分为以下几类:集成开发环境:例如XAMPP、WAMP、MAMP,这</div>
                        </li>
                        <li><a href="/article/1835498925755297792.htm"
                               title="DIV+CSS+JavaScript技术制作网页(旅游主题网页设计与制作)云南大理" target="_blank">DIV+CSS+JavaScript技术制作网页(旅游主题网页设计与制作)云南大理</a>
                            <span class="text-muted">STU学生网页设计</span>
    <a class="tag" taget="_blank" href="/search/%E7%BD%91%E9%A1%B5%E8%AE%BE%E8%AE%A1/1.htm">网页设计</a><a class="tag" taget="_blank" href="/search/%E6%9C%9F%E6%9C%AB%E7%BD%91%E9%A1%B5%E4%BD%9C%E4%B8%9A/1.htm">期末网页作业</a><a class="tag" taget="_blank" href="/search/html%E9%9D%99%E6%80%81%E7%BD%91%E9%A1%B5/1.htm">html静态网页</a><a class="tag" taget="_blank" href="/search/html5%E6%9C%9F%E6%9C%AB%E5%A4%A7%E4%BD%9C%E4%B8%9A/1.htm">html5期末大作业</a><a class="tag" taget="_blank" href="/search/%E7%BD%91%E9%A1%B5%E8%AE%BE%E8%AE%A1/1.htm">网页设计</a><a class="tag" taget="_blank" href="/search/web%E5%A4%A7%E4%BD%9C%E4%B8%9A/1.htm">web大作业</a>
                            <div>️精彩专栏推荐作者主页:【进入主页—获取更多源码】web前端期末大作业:【HTML5网页期末作业(1000套)】程序员有趣的告白方式:【HTML七夕情人节表白网页制作(110套)】文章目录二、网站介绍三、网站效果▶️1.视频演示2.图片演示四、网站代码HTML结构代码CSS样式代码五、更多源码二、网站介绍网站布局方面:计划采用目前主流的、能兼容各大主流浏览器、显示效果稳定的浮动网页布局结构。网站程</div>
                        </li>
                        <li><a href="/article/1835498547785592832.htm"
                               title="【华为OD机试真题2023B卷 JAVA&JS】We Are A Team" target="_blank">【华为OD机试真题2023B卷 JAVA&JS】We Are A Team</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/%E7%AE%97%E6%B3%95/1.htm">算法</a><a class="tag" taget="_blank" href="/search/%E5%8D%8E%E4%B8%BA/1.htm">华为</a><a class="tag" taget="_blank" href="/search/javascript/1.htm">javascript</a>
                            <div>华为OD2023(B卷)机试题库全覆盖,刷题指南点这里WeAreATeam时间限制:1秒|内存限制:32768K|语言限制:不限题目描述:总共有n个人在机房,每个人有一个标号(1<=标号<=n),他们分成了多个团队,需要你根据收到的m条消息判定指定的两个人是否在一个团队中,具体的:1、消息构成为:abc,整数a、b分别代</div>
                        </li>
                        <li><a href="/article/1835496149843275776.htm"
                               title="关于城市旅游的HTML网页设计——(旅游风景云南 5页)HTML+CSS+JavaScript" target="_blank">关于城市旅游的HTML网页设计——(旅游风景云南 5页)HTML+CSS+JavaScript</a>
                            <span class="text-muted">二挡起步</span>
    <a class="tag" taget="_blank" href="/search/web%E5%89%8D%E7%AB%AF%E6%9C%9F%E6%9C%AB%E5%A4%A7%E4%BD%9C%E4%B8%9A/1.htm">web前端期末大作业</a><a class="tag" taget="_blank" href="/search/javascript/1.htm">javascript</a><a class="tag" taget="_blank" href="/search/html/1.htm">html</a><a class="tag" taget="_blank" href="/search/css/1.htm">css</a><a class="tag" taget="_blank" href="/search/%E6%97%85%E6%B8%B8/1.htm">旅游</a><a class="tag" taget="_blank" href="/search/%E9%A3%8E%E6%99%AF/1.htm">风景</a>
                            <div>⛵源码获取文末联系✈Web前端开发技术描述网页设计题材,DIV+CSS布局制作,HTML+CSS网页设计期末课程大作业|游景点介绍|旅游风景区|家乡介绍|等网站的设计与制作|HTML期末大学生网页设计作业,Web大学生网页HTML:结构CSS:样式在操作方面上运用了html5和css3,采用了div+css结构、表单、超链接、浮动、绝对定位、相对定位、字体样式、引用视频等基础知识JavaScrip</div>
                        </li>
                        <li><a href="/article/1835496148601761792.htm"
                               title="HTML网页设计制作大作业(div+css) 云南我的家乡旅游景点 带文字滚动" target="_blank">HTML网页设计制作大作业(div+css) 云南我的家乡旅游景点 带文字滚动</a>
                            <span class="text-muted">二挡起步</span>
    <a class="tag" taget="_blank" href="/search/web%E5%89%8D%E7%AB%AF%E6%9C%9F%E6%9C%AB%E5%A4%A7%E4%BD%9C%E4%B8%9A/1.htm">web前端期末大作业</a><a class="tag" taget="_blank" href="/search/web%E8%AE%BE%E8%AE%A1%E7%BD%91%E9%A1%B5%E8%A7%84%E5%88%92%E4%B8%8E%E8%AE%BE%E8%AE%A1/1.htm">web设计网页规划与设计</a><a class="tag" taget="_blank" href="/search/html/1.htm">html</a><a class="tag" taget="_blank" href="/search/css/1.htm">css</a><a class="tag" taget="_blank" href="/search/javascript/1.htm">javascript</a><a class="tag" taget="_blank" href="/search/dreamweaver/1.htm">dreamweaver</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a>
                            <div>Web前端开发技术描述网页设计题材,DIV+CSS布局制作,HTML+CSS网页设计期末课程大作业游景点介绍|旅游风景区|家乡介绍|等网站的设计与制作HTML期末大学生网页设计作业HTML:结构CSS:样式在操作方面上运用了html5和css3,采用了div+css结构、表单、超链接、浮动、绝对定位、相对定位、字体样式、引用视频等基础知识JavaScript:做与用户的交互行为文章目录前端学习路线</div>
                        </li>
                        <li><a href="/article/1835495770502033408.htm"
                               title="Day17笔记-高阶函数" target="_blank">Day17笔记-高阶函数</a>
                            <span class="text-muted">~在杰难逃~</span>
    <a class="tag" taget="_blank" href="/search/Python/1.htm">Python</a><a class="tag" taget="_blank" href="/search/%E7%AC%94%E8%AE%B0/1.htm">笔记</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</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/pycharm/1.htm">pycharm</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90/1.htm">数据分析</a>
                            <div>高阶函数【重点掌握】函数的本质:函数是一个变量,函数名是一个变量名,一个函数可以作为另一个函数的参数或返回值使用如果A函数作为B函数的参数,B函数调用完成之后,会得到一个结果,则B函数被称为高阶函数常用的高阶函数:map(),reduce(),filter(),sorted()1.map()map(func,iterable),返回值是一个iterator【容器,迭代器】func:函数iterab</div>
                        </li>
                        <li><a href="/article/1835492740536823808.htm"
                               title="node.js学习" target="_blank">node.js学习</a>
                            <span class="text-muted">小猿L</span>
    <a class="tag" taget="_blank" href="/search/node.js/1.htm">node.js</a><a class="tag" taget="_blank" href="/search/node.js/1.htm">node.js</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a><a class="tag" taget="_blank" href="/search/vim/1.htm">vim</a>
                            <div>node.js学习实操及笔记温故node.js,node.js学习实操过程及笔记~node.js学习视频node.js官网node.js中文网实操笔记githubcsdn笔记为什么学node.js可以让别人访问我们编写的网页为后续的框架学习打下基础,三大框架vuereactangular离不开node.jsnode.js是什么官网:node.js是一个开源的、跨平台的运行JavaScript的运行</div>
                        </li>
                        <li><a href="/article/1835485429059645440.htm"
                               title="docker" target="_blank">docker</a>
                            <span class="text-muted">igotyback</span>
    <a class="tag" taget="_blank" href="/search/eureka/1.htm">eureka</a><a class="tag" taget="_blank" href="/search/%E4%BA%91%E5%8E%9F%E7%94%9F/1.htm">云原生</a>
                            <div>Docker容器的文件系统是隔离的,但是可以通过挂载卷(Volumes)或绑定挂载(BindMounts)将宿主机的文件系统目录映射到容器内部。要查看Docker容器的映射路径,可以使用以下方法:查看容器配置:使用dockerinspect命令可以查看容器的详细配置信息,包括挂载的卷。例如:bashdockerinspect在输出的JSON格式中,查找"Mounts"部分,这里会列出所有的挂载信息</div>
                        </li>
                        <li><a href="/article/1835476093189058560.htm"
                               title="Java 重写(Override)与重载(Overload)" target="_blank">Java 重写(Override)与重载(Overload)</a>
                            <span class="text-muted">叨唧唧的</span>
    
                            <div>Java重写(Override)与重载(Overload)重写(Override)重写是子类对父类的允许访问的方法的实现过程进行重新编写,返回值和形参都不能改变。即外壳不变,核心重写!重写的好处在于子类可以根据需要,定义特定于自己的行为。也就是说子类能够根据需要实现父类的方法。重写方法不能抛出新的检查异常或者比被重写方法申明更加宽泛的异常。例如:父类的一个方法申明了一个检查异常IOExceptio</div>
                        </li>
                        <li><a href="/article/1835473830873755648.htm"
                               title="简单了解 JVM" target="_blank">简单了解 JVM</a>
                            <span class="text-muted">记得开心一点啊</span>
    <a class="tag" taget="_blank" href="/search/jvm/1.htm">jvm</a>
                            <div>目录♫什么是JVM♫JVM的运行流程♫JVM运行时数据区♪虚拟机栈♪本地方法栈♪堆♪程序计数器♪方法区/元数据区♫类加载的过程♫双亲委派模型♫垃圾回收机制♫什么是JVMJVM是JavaVirtualMachine的简称,意为Java虚拟机。虚拟机是指通过软件模拟的具有完整硬件功能的、运行在一个完全隔离的环境中的完整计算机系统(如:JVM、VMwave、VirtualBox)。JVM和其他两个虚拟机</div>
                        </li>
                        <li><a href="/article/1835471058648526848.htm"
                               title="1分钟解决 -bash: mvn: command not found,在Centos 7中安装Maven" target="_blank">1分钟解决 -bash: mvn: command not found,在Centos 7中安装Maven</a>
                            <span class="text-muted">Energet!c</span>
    <a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a>
                            <div>1分钟解决-bash:mvn:commandnotfound,在Centos7中安装Maven检查Java环境1下载Maven2解压Maven3配置环境变量4验证安装5常见问题与注意事项6总结检查Java环境Maven依赖Java环境,请确保系统已经安装了Java并配置了环境变量。可以通过以下命令检查:java-version如果未安装,请先安装Java。1下载Maven从官网下载:前往Apach</div>
                        </li>
                        <li><a href="/article/1835469672334585856.htm"
                               title="Java企业面试题3" target="_blank">Java企业面试题3</a>
                            <span class="text-muted">马龙强_</span>
    <a class="tag" taget="_blank" href="/search/java/1.htm">java</a>
                            <div>1.break和continue的作用(智*图)break:用于完全退出一个循环(如for,while)或一个switch语句。当在循环体内遇到break语句时,程序会立即跳出当前循环体,继续执行循环之后的代码。continue:用于跳过当前循环体中剩余的部分,并开始下一次循环。如果是在for循环中使用continue,则会直接进行条件判断以决定是否执行下一轮循环。2.if分支语句和switch分</div>
                        </li>
                        <li><a href="/article/1835468916290318336.htm"
                               title="JVM、JRE和 JDK:理解Java开发的三大核心组件" target="_blank">JVM、JRE和 JDK:理解Java开发的三大核心组件</a>
                            <span class="text-muted">Y雨何时停T</span>
    <a class="tag" taget="_blank" href="/search/Java/1.htm">Java</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a>
                            <div>Java是一门跨平台的编程语言,它的成功离不开背后强大的运行环境与开发工具的支持。在Java的生态中,JVM(Java虚拟机)、JRE(Java运行时环境)和JDK(Java开发工具包)是三个至关重要的核心组件。本文将探讨JVM、JDK和JRE的区别,帮助你更好地理解Java的运行机制。1.JVM:Java虚拟机(JavaVirtualMachine)什么是JVM?JVM,即Java虚拟机,是Ja</div>
                        </li>
                        <li><a href="/article/1835464504918503424.htm"
                               title="Java面试题精选:消息队列(二)" target="_blank">Java面试题精选:消息队列(二)</a>
                            <span class="text-muted">芒果不是芒</span>
    <a class="tag" taget="_blank" href="/search/Java%E9%9D%A2%E8%AF%95%E9%A2%98%E7%B2%BE%E9%80%89/1.htm">Java面试题精选</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/kafka/1.htm">kafka</a>
                            <div>一、Kafka的特性1.消息持久化:消息存储在磁盘,所以消息不会丢失2.高吞吐量:可以轻松实现单机百万级别的并发3.扩展性:扩展性强,还是动态扩展4.多客户端支持:支持多种语言(Java、C、C++、GO、)5.KafkaStreams(一个天生的流处理):在双十一或者销售大屏就会用到这种流处理。使用KafkaStreams可以快速的把销售额统计出来6.安全机制:Kafka进行生产或者消费的时候会</div>
                        </li>
                        <li><a href="/article/1835462485629562880.htm"
                               title="白骑士的Java教学基础篇 2.5 控制流语句" target="_blank">白骑士的Java教学基础篇 2.5 控制流语句</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%95%99%E5%AD%A6/1.htm">教学</a><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>欢迎继续学习Java编程的基础篇!在前面的章节中,我们了解了Java的变量、数据类型和运算符。接下来,我们将探讨Java中的控制流语句。控制流语句用于控制程序的执行顺序,使我们能够根据特定条件执行不同的代码块,或重复执行某段代码。这是编写复杂程序的基础。通过学习这一节内容,你将掌握如何使用条件语句和循环语句来编写更加灵活和高效的代码。条件语句条件语句用于根据条件的真假来执行不同的代码块。if语句‘</div>
                        </li>
                        <li><a href="/article/1835462232612368384.htm"
                               title="python语法——三目运算符" target="_blank">python语法——三目运算符</a>
                            <span class="text-muted">HappyRocking</span>
    <a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/%E4%B8%89%E7%9B%AE%E8%BF%90%E7%AE%97%E7%AC%A6/1.htm">三目运算符</a>
                            <div>在java中,有三目运算符,如:intc=(a>b)?a:b表示c取两者中的较大值。但是在python,不能直接这样使用,估计是因为冒号在python有分行的关键作用。那么在python中,如何实现类似功能呢?可以使用ifelse语句,也是一行可以完成,格式为:aifbelsec表示如果b为True,则表达式等于a,否则等于c。如:c=(aif(a>b)elseb)同样是完成了取最大值的功能。</div>
                        </li>
                        <li><a href="/article/1835457442260021248.htm"
                               title="ArrayList 源码解析" target="_blank">ArrayList 源码解析</a>
                            <span class="text-muted">程序猿进阶</span>
    <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/ArrayList/1.htm">ArrayList</a><a class="tag" taget="_blank" href="/search/List/1.htm">List</a><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/%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96/1.htm">性能优化</a><a class="tag" taget="_blank" href="/search/%E6%9E%B6%E6%9E%84%E8%AE%BE%E8%AE%A1/1.htm">架构设计</a><a class="tag" taget="_blank" href="/search/idea/1.htm">idea</a>
                            <div>ArrayList是Java集合框架中的一个动态数组实现,提供了可变大小的数组功能。它继承自AbstractList并实现了List接口,是顺序容器,即元素存放的数据与放进去的顺序相同,允许放入null元素,底层通过数组实现。除该类未实现同步外,其余跟Vector大致相同。每个ArrayList都有一个容量capacity,表示底层数组的实际大小,容器内存储元素的个数不能多于当前容量。当向容器中添</div>
                        </li>
                        <li><a href="/article/1835454921990828032.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/%E6%A1%86%E6%9E%B6/1.htm">框架</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E4%BB%BB%E5%8A%A1/1.htm">任务</a><a class="tag" taget="_blank" href="/search/html%E8%A7%A3%E6%9E%90%E5%99%A8/1.htm">html解析器</a><a class="tag" taget="_blank" href="/search/%E5%AD%98%E5%82%A8/1.htm">存储</a><a class="tag" taget="_blank" href="/search/%E7%94%B5%E5%AD%90%E5%95%86%E5%8A%A1/1.htm">电子商务</a>
                            <div>一、架构图那里搜网络爬虫框架主要针对电子商务网站进行数据爬取,分析,存储,索引。爬虫:爬虫负责爬取,解析,处理电子商务网站的网页的内容数据库:存储商品信息索引:商品的全文搜索索引Task队列:需要爬取的网页列表Visited表:已经爬取过的网页列表爬虫监控平台:web平台可以启动,停止爬虫,管理爬虫,task队列,visited表。二、爬虫1.流程1)Scheduler启动爬虫器,TaskMast</div>
                        </li>
                        <li><a href="/article/1835454543471669248.htm"
                               title="Java:爬虫框架" target="_blank">Java:爬虫框架</a>
                            <span class="text-muted">dingcho</span>
    <a class="tag" taget="_blank" href="/search/Java/1.htm">Java</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E7%88%AC%E8%99%AB/1.htm">爬虫</a>
                            <div>一、ApacheNutch2【参考地址】Nutch是一个开源Java实现的搜索引擎。它提供了我们运行自己的搜索引擎所需的全部工具。包括全文搜索和Web爬虫。Nutch致力于让每个人能很容易,同时花费很少就可以配置世界一流的Web搜索引擎.为了完成这一宏伟的目标,Nutch必须能够做到:每个月取几十亿网页为这些网页维护一个索引对索引文件进行每秒上千次的搜索提供高质量的搜索结果简单来说Nutch支持分</div>
                        </li>
                        <li><a href="/article/1835450890077696000.htm"
                               title="python怎么将png转为tif_png转tif" target="_blank">python怎么将png转为tif_png转tif</a>
                            <span class="text-muted">weixin_39977276</span>
    
                            <div>发国外的文章要求图片是tif,cmyk色彩空间的。大小尺寸还有要求。比如网上大神多,找到了一段代码,感谢!https://www.jianshu.com/p/ec2af4311f56https://github.com/KevinZc007/image2Tifimportjava.awt.image.BufferedImage;importjava.io.File;importjava.io.Fi</div>
                        </li>
                        <li><a href="/article/1835448239864770560.htm"
                               title="JavaScript 中,深拷贝(Deep Copy)和浅拷贝(Shallow Copy)" target="_blank">JavaScript 中,深拷贝(Deep Copy)和浅拷贝(Shallow Copy)</a>
                            <span class="text-muted">跳房子的前端</span>
    <a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF%E9%9D%A2%E8%AF%95/1.htm">前端面试</a><a class="tag" taget="_blank" href="/search/javascript/1.htm">javascript</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/ecmascript/1.htm">ecmascript</a>
                            <div>在JavaScript中,深拷贝(DeepCopy)和浅拷贝(ShallowCopy)是用于复制对象或数组的两种不同方法。了解它们的区别和应用场景对于避免潜在的bugs和高效地处理数据非常重要。以下是对深拷贝和浅拷贝的详细解释,包括它们的概念、用途、优缺点以及实现方式。1.浅拷贝(ShallowCopy)概念定义:浅拷贝是指创建一个新的对象或数组,其中包含了原对象或数组的基本数据类型的值和对引用数</div>
                        </li>
                        <li><a href="/article/1835447859219099648.htm"
                               title="06选课支付模块之基于消息队列发送支付通知消息" target="_blank">06选课支付模块之基于消息队列发送支付通知消息</a>
                            <span class="text-muted">echo 云清</span>
    <a class="tag" taget="_blank" href="/search/%E5%AD%A6%E6%88%90%E5%9C%A8%E7%BA%BF/1.htm">学成在线</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/rabbitmq/1.htm">rabbitmq</a><a class="tag" taget="_blank" href="/search/%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97/1.htm">消息队列</a><a class="tag" taget="_blank" href="/search/%E6%94%AF%E4%BB%98%E9%80%9A%E7%9F%A5/1.htm">支付通知</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E6%88%90%E5%9C%A8%E7%BA%BF/1.htm">学成在线</a>
                            <div>消息队列发送支付通知消息需求分析订单服务作为通用服务,在订单支付成功后需要将支付结果异步通知给其他对接的微服务,微服务收到支付结果根据订单的类型去更新自己的业务数据技术方案使用消息队列进行异步通知需要保证消息的可靠性即生产端将消息成功通知到服务端:消息发送到交换机-->由交换机发送到队列-->消费者监听队列,收到消息进行处理,参考文章02-使用Docker安装RabbitMQ-CSDN博客生产者确</div>
                        </li>
                        <li><a href="/article/1835444076007223296.htm"
                               title="JAVA·一个简单的登录窗口" target="_blank">JAVA·一个简单的登录窗口</a>
                            <span class="text-muted">MortalTom</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%AD%A6%E4%B9%A0/1.htm">学习</a>
                            <div>文章目录概要整体架构流程技术名词解释技术细节资源概要JavaSwing是Java基础类库的一部分,主要用于开发图形用户界面(GUI)程序整体架构流程新建项目,导入sql.jar包(链接放在了文末),编译项目并运行技术名词解释一、特点丰富的组件提供了多种可视化组件,如按钮(JButton)、文本框(JTextField)、标签(JLabel)、下拉列表(JComboBox)等,可以满足不同的界面设计</div>
                        </li>
                        <li><a href="/article/1835438028009598976.htm"
                               title="WebMagic:强大的Java爬虫框架解析与实战" target="_blank">WebMagic:强大的Java爬虫框架解析与实战</a>
                            <span class="text-muted">Aaron_945</span>
    <a class="tag" taget="_blank" href="/search/Java/1.htm">Java</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E7%88%AC%E8%99%AB/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>文章目录引言官网链接WebMagic原理概述基础使用1.添加依赖2.编写PageProcessor高级使用1.自定义Pipeline2.分布式抓取优点结论引言在大数据时代,网络爬虫作为数据收集的重要工具,扮演着不可或缺的角色。Java作为一门广泛使用的编程语言,在爬虫开发领域也有其独特的优势。WebMagic是一个开源的Java爬虫框架,它提供了简单灵活的API,支持多线程、分布式抓取,以及丰富的</div>
                        </li>
                        <li><a href="/article/1835437775344726016.htm"
                               title="博客网站制作教程" target="_blank">博客网站制作教程</a>
                            <span class="text-muted">2401_85194651</span>
    <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/maven/1.htm">maven</a>
                            <div>首先就是技术框架:后端:Java+SpringBoot数据库:MySQL前端:Vue.js数据库连接:JPA(JavaPersistenceAPI)1.项目结构blog-app/├──backend/│├──src/main/java/com/example/blogapp/││├──BlogApplication.java││├──config/│││└──DatabaseConfig.java</div>
                        </li>
                        <li><a href="/article/1835435506645692416.htm"
                               title="00. 这里整理了最全的爬虫框架(Java + Python)" target="_blank">00. 这里整理了最全的爬虫框架(Java + Python)</a>
                            <span class="text-muted">有一只柴犬</span>
    <a class="tag" taget="_blank" href="/search/%E7%88%AC%E8%99%AB%E7%B3%BB%E5%88%97/1.htm">爬虫系列</a><a class="tag" taget="_blank" href="/search/%E7%88%AC%E8%99%AB/1.htm">爬虫</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a>
                            <div>目录1、前言2、什么是网络爬虫3、常见的爬虫框架3.1、java框架3.1.1、WebMagic3.1.2、Jsoup3.1.3、HttpClient3.1.4、Crawler4j3.1.5、HtmlUnit3.1.6、Selenium3.2、Python框架3.2.1、Scrapy3.2.2、BeautifulSoup+Requests3.2.3、Selenium3.2.4、PyQuery3.2</div>
                        </li>
                        <li><a href="/article/1835429581205630976.htm"
                               title="JAVA学习笔记之23种设计模式学习" target="_blank">JAVA学习笔记之23种设计模式学习</a>
                            <span class="text-muted">victorfreedom</span>
    <a class="tag" taget="_blank" href="/search/Java%E6%8A%80%E6%9C%AF/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/android/1.htm">android</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E5%B8%B8%E7%94%A8%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/1.htm">常用设计模式</a>
                            <div>博主最近买了《设计模式》这本书来学习,无奈这本书是以C++语言为基础进行说明,整个学习流程下来效率不是很高,虽然有的设计模式通俗易懂,但感觉还是没有充分的掌握了所有的设计模式。于是博主百度了一番,发现有大神写过了这方面的问题,于是博主迅速拿来学习。一、设计模式的分类总体来说设计模式分为三大类:创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。结构型模式,共七种:适配器</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>