【Docker】Compose容器编排:微服务实战

news2024/11/16 9:16:21

Docker-Compose是Docker官方的开源项目, 负责实现对Docker容器集群的快速编排。是一个工具软件,可以 管理多个 Docker 容器 组成一个应用。你需要 定义一个 YAML 格式的配置文件docker-compose.yml ,写好多个容器之间的调用关系。然后,只要一个命令,就能 同时启动/关闭这些容器

  1. 例如要实现一个Web微服务项目,除了Web服务容器本身,往往还需要再加上后端的数据库mysql服务容器,redis服务器,注册中心eureka,甚至还包括负载均衡容器等等。。。。。。
  2. Compose允许用户通过一个单独的docker-compose.yml模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)。
  3. 可以很容易地用一个配置文件定义一个多容器的应用,然后使用一条指令安装这个应用的所有依赖,完成构建。Docker-Compose 解决了容器与容器之间如何管理编排的问题。
    在这里插入图片描述

一、Compose核心概念与常用命令

核心概念

  • 一文件:docker-compose.yml
  • 两要素
    • 服务(service):一个个应用容器实例,比如订单微服务、库存微服务、mysql容器、nginx容器或者redis容器
    • 工程(project):由一组关联的应用容器组成的一个完整业务单元,在 docker-compose.yml 文件中定义。

使用步骤

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

常用命令

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

二、创建微服务

  1. 项目结构

    在这里插入图片描述

  2. 改 pom.xml

    <?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 http://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>
        <packaging>jar</packaging>
    
        <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>
                    <version>2.2.1.RELEASE</version>
                    <configuration>
                        <!--<mainClass>com.wang.docker.DockerBootApplication</mainClass>-->
                    </configuration>
                    <executions>
                        <execution>
                            <id>repackage</id>
                            <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>
    
  3. 写 application.properties

    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://114.132.162.129: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=114.132.162.129
    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.wang.docker.entities
    # ========================swagger=====================
    spring.swagger2.enabled=true
    
  4. 主启动

    package com.wang.docker;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import tk.mybatis.spring.annotation.MapperScan;
    
    /**
     * @ClassName: DockerBootApplication
     * @Description
     * @Author:我自己
     * @Date: 2022/8/6  16:14
     * @Version 1.0
     */
    @SpringBootApplication
    @MapperScan("com.wang.docker.mapper") //import tk.mybatis.spring.annotation.MapperScan;
    public class DockerBootApplication {
        public static void main(String[] args) {
            SpringApplication.run(DockerBootApplication.class,args);
        }
    }
    
  5. Controller:UserController

    package com.wang.docker.controller;
    
    import cn.hutool.core.util.IdUtil;
    import com.wang.docker.entities.User;
    import com.wang.docker.service.UserService;
    import io.swagger.annotations.Api;
    import io.swagger.annotations.ApiOperation;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.web.bind.annotation.*;
    
    import javax.annotation.Resource;
    import java.util.Random;
    
    /**
     * @ClassName: UserController
     * @Description
     * @Author:我自己
     * @Date: 2022/8/6  16:16
     * @Version 1.0
     */
    @RestController
    @Api(description = "用户User接口")
    @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("wfc"+i);
                user.setPassword(IdUtil.simpleUUID().substring(0,6));
                user.setSex((byte) new Random().nextInt(2));
    
                userService.addUser(user);
            }
        }
    
       /* @ApiOperation("删除1条记录")
        @RequestMapping(value = "/user/delete/{id}",method = RequestMethod.POST)
        public void deleteUser(@PathVariable Integer id)
        {
            userService.deleteUser(id);
        }
    
        @ApiOperation("修改1条记录")
        @RequestMapping(value = "/user/update",method = RequestMethod.POST)
        public void updateUser(@RequestBody UserDTO userDTO)
        {
            User user = new User();
            BeanUtils.copyProperties(userDTO,user);
            userService.updateUser(user);
        }*/
    
        @ApiOperation("查询1条记录")
        @RequestMapping(value = "/user/find/{id}",method = RequestMethod.GET)
        public User findUserById(@PathVariable Integer id)
        {
            return userService.findUserById(id);
        }
    
    }
    
  6. service:UserService

    package com.wang.docker.service;
    
    import com.wang.docker.entities.User;
    import com.wang.docker.mapper.UserMapper;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.stereotype.Service;
    
    import javax.annotation.Resource;
    
    /**
     * @ClassName: UserService
     * @Description
     * @Author:我自己
     * @Date: 2022/8/7  11:01
     * @Version 1.0
     */
    @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. mapper Interface:UserMappper

    package com.wang.docker.mapper;
    
    import com.wang.docker.entities.User;
    import tk.mybatis.mapper.common.Mapper;
    
    public interface UserMapper extends Mapper<User> {
    }
    
  8. mapper XML:Usermapper.xml

    <?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.wang.docker.mapper.UserMapper">
      <resultMap id="BaseResultMap" type="com.wang.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>
    
  9. entities:User

    package com.wang.docker.entities;
    
    import java.io.Serializable;
    import java.util.Date;
    import javax.persistence.*;
    
    @Table(name = "t_user")
    public class User implements Serializable {
        @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;
        }
    }
    
    
  10. entities:UserDTO

    package com.wang.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;
    /**
     * @ClassName: UserDTO
     * @Description
     * @Author:我自己
     * @Date: 2022/8/7  10:58
     * @Version 1.0
     */
    @AllArgsConstructor
    @NoArgsConstructor
    @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 +
                    '}';
        }
    }
    
    
  11. config:RedisConfig

    package com.wang.docker.config;
    
    import org.springframework.context.annotation.Bean;
    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;
    
    /**
     * @ClassName: RedisConfig
     * @Description
     * @Author:我自己
     * @Date: 2022/8/7  10:55
     * @Version 1.0
     */
    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;
        }
    }
    
  12. config:SwaggerConfig

    package com.wang.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;
    
    /**
     * @ClassName: SwaggerConfig
     * @Description
     * @Author:我自己
     * @Date: 2022/8/7  10:55
     * @Version 1.0
     */
    @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.wang.docker")) //你自己的package
                    .paths(PathSelectors.any())
                    .build();
        }
    
        public ApiInfo apiInfo() {
            return new ApiInfoBuilder()
                    .title("aaaa测试"+"\t"+new SimpleDateFormat("yyyy-MM-dd").format(new Date()))
                    .description("docker-compose")
                    .version("1.0")
                    .termsOfServiceUrl("https://www.atguigu.com/")
                    .build();
        }
    
    }
    

对比案例:不使用 Compose和自定义网络

  1. mvn package 命令将微服务形成新的jar包,并上传到服务器目录下 /myfile/Dockerfile_Compose-Test1

    在这里插入图片描述

  2. 编写Dockerfile

    FROM java:8
    MAINTAINER Lzwei.cn
    # VOLUME 指定临时文件目录为/tmp,在主机/var/lib/docker目录下创建了一个临时文件并链接到容器的/tmp
    VOLUME /tmp
    ADD docker_boot-0.0.1-SNAPSHOT.jar lzwei_docker.jar
    # 运行jar包
    RUN bash -c 'touch /lzwei_docker.jar'
    ENTRYPOINT ["java","-jar","/lzwei_docker.jar"]
    EXPOSE 6001
    
  3. 构建镜像

    docker build -t lzwei_docker:1.6 .
    

    在这里插入图片描述

  4. 启动 mysql容器实例

    docker run -d -p 3306:3306 --privileged=true -v /mydata/mysql/node1/conf:/etc/mysql/conf.d -v /mydata/mysql/node1/logs:/logs -v /mydata/mysql/node1/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql57 mysql:5.7
    

    在这里插入图片描述

  5. 进入 mysql57:3306,建库(db2021)、建表(t_user)

    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='用户表';
    

    在这里插入图片描述

  6. 启动 redis容器实例

    docker run -d -p 6379:6379 --privileged=true -v /mydata/redis/node1/redis.conf:/etc/redis/redis.conf -v /mydata/redis/node1/data:/data --name redis6016 redis:6.0.16 redis-server /etc/redis/redis.conf
    

    在这里插入图片描述

  7. 启动 微服务容器实例

    docker run -d -p 6001:6001 lzwei_docker:1.6
    

    在这里插入图片描述

  8. swagger 测试:http://114.132.162.129:6001/swagger-ui.html

    在这里插入图片描述

    在这里插入图片描述

总结:这种方式会出现哪些问题?

  • 不使用 Compose
    • 需要严格按照顺序启动服务,且容器数量过多需要执行多时条 run命令 时容易混淆造成阻碍
  • 不使用 自定义网络
    • 容器间使用 容器IP 进行访问时,容器的启停有可能导致 容器IP 发生变化,造成映射出错。要么生产IP写死(可以但是不推荐),要么通过服务调用

使用案例:Compose+自定义网络

清除 redis6016和mysql57 持久化的数据

  1. 创建 docker-compose.yml

    在这里插入图片描述

    version: "3"
     
    services:
      users:
        image: lzwei_docker:1.7
        container_name: users
        ports:
          - "6001:6001"
        volumes:
          - /mydata/users:/data
        networks: 
          - lzwei_net
        depends_on: 
          - redis6016
          - mysql57
     
      redis6016:
        image: redis:6.0.16
        ports:
          - "6379:6379"
        volumes:
          - /mydata/redis/node1/redis.conf:/etc/redis/redis.conf
          - /mydata/redis/node1/data:/data
        networks: 
          - lzwei_net
        command: redis-server /etc/redis/redis.conf
     
      mysql57:
        image: mysql:5.7
        environment:
          MYSQL_ROOT_PASSWORD: '123456'
          MYSQL_ALLOW_EMPTY_PASSWORD: 'no'
          MYSQL_DATABASE: 'db2021'
          MYSQL_USER: 'lzwei'
          MYSQL_PASSWORD: 'lzwei'
        ports:
           - "3306:3306"
        volumes:
           - /mydata/mysql/node1/conf:/etc/mysql
           - /mydata/mysql/node1/logs:/var/log/mysql
           - /mydata/mysql/node1/data:/var/lib/mysql
        networks:
          - lzwei_net
        command: --default-authentication-plugin=mysql_native_password #解决外部无法访问
     
    networks: 
       lzwei_net: 
    
  2. 修改 application.properties

    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://114.132.162.129:3306/db2021?useUnicode=true&characterEncoding=utf-8&useSSL=false
    spring.datasource.url=jdbc:mysql://mysql57: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=114.132.162.129
    spring.redis.host=redis6016
    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.wang.docker.entities
    # ========================swagger=====================
    spring.swagger2.enabled=true
    
  3. mvn package 命令将微服务形成新的jar包,并上传到服务器目录下 /myfile/Dockerfile_Compose-Test2

    在这里插入图片描述

  4. 编写 Dockerfile

    FROM java:8
    MAINTAINER Lzwei.cn
    # VOLUME 指定临时文件目录为/tmp,在主机/var/lib/docker目录下创建了一个临时文件并链接到容器的/tmp
    VOLUME /tmp
    ADD docker_boot-0.0.1-SNAPSHOT.jar lzwei_docker.jar
    # 运行jar包
    RUN bash -c 'touch /lzwei_docker.jar'
    ENTRYPOINT ["java","-jar","/lzwei_docker.jar"]
    EXPOSE 6001
    
  5. 构建镜像

    docker build -t lzwei_docker:1.7 .
    

    在这里插入图片描述

  6. 一键启动容器: docker-compose up 或者 执行 docker-compose up -d

    在这里插入图片描述

  7. swagger 测试:http://114.132.162.129:6001/swagger-ui.html

    在这里插入图片描述

  8. 一键停止:docker compose stop

    在这里插入图片描述

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

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

相关文章

GeoTools快速入门

本文将帮助读者获取GeoTools的源代码并进行编译。下载源代码并进行编译有助于读者对GeoTools建立整体性的理解&#xff0c;帮助读者厘清GeoTools的模块划分。同时因为GeoTools是一个开源类库&#xff0c;读者在实际使用中遇到的一些问题可以通过直接阅读GeoTools源代码来进行解…

vue3+ts项目中封装3d单柱柱状图

vue3ts项目中封装单柱的柱状图 成品图 下载echarts npm i echarts 封装组件为Barchart.vue文件 <template> </template><script setup lang"ts"> import { nextTick, watch } from vue import echarts from /assets/ts/echarts; import useRes…

[附源码]计算机毕业设计在线项目管理Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

十三、Vue CLI(2)

本章概要 项目结构编写一个 Hello 组件package.json 13.4 项目结构 通过 Vue CLI 生成的项目的目录结构及各文件夹和文件的用途说明如下&#xff1a; |--node_modules //项目依赖的模块 |--public //该目录下的文件不会被 Webpack 编译压缩处理&…

Springboot社区疫情防控系统毕业设计,社区疫情防控管理系统设计与实现,毕设作品参考

功能清单 【后台管理员功能】 关于我们设置&#xff1a;设置学校简介、联系我们、加入我们、法律声明、学校详情 广告管理&#xff1a;设置小程序首页轮播图广告和链接 留言列表&#xff1a;所有用户留言信息列表&#xff0c;支持删除 会员列表&#xff1a;查看所有注册会员信…

【树莓派开发日记2 】树莓派安装Ubuntu22系统及启动黑屏等问题的踩坑记录

树莓派安装Ubuntu22系统及启动黑屏等问题的踩坑记录 在成功进行了组装后&#xff0c;就到了最为关键的部分了&#xff0c;进行树莓派的系统烧录。虽然树莓派有自己对应的系统&#xff0c;raspbian&#xff0c;但是绝大部分的开发者还是会选择Ubuntu系统作为主要的开发系统 Ub…

软件架构模式

如果有兴趣了解更多相关内容&#xff0c;欢迎来我的个人网站看看&#xff1a;瞳孔空间 创建软件系统基本结构的原则称为软件体系结构。软件结构由软件元素及其相互关系组成&#xff0c;这些元素起着蓝图的作用&#xff0c;规划了要执行的任务的模式。软件设计团队极大地依赖于…

【java】2-串行与并发分别将计数器从1累加到10亿

串行、并行、并发 串行是100个人的队伍从一条通道里顺序通行 并行是100个人从n(n>1)条通道分别通行 并发是只有一条通道&#xff0c;100个人排成n个队伍&#xff0c;每队依次派一个人从通道通行&#xff1b;或是有m条通道&#xff0c;100个人排成n个队伍&#xff0c;各个队…

[附源码]计算机毕业设计SpringBoot心理健康系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Spark3 AQE (Adaptive Query Execution) 一文搞懂 新特性

Spark 3 AQE (Adaptive Query Execution) 序 在搭建平台的过程中&#xff0c;我们使用 CDH 6.3.2 进行搭建&#xff0c;但 CDH 中阉割掉了 spark-sql 功能&#xff0c;所以我们外挂了 Spark 3&#xff0c;补充 spark-sql 功能&#xff0c;版本为 3.3。在使用的过程中&#xff…

【抓包工具】win 10 / win 11:WireShark 下载、安装、使用

目录 一、WireShark 下载 二、WireShark 安装 &#xff08;1&#xff09;双击运行安装程序 &#xff08;2&#xff09;Choose Components&#xff1a;选择组件 &#xff08;3&#xff09;Additional Tasks&#xff1a;附加任务 &#xff08;4&#xff09;Choose lnstall …

精品基于Java的社区团购系统SSM

《基于Java的社区团购系统》该项目含有源码、论文等资料、配套开发软件、软件安装教程、项目发布教程等 使用技术&#xff1a; 开发语言&#xff1a;Java 框架&#xff1a;ssm 技术&#xff1a;JSP JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xf…

【JUC】并发编程学习笔记(二)

JUC并发编程五、多线程锁5.1、synchronized实现同步的基础5.2、公平锁与非公平锁5.3、可重入锁5.4、死锁5.4.1、概念5.4.2、案例5.4.3、查看死锁六、Callable接口6.1、概述6.2、FutureTask概述和原理6.3、案例七、辅助类7.1、减少计数CountDownLatch7.2、循环棚栏CyclicBarrier…

[HITCON CTF 2022] Superprime,rev Meow_way,BabySSS格基约减法,Secret共模攻击模未知

目录 Superprime Reverse Meow_way BabySSS Secret Superprime 这个题5层RSA加密&#xff0c;很简单就是要带条件爆破5组p,q&#xff0c;一开始看错了&#xff0c;对为5组是一一对应的&#xff0c;回头发现后边两对不是对应的。 from Crypto.Util.number import getPrime,…

[附源码]Python计算机毕业设计Django旅游度假村管理系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

计算程序运行时间:计算或者不计算sleep()的两种情况perf_counter()和process_time()

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 计算程序运行时间&#xff1a; 计算或者不计算sleep()的两种情况 perf_counter()和process_time() [太阳]选择题 对下面描述错误的选项为&#xff1f; import time print(使用perf_counter…

[附源码]计算机毕业设计作业管理系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

【Matplotlib绘制图像大全】(二十四):Matplotlib为图像添加网格信息

前言 大家好,我是阿光。 本专栏整理了《Matplotlib绘制图像大全》,内包含了各种常见的绘图方法,以及Matplotlib各种内置函数的使用方法,帮助我们快速便捷的绘制出数据图像。 正在更新中~ ✨ 🚨 我的项目环境: 平台:Windows10语言环境:python3.7编译器:PyCharmMatp…

Mybatis练习(多条件查询)

Mybatis练习(多条件查询) 概述 功能实现的步骤&#xff1a; 编写接口方法 参数&#xff1a;所有查询条件结果&#xff1a;List 在映射配置文件中编写SQL语句 编写测试方法并执行 编写接口方法 在 BrandMapper 接口中定义多条件查询的方法。 而该功能有三个参数&#xf…

排序算法两万字总结(C语言实现)

文章目录前言一、排序的概念二、常见的排序算法排序实现的接口(1)插入排序基本思想1.直接插入排序1.1代码实现1.2直接插入排序特性总结2.希尔排序(缩小增量排序)2.1代码实现2.2希尔排序的特性总结(2)选择排序基本思想1.直接选择排序1.1代码实现1.2直接选择排序的特性总结2.堆排…