【docker16】Docker-Compose容器编排

目录

  • 1.是什么
  • 2.作用
  • 3.下载地址
    • 3.1官网
    • 3.2官网下载
    • 3.3安装步骤
    • 3.4卸载步骤
  • 4.Compose核心概念
    • 4.1一文件
    • 4.2两要素
  • 5.Compose的使用步骤
  • 6.Compose常用命令
  • 7.Compose编排微服务
    • 7.1升级改造docker_boot
      • 1.以前的基础版
      • 2.SQL建表建库
      • 3.一键生成说明
      • 4.改POM
      • 5.写YML
      • 6.主启动
      • 7.业务类
        • 7.1config配置类
        • 7.2新建entity
        • 7.3新建mapper
        • 7.4新建业务类
        • 7.5新建controller
      • 8.打jar包
      • 9.编写Dockerfile
      • 10.构建镜像
    • 7.2不用Compose的案例
      • 7.2.1单独的mysql容器实例
      • 7.2.2单独的redis容器实例
      • 7.2.3微服务工程
    • 7.3swagger测试
    • 7.4所存在的问题
    • 7.5使用Compose
      • 7.5.1编写docker-compose.yml文件
      • 7.5.2第二次修改微服务工程docker_boot
        • 1.写YML
        • 2.打包
        • 3.编写Dockerfile
        • 4.构建镜像
      • 7.5.3执行docker-compose up或者docker-compose up -d
      • 7.5.4进入mysql容器实例并新建库db2021+新建表t_user
      • 7.5.5测试通过
      • 7.5.6关停

1.是什么

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

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

2.作用

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

问题: 如果我需要同时部署好多个服务,难道要每个服务单独写Dockerfile然后在构建镜像嘛?这样会很麻烦,所以docker官方给我们提供了docker-compose多服务部署的工具

例如: 要实现一个web项目,除了web服务容器本身,往往还需要加上后端的数据库mysql服务容器,redis服务器,注册中心eureka,甚至还包括负载均衡容器等等

Compose允许用户通过一个单独的docker-compose.yml模板文件(YAML格式)来定义一组相关联的应用容器作为一个项目(project)。可以很容易的用一个配置文件定义一个多容器的应用,然后使用一条指令安装这个应用的所有依赖,完成构建,Docker-Compose解决了容器与容器之间如何管理编排的问题。

3.下载地址

3.1官网

官网

3.2官网下载

下载网址
【docker16】Docker-Compose容器编排_第2张图片
【docker16】Docker-Compose容器编排_第3张图片

3.3安装步骤

新版安装步骤可以看官网

命令1: curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
命令2: chmod +x /usr/local/bin/docker-compose
命令3: docker-compose --version

【docker16】Docker-Compose容器编排_第4张图片

3.4卸载步骤

命令: rm /usr/local/bin/docker-compose

4.Compose核心概念

4.1一文件

docker-compose.yml

4.2两要素

  • 服务(service)
    一个个应用容器实例,比如订单微服务、库存微服务、mysql容器、nginx容器或者redis容器
  • 工程(project)
    由一组关联应用容器组成的一个完整业务单元,在docker-compose.yml文件中定义文件
    【docker16】Docker-Compose容器编排_第5张图片

5.Compose的使用步骤

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

【docker16】Docker-Compose容器编排_第6张图片

6.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 #停止服务

7.Compose编排微服务

7.1升级改造docker_boot

1.以前的基础版

【docker16】Docker-Compose容器编排_第7张图片

2.SQL建表建库

【docker16】Docker-Compose容器编排_第8张图片

USE db2023;

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 = 1114 DEFAULT CHARSET = utf8 COMMENT = '用户表'

3.一键生成说明

4.改POM


<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.0modelVersion>
    <parent>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-parentartifactId>
        <version>2.5.6version>
        <relativePath/> 
    parent>
    <groupId>com.atguigu.dockergroupId>
    <artifactId>docker_bootartifactId>
    <version>0.0.1-SNAPSHOTversion>

    <properties>
        <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
        <maven.compiler.source>1.8maven.compiler.source>
        <maven.compiler.target>1.8maven.compiler.target>
        <junit.version>4.12junit.version>
        <log4j.version>1.2.17log4j.version>
        <lombok.version>1.16.18lombok.version>
        <mysql.version>5.1.47mysql.version>
        <druid.version>1.1.16druid.version>
        <mapper.version>4.1.5mapper.version>
        <mybatis.spring.boot.version>1.3.0mybatis.spring.boot.version>
    properties>

    <dependencies>
        
        <dependency>
            <groupId>com.google.guavagroupId>
            <artifactId>guavaartifactId>
            <version>23.0version>
        dependency>
        
        <dependency>
            <groupId>org.redissongroupId>
            <artifactId>redissonartifactId>
            <version>3.13.4version>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-actuatorartifactId>
        dependency>
        
        <dependency>
            <groupId>io.springfoxgroupId>
            <artifactId>springfox-swagger2artifactId>
            <version>2.9.2version>
        dependency>
        <dependency>
            <groupId>io.springfoxgroupId>
            <artifactId>springfox-swagger-uiartifactId>
            <version>2.9.2version>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-data-redisartifactId>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-cacheartifactId>
        dependency>
        
        <dependency>
            <groupId>org.apache.commonsgroupId>
            <artifactId>commons-pool2artifactId>
        dependency>
        
        <dependency>
            <groupId>redis.clientsgroupId>
            <artifactId>jedisartifactId>
            <version>3.1.0version>
        dependency>
        
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <version>5.1.47version>
        dependency>
        
        <dependency>
            <groupId>com.alibabagroupId>
            <artifactId>druid-spring-boot-starterartifactId>
            <version>1.1.10version>
        dependency>
        <dependency>
            <groupId>com.alibabagroupId>
            <artifactId>druidartifactId>
            <version>${druid.version}version>
        dependency>
        
        <dependency>
            <groupId>org.mybatis.spring.bootgroupId>
            <artifactId>mybatis-spring-boot-starterartifactId>
            <version>${mybatis.spring.boot.version}version>
        dependency>
        
        
        <dependency>
            <groupId>cn.hutoolgroupId>
            <artifactId>hutool-allartifactId>
            <version>5.2.3version>
        dependency>
        <dependency>
            <groupId>junitgroupId>
            <artifactId>junitartifactId>
            <version>${junit.version}version>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-devtoolsartifactId>
            <scope>runtimescope>
            <optional>trueoptional>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
        dependency>
        <dependency>
            <groupId>log4jgroupId>
            <artifactId>log4jartifactId>
            <version>${log4j.version}version>
        dependency>
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <version>${lombok.version}version>
            <optional>trueoptional>
        dependency>
        
        <dependency>
            <groupId>javax.persistencegroupId>
            <artifactId>persistence-apiartifactId>
            <version>1.0.2version>
        dependency>
        
        <dependency>
            <groupId>tk.mybatisgroupId>
            <artifactId>mapperartifactId>
            <version>${mapper.version}version>
        dependency>
    dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackagegoal>
                        goals>
                    execution>
                executions>
            plugin>
            <plugin>
                <groupId>org.apache.maven.pluginsgroupId>
                <artifactId>maven-resources-pluginartifactId>
                <version>3.1.0version>
            plugin>
        plugins>
    build>

project>

5.写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://192.168.100.130:3306/db2023?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.100.130
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

6.主启动

package com.atguigu.docker;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import tk.mybatis.spring.annotation.MapperScan;

@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);
    }

}

7.业务类

7.1config配置类
package com.atguigu.docker.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.io.Serializable;

/**
 * 简要描述
 *
 * @Author: ASuLe
 * @Date: 2023/1/14 13:21
 * @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;
    }
}

package com.atguigu.docker.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 简要描述
 *
 * @Author: ASuLe
 * @Date: 2023/1/14 13:22
 * @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.docker")) //你自己的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();
    }
}

7.2新建entity
package com.atguigu.docker.entities;

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;
    }
}
package com.atguigu.docker.entities;

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;

/**
 * 简要描述
 *
 * @Author: ASuLe
 * @Date: 2023/1/14 13:24
 * @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 +
                '}';
    }
}
7.3新建mapper
package com.atguigu.docker.mapper;

import com.atguigu.docker.entities.User;
import tk.mybatis.mapper.common.Mapper;

public interface UserMapper extends Mapper<User> {
}

DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.study.docker.mapper.UserMapper">
    <resultMap id="BaseResultMap" type="com.atguigu.docker.entities.User">
        
        <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>
7.4新建业务类
package com.atguigu.docker.service;

import com.atguigu.docker.entities.User;
import com.atguigu.docker.mapper.UserMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * 简要描述
 *
 * @Author: ASuLe
 * @Date: 2023/1/14 13:14
 * @Version: 1.0
 * @Description: 文件作用详细描述....
 */
@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;
    }
}

7.5新建controller
package com.atguigu.docker.controller;

import cn.hutool.core.util.IdUtil;
import com.atguigu.docker.entities.User;
import com.atguigu.docker.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.Random;

/**
 * 简要描述
 *
 * @Author: ASuLe
 * @Date: 2023/1/14 13:33
 * @Version: 1.0
 * @Description: 文件作用详细描述....
 */
@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);
    }
}

8.打jar包

mvn package命令将微服务形成新的jar包并上传到Linux服务器/mydocker目录下
【docker16】Docker-Compose容器编排_第9张图片

9.编写Dockerfile

【docker16】Docker-Compose容器编排_第10张图片

# 基础镜像使用java
FROM java:8
# 作者
MAINTAINER asule
# VOLUME 指定临时文件目录为/tmp,在主机/var/lib/docker目录下创建了一个临时文件并
链接到容器的/tmp
VOLUME /tmp
# 将jar包添加到容器中并更名为asule_docker.jar
ADD docker_boot-0.0.1-SNAPSHOT.jar asule_docker.jar
# 运行jar包
RUN bash -c 'touch /asule_docker.jar'
ENTRYPOINT ["java","-jar","/asule_docker.jar"]
#暴露6001端口作为微服务
EXPOSE 6001

10.构建镜像

命令: docker build -t asule_docker:1.6 .

【docker16】Docker-Compose容器编排_第11张图片
【docker16】Docker-Compose容器编排_第12张图片

7.2不用Compose的案例

7.2.1单独的mysql容器实例

  1. 新建mysql容器实例
    命令:docker run -d -p 3306:3306 --privileged=true -v /asuleuse/mysql/conf:/etc/mysql/conf.d -v /asuleuse/mysql/logs:/logs -v /asuleuse/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql57 mysql:5.7
    【docker16】Docker-Compose容器编排_第13张图片

  2. 进入mysql容器实例并新建db2023+新建表t_user
    在这里插入图片描述
    【docker16】Docker-Compose容器编排_第14张图片

7.2.2单独的redis容器实例

命令:docker run -d -p 6379:6379 --privileged=true -v /app/redis.conf:/etc/redis/redis.conf -v /app/redis/data:/data --name redis608 redis:6.0.8 redis-server /etc/redis/redis.conf
【docker16】Docker-Compose容器编排_第15张图片
在这里插入图片描述

7.2.3微服务工程

命令: docker run -d -p 6001:6001 容器ID
【docker16】Docker-Compose容器编排_第16张图片

上面三个容器实例依次顺序启动,但是如果有30

7.3swagger测试

命令: http://192.168.100.130:6001/swagger-ui.html
【docker16】Docker-Compose容器编排_第17张图片
【docker16】Docker-Compose容器编排_第18张图片
【docker16】Docker-Compose容器编排_第19张图片
mysql
【docker16】Docker-Compose容器编排_第20张图片
redis
【docker16】Docker-Compose容器编排_第21张图片

7.4所存在的问题

【docker16】Docker-Compose容器编排_第22张图片

问题1: 先后顺序要求固定,先启动mysql+redis才能启动微服务访问
问题2: 多次run命令
问题3: 容器间的启停或宕机,有可能导致IP地址对应的容器实例变化,映射出错,要么生产IP写死(可以但是不推荐),要么服务调用

7.5使用Compose

7.5.1编写docker-compose.yml文件

version: "3"

services:
  #下面相当于 docker run -d -p 6001:6001 -V /app/microService:/data --network atguigu_net --name ms01 zzyy_docker:1.6
  #microService随便定义名字,只要不冲突就行
  microService:
    #运行的镜像是asule_docker:1.6
    image: asule_docker:1.6
    #容器名字ms01,即--name ms01
    container_name: ms01
    ports:
      - "6001:6001"
    #相当于-V /app/microService:/data
    volumes:
      - /app/microService:/data
    #希望三个容器都跑在同一个网段,相当于--network atguigu_net
    networks:
      - atguigu_net
    #这个容器依赖于下面的两个容器,也就是说要下面两个微服务先启动,该服务才会启动
    depends_on:
      - redis
      - mysql
  
  redis:
    image: redis
    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: 'db2023'
      MYSQL_USER: 'asule'
      MYSQL_PASSWORD: 'asuke123'
    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 #解决外部无法访问

#创建三个容器的网段,指定了这个网络以后,我们的微服务就不用写死ip了,可以通过redis和mysql这两个服务名来访问两个微服务
#相当于docker network create atguigu_net
networks:
  atguigu_net:

【docker16】Docker-Compose容器编排_第23张图片

7.5.2第二次修改微服务工程docker_boot

1.写YML

修改成通过服务名访问,与IP无关
将固定写死的IP换成服务名
【docker16】Docker-Compose容器编排_第24张图片
【docker16】Docker-Compose容器编排_第25张图片

2.打包

【docker16】Docker-Compose容器编排_第26张图片

3.编写Dockerfile

还是原来的

4.构建镜像

首先关闭原来的删除原来的
【docker16】Docker-Compose容器编排_第27张图片
创建新的镜像
命令: docker build -t asule_docker:1.6 .
【docker16】Docker-Compose容器编排_第28张图片

7.5.3执行docker-compose up或者docker-compose up -d

命令: docker-compose config -q
如果没有任何提示说明语法格式是正确的
在这里插入图片描述

命令: docker-compose up -d
【docker16】Docker-Compose容器编排_第29张图片
查看网络
根据docker-compose编排规矩,会根据所在路径加一个前缀
【docker16】Docker-Compose容器编排_第30张图片
如果没有指定容器名字
【docker16】Docker-Compose容器编排_第31张图片
会加上前后缀
【docker16】Docker-Compose容器编排_第32张图片
查看所运行的实例,由于6.0.8启动不了,修改了配置文件,使用了redis最新版

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

查看redis
在这里插入图片描述
建表并查看mysql
【docker16】Docker-Compose容器编排_第33张图片

7.5.5测试通过

【docker16】Docker-Compose容器编排_第34张图片
执行测试
【docker16】Docker-Compose容器编排_第35张图片
查看redis
【docker16】Docker-Compose容器编排_第36张图片

查看数据库
【docker16】Docker-Compose容器编排_第37张图片

【docker16】Docker-Compose容器编排_第38张图片

7.5.6关停

命令: docker-compose stop

在这里插入图片描述

十几、二十个用docker-compose可以,但是更多的话就要上k8s

你可能感兴趣的:(docker学习,docker,容器,运维)