Docker Compose使用
Docker-Compose是什么
docker建议我们每一个容器中只运行一个服务,因为doker容器本身占用资源极少,所以最好是将每个服务单独分割开来,但是这样我们又面临了一个问题:
如果我需要同时部署好多个服务,难道要每个服务单独写Dockerfile然后在构建镜像,构建容器,这样累都累死了,所以docker官方给我们提供了docker-compose多服务部署的工具。
例如要实现一个Web微服务项目,除了Web服务容器本身,往往还需要再加上后端的数据库mysqI服务容器,redis服务容器,注册中心naocs,甚至还包括负载均衡容器等等。。。
Compose允许用户通过一个单独的docker-compose.yml模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project),
可以很容易地用一个配置文件定义一个多容器的应用,然后使用一条指令安装这个应用的所有依赖,完成构建。Docker-Compose 解决了容器与容器之间如何管理编排的问题。
Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。它使用一个 YAML 文件来配置应用程序的服务,然后使用一个单一的命令部署和启动应用程序的全部服务。
使用 Docker Compose 的主要优势包括:
- 简化容器编排: Compose 允许你在单个配置文件中定义整个应用程序栈,包括不同的服务、网络和存储卷等。这大大简化了容器编排的复杂性。
- 一致的开发环境: Compose 确保开发、测试和生产环境的一致性,因为所有环境都使用相同的 Compose 文件。
- 快速部署: Compose 可以一次性启动应用程序的所有服务,大大加快了部署速度。
- 扩展性: Compose 允许你轻松地扩展应用程序的任何服务。
使用 Docker Compose 的一般流程如下:
- 创建一个
docker-compose.yml文件,定义应用程序的服务。 - 在终端中运行
docker-compose up命令来启动应用程序。 - 运行
docker-compose down命令来停止并删除容器。
Compose 支持多种配置选项,例如指定服务的镜像、端口映射、环境变量、依赖关系等。这使得管理复杂的多容器应用程序变得更加简单和高效。
下载安装
如果你的网很慢,访问不了外网,可以去这里的百度盘直接下载,也包括下面微服务用到的jar包
链接:https://pan.baidu.com/s/1LcwN-LbfKt10ul8d9_-sCA
提取码:wzyy
官网地址
https://docs.docker.com/compose/
在 CentOS 下下载最新版本的 Docker Compose 文件,可以使用以下命令:
curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
这个命令会:
- 使用
curl命令从 GitHub 上下载最新版本的 Docker Compose 文件。 - 将文件保存到
/usr/local/bin/docker-compose目录下。
下载完成后,还需要执行以下命令来赋予可执行权限:
chmod +x /usr/local/bin/docker-compose
这样就可以在 CentOS 系统上使用 docker-compose 命令了。
如果你想确认当前安装的 Docker Compose 版本,可以执行以下命令:
docker-compose --version
这将显示已安装的 Docker Compose 版本信息。
需要注意的是,这个命令下载的是最新版本的 Docker Compose。如果你需要使用特定版本,可以在下载链接中指定版本号,例如:
curl -L https://github.com/docker/compose/releases/download/v2.17.3/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
这将下载 v2.17.3 版本的 Docker Compose。
执行上述命令
[root@localhost ~]# curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose% Total % Received % Xferd Average Speed Time Time Time CurrentDload Upload Total Spent Left Speed0 0 0 0 0 0 0 0 --:--:-- 0:00:01 --:--:-- 00 0 0 0 0 0 0 0 --:--:-- 0:00:01 --:--:-- 0
100 60.0M 100 60.0M 0 0 156k 0 0:06:33 0:06:33 --:--:-- 570k
[root@localhost ~]# chmod +x /usr/local/bin/docker-compose
[root@localhost ~]# docker-compose --version
Docker Compose version v2.27.0
[root@localhost ~]#
如果想要卸载,执行
rm /usr/local/bin/docker-compose
核心概念
Docker Compose 的核心概念包括以下几点,其中最重要的是
服务、配置文件和工程。可以理解为:通过配置文件 (
docker-compose.yml),将多个服务 (Services),组合成一个工程 (project) 。
- 服务 (
Services): Docker Compose 的基本构建块是服务。一个服务代表一个 Docker 容器,可以包含应用程序、数据库、消息队列等组件。每个服务都有自己的配置,如镜像、端口映射、环境变量等。 - 配置文件 (
docker-compose.yml): 所有的 Compose 配置都定义在一个 YAML 格式的配置文件中,通常命名为docker-compose.yml。该文件描述了整个应用程序的结构,包括各个服务、网络和卷的定义。 - 工程 (
project):在 Docker Compose 中,Project 表示一组相关的服务,它们会被一起管理和部署。docker-compose.yml文件定义了 Project 中的所有服务、网络和卷,同一个 Project 可以包含多个 docker-compose.yml 文件,比如一个用于开发环境、一个用于生产环境。 - 网络 (Networks): Docker Compose 可以自动创建并管理容器之间的网络连接。你可以为不同的服务指定不同的网络,实现容器之间的隔离和通信。
- 卷 (Volumes): Compose 可以管理持久化数据存储,包括创建和挂载卷。这样可以确保数据在容器重启或删除后不会丢失。
- 命令行工具 (docker-compose): Compose 提供了一个命令行工具
docker-compose,可用于管理整个应用程序的生命周期,包括构建、启动、停止、查看日志等操作。 - 扩展性 (Scaling): Compose 支持轻松地水平扩展服务实例的数量,可以根据需求动态增加或减少容器的数量。
- 依赖管理: Compose 会自动处理服务之间的依赖关系,确保先启动依赖服务再启动被依赖服务。
总的来说,Docker Compose 提供了一种声明式的方式来定义和管理整个应用程序的基础设施,使得应用程序的部署和扩展变得更加简单和高效。
使用步骤
- 编写
Dockerfile定义各个微服务应用并构建出对应的镜像文件。 - 使用
docker-compose.yml定义一个完整业务单元,安排好整体应用中的各个容器服务。 - 最后,执行
docker-compose up命令来启动并运行整个应用程序,完成一键部署上线。
常用的命令
Docker Compose 提供了一系列常用的命令,下面是一些常用的命令及其用途:
-
docker-compose up
- 启动并运行整个应用程序
- 可以使用
-d参数在后台运行 - 如果镜像不存在,会自动构建
-
docker-compose down
- 停止并删除整个应用程序
- 包括容器、网络和卷
-
docker-compose ps
列出当前 Project 中正在运行的容器
-
docker-compose build
构建或重新构建服务的镜像
-
docker-compose start/stop/restart
分别启动、停止或重启整个应用程序
-
docker-compose logs 服务id
查看应用程序的日志输出,可以使用
-f参数实时查看日志
-
docker-compose exec 服务id
进入正在运行的容器内部,可以在容器内部执行命令
-
docker-compose config
验证并查看
docker-compose.yml文件的配置docker-compose config -q: 检查配置,只是在出现问题时才会输出信息
-
docker-compose pull:
拉取服务所需的镜像
-
docker-compose scale
动态调整某个服务的容器数量
这些只是 Docker Compose 最常用的一些命令,实际上 Compose 还有更多功能和命令可供使用。
编写配置文件
写一个docker-compose.yml,并进行服务编排
要确保下面配置中,所有的volumes:下面的挂载点目录已存在,不存在要先创建
(注意:目前新版的docker-compose默认可以不用写version了)
services:#自定义的服务名,必须小写eureka7001:#指定dockerfile来构建镜像并运行实例,context用来指定Dockerfile所在的目录build:context: /wzy/cloud-images/eurekadockerfile: Dockerfile#image: eureka_docker:1.0 #如果有现成的镜像,可以在这里指定,直接用来运行容器,使用此项要注释掉build及其内容#container_name: eureka01 指定容器的名字,如果不指定,会由docker自动生成ports:- "7001:7001"#挂载容器卷 volumes:- /wzy/eurekaService:/data #指定使用的网络,所有服务的网络一致,即可以使用服务名通信忽略ip地址 networks:- wzy_net#自定义的服务名,必须小写payment8001:build:context: /wzy/cloud-images/pay8001dockerfile: Dockerfile #image: payment01_docker:1.0#container_name: payment01ports:- "8001:8001"volumes:- /wzy/paymentMysqlService:/data networks:- wzy_net#指定本服务依赖的服务,会等依赖的服务运行后在运行本服务 depends_on:- eureka7001 - mysql #自定义的服务名,必须小写 payment8002:build:context: /wzy/cloud-images/pay8002dockerfile: Dockerfile #image: payment02_docker:1.0#container_name: payment02ports:- "8002:8002"volumes:- /wzy/paymentRedisService:/data networks:- wzy_netdepends_on:- eureka7001- redis #自定义的服务名,必须小写,也可以叫别的,springboot服务可以在yaml中将redis的ip换成这个名字 redis:image: redis:6.2.6ports:- "6379:6379"volumes:- /wzy/redis/redis.conf:/etc/redis/redis.conf- /wzy/redis/data:/data networks:- wzy_net#运行指令 command: redis-server /etc/redis/redis.conf #自定义的服务名,必须小写,也可以叫别的,springboot服务可以在yaml中将redis的ip换成这个名字 mysql:image: mysql:latest#环境参数配置environment:#注意这里的密码要和微服务连接mysql的配置对应上MYSQL_ROOT_PASSWORD: '123456'MYSQL_ALLOW_EMPTY_PASSWORD: 'NO'MYSQL_DATABASE: 'mybatis-plus'MYSQL_USER: 'wzy'MYSQL_PASSWORD: '123456'ports:- "3306:3306"volumes: - /wzy/mysql/log:/var/log/mysql- /wzy/mysql/data:/var/lib/mysql- /wzy/mysql/conf:/etc/mysql/conf.dnetworks:- wzy_netcommand: --default-authentication-plugin=mysql_native_password #解决外部无法访问#创建网络
networks:wzy_net:
微服务展示
除了docker中的redis及mysql之外,这里还用了三个springcloud服务做演示:
- mysql的微服务实现向mysql数据库插入数据
- redis的微服务实现向redis插入数据
- eureka中会注册上面两个微服务
eureka的服务
主要展示配置文件,代码就不展示了,需要的话去上面的下载安装标题处提取
主要是hostname,这里写成了eureka7001,就是上面编排文件的eureka的服务名,因为配置网络后可以直接忽略ip使用服务名,可以解决网络ip变动服务通信失败问题
server:port: 7001eureka:instance:#用docker服务名,不用iphostname: eureka7001client:#表示是否将自己注册进eureka,本moudle本身就是注册中心,不需要注册register-with-eureka: false#表示自己就是注册中心,维护服务实例,其他服务要注册到本moudle中fetch-registry: false#设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址service-url:#defaultZone: http://erueka7002.com:7002/eureka #集群配置指向另一个服务注册中心defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #单机配置#Eureka自我保护模式:当微服务在默认90秒内不发送心跳给eureka注册中心后,不会立刻抹除微服务得信息server:enable-self-preservation: false #禁用自我保护eviction-interval-timer-in-ms: 5000 #毫秒,设置多少毫秒微服务不可用就剔除
mysql的微服务
sql
代码中要用到的表
CREATE TABLE `number_test` (`one` int NOT NULL,`two` varchar(255) DEFAULT NULL,`three` varchar(255) DEFAULT NULL,`four` varchar(255) DEFAULT NULL,PRIMARY KEY (`one`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
ymal
数据库
datasource的url处使用编排文件的服务名,eureka的service-url的defaultZone用编排文件中erueka注册中心的服务名
server:port: 8001spring:application:name: cloud-payment-servicedatasource:driver-class-name: com.mysql.cj.jdbc.Driver#mysql:3306,使用docker服务名,不用ipurl: jdbc:mysql://mysql:3306/mybatis-plus?nullCatalogMeansCurrent=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8username: wzypassword: 123456mybatis-plus:mapper-locations: classpath:/mapper/*Mapper.xmleureka:client:#表示是否将自己注册进eurekaregister-with-eureka: true#是否从eurekaServer抓取已有注册信息,默认为true。单点无所谓,集群必须设置true才能配合Ribbon使用负载均衡fetchRegistry: true#入驻的eureka服务地址service-url:#############使用docker服务名,不用ip#############defaultZone: http://eureka7001:7001/eureka #单机版#defaultZone: http://erueka7001.com:7001/eureka,http://erueka7002.com:7002/eureka #集群版#配置eureka前台界面服务名字的status名字显示instance:instance-id: payment8001prefer-ip-address: true #访问路径可以显示ip地址#Eureka客户端向服务端发送心跳的时间间隔,单位秒lease-renewal-interval-in-seconds: 10#Eureka服务端在收到最后一次心跳后等待时间上限,单位秒(默认是90秒),超时将认为服务不可用lease-expiration-duration-in-seconds: 20
Controller
@RestController
@RequestMapping("ntest")
public class NumberTestController {@Autowiredprivate NumberTestService numberTestService;@GetMapping("save")public boolean insertTest(){NumberTest test = new NumberTest();test.setOne(1);test.setTwo("2");test.setThree("3");test.setFour("4");return numberTestService.save(test);}}
访问地址
http://localhost:8001/ntest/save
redis的微服务
yaml
host处使用编排redis的服务名,因为本微服务要连接docker的redis容器
server:port: 8002spring:application:name: cloud-payment-serviceredis:#使用docker服务名,不用iphost: redisport: 6379lettuce:shutdown-timeout: 0 # 连接超时时间(毫秒)pool:max-active: 8max-wait: -1max-idle: 500min-idle: 0eureka:client:#表示是否将自己注册进eurekaregister-with-eureka: true#是否从eurekaServer抓取已有注册信息,默认为true。单点无所谓,集群必须设置true才能配合Ribbon使用负载均衡fetchRegistry: true#入驻的eureka服务地址service-url:#############使用docker服务名,不用ip#############defaultZone: http://eureka7001:7001/eureka #单机版#defaultZone: http://erueka7001.com:7001/eureka,http://erueka7002.com:7002/eureka #集群版#配置eureka前台界面服务名字的status名字显示instance:instance-id: payment8002prefer-ip-address: true #访问路径可以显示ip地址
config
/*** SpringBoot自动帮我们在容器中生成了一个RedisTemplate和一个StringRedisTemplate。* 但是,这个RedisTemplate的泛型是<Object,Object>,写代码不方便,需要写好多类型转换的代码;* 我们需要一个泛型为<String,Object>形式的RedisTemplate。* 并且,这个默认的RedisTemplate没有设置数据存在Redis时,key及value的序列化方式。如果不序列化,写入redis会报错** */
@Configuration
public class RedisConfig {@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();template.setConnectionFactory(factory);Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);ObjectMapper om = new ObjectMapper();om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);jackson2JsonRedisSerializer.setObjectMapper(om);StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();// key采用String的序列化方式,此处为除hash外其他的类型全部做设置template.setKeySerializer(stringRedisSerializer);// hash的key也采用String的序列化方式template.setHashKeySerializer(stringRedisSerializer);// value序列化方式采用jacksontemplate.setValueSerializer(jackson2JsonRedisSerializer);// hash的value序列化方式采用jacksontemplate.setHashValueSerializer(jackson2JsonRedisSerializer);template.afterPropertiesSet();return template;}
}
controller
@RestController
@RequestMapping("payment")
public class payment {@Autowiredprivate RedisTemplate redisTemplate;@GetMapping("/redis")public void setCacheObject() {redisTemplate.opsForValue().set("test-key", "test-value");}
}
访问地址
http://localhost:8002/payment/redis
编写Dockerfile
没有写mysql与redis的Dockerfile,因为如果本地没有镜像会自动拉取,我这里复用了以前的镜像,详细安装请参考本专栏的docker安装应用部分:
https://blog.csdn.net/onePlus5T/article/details/139102535
构建eureka的Dockerfile,连同jar包放入编排文件指定的/wzy/cloud-images/eureka目录中
#基础镜像使用java
FROM java:8#作者
MAINTAINER wzy#VOLUME指定临时文件目录为/tmp,在主机/var/lib/docker目录下创建了一个临时文件并链接到容器的/tmp
VOLUME /tmp#将jar包添加到容器中并更名为wzy_eureka.jar
ADD cloud-eureka-server-1.0-SNAPSHOT.jar wzy_eureka.jar# 运行jar包
RUN bash -c 'touch /wzy_eureka.jar'
ENTRYPOINT ["java","-jar","/wzy_eureka.jar"]#暴露7001端口,因为上面的代码的端口也是7001
EXPOSE 7001
构建mysql微服务-8001的Dockerfile,连同jar包放入编排文件指定的/wzy/cloud-images/pay8001目录中
#基础镜像使用java
FROM java:8#作者
MAINTAINER wzy#VOLUME指定临时文件目录为/tmp,在主机/var/lib/docker目录下创建了一个临时文件并链接到容器的/tmp
VOLUME /tmp#将jar包添加到容器中并更名为wzy_payment8001.jar
ADD cloud-provider-payment8001-1.0-SNAPSHOT.jar wzy_payment8001.jar# 运行jar包
RUN bash -c 'touch /wzy_payment8001.jar'
ENTRYPOINT ["java","-jar","/wzy_payment8001.jar"]#暴露8001端口,因为上面的代码的端口也是8001
EXPOSE 8001
构建redis微服务-8002的Dockerfile,连同jar包放入编排文件指定的/wzy/cloud-images/pay8002目录中
#基础镜像使用java
FROM java:8#作者
MAINTAINER wzy#VOLUME指定临时文件目录为/tmp,在主机/var/lib/docker目录下创建了一个临时文件并链接到容器的/tmp
VOLUME /tmp#将jar包添加到容器中并更名为wzy_payment8002.jar
ADD cloud-provider-payment8002-1.0-SNAPSHOT.jar wzy_payment8002.jar# 运行jar包
RUN bash -c 'touch /wzy_payment8002.jar'
ENTRYPOINT ["java","-jar","/wzy_payment8002.jar"]#暴露8002端口,因为上面的代码的端口也是8002
EXPOSE 8002
运行编排
无论将 docker-compose.yml 文件放在哪里,只要确保在执行 Docker Compose 命令时,能正确地指定 Compose 文件的路径即可。比如:
docker-compose -f /wzy/docker-compose.yml up -d
再执行前,可以检查编排配置文件是否有问题,如果执行如下命令没有如何输出,就是没问题 (这里建议先去yaml在线格式化网站校验一下):
docker-compose config -q
这里建议将docker相关内容进行统一存放,我就是存放在了wzy的路径,直接运行:
[root@localhost wzy]# docker-compose config -q
[root@localhost wzy]# docker-compose -f /wzy/docker-compose.yml up -d
[+] Building 35.9s (20/20) FINISHED docker:default=> [eureka7001 internal] load build definition from Dockerfile 0.1s=> => transferring dockerfile: 579B 0.0s=> [payment8002 internal] load metadata for docker.io/library/java:8 30.8s=> [eureka7001 internal] load .dockerignore 0.0s=> => transferring context: 2B 0.0s=> [eureka7001 internal] load build context 0.3s=> => transferring context: 48.86MB 0.3s=> CACHED [payment8002 1/3] FROM docker.io/library/java:8@sha256:c1ff613e8ba258 0.0s=> [eureka7001 2/3] ADD cloud-eureka-server-1.0-SNAPSHOT.jar wzy_eureka.jar 0.3s=> [eureka7001 3/3] RUN bash -c 'touch /wzy_eureka.jar' 1.0s=> [eureka7001] exporting to image 0.2s=> => exporting layers 0.2s=> => writing image sha256:7927120cce252cd5db9ac32eca62c814f6f9005029a9585b9927 0.0s=> => naming to docker.io/library/wzy-eureka7001 0.0s=> [payment8001 internal] load build definition from Dockerfile 0.0s=> => transferring dockerfile: 606B 0.0s=> [payment8002 internal] load build definition from Dockerfile 0.0s=> => transferring dockerfile: 606B 0.0s=> [payment8002 internal] load .dockerignore 0.0s=> => transferring context: 2B 0.0s=> [payment8001 internal] load .dockerignore 0.0s=> => transferring context: 2B 0.0s=> [payment8001 internal] load build context 0.5s=> => transferring context: 66.18MB 0.5s=> [payment8002 internal] load build context 0.5s=> => transferring context: 60.94MB 0.5s=> [payment8001 2/3] ADD cloud-provider-payment8001-1.0-SNAPSHOT.jar wzy_paymen 0.5s=> [payment8002 2/3] ADD cloud-provider-payment8002-1.0-SNAPSHOT.jar wzy_paymen 0.6s=> [payment8001 3/3] RUN bash -c 'touch /wzy_payment8001.jar' 0.9s=> [payment8002 3/3] RUN bash -c 'touch /wzy_payment8002.jar' 0.7s=> [payment8001] exporting to image 0.3s=> => exporting layers 0.3s=> => writing image sha256:983970a54834e6e04ad037f12e5623fd43fc270d5358173ab8a9 0.0s=> => naming to docker.io/library/wzy-payment8001 0.0s=> [payment8002] exporting to image 0.3s=> => exporting layers 0.3s=> => writing image sha256:f9ba7c533f0efb7138d0906c10c26a66b4bd3bb73d79317dbd8d 0.0s=> => naming to docker.io/library/wzy-payment8002 0.0s
[+] Running 6/6✔ Network wzy_wzy_net Created 0.9s ✔ Container wzy-eureka7001-1 Started 1.2s ✔ Container wzy-redis-1 Started 1.5s ✔ Container wzy-mysql-1 Started 1.6s ✔ Container wzy-payment8001-1 Started 4.7s ✔ Container wzy-payment8002-1 Started
[root@localhost wzy]#
以上全部Started就是成功。
注意:上面编排后生成的名字有一些变化,比如redis服务名变成了wzy-redis-1,这是在没有指定名字的情况下docker自己加的,并不影响使用
建表
这时,mysql会根据编排文件自动建立mybatis-plus库,但并不会自动建表:
[root@localhost wzy]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
afe3ca78cc28 wzy-payment8002 "java -jar /wzy_paym…" 8 seconds ago Up 4 seconds 0.0.0.0:8002->8002/tcp, :::8002->8002/tcp wzy-payment8002-1
6e169d6e50de wzy-payment8001 "java -jar /wzy_paym…" 8 seconds ago Up 4 seconds 0.0.0.0:8001->8001/tcp, :::8001->8001/tcp wzy-payment8001-1
490549ec53e8 wzy-eureka7001 "java -jar /wzy_eure…" 8 seconds ago Up 6 seconds 0.0.0.0:7001->7001/tcp, :::7001->7001/tcp wzy-eureka7001-1
2d9e86240ee2 mysql:latest "docker-entrypoint.s…" 20 hours ago Up 6 seconds 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp wzy-mysql-1
d8f5e56fde6d redis:6.2.6 "docker-entrypoint.s…" 20 hours ago Up 6 seconds 0.0.0.0:6379->6379/tcp, :::6379->6379/tcp wzy-redis-1
[root@localhost wzy]# docker exec -it 2d9e86240ee2 /bin/bash
root@2d9e86240ee2:/# mysql -u wzy -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.27 MySQL Community Server - GPLCopyright (c) 2000, 2021, Oracle and/or its affiliates.Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mybatis-plus |
+--------------------+
2 rows in set (0.01 sec)mysql> use mybatis-plus;
Database changed
mysql> select * from number_test;
ERROR 1146 (42S02): Table 'mybatis-plus.number_test' doesn't exist
mysql>
我们需要手动建表,不然8001服务执行新增会报错:
mysql> CREATE TABLE `number_test` (-> `one` int NOT NULL,-> `two` varchar(255) DEFAULT NULL,-> `three` varchar(255) DEFAULT NULL,-> `four` varchar(255) DEFAULT NULL,-> PRIMARY KEY (`one`)-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
Query OK, 0 rows affected (0.05 sec)mysql> select * from number_test;
Empty set (0.10 sec)mysql>
验证
宿主机直接访问我的虚拟机erueka,可以看到有应用列表有8001与8002,二者成功注册到eureka中

或者直接虚拟机里看:

执行8001的controller,插入数据


验证8002-redis服务
先看所有的key,这是没有:
[root@localhost wzy]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0bb97a880a91 wzy-payment8001 "java -jar /wzy_paym…" 22 minutes ago Up 22 minutes 0.0.0.0:8001->8001/tcp, :::8001->8001/tcp wzy-payment8001-1
918f761ead06 wzy-payment8002 "java -jar /wzy_paym…" 22 minutes ago Up 22 minutes 0.0.0.0:8002->8002/tcp, :::8002->8002/tcp wzy-payment8002-1
2d9e86240ee2 mysql:latest "docker-entrypoint.s…" 22 minutes ago Up 22 minutes 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp wzy-mysql-1
d8f5e56fde6d redis:6.2.6 "docker-entrypoint.s…" 22 minutes ago Up 22 minutes 0.0.0.0:6379->6379/tcp, :::6379->6379/tcp wzy-redis-1
240276cd95f1 wzy-eureka7001 "java -jar /wzy_eure…" 22 minutes ago Up 22 minutes 0.0.0.0:7001->7001/tcp, :::7001->7001/tcp wzy-eureka7001-1[root@localhost wzy]# docker exec -it d8f5e56fde6d /bin/bash
root@d8f5e56fde6d:/data# redis-cli
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379>
然后虚拟机中请求:

再查看redis:

注意点
如果遇到问题需要重新编排,或者修改了微服务的yaml配置或代码,要记得将镜像与容器一并删除,在重新编排。
相关文章:
Docker Compose使用
Docker-Compose是什么 docker建议我们每一个容器中只运行一个服务,因为doker容器本身占用资源极少,所以最好是将每个服务单独分割开来,但是这样我们又面临了一个问题: 如果我需要同时部署好多个服务,难道要每个服务单独写Docker…...
如何优雅的卸载linux上的todesk
要优雅地卸载Linux上的ToDesk,您可以按照以下步骤操作: 打开终端。 输入以下命令来停止ToDesk服务(如果它正在运行的话): sudo systemctl stop todesk 然后,使用包管理器卸载ToDesk。如果您使用的是apt&…...
【Vue】el-checkbox多选框实现单选效果,选中一个选项则自动取消其他勾选
🤵 作者:coderYYY 🧑 个人简介:前端程序媛,目前主攻web前端,后端辅助,其他技术知识也会偶尔分享🍀欢迎和我一起交流!🚀(评论和私信一般会回&#…...
Linux中使用vi编辑器自动缩进4个字符
平常在Linux操作系统下书写shell脚本内容,或是把写好的shell内容直接复制到vi编辑器中,本来缩进好的字符,会自动变乱,这是因为Linux的vi编辑器默认是缩进8个字符造成,可以使用下面2个方法解决该问题的发生。 1、本用户…...
#笔记#笔记#其他
大鱼论文是一款非常靠谱、方便、值得推荐的论文写作工具。无论是在学术研究中还是在日常写作中,大鱼论文都能够帮助用户轻松完成论文的写作工作。 首先,大鱼论文提供了强大的查重降重功能,能够帮助用户快速定位论文中可能存在的抄袭问题&…...
gtask笔记
1、创建Task GTask *g_task_new (gpointer source_object, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer callback_data); source_object:GObject对象,拥有者 cancellable:可否取消 callback:task完成后…...
【Linux学习】深入探索进程等待与进程退出码和退出信号
文章目录 退出码return退出 进程的等待进程等待的方法 退出码 main函数的返回值:进程的退出码。 一般为0表示成功,非0表示失败。 每一个非0退出码都表示一个失败的原因; echo $?命令 作用:查看进程退出码。…...
Linux:线程
文章目录 前言1. 线程概念1.1 什么是线程1.2 线程比进程更加轻量化1.3 虚拟地址到物理地址的转化物理内存的管理页表 1.4 线程的优点1.5 线程的缺点1.6 线程异常1.7 线程用途 2. 进程 vs 线程3. 线程控制3.1 线程创建3.2 线程退出3.3 线程等待3.4 分离线程3.5 线程取消 4. 线程…...
卡到BUG了:删除重发白得积分(以前删除会扣减积分)
以前是:删除文章,积分减少,点赞积分减少,从回收站恢复文章,积分恢复,点赞数恢复但点赞积分不恢复。也就是删除重发总积分减少点赞的积分,有损失。 今天是:删除文章,积分不…...
轻松拿捏C语言——【字符函数】字符分类函数、字符转换函数
🥰欢迎关注 轻松拿捏C语言系列,来和 小哇 一起进步!✊ 🌈感谢大家的阅读、点赞、收藏和关注💕 🌹如有问题,欢迎指正 感谢 目录👑 一、字符分类函数🌙 二、字符转换函数…...
【Rust日报】ratatui版本更新
[new ver] ratatui v0.26.3 一个构建终端用户界面的库。新版本包括: 修复Unicode 截断 bug对颜色更好地序列化更快的渲染弃用assert_buffer_eq宏暴露错误类型常量函数和类型 官网: https://ratatui.rs/ 链接: https://ratatui.rs/highlights/v0263/ [new lib] ansi2…...
力扣每日一题 5/28
题目:2951-找出峰值 给你一个下标从 0 开始的数组 mountain 。你的任务是找出数组 mountain 中的所有 峰值。 以数组形式返回给定数组中 峰值 的下标,顺序不限 。 注意: 峰值 是指一个严格大于其相邻元素的元素。数组的第一个和最后一个元…...
async函数和await函数
一、async函数 async是一个加在函数前的修饰符,被async定义的函数会默认返回一个Promise对象resolve的值。 因此对async函数可以直接then,返回值就是then方法传入的函数。 // async基础语法 async function fun0(){console.log(1);return 1; } fun0()…...
Redis面试题深度解析
1、我看你做的项目中,都用到了redis,你在最近的项目中哪些场景使用了redis呢? 2、缓存穿透 布隆过滤器的误判现象 Redisson和Guava都对布隆过滤器进行了实现 3、缓存击穿 互斥锁,就是一个线程来修改,并占据了锁,另外其…...
Ubuntu 22.04 .NET8 程序 环境安装和运行
前言 我们需要将.NET8编写的console控制台程序,部署在Ubuntu服务器上运行。 安装.NET运行时 1.增加微软包安装源 wget https://packages.microsoft.com/config/ubuntu/22.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb sudo dpkg -i packages…...
MetaRTC-ffmpeg arm移植
touch cmake_arm.sh 添加 rm -rf build mkdir build cd build ARCHaarch64.cmake cmake -DCMAKE_BUILD_TYPERelease -DCMAKE_TOOLCHAIN_FILE../$ARCH .. maketouch cmake_arm.sh 添加 SET(CMAKE_SYSTEM_NAME Linux) SET(CMAKE_C_COMPILER /home/yqw/MetaRTC/BC/stbgcc-6.3-1…...
【乐吾乐3D可视化组态编辑器】模型类型与属性
编辑器地址:3D可视化组态 - 乐吾乐Le5le 本章主要为您介绍模型的属性功能。 一个模型至少会包含一个节点(Node),从节点类型上可以分为转换节点(TransformNode)、网格(Mesh)、实例网…...
PyQt下拉框QComboBox点击下拉时即更新下拉数据
在 PyQt 中,QComboBox 控件本身并没有直接的事件或信号来指示下拉列表何时被打开(即用户点击了下拉箭头)。但是,你可以通过其他方式间接地实现这个功能,比如通过重写 QComboBox 的某些方法或者在用户与 QComboBox 交互…...
网上有哪些正规的兼职副业赚钱平台?分享10类正规的网上兼职赚钱平台,让你在家也能赚钱~
在如今的快节奏社会中,越来越多的人开始寻求兼职副业来增加收入。而随着互联网的普及,网上赚钱平台成为了许多人选择的方式之一。然而,面对众多的网上赚钱平台,我们要如何辨别哪些是正规可靠的呢?在本文中,…...
Spring:JWT
文章目录 一、介绍 一、介绍 JWT(JSON Web Token)是一种开放标准(RFC 7519)的方法,用于在双方之间安全地传输信息。这些信息可以是验证、授权、信息交换等。JWT 通常被用于在客户端和服务器之间传递用户信息ÿ…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...
linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...
2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...
零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...
LLaMA-Factory 微调 Qwen2-VL 进行人脸情感识别(二)
在上一篇文章中,我们详细介绍了如何使用LLaMA-Factory框架对Qwen2-VL大模型进行微调,以实现人脸情感识别的功能。本篇文章将聚焦于微调完成后,如何调用这个模型进行人脸情感识别的具体代码实现,包括详细的步骤和注释。 模型调用步骤 环境准备:确保安装了必要的Python库。…...
Windows电脑能装鸿蒙吗_Windows电脑体验鸿蒙电脑操作系统教程
鸿蒙电脑版操作系统来了,很多小伙伴想体验鸿蒙电脑版操作系统,可惜,鸿蒙系统并不支持你正在使用的传统的电脑来安装。不过可以通过可以使用华为官方提供的虚拟机,来体验大家心心念念的鸿蒙系统啦!注意:虚拟…...
基于江科大stm32屏幕驱动,实现OLED多级菜单(动画效果),结构体链表实现(独创源码)
引言 在嵌入式系统中,用户界面的设计往往直接影响到用户体验。本文将以STM32微控制器和OLED显示屏为例,介绍如何实现一个多级菜单系统。该系统支持用户通过按键导航菜单,执行相应操作,并提供平滑的滚动动画效果。 本文设计了一个…...
【Java基础】向上转型(Upcasting)和向下转型(Downcasting)
在面向对象编程中,转型(Casting) 是指改变对象的引用类型,主要涉及 继承关系 和 多态。 向上转型(Upcasting) ⬆️ 定义 将 子类对象 赋值给 父类引用(自动完成,无需强制转换&…...
