微服务开发与实战Day02 - Docker

news2024/12/31 6:52:28

一、Docker快速入门

快速构建、运行、管理应用的工具

安装部署教程:Docs

1. 部署MySQL

测试连接:

镜像和容器

当我们利用Docker安装应用时,Docker会自动搜索并下载应用镜像(image)。镜像不仅包含应用本身,还包含应用运行所需的环境、配置、系统函数库。Docker会在运行镜像时创建一个隔离环境,称为容器(container)

镜像仓库:存储和管理镜像的平台,Docker官方维护了一个公共仓库:Dokcer Hub

2. 命令解读

docker run -d \

 --name mysql \

 -p 3306:3306 \

 -e TZ=Asia/Shanghai \

 -e MYSQL_ROOT_PASSWORD=123 \

 mysql

  • docker run -d :创建并运行一个容器,-d则是让容器以后台进程运行

  • --name mysql : 给容器起个名字叫mysql,你可以叫别的

  • -p 3306:3306 : 设置端口映射。

    • 容器是隔离环境,外界不可访问。但是可以宿主机端口映射容器内到端口,当访问宿主机指定端口时,就是在访问容器内的端口了。

    • 容器内端口往往是由容器内的进程决定,例如MySQL进程默认端口是3306,因此容器内端口一定是3306;而宿主机端口则可以任意指定,一般与容器内保持一致。

    • 格式: -p 宿主机端口:容器内端口,示例中就是将宿主机的3306映射到容器内的3306端口

  • -e TZ=Asia/Shanghai : 配置容器内进程运行时的一些参数

    • 格式:-e KEY=VALUE,KEY和VALUE都由容器内进程决定

    • 案例中,TZ=Asia/Shanghai是设置时区;MYSQL_ROOT_PASSWORD=123是设置MySQL默认密码

  • mysql : 设置镜像名称,Docker会根据这个名字搜索并下载镜像

    • 格式:REPOSITORY:TAG,例如mysql:5.7,其中REPOSITORY可以理解为镜像名,TAG是版本号

    • 在未指定TAG的情况下,默认是最新版本,也就是mysql:latest

二、Docker基础

1. 常见命令

Reference documentation | Docker Docs

Docker最常见的命令就是操作镜像、容器的命令,详见官方文档:https://docs.docker.com/

1.1 常用命令

命令说明
docker pull拉取镜像
docker push推送镜像到DockerRegistry
docker images查看本地镜像
docker rmi删除本地镜像
docker run创建并运行容器(不能重复创建)
docker stop停止指定容器
docker start启动指定容器
docker restart重新启动容器
docker rm删除指定容器
docker ps查看容器
docker logs查看容器运行日志
docker exec 进入容器
docker save保存镜像到本地压缩文件
docker load加载本地压缩文件到镜像
docker inspect查看容器详细信息

补充:默认情况下,每次重启虚拟机我们都需要手动启动Docker和Docker中的容器。通过命令可以实现开机自启动:

# Docker开机自启
systemctl enable docker

# Docker容器开机自启
docker update --restart=always [容器名/容器id]

案例:查看DockerHub,拉取Nginx镜像,创建并运行Nginx容器

需求:

  • 在DockerHub中搜索Nginx镜像,查看镜像的名称
  • 拉取Nginx镜像
  • 查看本地镜像列表
  • 创建并运行Nginx容器
  • 查看容器
  • 停止容器
  • 再次启动容器
  • 进入Nginx容器
  • 删除容器

①在DockerHub中搜索Nginx镜像,查看镜像的名称

②拉取Nginx镜像

docker pull nginx

③查看本地镜像列表

docker images

④将Nginx镜像保存为一个.tar文件

docker save -o nginx.tar nginx:latest

⑤查看容器

ll

⑥删除镜像

docker rmi nginx:latest

⑦加载Docker镜像

docker load -i nginx.tar

⑧创建并运行Nginx容器

docker run -d --name nginx -p 80:80 nginx

⑨验证是否运行成功

docker ps
或
docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"

⑩停止Nginx容器

docker stop nginx

11. 运行容器

docker start nginx

12. 查看nginx日志

docker logs nginx

13. 进入容器内部

docker exec -it nginx bash

退出:exit

1.2 命令别名

给常用的Docker命令起别名,方便我们访问:

i:进入编辑模式;先按Esc,后输入:wq保存退出。

# 修改/root/.bashrc文件
vi /root/.bashrc
内容如下:
# .bashrc

# User specific aliases and functions

alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
alias dps='docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"'
alias dis='docker images'

# Source global definitions
if [ -f /etc/bashrc ]; then
        . /etc/bashrc
fi

然后,质量命令使别名生效

source /root/.bashrc

2. 数据卷

数据卷(volume)是一个虚拟目录,是容器内目录宿主机目录之间映射的桥梁,方便我们操作容器内文件,或者方便迁移容器产生的数据。

以Nginx为例,我们知道Nginx中有两个关键的目录:

  • html:放置一些静态资源

  • conf:放置配置文件

如果我们要让Nginx代理我们的静态资源,最好是放到html目录;如果我们要修改Nginx的配置,最好是找到conf下的nginx.conf文件。

但遗憾的是,容器运行的Nginx所有的文件都在容器内部。所以我们必须利用数据卷将两个目录与宿主机目录关联,方便我们操作。如图:

在上图中:

  • 我们创建了两个数据卷:confhtml

  • Nginx容器内部的conf目录和html目录分别与两个数据卷关联。

  • 而数据卷conf和html分别指向了宿主机的/var/lib/docker/volumes/conf/_data目录和/var/lib/docker/volumes/html/_data目录

这样以来,容器内的confhtml目录就 与宿主机的confhtml目录关联起来,我们称为挂载。此时,我们操作宿主机的/var/lib/docker/volumes/html/_data就是在操作容器内的/usr/share/nginx/html/_data目录。只要我们将静态资源放入宿主机对应目录,就可以被Nginx代理了。

小提示

/var/lib/docker/volumes这个目录就是默认的存放所有容器数据卷的目录,其下再根据数据卷名称创建新目录,格式为/数据卷名/_data

为什么不让容器目录直接指向宿主机目录呢

  • 因为直接指向宿主机目录就与宿主机强耦合了,如果切换了环境,宿主机目录就可能发生改变了。由于容器一旦创建,目录挂载就无法修改,这样容器就无法正常工作了。

  • 但是容器指向数据卷,一个逻辑名称,而数据卷再指向宿主机目录,就不存在强耦合。如果宿主机目录发生改变,只要改变数据卷与宿主机目录之间的映射关系即可。

不过,我们通过由于数据卷目录比较深,不好寻找,通常我们也允许让容器直接与宿主机目录挂载而不使用数据卷。

命令说明
docker volume create创建数据卷
docker volume ls查看所有数据卷
docker volume rm删除指定数据卷
docker volume inspect查看某个数据卷的详情
docker volume prune清除数据卷

注意:容器与数据卷的挂载要在创建容器时配置,对于创建好的容器,是不能设置数据卷的。而且创建容器的过程中,数据卷会自动创建。

  • 在执行docker run命令时,使用 -v 数据卷:容器内目录 可以完成数据卷挂载
  • 当创建容器时,如果挂载了数据卷且数据卷不存在,会自动创建数据卷。 

案例1:利用Nginx容器部署静态资源

需求:

  • 创建Nginx容器,修改nginx容器内的html目录下的index.html文件,查看变化
  • 将静态资源部署到nginx的html目录

①进入nginx容器

docker exec -it nginx bash

②进入index.html文件存放目录

cd /usr/share/nginx/html

③查看目录下的所有文件

ls

④试图编辑index.html文件 -> command not found.

vi index.html

⑤先删除nginx容器

docker rm -f nginx

⑥创建并运行容器

 docker run -d --name nginx -p 80:80 -v html:/usr/share/nginx/html nginx

⑦查看容器列表

docker ps

⑧查看数据卷列表

docker volume ls

⑨查看数据卷的详情信息

docker volume inspect html

⑩进入目录,查看文件

cd /var/lib/docker/volumes/html/_data
ll

11. 打开index.html

cat index.html

案例2:mysql容器的数据挂载

  •  在执行docker run命令时,使用 -v 本地目录:容器内目录 可以完成本地目录挂载
  • 本地目录或文件必须以 /./开头,如果直接以名字开头,会被识别为数据卷名而非本地目录名
  • 例如:
-v mysql:/var/lib/mysql # 会被识别为一个数据卷叫mysql,运行时会自动创建这个数据卷
-v ./mysql:/var/lib/mysql # 会被识别为当前目录下的mysql目录,运行时如果不存在会创建目录

需求:

  • 查看mysql容器,判断是否有数据卷挂载
  • 基于宿主机目录实现MySQL数据目录、配置文件、初始化脚本的挂载

        ①挂载/root/mysql/data到容器内的/var/lib/mysql目录

        ②挂载/root/mysql/init到容器内的/docker-entrypoint-initdb.d目录,携带课前资料准备的SQL脚本

        ③挂载/root/mysql/conf到容器内的/etc/mysql/conf.d目录,携带课前资料准备的配置文件

①查看mysql容器详情(匿名数据卷,不方便管理)

docker inspect mysql

②创建文件夹

mkdir mysql # 根目录下
cd mysql/
mkdir data
mkdir conf
mkdir init

③把资料中的两个文件夹拖拽上传到mysql目录下

④删除原来的mysql容器

cd ~
docker rm -f mysql

⑤创建并运行mysql容器,挂载本地目录

docker run -d \
  --name mysql \
  -p 3306:3306 \
  -e TZ=Asia/Shanghai \
  -e MYSQL_ROOT_PASSWORD=123456 \
  -v ./mysql/data:/var/lib/mysql \
  -v ./mysql/conf:/etc/mysql/conf.d \
  -v ./mysql/init:/docker-entrypoint-initdb.d \
  mysql

3. 自定义镜像

镜像就是包含了应用程序、程序运行的系统函数库、运行配置等文件的文件包。构建镜像的过程其实就是把上述文件打包的过程。

3.1 镜像结构

第一步中需要的Linux运行环境,通用性很强,所以Docker官方就制作了这样的只包含Linux运行环境的镜像。我们在制作java镜像时,就无需重复制作,直接使用Docker官方提供的CentOS或Ubuntu镜像作为基础镜像。然后再搭建其它层即可,这样逐层搭建,最终整个Java项目的镜像结构如图所示:

3.2 Dockerfile

Dockerfile就是一个文本文件,其中包含一个个的指令(Instruction),用指令来说明要执行什么操作来构建镜像。将来Docker可以根据Dockerfile帮我们构建镜像。常见指令如下:

指令说明示例
FROM指定基础镜像FROM centos:6
ENV设置环境变量,可在后面指令使用ENV key value
COPY拷贝本地文件到镜像的指令目录COPY ./jrell.tar.gz /tmp
RUN执行Linux的shell命令,一般是安装过程的命令RUN tar -zxvf /tmp/jrell.tar.gz && EXPORTS path=/tmp/jrell:$path
EXPOSE指定容器运行时监听的端口,是给镜像使用者看的EXPOSE 8080
ENTRYPOINT镜像中应用的启动命令,容器运行时调用ENTRYPOINT java -jar xx.jar

官方文档:https://docs.docker.com/engine/reference/builder

我们可以基于Ubuntu基础镜像,利用Dockerfile描述镜像结构,也可以直接基于JDK为基础镜像,省略前面的步骤:

# 指定基础镜像
FROM ubuntu:16.04
# 配置环境变量,JDK的安装目录、容器内时区
ENV JAVA_DIR=/usr/local
ENV TZ=Asia/Shanghai
# 拷贝jdk和java项目的包
COPY ./jdk8.tar.gz $JAVA_DIR/
COPY ./docker-demo.jar /tmp/app.jar
# 设定时区
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 安装JDK
RUN cd $JAVA_DIR \
 && tar -xf ./jdk8.tar.gz \
 && mv ./jdk1.8.0_144 ./java8
# 配置环境变量
ENV JAVA_HOME=$JAVA_DIR/java8
ENV PATH=$PATH:$JAVA_HOME/bin
# 指定项目监听的端口
EXPOSE 8080
# 入口,java项目的启动命令
ENTRYPOINT ["java", "-jar", "/app.jar"]
# 基础镜像
FROM openjdk:11.0-jre-buster
# 设定时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 拷贝jar包
COPY docker-demo.jar /app.jar
# 入口
ENTRYPOINT ["java", "-jar", "/app.jar"]

当编写好了Dockerfile,可以利用下面的命令来构建镜像:

docker build -t myImage:1.0 .
  • -t:是给镜像起名,格式依然是repository:tag的格式,不指定tag时,默认为latest
  • .:是指定Dockerfile所在目录,如果就在当前目录,则指定为 "."

①上传资料里的demo文件夹到root目录下,删除其中的logs文件夹

②上传资料里的images/jdk.tar到root目录下

③加载镜像

docker load -i jdk.tar

④进入demo文件夹,执行构建命令

cd demo/
docker build -t docker-demo .

⑤运行

docker run -d --name dd -p 8080:8080 docker-demo

⑥查看运行状态

dps

⑦查看运行日志

docker logs -f dd

⑧通过网址访问(记得加上/hello/count

http://192.168.126.151:8080/hello/count

3.3 总结

1. 镜像的结构是怎么样的?

答:镜像中包含了应用程序所需要的运行环境、函数库、配置,以及应用本身等各种文件,这些文件分层打包而成。

2. Dockerfile是做什么的?

答:Dockerfile就是利用固定的指令来描述镜像的结构和构建过程,这样Docker才可以一次来构建镜像。

3. 构建镜像的命令是什么?

答:docker build -t 镜像名 Dockerfile目录

4. 容器网络

默认情况下,所有容器都是以bridge方式连接到Docker的一个虚拟网桥上:

容器的网络IP其实是一个虚拟的IP,其值并不固定与某一个容器绑定,如果我们在开发时写死某个IP,而在部署时很可能MySQL容器的IP会发生变化,连接会失败。

加入自定义网络的容器才可以通过容器名互相访问,Docker的网络操作命令如下:

命令说明
docker network create创建一个网络
docker network ls查看所有网络
docker network rm删除指定网络
docker network prune清除未使用的网络
docker network connect使指定容器连接加入某网络
docker network disconnect使指定容器连接离开某网络
docker network inspect查看网络详细信息

①创建一个网络

docker network create heima

ip addr

②使mysql容器连接加入黑马

docker network connect heima mysql
docker inspect mysql

现在mysql有两个network

③创建并运行容器的同时加入网络

docker run -d --name dd -p 8080:8080 --network heima  docker-demo
docker inspect dd

只有默认网桥

④进入dd容器

docker exec -it dd bash
ping mysql

ping nginx

三、项目部署

1. 部署Java应用

需求:将课前资料提供的hmall项目打包为镜像并部署,镜像名为hmall

①在IDEA打开hmall项目,修改pom.xml里lombok的版本号为1.18.30 (我用的JDK22)

<org.projectlombok.version>1.18.30</org.projectlombok.version>

②在application-dev.yaml中把数据库连接信息改成自己的

hm:
  db:
    host: mysql #容器名称
    pw: 123456

在application-local.yaml中修改相关信息

hm:
  db:
    host: 192.168.126.151 # 修改为你自己的虚拟机IP地址
    pw: 123456 # 修改为docker中的MySQL密码

③使用package打包(如果下载下来的项目中有一些文件名多了一些日期字段记得删除)

④把打包后的jar包和Dockerfile上传到虚拟机的root目录下

⑤构建

docker build -t hmall .

⑥查看

⑦删除dd容器,避免端口冲突

docker rm -f dd

⑧运行项目

docker run -d --name hm -p 8080:8080 --network heima hmall

⑨查看日志

docker logs -f hm

⑩访问测试

2. 部署前端

需求:创建一个新的nginx容器,将课前资料提供的nginx.conf、html目录与容器挂载

①把资料里的整个nginx文件夹上传到虚拟机的root目录下

注意,nginx.conf里的names字段要与虚拟机里配置的一致(记得修改两处

②先删除之前的nginx容器

docker rm -f nginx

③创建并运行容器

docker run -d \
  --name nginx \
  -p 18080:18080 \
  -p 18081:18081 \
  -v /root/nginx/html:/usr/share/nginx/html \
  -v /root/nginx/nginx.conf:/etc/nginx/nginx.conf \
  --network heima \
  nginx

④查看容器列表

⑤访问测试

docker logs -f hm

3. DockerCompose

Docker Compose通过一个单独的docker-compose.yml模板文件(YAMl格式)来定义一组相关联的应用容器,帮助我们实现多个相互关联的Docker容器的快速部署

docker compose的命令格式如下:

docker compose [OPTIONS] [COMMAND]
类型参数或指令说明
Options-f指定compose文件的路径和名称
-p指定project名称
Commandsup创建并启动所有service容器
down停止并移除所有容器、网络
ps列出所有启动的容器
logs查看指定容器的日志
stop停止容器
start启动容器
restart重启容器
top查看运行的进程
exec在指定的运行中容器中执行命令

步骤:

①把资料里的docker-compose.yml上传到虚拟机root目录下

version: "3.8"

services:
  mysql:
    image: mysql
    container_name: mysql
    ports:
      - "3306:3306"
    environment:
      TZ: Asia/Shanghai
      MYSQL_ROOT_PASSWORD: 123456
    volumes:
      - "./mysql/conf:/etc/mysql/conf.d"
      - "./mysql/data:/var/lib/mysql"
      - "./mysql/init:/docker-entrypoint-initdb.d"
    networks:
      - hm-net
  hmall:
    build: 
      context: .
      dockerfile: Dockerfile
    container_name: hmall
    ports:
      - "8080:8080"
    networks:
      - hm-net
    depends_on:
      - mysql
  nginx:
    image: nginx
    container_name: nginx
    ports:
      - "18080:18080"
      - "18081:18081"
    volumes:
      - "./nginx/nginx.conf:/etc/nginx/nginx.conf"
      - "./nginx/html:/usr/share/nginx/html"
    depends_on:
      - hmall
    networks:
      - hm-net
networks:
  hm-net:
    name: hmall

②把root/nginx/nginx.conf里的内容改回来(proxy-pass)

③删除之前创建的所有容器

docker rm -f nginx hm mysql/

④删除镜像hmall和docker-demo

docker rmi hmall docker-demo

⑤使用DockerCompose一键部署

docker compose up -d

注:有警告是因为在新的Docker Compose格式中version字段被移除了。

⑥查看所有启动的容器

docker compose ps

⑦查看容器列表

dis

⑧访问测试

⑨停止并移除所有容器、网络

docker compose down

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

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

相关文章

数字IC后端物理验证PV | TSMC 12nm Calibre Base Layer DRC案例解析

基于TSMC 12nm ARM A55 upf flow后端设计实现训练营将于6月中旬正式开班&#xff01;小班教学&#xff01;目前还有3个名额&#xff0c;招满为止&#xff01;有需要可以私信小编 ic-backend2018报名。吾爱IC社区所有训练营课程均为直播课&#xff01; 这个课程支持升级成双核A…

LeetCode322.零钱兑换

文章目录 题目描述解题思路递归记忆化搜索动态规划另一种实现 题目描述 https://leetcode.cn/problems/coin-change/description/?envTypestudy-plan-v2&envIdtop-interview-150 给你一个整数数组 coins &#xff0c;表示不同面额的硬币&#xff1b;以及一个整数 amount …

【全开源】废品回收垃圾回收小程序APP公众号源码PHP版本

&#x1f31f;废品回收小程序&#xff1a;绿色生活的新助手&#x1f331; 一、引言 随着环保意识的逐渐提高&#xff0c;废品回收成为了我们日常生活中的重要一环。但是&#xff0c;如何更方便、高效地进行废品回收呢&#xff1f;今天&#xff0c;我要向大家推荐一款超级实用的…

UE4获取动画序列资产的动画时长

谢谢”朝闻道“大佬的指点~

如何理解与学习数学分析——第二部分——数学分析中的基本概念——第6章——级数

第2 部分&#xff1a;数学分析中的基本概念 (Concepts in Analysis) 6. 级数(Series) 本章从等比级数(geometric series)开始&#xff0c;研究可以使用公式计算无限和的条件。它讨论了部分和与级数收敛的符号、图形表示和定义&#xff0c;并将它们应用于调和级数。它介绍了级…

从提示工程到代理工程:构建高效AI代理的策略框架概述

自ChatGPT推出以来&#xff0c;仅仅一年多的时间里&#xff0c;公众对于“人工智能”&#xff08;AI&#xff09;的认识已经发生了根本性的变化。这种变化部分源于公众意识的提高&#xff0c;更多则是基于这样一个认识&#xff1a;AI驱动的系统不仅可能&#xff0c;而且可能已经…

靠AI创意,我已经变现20w!

之前我一直在各个平台&#xff0c;分享各类的 AI 工具&#xff0c;但单纯地为了学而学&#xff0c;是没有任何意义的。 这些 AI 工具&#xff0c;学会了放着吃灰&#xff0c;那就太亏了&#xff01; 最近在和粉丝聊的过程中&#xff0c;发现大家对 AI 副业还是挺感兴趣的。 …

「Qt Widget中文示例指南」如何实现一个简单的RHI小部件示例(二)

Qt 是目前最先进、最完整的跨平台C开发工具。它不仅完全实现了一次编写&#xff0c;所有平台无差别运行&#xff0c;更提供了几乎所有开发过程中需要用到的工具。如今&#xff0c;Qt已被运用于超过70个行业、数千家企业&#xff0c;支持数百万设备及应用。 本文将为大家演示如…

重学java 52.Collections集合工具类、泛型

"我已不在地坛&#xff0c;地坛在我" —— 《想念地坛》 24.5.28 一、Collections集合工具类 1.概述:集合工具类 2.特点: a.构造私有 b.方法都是静态的 3.使用:类名直接调用 4.方法: static <T> boolean addAll(collection<? super T>c,T... el…

学习笔记——IP地址网络协议——网络掩码(Netmask)

三、网络掩码(Netmask) 1、网络掩码概述 网络掩码(Netmask)又称子网掩码(Subnet Mask)网络掩码为32 bit&#xff0c;与IP地址的位数一样&#xff0c;通常也以点分十进制数来表示。 子网掩码不能单独存在&#xff0c;它必须结合IP地址一起使用。子网掩码只有一个作用&#xf…

SpringBoot 单元测试 指定 环境

如上图所示&#xff0c;在配置窗口中添加--spring.profiles.activedev&#xff0c;就可以了。

创建采购订单免费行项目,注意事项

1.我在使用bapi&#xff08;BAPI_PO_CREATE1&#xff09;创建采购订单免费行项目的时候&#xff0c;还是报错了请输入净价格。 解决方式&#xff1a;把这些数据都赋值好&#xff0c;那么你的采购订单行项目就是免费项目。 BAPIMEPOITEM-IR_IND 空 &#xff08;发票收据标识&am…

【C语言】文件操作(终卷)

前言 我们在上一卷中了解了顺序读写的函数&#xff0c;现在就让我们从随机读写的函数开始吧。 什么是随机读写&#xff1f; 就是想在哪个位置读或写都行&#xff0c;比较自由。文件打开时光标默认在起始位置。想从后面的某个部分读或写&#xff0c;就得让文件指针来到那个位…

Linux系统Docker部署Apache Superset并实现远程访问详细流程

目录 前言 1. 使用Docker部署Apache Superset 1.1 第一步安装docker 、docker compose 1.2 克隆superset代码到本地并使用docker compose启动 2. 安装cpolar内网穿透&#xff0c;实现公网访问 3. 设置固定连接公网地址 前言 作者简介&#xff1a; 懒大王敲代码&#xff0…

【小工具】电磨机

BUSCH DREMEL3000 博世 琢美 技术规范

儿童护眼灯什么牌子好点?五款儿童护眼灯品牌推荐

儿童护眼灯什么牌子好点&#xff1f;根据往年的统计&#xff0c;我国青少年近视率位居世界第一&#xff0c;儿童青少年总体近视率达到了52.7%。其中&#xff0c;6岁儿童的近视率为14.5%&#xff0c;小学生为36.0%&#xff0c;初中生为71.6%&#xff0c;高中生为81%。造成近视的…

事务与锁的顺序不对导致并发的问题

错误使用锁和事务导致并发 在事务中添加锁来解决并发的问题&#xff0c;这并没有解决并发的问题。 Transactional Override public void execute(){try {lock.lock()// 开启锁// 查询出数据mapper.select();// 根据查询出数据计算并写入到数据库中mapper.udpate()} finally {…

Java 中的 Map 集合:入门篇

在 Java 编程中&#xff0c;Map 是用于存储键值对。它提供了快速的查找和检索功能&#xff0c;是处理大量数据的理想选择。 本文将深入介绍 Java 中的 Map 集合&#xff0c;包括其基本概念、常见实现类、典型用法以及一些常见问题的解决方案。 1. Map 的基本概念 Map 是一种键…

#01 Stable Diffusion基础入门:了解AI图像生成

文章目录 前言什么是Stable Diffusion?Stable Diffusion的工作原理如何使用Stable Diffusion?Stable Diffusion的应用场景结论 前言 在当今迅速发展的人工智能领域&#xff0c;AI图像生成技术以其独特的魅力吸引了广泛的关注。Stable Diffusion作为其中的一项前沿技术&#…

2. keepalived结合LVS配合使用

keepalived结合LVS配合使用 1、后端nfs存储提供项目文件2、后端nfs上集中安装MySQL&#xff0c;共用数据库3、业务服务器通过LNMP正常部署wordpress博客&#xff0c;客户端通过DNS解析可正常访问4、所有业务服务器上修改arp参数、配置VIP5、配置keepalived实现LVS高可用5.1 kee…