Docker-compose容器编排
1. Docker-compose是什么?
Compose 是 Docker 公司推出的一个工具软件,可以管理多个 Docker 容器组成一个应用。你需要定义一个 YAML 格式的配置文件docker-compose.yml,写好多个容器之间的调用关系。然后,只要一个命令,就能同时启动/关闭这些容器
Docker-Compose是Docker官方的开源项目, 负责实现对Docker容器集群的快速编排。
2. Docker-compose能干什么?
docker建议我们每一个容器中只运行一个服务,因为docker容器本身占用资源极少,所以最好是将每个服务单独的分割开来但是这样我们又面临了一个问题?
如果我需要同时部署好多个服务,难道要每个服务单独写Dockerfile然后在构建镜像,构建容器,这样累都累死了,所以docker官方给我们提供了docker-compose多服务部署的工具
例如要实现一个Web微服务项目,除了Web服务容器本身,往往还需要再加上后端的数据库mysql服务容器,redis服务器,注册中心eureka,甚至还包括负载均衡容器等等。。。。。。
Compose允许用户通过一个单独的docker-compose.yml模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)。
可以很容易地用一个配置文件定义一个多容器的应用,然后使用一条指令安装这个应用的所有依赖,完成构建。Docker-Compose 解决了容器与容器之间如何管理编排的问题。
3. Docker-compose去哪下
官网:文档地址
https://docs.docker.com/compose/compose-file/compose-file-v3/
官网下载
https://docs.docker.com/compose/install/
curl -SL https://github.com/docker/compose/releases/download/v2.6.1/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
docker-compose --version
卸载步骤
sudo rm /usr/local/bin/docker-compose
4. Compose核心概念
4.1 一文件
docker-compose.yml
4.2 两要素
4.2.1 服务(service)
一个个应用容器实例,比如订单微服务、库存微服务、mysql容器、nginx容器或者redis容器。
4.2.2 工程(project)
由一组关联的应用容器组成的一个完整业务单元,在 docker-compose.yml 文件中定义。
4.3 Compose使用的三个步骤
4.3.1 编写Dockerfile定义各个微服务应用并构建出对应的镜像文件
4.3.2 使用 docker-compose.yml 定义一个完整业务单元,安排好整体应用中的各个容器服务。
4.3.3 最后,执行docker-compose up命令 来启动并运行整个应用程序,完成一键部署上线
4.4 Compose常用命令
常用命令 | 解释说明 |
---|---|
docker-compose -h | # 查看帮助 |
docker-compose up | # 启动所有docker-compose服务 |
docker-compose up -d | # 启动所有docker-compose服务并后台运行 |
docker-compose down | # 停止并删除容器、网络、卷、镜像。 |
docker-compose exec yml里面的服务id | # 进入容器实例内部 docker-compose exec docker-compose.yml文件中写的服务id /bin/bash |
docker-compose ps | # 展示当前docker-compose编排过的运行的所有容器 |
docker-compose top | # 展示当前docker-compose编排过的容器进程 |
docker-compose logs yml里面的服务id | # 查看容器输出日志 |
docker-compose config | # 检查配置 |
docker-compose config -q | # 检查配置,有问题才有输出 |
docker-compose restart | # 重启服务 |
docker-compose start | # 启动服务 |
docker-compose stop | # 停止服务 |
4.5 Compose编排微服务
4.5.1 改pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.6</version>
<!--<version>2.3.10.RELEASE</version>-->
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.atguigu.docker</groupId>
<artifactId>docker_boot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<junit.version>4.12</junit.version>
<log4j.version>1.2.17</log4j.version>
<lombok.version>1.16.18</lombok.version>
<mysql.version>5.1.47</mysql.version>
<druid.version>1.1.16</druid.version>
<mapper.version>4.1.5</mapper.version>
<mybatis.spring.boot.version>1.3.0</mybatis.spring.boot.version>
</properties>
<dependencies>
<!--guava Google 开源的 Guava 中自带的布隆过滤器-->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>23.0</version>
</dependency>
<!-- redisson -->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.13.4</version>
</dependency>
<!--SpringBoot通用依赖模块-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--swagger2-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<!--SpringBoot与Redis整合依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--springCache-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!--springCache连接池依赖包-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<!-- jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.1.0</version>
</dependency>
<!--Mysql数据库驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!--SpringBoot集成druid连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<!--mybatis和springboot整合-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.spring.boot.version}</version>
</dependency>
<!-- 添加springboot对amqp的支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
</dependency>
<!--通用基础配置junit/devtools/test/log4j/lombok/hutool-->
<!--hutool-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.2.3</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<optional>true</optional>
</dependency>
<!--persistence-->
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0.2</version>
</dependency>
<!--通用Mapper-->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper</artifactId>
<version>${mapper.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
</plugin>
</plugins>
</build>
</project>
4.5.2 写yml
server.port=6001
# ========================alibaba.druid相关配置=====================
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://xxx.xx.xx.xxx:3308/DB2021?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.druid.test-while-idle=false
# ========================redis相关配置=====================
spring.redis.database=0
spring.redis.host=xxx.xx.xx.xxx
spring.redis.port=6379
spring.redis.password=
spring.redis.lettuce.pool.max-active=8
spring.redis.lettuce.pool.max-wait=-1ms
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.min-idle=0
# ========================mybatis相关配置===================
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=com.atguigu.docker.entities
# ========================swagger=====================
spring.swagger2.enabled=true
#mq中间件连接方式
spring.rabbitmq.host=xxx.xx.xx.xxx
spring.rabbitmq.port=5672
spring.rabbitmq.username=admin
spring.rabbitmq.password=admin
4.5.3 主启动
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import tk.mybatis.spring.annotation.MapperScan;
/**
* @author LongXi
* @create 2022-07-12 22:45
*/
@SpringBootApplication
@MapperScan("com.atguigu.docker.mapper")
//import tk.mybatis.spring.annotation.MapperScan;
public class DockerBootApplication {
public static void main(String[] args) {
SpringApplication.run(DockerBootApplication.class, args);
}
}
4.5.4 业务类
UserService
package com.longxi.service;
import com.longxi.entity.User;
import com.longxi.mapper.UserMapper;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PathVariable;
import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;
/**
* @author LongXi
* @create 2022-07-17 22:38
*/
@Service
@Slf4j
public class UserService {
public static final String CACHE_KEY_USER = "user:";
@Resource
private UserMapper userMapper;
@Resource
private RedisTemplate redisTemplate;
/**
* addUser
*
* @param user
*/
public void addUser(User user) {
//1 先插入mysql并成功
int i = userMapper.insertSelective(user);
if (i > 0) {
//2 需要再次查询一下mysql将数据捞回来并ok
user = userMapper.selectByPrimaryKey(user.getId());
//3 将捞出来的user存进redis,完成新增功能的数据一致性。
String key = CACHE_KEY_USER + user.getId();
redisTemplate.opsForValue().set(key, user);
}
}
/**
* addUser
*
* @param user
*/
public void updateUser(User user) {
//1 先插入mysql并成功
int i = userMapper.updateByPrimaryKeySelective(user);
if (i > 0) {
//2 需要再次查询一下mysql将数据捞回来并ok
user = userMapper.selectByPrimaryKey(user.getId());
//3 将捞出来的user存进redis,完成新增功能的数据一致性。
String key = CACHE_KEY_USER + user.getId();
redisTemplate.opsForValue().set(key, user);
}
}
/**
* addUser
*
* @param id
*/
public void deleteUser(Integer id) {
//1 需要再次查询一下mysql将数据捞回来并ok
User user = userMapper.selectByPrimaryKey(id);
//2 删除mysql并成功
int i = userMapper.deleteByPrimaryKey(id);
if (i > 0) {
//3 将捞出来的user从reids删除,完成新增功能的数据一致性。
String key = CACHE_KEY_USER + user.getId();
redisTemplate.delete(key);
}
}
/**
* findUserById
*
* @param id
* @return
*/
public User findUserById(Integer id) {
User user = null;
String key = CACHE_KEY_USER + id;
//1 先从redis里面查询,如果有直接返回结果,如果没有再去查询mysql
user = (User) redisTemplate.opsForValue().get(key);
if (user == null) {
//2 redis里面无,继续查询mysql
user = userMapper.selectByPrimaryKey(id);
if (user == null) {
//3.1 redis+mysql 都无数据
//你具体细化,防止多次穿透,我们规定,记录下导致穿透的这个key回写redis
return user;
} else {
//3.2 mysql有,需要将数据写回redis,保证下一次的缓存命中率
redisTemplate.opsForValue().set(key, user);
}
}
return user;
}
}
UserMapper
/**
* @author LongXi
* @create 2022-07-17 22:35
*/
import com.longxi.entity.User;
import org.mybatis.spring.annotation.MapperScan;
import tk.mybatis.mapper.common.Mapper;
@org.apache.ibatis.annotations.Mapper
public interface UserMapper extends Mapper<User> {
}
user.java
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import java.util.Date;
@Table(name = "t_user")
public class User {
@Id
@GeneratedValue(generator = "JDBC")
private Integer id;
/**
* 用户名
*/
private String username;
/**
* 密码
*/
private String password;
/**
* 性别 0=女 1=男
*/
private Byte sex;
/**
* 删除标志,默认0不删除,1删除
*/
private Byte deleted;
/**
* 更新时间
*/
@Column(name = "update_time")
private Date updateTime;
/**
* 创建时间
*/
@Column(name = "create_time")
private Date createTime;
/**
* @return id
*/
public Integer getId() {
return id;
}
/**
* @param id
*/
public void setId(Integer id) {
this.id = id;
}
/**
* 获取用户名
*
* @return username - 用户名
*/
public String getUsername() {
return username;
}
/**
* 设置用户名
*
* @param username 用户名
*/
public void setUsername(String username) {
this.username = username;
}
/**
* 获取密码
*
* @return password - 密码
*/
public String getPassword() {
return password;
}
/**
* 设置密码
*
* @param password 密码
*/
public void setPassword(String password) {
this.password = password;
}
/**
* 获取性别 0=女 1=男
*
* @return sex - 性别 0=女 1=男
*/
public Byte getSex() {
return sex;
}
/**
* 设置性别 0=女 1=男
*
* @param sex 性别 0=女 1=男
*/
public void setSex(Byte sex) {
this.sex = sex;
}
/**
* 获取删除标志,默认0不删除,1删除
*
* @return deleted - 删除标志,默认0不删除,1删除
*/
public Byte getDeleted() {
return deleted;
}
/**
* 设置删除标志,默认0不删除,1删除
*
* @param deleted 删除标志,默认0不删除,1删除
*/
public void setDeleted(Byte deleted) {
this.deleted = deleted;
}
/**
* 获取更新时间
*
* @return update_time - 更新时间
*/
public Date getUpdateTime() {
return updateTime;
}
/**
* 设置更新时间
*
* @param updateTime 更新时间
*/
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
/**
* 获取创建时间
*
* @return create_time - 创建时间
*/
public Date getCreateTime() {
return createTime;
}
/**
* 设置创建时间
*
* @param createTime 创建时间
*/
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
}
UserDTO
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.Date;
@NoArgsConstructor
@AllArgsConstructor
@Data
@ApiModel(value = "用户信息")
public class UserDTO implements Serializable {
@ApiModelProperty(value = "用户ID")
private Integer id;
@ApiModelProperty(value = "用户名")
private String username;
@ApiModelProperty(value = "密码")
private String password;
@ApiModelProperty(value = "性别 0=女 1=男 ")
private Byte sex;
@ApiModelProperty(value = "删除标志,默认0不删除,1删除")
private Byte deleted;
@ApiModelProperty(value = "更新时间")
private Date updateTime;
@ApiModelProperty(value = "创建时间")
private Date createTime;
/**
* @return id
*/
public Integer getId() {
return id;
}
/**
* @param id
*/
public void setId(Integer id) {
this.id = id;
}
/**
* 获取用户名
*
* @return username - 用户名
*/
public String getUsername() {
return username;
}
/**
* 设置用户名
*
* @param username 用户名
*/
public void setUsername(String username) {
this.username = username;
}
/**
* 获取密码
*
* @return password - 密码
*/
public String getPassword() {
return password;
}
/**
* 设置密码
*
* @param password 密码
*/
public void setPassword(String password) {
this.password = password;
}
/**
* 获取性别 0=女 1=男
*
* @return sex - 性别 0=女 1=男
*/
public Byte getSex() {
return sex;
}
/**
* 设置性别 0=女 1=男
*
* @param sex 性别 0=女 1=男
*/
public void setSex(Byte sex) {
this.sex = sex;
}
/**
* 获取删除标志,默认0不删除,1删除
*
* @return deleted - 删除标志,默认0不删除,1删除
*/
public Byte getDeleted() {
return deleted;
}
/**
* 设置删除标志,默认0不删除,1删除
*
* @param deleted 删除标志,默认0不删除,1删除
*/
public void setDeleted(Byte deleted) {
this.deleted = deleted;
}
/**
* 获取更新时间
*
* @return update_time - 更新时间
*/
public Date getUpdateTime() {
return updateTime;
}
/**
* 设置更新时间
*
* @param updateTime 更新时间
*/
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
/**
* 获取创建时间
*
* @return create_time - 创建时间
*/
public Date getCreateTime() {
return createTime;
}
/**
* 设置创建时间
*
* @param createTime 创建时间
*/
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", sex=" + sex +
'}';
}
}
4.5.5 启动出现错误
org.springframework.amqp.AmqpTimeoutException: java.util.concurrent.TimeoutException
at org.springframework.amqp.rabbit.support.RabbitExceptionTranslator.convertRabbitAccessException(RabbitExceptionTranslator.java:73) ~[spring-rabbit-2.3.11.jar:2.3.11]
at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.createBareConnection(AbstractConnectionFactory.java:602) ~[spring-rabbit-2.3.11.jar:2.3.11]
at org.springframework.amqp.rabbit.connection.CachingConnectionFactory.createConnection(CachingConnectionFactory.java:724) ~[spring-rabbit-2.3.11.jar:2.3.11]
at org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils.createConnection(ConnectionFactoryUtils.java:252) ~[spring-rabbit-2.3.11.jar:2.3.11]
at org.springframework.amqp.rabbit.core.RabbitTemplate.doExecute(RabbitTemplate.java:2163) ~[spring-rabbit-2.3.11.jar:2.3.11]
at org.springframework.amqp.rabbit.core.RabbitTemplate.execute(RabbitTemplate.java:2136) ~[spring-rabbit-2.3.11.jar:2.3.11]
at org.springframework.amqp.rabbit.core.RabbitTemplate.execute(RabbitTemplate.java:2116) ~[spring-rabbit-2.3.11.jar:2.3.11]
at org.springframework.boot.actuate.amqp.RabbitHealthIndicator.getVersion(RabbitHealthIndicator.java:49) ~[spring-boot-actuator-2.5.6.jar:2.5.6]
at org.springframework.boot.actuate.amqp.RabbitHealthIndicator.doHealthCheck(RabbitHealthIndicator.java:44) ~[spring-boot-actuator-2.5.6.jar:2.5.6]
at org.springframework.boot.actuate.health.AbstractHealthIndicator.health(AbstractHealthIndicator.java:82) ~[spring-boot-actuator-2.5.6.jar:2.5.6]
at org.springframework.boot.actuate.health.HealthIndicator.getHealth(HealthIndicator.java:37) [spring-boot-actuator-2.5.6.jar:2.5.6]
at org.springframework.boot.actuate.health.HealthEndpoint.getHealth(HealthEndpoint.java:71) [spring-boot-actuator-2.5.6.jar:2.5.6]
at org.springframework.boot.actuate.health.HealthEndpoint.getHealth(HealthEndpoint.java:39) [spring-boot-actuator-2.5.6.jar:2.5.6]
at org.springframework.boot.actuate.health.HealthEndpointSupport.getContribution(HealthEndpointSupport.java:99) [spring-boot-actuator-2.5.6.jar:2.5.6]
at org.springframework.boot.actuate.health.HealthEndpointSupport.getAggregateHealth(HealthEndpointSupport.java:110) [spring-boot-actuator-2.5.6.jar:2.5.6]
at org.springframework.boot.actuate.health.HealthEndpointSupport.getContribution(HealthEndpointSupport.java:96) [spring-boot-actuator-2.5.6.jar:2.5.6]
at org.springframework.boot.actuate.health.HealthEndpointSupport.getHealth(HealthEndpointSupport.java:74) [spring-boot-actuator-2.5.6.jar:2.5.6]
at org.springframework.boot.actuate.health.HealthEndpointSupport.getHealth(HealthEndpointSupport.java:61) [spring-boot-actuator-2.5.6.jar:2.5.6]
at org.springframework.boot.actuate.health.HealthEndpoint.health(HealthEndpoint.java:65) [spring-boot-actuator-2.5.6.jar:2.5.6]
at org.springframework.boot.actuate.health.HealthEndpoint.health(HealthEndpoint.java:55) [spring-boot-actuator-2.5.6.jar:2.5.6]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_231]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_231]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_231]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_231]
at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:282) [spring-core-5.3.12.jar:5.3.12]
at org.springframework.boot.actuate.endpoint.invoke.reflect.ReflectiveOperationInvoker.invoke(ReflectiveOperationInvoker.java:74) [spring-boot-actuator-2.5.6.jar:2.5.6]
at org.springframework.boot.actuate.endpoint.annotation.AbstractDiscoveredOperation.invoke(AbstractDiscoveredOperation.java:60) [spring-boot-actuator-2.5.6.jar:2.5.6]
at org.springframework.boot.actuate.endpoint.jmx.EndpointMBean.invoke(EndpointMBean.java:121) [spring-boot-actuator-2.5.6.jar:2.5.6]
at org.springframework.boot.actuate.endpoint.jmx.EndpointMBean.invoke(EndpointMBean.java:96) [spring-boot-actuator-2.5.6.jar:2.5.6]
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819) [na:1.8.0_231]
at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801) [na:1.8.0_231]
at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1468) [na:1.8.0_231]
at javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:76) [na:1.8.0_231]
at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1309) [na:1.8.0_231]
at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1401) [na:1.8.0_231]
at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:829) [na:1.8.0_231]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_231]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_231]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_231]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_231]
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:357) [na:1.8.0_231]
at sun.rmi.transport.Transport$1.run(Transport.java:200) [na:1.8.0_231]
at sun.rmi.transport.Transport$1.run(Transport.java:197) [na:1.8.0_231]
at java.security.AccessController.doPrivileged(Native Method) [na:1.8.0_231]
at sun.rmi.transport.Transport.serviceCall(Transport.java:196) [na:1.8.0_231]
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:573) [na:1.8.0_231]
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:834) [na:1.8.0_231]
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:688) [na:1.8.0_231]
at java.security.AccessController.doPrivileged(Native Method) [na:1.8.0_231]
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:687) [na:1.8.0_231]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[na:1.8.0_231]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[na:1.8.0_231]
at java.lang.Thread.run(Thread.java:748) ~[na:1.8.0_231]
Caused by: java.util.concurrent.TimeoutException: null
at com.rabbitmq.utility.BlockingCell.get(BlockingCell.java:77) ~[amqp-client-5.12.0.jar:5.12.0]
at com.rabbitmq.utility.BlockingCell.uninterruptibleGet(BlockingCell.java:120) ~[amqp-client-5.12.0.jar:5.12.0]
at com.rabbitmq.utility.BlockingValueOrException.uninterruptibleGetValue(BlockingValueOrException.java:36) ~[amqp-client-5.12.0.jar:5.12.0]
at com.rabbitmq.client.impl.AMQChannel$BlockingRpcContinuation.getReply(AMQChannel.java:502) ~[amqp-client-5.12.0.jar:5.12.0]
at com.rabbitmq.client.impl.AMQConnection.start(AMQConnection.java:326) ~[amqp-client-5.12.0.jar:5.12.0]
at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:1222) ~[amqp-client-5.12.0.jar:5.12.0]
at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:1170) ~[amqp-client-5.12.0.jar:5.12.0]
at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.connectAddresses(AbstractConnectionFactory.java:640) ~[spring-rabbit-2.3.11.jar:2.3.11]
at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.connect(AbstractConnectionFactory.java:615) ~[spring-rabbit-2.3.11.jar:2.3.11]
at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.createBareConnection(AbstractConnectionFactory.java:565) ~[spring-rabbit-2.3.11.jar:2.3.11]
没有配置RabbitMq导致,
4.5.6 解决方法:在docker上装 rabbitMq
下载镜像
docker pull rabbitmq:management
启动容器
docker run -d --hostname localhost --name rabbitmq -p 15672:15672 -p 5672:5672 rabbitmq:management
使用命令添加用户并授权
添加用户
rabbitmqctl add_user admin admin
设置permissions
rabbitmqctl set_permissions -p "/" admin ".*" ".*" ".*"
设置用户角色
rabbitmqctl set_user_tags admin administrator
查看新添加的admin
rabbitmqctl list_users
查看用于的权限
rabbitmqctl list_permissions -p /
成功启动
.Swagger2Controller#getDocumentation(String, HttpServletRequest)]
2022-07-19 22:40:43.041 INFO 42084 --- [ restartedMain] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729
2022-07-19 22:40:43.444 INFO 42084 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 6001 (http) with context path ''
2022-07-19 22:40:43.445 INFO 42084 --- [ restartedMain] d.s.w.p.DocumentationPluginsBootstrapper : Context refreshed
2022-07-19 22:40:43.464 INFO 42084 --- [ restartedMain] d.s.w.p.DocumentationPluginsBootstrapper : Found 1 custom documentation plugin(s)
2022-07-19 22:40:43.498 INFO 42084 --- [ restartedMain] s.d.s.w.s.ApiListingReferenceScanner : Scanning for api listing references
2022-07-19 22:40:43.529 INFO 42084 --- [ restartedMain] com.longxi.DockerBootApplication : Started DockerBootApplication in 10.775 seconds (JVM running for 14.262)
2022-07-19 22:40:45.250 INFO 42084 --- [)-192.168.3.237] o.s.a.r.c.CachingConnectionFactory : Attempting to connect to: [116.62.35.129:5672]
2022-07-19 22:40:45.253 INFO 42084 --- [)-192.168.3.237] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2022-07-19 22:40:45.254 INFO 42084 --- [)-192.168.3.237] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2022-07-19 22:40:45.256 INFO 42084 --- [)-192.168.3.237] o.s.web.servlet.DispatcherServlet : Completed initialization in 2 ms
2022-07-19 22:40:45.508 INFO 42084 --- [)-192.168.3.237] o.s.a.r.c.CachingConnectionFactory : Created new connection: rabbitConnectionFactory#fcd2f75:0/SimpleConnection@37cdbe34 [delegate=amqp://admin@116.62.35.129:5672/, localPort= 62258]
4.5.7 mvn package命令将微服务形成新的jar包 并上传到Linux服务器/myfile3目录下
4.5.8 编写Dockerfile
# 基础镜像使用java
FROM java:8
# 作者
MAINTAINER longxi
# VOLUME 指定临时文件目录为/tmp,在主机/var/lib/docker目录下创建了一个临时文件并链接到容器的/tmp
VOLUME /tmp
# 将jar包添加到容器中并更名为longxi_docker.jar
ADD docker_boot-0.0.1-SNAPSHOT.jar longxi_docker.jar
# 运行jar包
RUN bash -c 'touch /longxi_docker.jar'
ENTRYPOINT ["java","-jar","/longxi_docker.jar"]
#暴露6001端口作为微服务
EXPOSE 6001
4.5.9 构建镜像
docker build -t longxi_docker:1.7 .
4.6 不用Compose
4.6.1 新建mysql容器实例
docker run -p 3306:3306 --name mysql57 --privileged=true -v /zzyyuse/mysql/conf:/etc/mysql/conf.d -v /zzyyuse/mysql/logs:/logs -v /zzyyuse/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
4.6.2 进入mysql容器实例并新建库db2021+新建表t_user
docker exec -it mysql57 /bin/bash
mysql -uroot -p
create database db2021;
use db2021;
CREATE TABLE `t_user` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`username` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '用户名',
`password` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '密码',
`sex` TINYINT(4) NOT NULL DEFAULT '0' COMMENT '性别 0=女 1=男 ',
`deleted` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0' COMMENT '删除标志,默认0不删除,1删除',
`update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
4.6.3 单独的redis容器实例
docker run -p 6379:6379 --name redis608 --privileged=true -v /app/redis/redis.conf:/etc/redis/redis.conf -v /app/redis/data:/data -d redis:6.0.8 redis-server /etc/redis/redis.conf
4.6.4 微服务工程
docker run -d -p 6001:6001 longxi_docker:1.7
上面三个容器实例依次顺序启动成功
4.6.5 postman测试
http://localhost:6001/user/add
4.6.6 上面成功了,有哪些问题?
- 先后顺序要求固定,先mysql+redis才能微服务访问成功
- 多个run命令…
- 容器间的启停或宕机,有可能导致IP地址对应的容器实例变化,映射出错, 要么生产IP写死(可以但是不推荐),要么通过服务调用
4.7 使用Compose:·服务编排,一套带走
4.7.1 编写docker-compose.yml文件
docker-compose.yml
version: "3"
services:
microService:
image: longxi_docker:1.7
container_name: ms01
ports:
- "6001:6001"
volumes:
- /app/microService:/data
networks:
- longxi_net
depends_on:
- redis
- mysql
redis:
image: redis:6.0.8
ports:
- "6379:6379"
volumes:
- /app/redis/redis.conf:/etc/redis/redis.conf
- /app/redis/data:/data
networks:
- longxi_net
command: redis-server /etc/redis/redis.conf
mysql:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: 'root'
MYSQL_ALLOW_EMPTY_PASSWORD: 'no'
MYSQL_DATABASE: 'db2021'
MYSQL_USER: 'longxi'
MYSQL_PASSWORD: 'longxi123'
ports:
- "3306:3306"
volumes:
- /app/mysql/db:/var/lib/mysql
- /app/mysql/conf/my.cnf:/etc/my.cnf
- /app/mysql/init:/docker-entrypoint-initdb.d
networks:
- longxi_net
command: --default-authentication-plugin=mysql_native_password #解决外部无法访问
networks:
longxi_net:
4.7.2 第二次修改微服务工程docker_boot,通过服务名访问,IP无关
server.port=6001
# ========================alibaba.druid相关配置=====================
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
#spring.datasource.url=jdbc:mysql://192.168.111.169:3306/db2021?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.url=jdbc:mysql://mysql:3306/db2021?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.druid.test-while-idle=false
# ========================redis相关配置=====================
spring.redis.database=0
#spring.redis.host=192.168.111.169
spring.redis.host=redis
spring.redis.port=6379
spring.redis.password=
spring.redis.lettuce.pool.max-active=8
spring.redis.lettuce.pool.max-wait=-1ms
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.min-idle=0
# ========================mybatis相关配置===================
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=com.atguigu.docker.entities
# ========================swagger=====================
spring.swagger2.enabled=true
4.7.3 mvn package命令将微服务形成新的jar包 并上传到Linux服务器/myfile4目录下
Dockerfile不用变更
4.7.4 重新构建镜像
docker build -t longxi_docker:1.8 .
4.7.5 执行 docker-compose up 或者 执行 docker-compose up -d
检查语法规范
docker-compose config -q
启动成功
4.7.5 测试一下
http://116.62.35.129:6001/user/add
插入成功