【docker16】Docker-Compose容器编排

news2025/1/15 20:37:41

1.是什么

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

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

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官网下载

下载网址
在这里插入图片描述
在这里插入图片描述

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

在这里插入图片描述

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文件中定义文件
    在这里插入图片描述

5.Compose的使用步骤

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

在这里插入图片描述

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.以前的基础版

在这里插入图片描述

2.SQL建表建库

在这里插入图片描述

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

<?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>
        <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>
        <!--通用基础配置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>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>3.1.0</version>
            </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> {
}
<?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.study.docker.mapper.UserMapper">
    <resultMap id="BaseResultMap" type="com.atguigu.docker.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>

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目录下
在这里插入图片描述

9.编写Dockerfile

在这里插入图片描述

# 基础镜像使用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 .

在这里插入图片描述
在这里插入图片描述

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
    在这里插入图片描述

  2. 进入mysql容器实例并新建db2023+新建表t_user
    在这里插入图片描述
    在这里插入图片描述

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
在这里插入图片描述
在这里插入图片描述

7.2.3微服务工程

命令: docker run -d -p 6001:6001 容器ID
在这里插入图片描述

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

7.3swagger测试

命令: http://192.168.100.130:6001/swagger-ui.html
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
mysql
在这里插入图片描述
redis
在这里插入图片描述

7.4所存在的问题

在这里插入图片描述

问题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:

在这里插入图片描述

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

1.写YML

修改成通过服务名访问,与IP无关
将固定写死的IP换成服务名
在这里插入图片描述
在这里插入图片描述

2.打包

在这里插入图片描述

3.编写Dockerfile

还是原来的

4.构建镜像

首先关闭原来的删除原来的
在这里插入图片描述
创建新的镜像
命令: docker build -t asule_docker:1.6 .
在这里插入图片描述

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

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

命令: docker-compose up -d
在这里插入图片描述
查看网络
根据docker-compose编排规矩,会根据所在路径加一个前缀
在这里插入图片描述
如果没有指定容器名字
在这里插入图片描述
会加上前后缀
在这里插入图片描述
查看所运行的实例,由于6.0.8启动不了,修改了配置文件,使用了redis最新版

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

查看redis
在这里插入图片描述
建表并查看mysql
在这里插入图片描述

7.5.5测试通过

在这里插入图片描述
执行测试
在这里插入图片描述
查看redis
在这里插入图片描述

查看数据库
在这里插入图片描述

在这里插入图片描述

7.5.6关停

命令: docker-compose stop

在这里插入图片描述

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

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

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

相关文章

JAVA导出Excel通用工具——第二篇:使用EasyExcel导出excel的多种情况的例子介绍

JAVA导出Excel通用工具——第二篇&#xff1a;使用EasyExcel导出excel的多种情况的例子介绍1. 前言2. 依赖3. 导出简单例子3.1 ① 基础入门例子3.1.1 核心代码3.1.2 效果展示3.2 ② 注解的简单使用3.2.1 ExcelIgnore3.2.2 ExcelProperty3.2.2.1 一般效果&#xff08;表头合并等…

MySQL高级【InnoDB引擎】

1&#xff1a;InnoDB引擎1.1&#xff1a;逻辑存储引擎 InnoDB的逻辑存储结构如下图所示: 1). 表空间 表空间是InnoDB存储引擎逻辑结构的最高层&#xff0c; 如果用户启用了参数 innodb_file_per_table(在 8.0版本中默认开启) &#xff0c;则每张表都会有一个表空间&#xff08…

【iOS】—— 初识block

block 文章目录block什么是block&#xff1f;block语法Block变量截获自动变量值__block说明符截获的自动变量block的三种存储类型NSGlobalBlockNSStackBlockNSMallocBlockblock的父类block循环引用未完待续什么是block&#xff1f; Blocks是带有自动变量&#xff08;局部变量&…

React--》初识React框架及其基本使用

目录 React React的安装与使用 JSX语法及使用 模块与组件 React开发者工具的安装 面向组件编程 React React是一个用于构建用户界面的JavaScript库。用户界面:HTML页面(前端)。React主要用来写HTML页面&#xff0c;或构建Web应用。 如果从 MVC的角度来看&#xff0c;…

第一天总结之后端登录功能的实现

第一天总结之后端登录功能的实现 一、 前端页面 从图片 很明显知道 两个intput输入框 一个输入username 一个输入password 从前端的页面代码 可以找到form表单 根据form表单的action属性了解到 点击登录跳转到 controller 层的 LoginServlet 二、controller 层 创建一个 Log…

2023年跨境电商新趋势,新手小白还有出路吗?

跨境电商一直位于我国对外开放的最前沿&#xff0c;当下已经成为我国进出口贸易的关键组成部分之一&#xff0c;是外贸企业顺利开展进出口业务的重要保障&#xff0c;更是拥有庞大发展潜力以及活力的贸易新业态。在经济全球化趋势下&#xff0c;充分发挥出跨境电商的战略新通道…

Java 包的使用详解

文章目录1. 概念2. 导入包中的类2.1 使用类的全路径2.2 导入包2.3 静态导入包3. 自定义包4. 包的访问权限控制5. 常用的包Java编程基础教程系列1. 概念 在开发过程中&#xff0c;会定义很多的类&#xff0c;随着类的定义越来越多&#xff0c;难免会出现类名重复的情况&#xf…

mac 安装redis

文章目录mac 安装redis使用Homebrew安装Redis1.搜索redis版本2.使用Homebrew安装命令3.查看是否安装完成4.启动redis服务5.查看redis服务进程6.redis-cli连接redis服务7.检测 redis 服务是否启动8.修改密码mac 安装redis 使用Homebrew安装Redis 首先这里需要安装homebrew 1.搜…

【Kubernetes 企业项目实战】03、基于 Alertmanager 发送报警到多个接收方(上)

目录 一、配置 Alertmanager 发送报警到 qq 邮箱 1.1 设置 163 邮箱 1.2 创建 alertmanager 配置文件 1.3 创建 prometheus 告警规则配置文件 1.4 安装 prometheus 和 alertmanager 1.5 部署 alertmanager 的 service 1.6 浏览器访问 Prometheus 和 alertmanager 二、配…

ELK日志(2)

elasticsearch群集状态颜色&#xff1a;灰色&#xff1a;未连接绿色&#xff1a;数据完整态黄色&#xff1a;副本不完整红色&#xff1a;数据分片不完整紫色&#xff1a;数据分片复制过程群集主机角色&#xff1a;主节点master&#xff1a;负责管理调度工作节点&#xff1a; 负…

从IPv6的普及看中国未来网络的发展

最近看了一篇《邬贺铨&#xff1a;IPv6或是未来主流网络》的文章,谈到了未来网络的发展问题。IPv6也许是未来主流网络的发展方向。那么什么是IPv6呢,不妨来看下关于他的另一篇文章《邬贺铨&#xff1a;IPv6是IPv6规模部署第三阶段重要抓手》。 他谈到&#xff0c;IPv6是下一代互…

单绞机张力开环控制(绞臂行星差速机构算法)

PLC的开环和闭环张力控制算法,可以参看下面的文章链接: PLC张力控制(开环闭环算法分析)_plc张力控制程序_RXXW_Dor的博客-CSDN博客里工业控制张力控制无处不在,也衍生出很多张力控制专用控制器,磁粉制动器等,本篇博客主要讨论PLC的张力控制相关应用和算法,关于绕线机的…

动态内存管理(1)

TIPS 1. 2. malloc, free, calloc, realloc 这些的基本前提都是在内存堆区 内存堆区不能与内存栈区两者混淆乱套 动态内存管理存在的原因 1. 为什么要有动态内存管理&#xff1f;其实我们之前学过比如说对内存的管理&#xff0c;比方说我申请一块内存空间&#xff1a; 1.…

任意方向边界框——day64 读论文:基于自适应目标定位特征卷积神经网络的高分辨率遥感影像多面向目标检测

Multi-Oriented Object Detection in High-Resolution Remote Sensing Imagery Based on Convolutional Neural Networks with Adaptive Object Orientation Features 基于自适应目标定位特征卷积神经网络的高分辨率遥感影像多面向目标检测1. Introduction2. Materials and Met…

jQuery ajax中dataFilter的用法

参考资料 jquery的ajax的dataFilter参数的使用 ⏹用于处理 XMLHttpRequest 原始响应数据的函数 运行在success函数之前, 对Ajax请求返回的原始数据进行预处理 可以对返回的json数据中的null属性进行过滤可以对返回的json数据添加一些自定义的属性 如果不返回原始数据,返回其他…

零代码连接邮箱腾讯云企业网盘,附件管理超轻松

在日常工作中&#xff0c;想必大家每天都会收到各种各样的工作邮件&#xff0c;并且很多重要的文件材料也是通过邮件附件的形式来传输的&#xff0c;那么如何一站式管理这些文件&#xff0c;对于提高办公效率就至关重要了。关于邮件附件管理&#xff0c;相信大家也都碰到过这样…

全面了解文件上传漏洞, 通关upload-labs靶场

靶场简介 upload-labs是一个专门用于学习文件上传漏洞攻击和防御的靶场。它提供了一系列模拟文件上传漏洞的实验环境&#xff0c;用于帮助用户了解文件上传漏洞的原理和防御技术。 这个靶场包括了常见的文件上传漏洞类型&#xff0c;如文件名欺骗、文件类型欺骗、文件上传功能…

1582_C代码实现的快速、可移植MD5信息摘要算法

全部学习汇总&#xff1a; GreyZhang/c_units: A small piece of code which can be reuse anywhere, I call it a unit. This is a collection of unit in C language! Ok, yes, it would be my toolbox. (github.com) 工作之中&#xff0c;同事用到了MD5信息摘要算法&#x…

面试加分题--socket是否是并发安全的?

今天和大家聊一个有点儿东西的面试题&#xff1a;socket是否是并发安全的&#xff1f; 为了帮助大家理解&#xff0c;我们先假设一个场景。 就拿游戏架构来说&#xff0c;我们想象中的游戏架构是下面这样的。 想象中的游戏架构 也就是用户客户端直接连接游戏核心逻辑服务器&…

解决⾃动驾驶中计算机视觉的⽬标检测问题

来源&#xff1a;投稿 作者&#xff1a;cairuyi01 编辑&#xff1a;学姐 最近读了《Object detection with location-aware deformable convolution and backward attention filtering》&#xff0c;这是⼀篇2019年刊登在CVPR上的CV论⽂。与解决普适性的CV任务不同&#xff0c…