【微服务实战之Docker容器】第十章-compose容器编排

目录

1、Compose简介

Compose 是 Docker 公司推出的一个工具软件,可以管理多个 Docker 容器组成一个应用。你需要定义一个 YAML 格式的配置文件docker-compose.yml,写好多个容器之间的调用关系。然后,只要一个命令,就能同时启动/关闭这些容器。

Docker-Compose是Docker官方的开源项目,负责实现对Docker容器集群的快速编排。

2、Compose能干啥

docker建议我们每一个容器中只运行一个服务,因为docker容器本身占用资源极少,所以最好是将每个服务单独的分割开来

但是这样我们又面临了一个问题? 如果我需要同时部署好多个服务,难道要每个服务单独写Dockerfile然后在构建镜像,构建容器,这样累都累死了,

所以docker官方给我们提供了docker-compose多服务部署的工具 例如要实现一个Web微服务项目,除了Web服务容器本身,往往还需要再加上后端的数据库mysql服务容器,redis服务器,注册中心eureka,甚至还包括负载均衡容器等等。。。。。。

Compose允许用户通过一个单独的docker-compose.yml模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)。

可以很容易地用一个配置文件定义一个多容器的应用,然后使用一条指令安装这个应用的所有依赖,完成构建。Docker-Compose 解决了容器与容器之间如何管理编排的问题。

3、 下载安装

官网: https://docs.docker.com/compose/compose-file/compose-file-v3/

官网下载网址: https://docs.docker.com/compose/install/

官网中给出的有详细的下载步骤

安装步骤:

其实意思就是从github上把compose下载下来,放到/usr/local/bin目录下,chmod设置上权限,然后就可以了!

这里不使用curl,手动从github上下载,再设置也是一样的效果。

bash 复制代码
curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
docker-compose --version 


卸载步骤:

bash 复制代码
sudo rm /usr/local/bin/docker-compose

4、Compose核心概念

一文件:

docker-compose.yml
两要素:

服务(service): 一个个应用容器实例,比如订单微服务、库存微服务、mysql容器、nginx容器或者redis容器。

工程(project):由一组关联的应用容器组成的一个完整业务单元,在 docker-compose.yml 文件中定义。

Compose使用的三个步骤:

  1. 编写Dockerfile定义各个微服务应用并构建出对应的镜像文件。
  2. 使用 docker-compose.yml 定义一个完整业务单元,安排好整体应用中的各个容器服务。
  3. 最后,执行docker-compose up命令 来启动并运行整个应用程序,完成一键部署上线

Compose常用命令

docker-compose up -d # 启动所有docker-compose服务并后台运行

docker-compose down # 停止并删除容器、网络、卷、镜像。

docker-compose exec yml里面的服务id # 进入容器实例内部

docker-compose exec docker-compose.yml文件中写的服务id /bin/bashdocker-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 # 停止服务

5、Compose编排微服务

5.1 改造升级微服务工程docker_boot

业务流程

我们在之前的docker_boot工程的基础上进行改造(Docker笔记8-微服务实战那一节的工程)
开始改造

  1. 建Mysql库表
    创建一个db2021数据库,建立下表用于我们的测试(稍后我们把它移到docker容器中)
sql 复制代码
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 = utf8 COMMENT = '用户表'
  1. POM文件(新增了一些依赖)
xml 复制代码
<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>
  1. 修改application.yml
    注意:将mysql和redis的ip改为你装docker那台服务器的IP
yml 复制代码
server:
  port: 6001
  # ========================alibaba.druid相关配置=====================
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://192.168.248.128:3306/db2021?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: 123456
    druid:
      test-while-idle: false
# ========================redis相关配置=====================
  redis:
    database: 0
    host: 192.168.248.128
    port: 6379
    password:
    lettuce:
      pool:
        max-active: 8
        max-wait: -1ms
        max-idle: 8
        min-idle: 0
  # ========================swagger=====================
  swagger2:
    enabled: true
# ========================mybatis相关配置===================
mybatis:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.atguigu.docker.entities
  1. 添加配置类
    controller同目录新建config目录
    新建RedisConfig配置类
java 复制代码
/**
 * @Author: Daisen.Z
 * @Date: 2022/5/12 17:47
 * @Version: 1.0
 * @Description:
 */
@Configuration
@Slf4j
public class RedisConfig {
    /**
     * @param lettuceConnectionFactory
     * @return redis序列化的工具配置类,下面这个请一定开启配置
     * 127.0.0.1:6379> keys *
     * 1) "ord:102"  序列化过
     * 2) "\xac\xed\x00\x05t\x00\aord:102"   野生,没有序列化过
     */
    @Bean
    public RedisTemplate<String, Serializable> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
        RedisTemplate<String, Serializable> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(lettuceConnectionFactory);
        //设置key序列化方式string
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        //设置value的序列化方式json
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
}

新建SwaggerConfig配置类

java 复制代码
/**
 * @Author: Daisen.Z
 * @Date: 2022/5/12 17:50
 * @Version: 1.0
 * @Description:
 */
@Configuration
@EnableSwagger2
public class SwaggerConfig {

    @Value("${spring.swagger2.enabled}")
    private Boolean enabled;

    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).enable(enabled).select().apis(RequestHandlerSelectors.basePackage("com.atguigu.springcloud"))
                //你自己的package
                .paths(PathSelectors.any()).build();
    }

    public ApiInfo apiInfo() {
        return new ApiInfoBuilder().title("尚硅谷Java大厂技术" + "\t" + new SimpleDateFormat("yyyy-MM-dd").format(new Date())).description("docker-compose").version("1.0").termsOfServiceUrl("https://www.atguigu.com/").build();
    }
    
}
  1. 新建entity
    新增entities包,包下新建两个类
    User:
java 复制代码
/**
 * @Author: Daisen.Z
 * @Date: 2022/5/12 17:53
 * @Version: 1.0
 * @Description:
 */
@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:

java 复制代码
/**
 * @Author: Daisen.Z
 * @Date: 2022/5/12 17:55
 * @Version: 1.0
 * @Description:
 */
@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 + '}';
    }
  1. 新建mapper
    新建mapper包
    包下新建接口UserMapper
java 复制代码
/**
 * @Author: Daisen.Z
 * @Date: 2022/5/12 17:56
 * @Version: 1.0
 * @Description:
 */
public interface UserMapper extends Mapper<User> {
}

src\main\resources路径下新建mapper文件夹并新增UserMapper.xml

bash 复制代码
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.atguigu.springcloud.mapper.UserMapper">
    <resultMap id="BaseResultMap" type="com.atguigu.springcloud.entities.User">
        <!--      WARNING - @mbg.generated    -->
        <id column="id" jdbcType="INTEGER" property="id"/>
        <result column="username" jdbcType="VARCHAR" property="username"/>
        <result column="password" jdbcType="VARCHAR" property="password"/>
        <result column="sex" jdbcType="TINYINT" property="sex"/>
        <result column="deleted" jdbcType="TINYINT" property="deleted"/>
        <result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
        <result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
    </resultMap>
</mapper>

主启动类上添加tk.mybatis.spring.annotation.MapperScan注解,扫描mapper

bash 复制代码
@MapperScan("com.atguigu.springcloud.mapper") //import tk.mybatis.spring.annotation.MapperScan
  1. 新建service
    新建service包
    新建UserService
java 复制代码
@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);
        }
    }

    /**
     * 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;
    }
}
  1. 新建controller
    UserController
java 复制代码
@Api(description = "用户User接口")
@RestController
@Slf4j
public class UserController {
    @Resource
    private UserService userService;

    @ApiOperation("数据库新增3条记录")
    @RequestMapping(value = "/user/add", method = RequestMethod.POST)
    public void addUser() {
        for (int i = 1; i <= 3; i++) {
            User user = new User();
            user.setUsername("zzyy" + i);
            user.setPassword(IdUtil.simpleUUID().substring(0, 6));
            user.setSex((byte) new Random().nextInt(2));
            userService.addUser(user);
        }
    }

    @ApiOperation("查询1条记录")
    @RequestMapping(value = "/user/find/{id}", method = RequestMethod.GET)
    public User findUserById(@PathVariable Integer id) {
        return userService.findUserById(id);
    }
}
  1. 将服务打包
    将服务打包,并上传到我们第八篇用过的Dockerfile的目录下(/mydocker)
  2. 构建Docker镜像
    在/mydocker目录下执行命令
bash 复制代码
docker build -t zzyy_docker:1.6 .

5.2 不使用Compose编排时

新建mysql容器实例

bash 复制代码
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

进入mysql容器实例并新建库db2021+新建表t_user

bash 复制代码
docker exec -it mysql57 /bin/bash
bash 复制代码
mysql -uroot -p123456
bash 复制代码
create database db2021;
bash 复制代码
use db2021;
bash 复制代码
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 = '用户表';
bash 复制代码
show tables;


新建redis容器实例

bash 复制代码
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
bash 复制代码
docker ps

启动成功
启动微服务工程

bash 复制代码
 docker run -d -p 6001:6001 zzyy_docker:1.6
bash 复制代码
docker ps

依次启动成功

如果jar包启动失败,请在Idea中测试下工程看是否正常。
访问测试

bash 复制代码
http://192.168.248.128:6001/swagger-ui.html#/

测试下插入接口

插入成功

现在程序是部署成功了,但是我们总结下会有哪些问题:

  1. 先后顺序要求固定,先mysql+redis才能微服务启动成功;
  2. 多个run命令...,真正的微服务环境下会更多;
  3. 容器间的启停或宕机,有可能导致IP地址对应的容器实例变化,映射出错,要么生产IP写死(可以但是不推荐),要么通过服务调用。

好,带着以上问题我们在来使用下Compose来部署程序

5.3 使用Compose编排时

首先,编辑一个docker-compose.yml文件

bash 复制代码
cd /mydocker
bash 复制代码
vim docker-compose.yml

输入如下内容(主要要去掉注释内容,否则粘进去会有问题),保存

bash 复制代码
# 版本
version: "3"

# 容器中可以放几个容器实例
services:
  # 等同于命令:docker run -d -p 6001:6001 -v /app/microService:/data --network atguigu_net --name ms01 zzyy_docker:1.6
  microService: # 服务名(自定义的,只要不冲突就可以)
    image: zzyy_docker:1.6 # 镜像
    container_name: ms01 # 启动的容器名
    ports:
      - "6001:6001" # 端口号
    volumes:
      - /app/microService:/data # 容器卷映射
    networks:
      - atguigu_net # 网关
    depends_on:
      - redis # 启动的前置条件1
      - mysql # 启动的前置条件2
  # 解释参照microService
  redis:
    image: redis:6.0.8
    ports:
      - "6379:6379"
    volumes:
      - /app/redis/redis.conf:/etc/redis/redis.conf
      - /app/redis/data:/data
    networks:
      - atguigu_net
    command: redis-server /etc/redis/redis.conf
  mysql:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: '123456'
      MYSQL_ALLOW_EMPTY_PASSWORD: 'no'
      MYSQL_DATABASE: 'db2021'
      MYSQL_USER: 'zzyy'
      MYSQL_PASSWORD: 'zzyy123'
      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:
        - atguigu_net
      command:
        --default-authentication-plugin=mysql_native_password #解决外部无法访问

# 相当于 docker network create atguigu_net
networks:
  atguigu_net:

接下来,我们再次修改我们的微服务程序,将配置文件中写死的IP改成对应的redis和mysql的服务名

然后重新打包,上传

把原来启动的容器都停止删除掉

bash 复制代码
docker ps 
bash 复制代码
docker rm -f d15baec3ae6c 62c15c6a6944 89a24598336b

好,已经全部删除了

bash 复制代码
docker ps -a 

接着,删除之前构建的zzyy_docker镜像

bash 复制代码
docker rmi 5ca47b9f90ef 15deebec1981

好,已经清除干净了~

重新编译一次我们新的jar包

bash 复制代码
docker build -t zzyy_docker:1.6 .

接着,我们开始测试使用Docker-Compose部署

开始使用Compose

bash 复制代码
Compose常用命令
docker-compose up -d                        # 启动所有docker-compose服务并后台运行
docker-compose down                         # 停止并删除容器、网络、卷、镜像。
docker-compose exec  yml里面的服务id                 # 进入容器实例内部  
docker-compose exec docker-compose.yml文件中写的服务id /bin/bashdocker-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      # 停止服务 

我们在/mydocker(放docker-compose.yml的目录下),执行下命令检查下yml文件格式是否有问题

bash 复制代码
docker-compose config -q

没有任何输出代表没有问题,有输出表示格式有异常,需要修改。

我们docker ps一下,目前还没有任何容器启动

接着执行启动命令

bash 复制代码
docker-compose up -d

再次查看下,发现三个容器都已启动

接着,我们重新进入Mysql容器,创建下数据库表,步骤和上面一样,不再重复。

接着,访问微服务的swagger接口进行测试添加

bash 复制代码
http://192.168.248.128:6001/swagger-ui.html#/

添加成功,证明服务正常,测试通过

OK,自己测试下玩玩吧~

相关推荐
ghie90906 小时前
利用 Docker 和 Kubernetes 实现微服务部署
docker·微服务·kubernetes
@大迁世界6 小时前
我用 Rust 重写了一个 Java 微服务,然后丢了工作
java·开发语言·后端·微服务·rust
晓py7 小时前
理解 MySQL 架构:从连接到存储的全景视图
数据库·mysql·架构
Hare_bai7 小时前
WPF的MVVM模式核心架构与实现细节
ui·架构·c#·wpf·交互·xaml·mvvm
milanyangbo7 小时前
谁生?谁死?从引用计数到可达性分析,洞悉GC的决策逻辑
java·服务器·开发语言·jvm·后端·算法·架构
刘孬孬沉迷学习7 小时前
5G网络gNB与核心网(5GC)连接架构及传输协议
网络·网络协议·tcp/ip·5g·架构·udp·信息与通信
文火冰糖的硅基工坊7 小时前
[人工智能-大模型-78]:模型层技术 - 深度神经网络的网络架构的演进,这不仅是一条技术路线图,更是一部 “机器如何逐步逼近人类认知方式” 的进化史诗。
人工智能·架构·dnn
小虚竹8 小时前
Tokio的多线程调度器架构:深度解析与实践
架构
奔跑吧 android8 小时前
【Docker】【03.使用docker搭建ubuntu20.04 Qt5.12 开发环境】
qt·docker·ubuntu20.04·qt5.12