• Docker容器:compose容器编排


    目录

    是什么

    能干什么

    安装

    一、官网

    二、下载

    三、安装步骤

    四、卸载

    Compose核心概念

    一、一个文件

    二、两个要素

    1.服务(service)

    2.工程(project)

    Compose的操作步骤

    Compose常用命令

    Compose编排Java微服务

    一、sql

    二、POM

    三、YML

    四、主启动类

    五、config配置类

    1.RedisConfig

    2.SwaggerConfig

    六、entities类

    1.User

    2.UserDTO

    七、mapper类

    1.UserMapper

    2.UserMapper.xml

    八、service类

    九、controller类

    十、打成jar包并上传

    十一、编写Dockerfile

    十二、构建镜像

    不使用Compose

    一、mysql容器实例

    二、redis容器实例

    三、微服务

    swagger测试

    一、验证写操作

    二、验证读操作

    存在的问题

    使用Compose

    一、编写docker-compose.yml文件

    二、修改微服务项目

    1.修改yml

    三、再次进行swagger测试

    四、关停


    是什么

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

    这玩意儿可是个项目哇!


    能干什么

    还记得咱们Java里面怎么新建对象吗,直接new一个出来。

    //没有对象怎么办 new一个出来

    在spring里面,咱们是通过xml来对多个对象进行统一的管理:在容器applicationContext.xml中对bean对象进行统一集中的管理。

    <bean id="" class="">

    而在Docker中,容器之间的启动可能会存在一定的先后顺序,加载条件等因素。所以咱们使用docker compose来对容器实例进行统一的管理,这里要使用到yml文件:docker-compose.yml这样可以做到对大量的容器实例进行统一的一键start,一键stop等大量操作。

    docker建议我们每一个容器中只运行一个服务,因为docker容器本身占用资源极少,所以最好是将每个服务单独的分割开来但是这样我们又面临了一个问题?如果我需要同时部署好多个服务,难道要每个服务单独写Dockerfile然后在构建镜像,构建容器,这样累都累死了,所以docker官方给我们提供了docker-compose多服务部署的工具例如要实现一个Web微服务项目,除了Web服务容器本身,往往还需要再加上后端的数据库mysql服务容器,redis服务器,注册中心eureka,甚至还包括负载均衡容器等等。Compose允许用户通过一个单独的docker-compose.yml模板文件(yml格式)来定义一组相关联的应用容器为一个项目(project)。可以很容易地用一个配置文件定义一个多容器的应用,然后使用一条指令安装这个应用的所有依赖,完成构建。Docker-Compose 解决了容器与容器之间如何管理编排的问题。


    安装

    一、官网

    官网地址:Compose file version 3 reference | Docker Documentation

    eb07e2c53cba4cac8aa4bbc68f535742.png

    可以看到左侧有2和3两个版本,官方给的建议是用v3。官网的内容其实非常多,跟着官网学其实也不错。


    二、下载

    下载地址:Install Docker Compose | Docker Documentation

    24ea151d75584bed9162e00dd2c00d4d.png

    官网的更新速度可能较快,直接跟着以下的步骤来


    三、安装步骤

    直接依次执行

    curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

    2bca21ac8cc64c11a2449f9e078340fa.png

    chmod +x /usr/local/bin/docker-compose

    95954e8f95994fb5b1a7d67b742b0207.png

    docker-compose --version

    3eb28f42a7c642ba8ea07690ce899dd6.png

    检查到版本号后代表安装成功


    四、卸载

    这里就不做截图演示了,卸载时直接执行以下命令即可:

    sudo rm /usr/local/bin/docker-compose 
    

    Compose核心概念

    一、一个文件

     docker-compose.yml 


    二、两个要素

    1.服务(service)

    一个个容器实例,比如微服务、mysql、Nginx、redis等

    2.工程(project)

    由一组关联的容器组成的一个完整的业务单元,在 docker-compose.yml 文件中进行定义。


    Compose的操作步骤

    使用的三个步骤如下:

    编写Dockerfile定义各个微服务应用并构建出对应的镜像文件

    使用 docker-compose.yml 定义一个完整的业务单元,安排好整体应用中的各个容器服务

    最后,执行 docker-compose up 命令来启动并运行整个应用程序,完整一键部署


    Compose常用命令

    docker-compose -h                           # 查看帮助
    docker-compose up                           # 启动所有docker-compose服务
    docker-compose down                         # 停止并删除容器、网络、卷、镜像
    docker-compose logs  yml里面的服务id          # 查看容器输出日志
    docker-compose config                       # 检查配置
    docker-compose config -q                    # 检查配置,有问题才有输出
    docker-compose restart                      # 重启服务
    docker-compose start                        # 启动服务
    docker-compose stop                         # 停止服务
    
    1. docker-compose exec yml里面的服务id # 进入容器实例内部
    2. docker-compose exec docker-compose.yml文件中写的服务id /bin/bash
    docker-compose ps                           # 展示当前docker-compose编排过的运行的所有容器
    docker-compose top                          # 展示当前docker-compose编排过的容器进程
    docker-compose up -d                        # 启动所有docker-compose服务并后台运行

    Compose编排Java微服务

    之前博客里写得发布微服务到容器其实里面也就只输出了一个UUID。这回咱们把mysql那些东西都加上,然后再使用docker compose进行编排管控。类如下:

    36a48364b2b74d7d8a4901190065dde0.png

    因为本篇文章的重点不在于Java、mysql、redis等方面,直接上代码:

    一、sql

    1. CREATE TABLE `t_user` (
    2. `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
    3. `username` varchar(50) NOT NULL DEFAULT '' COMMENT '用户名',
    4. `password` varchar(50) NOT NULL DEFAULT '' COMMENT '密码',
    5. `sex` tinyint(4) NOT NULL DEFAULT '0' COMMENT '性别 0=女 1=男 ',
    6. `deleted` tinyint(4) unsigned NOT NULL DEFAULT '0' COMMENT '删除标志,默认0不删除,1删除',
    7. `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
    8. `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
    9. PRIMARY KEY (`id`)
    10. ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='用户表'

    二、POM

    1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    3. <modelVersion>4.0.0modelVersion>
    4. <parent>
    5. <groupId>org.springframework.bootgroupId>
    6. <artifactId>spring-boot-starter-parentartifactId>
    7. <version>2.5.6version>
    8. <relativePath/>
    9. parent>
    10. <groupId>com.examplegroupId>
    11. <artifactId>dockerartifactId>
    12. <version>0.0.1-SNAPSHOTversion>
    13. <properties>
    14. <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
    15. <maven.compiler.source>1.8maven.compiler.source>
    16. <maven.compiler.target>1.8maven.compiler.target>
    17. <junit.version>4.12junit.version>
    18. <log4j.version>1.2.17log4j.version>
    19. <lombok.version>1.16.18lombok.version>
    20. <mysql.version>5.1.47mysql.version>
    21. <druid.version>1.1.16druid.version>
    22. <mapper.version>4.1.5mapper.version>
    23. <mybatis.spring.boot.version>1.3.0mybatis.spring.boot.version>
    24. properties>
    25. <dependencies>
    26. <dependency>
    27. <groupId>com.google.guavagroupId>
    28. <artifactId>guavaartifactId>
    29. <version>23.0version>
    30. dependency>
    31. <dependency>
    32. <groupId>org.redissongroupId>
    33. <artifactId>redissonartifactId>
    34. <version>3.13.4version>
    35. dependency>
    36. <dependency>
    37. <groupId>org.springframework.bootgroupId>
    38. <artifactId>spring-boot-starter-webartifactId>
    39. dependency>
    40. <dependency>
    41. <groupId>org.springframework.bootgroupId>
    42. <artifactId>spring-boot-starter-actuatorartifactId>
    43. dependency>
    44. <dependency>
    45. <groupId>io.springfoxgroupId>
    46. <artifactId>springfox-swagger2artifactId>
    47. <version>2.9.2version>
    48. dependency>
    49. <dependency>
    50. <groupId>io.springfoxgroupId>
    51. <artifactId>springfox-swagger-uiartifactId>
    52. <version>2.9.2version>
    53. dependency>
    54. <dependency>
    55. <groupId>org.springframework.bootgroupId>
    56. <artifactId>spring-boot-starter-data-redisartifactId>
    57. dependency>
    58. <dependency>
    59. <groupId>org.springframework.bootgroupId>
    60. <artifactId>spring-boot-starter-cacheartifactId>
    61. dependency>
    62. <dependency>
    63. <groupId>org.apache.commonsgroupId>
    64. <artifactId>commons-pool2artifactId>
    65. dependency>
    66. <dependency>
    67. <groupId>redis.clientsgroupId>
    68. <artifactId>jedisartifactId>
    69. <version>3.1.0version>
    70. dependency>
    71. <dependency>
    72. <groupId>mysqlgroupId>
    73. <artifactId>mysql-connector-javaartifactId>
    74. <version>5.1.47version>
    75. dependency>
    76. <dependency>
    77. <groupId>com.alibabagroupId>
    78. <artifactId>druid-spring-boot-starterartifactId>
    79. <version>1.1.10version>
    80. dependency>
    81. <dependency>
    82. <groupId>com.alibabagroupId>
    83. <artifactId>druidartifactId>
    84. <version>${druid.version}version>
    85. dependency>
    86. <dependency>
    87. <groupId>org.mybatis.spring.bootgroupId>
    88. <artifactId>mybatis-spring-boot-starterartifactId>
    89. <version>${mybatis.spring.boot.version}version>
    90. dependency>
    91. <dependency>
    92. <groupId>org.springframework.bootgroupId>
    93. <artifactId>spring-boot-starter-amqpartifactId>
    94. dependency>
    95. <dependency>
    96. <groupId>commons-codecgroupId>
    97. <artifactId>commons-codecartifactId>
    98. <version>1.10version>
    99. dependency>
    100. <dependency>
    101. <groupId>cn.hutoolgroupId>
    102. <artifactId>hutool-allartifactId>
    103. <version>5.2.3version>
    104. dependency>
    105. <dependency>
    106. <groupId>junitgroupId>
    107. <artifactId>junitartifactId>
    108. <version>${junit.version}version>
    109. dependency>
    110. <dependency>
    111. <groupId>org.springframework.bootgroupId>
    112. <artifactId>spring-boot-devtoolsartifactId>
    113. <scope>runtimescope>
    114. <optional>trueoptional>
    115. dependency>
    116. <dependency>
    117. <groupId>org.springframework.bootgroupId>
    118. <artifactId>spring-boot-starter-testartifactId>
    119. <scope>testscope>
    120. dependency>
    121. <dependency>
    122. <groupId>log4jgroupId>
    123. <artifactId>log4jartifactId>
    124. <version>${log4j.version}version>
    125. dependency>
    126. <dependency>
    127. <groupId>org.projectlombokgroupId>
    128. <artifactId>lombokartifactId>
    129. <version>${lombok.version}version>
    130. <optional>trueoptional>
    131. dependency>
    132. <dependency>
    133. <groupId>javax.persistencegroupId>
    134. <artifactId>persistence-apiartifactId>
    135. <version>1.0.2version>
    136. dependency>
    137. <dependency>
    138. <groupId>tk.mybatisgroupId>
    139. <artifactId>mapperartifactId>
    140. <version>${mapper.version}version>
    141. dependency>
    142. dependencies>
    143. <build>
    144. <plugins>
    145. <plugin>
    146. <groupId>org.springframework.bootgroupId>
    147. <artifactId>spring-boot-maven-pluginartifactId>
    148. plugin>
    149. <plugin>
    150. <groupId>org.apache.maven.pluginsgroupId>
    151. <artifactId>maven-resources-pluginartifactId>
    152. <version>3.1.0version>
    153. plugin>
    154. plugins>
    155. build>
    156. project>

    三、YML

    1. server.port=6001
    2. # ========================alibaba.druid=========================
    3. spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
    4. spring.datasource.driver-class-name=com.mysql.jdbc.Driver
    5. spring.datasource.url=jdbc:mysql://192.168.150.30:3306/dbtest?useUnicode=true&characterEncoding=utf-8&useSSL=false
    6. spring.datasource.username=root
    7. spring.datasource.password=你自己的密码
    8. spring.datasource.druid.test-while-idle=false
    9. # ========================redis=========================
    10. spring.redis.database=0
    11. spring.redis.host=192.168.150.30
    12. spring.redis.port=6379
    13. spring.redis.password=
    14. spring.redis.lettuce.pool.max-active=8
    15. spring.redis.lettuce.pool.max-wait=-1ms
    16. spring.redis.lettuce.pool.max-idle=8
    17. spring.redis.lettuce.pool.min-idle=0
    18. # ========================mybatis=======================
    19. mybatis.mapper-locations=classpath:mapper/*.xml
    20. mybatis.type-aliases-package=docker.entities
    21. # ========================swagger=====================
    22. spring.swagger2.enabled=true

    四、主启动类

    1. package docker.controller;
    2. import cn.hutool.core.util.IdUtil;
    3. import cn.hutool.core.util.ReferenceUtil;
    4. import docker.entities.User;
    5. import docker.entities.UserDTO;
    6. import docker.service.UserService;
    7. import io.swagger.annotations.Api;
    8. import io.swagger.annotations.ApiOperation;
    9. import io.swagger.models.auth.In;
    10. import lombok.extern.slf4j.Slf4j;
    11. import org.springframework.beans.BeanUtils;
    12. import org.springframework.beans.factory.annotation.Autowired;
    13. import org.springframework.web.bind.annotation.*;
    14. import javax.annotation.Resource;
    15. import java.util.Random;
    16. @Api(description = "用户User接口")
    17. @RestController
    18. @Slf4j
    19. public class UserController
    20. {
    21. @Resource
    22. private UserService userService;
    23. @ApiOperation("数据库新增3条记录")
    24. @RequestMapping(value = "/user/add",method = RequestMethod.POST)
    25. public void addUser()
    26. {
    27. for (int i = 1; i <=3; i++) {
    28. User user = new User();
    29. user.setUsername("van"+i);
    30. user.setPassword(IdUtil.simpleUUID().substring(0,6));
    31. user.setSex((byte) new Random().nextInt(2));
    32. userService.addUser(user);
    33. }
    34. }
    35. @ApiOperation("查询1条记录")
    36. @RequestMapping(value = "/user/find/{id}",method = RequestMethod.GET)
    37. public User findUserById(@PathVariable Integer id)
    38. {
    39. return userService.findUserById(id);
    40. }
    41. }

    五、config配置类

    1.RedisConfig

    1. package docker.config;
    2. import lombok.extern.slf4j.Slf4j;
    3. import org.springframework.context.annotation.Bean;
    4. import org.springframework.context.annotation.Configuration;
    5. import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
    6. import org.springframework.data.redis.core.RedisTemplate;
    7. import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
    8. import org.springframework.data.redis.serializer.StringRedisSerializer;
    9. import java.io.Serializable;
    10. @Configuration
    11. @Slf4j
    12. public class RedisConfig {
    13. /**
    14. * @param lettuceConnectionFactory
    15. * @return redis序列化的工具配置类,下面这个请一定开启配置
    16. * 127.0.0.1:6379> keys *
    17. * 1) "ord:102" 序列化过
    18. * 2) "\xac\xed\x00\x05t\x00\aord:102" 野生,没有序列化过
    19. */
    20. @Bean
    21. public RedisTemplate redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
    22. RedisTemplate redisTemplate = new RedisTemplate<>();
    23. redisTemplate.setConnectionFactory(lettuceConnectionFactory);
    24. //设置key序列化方式string
    25. redisTemplate.setKeySerializer(new StringRedisSerializer());
    26. //设置value的序列化方式json
    27. redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
    28. redisTemplate.setHashKeySerializer(new StringRedisSerializer());
    29. redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
    30. redisTemplate.afterPropertiesSet();
    31. return redisTemplate;
    32. }
    33. }

    2.SwaggerConfig

    1. package docker.config;
    2. import org.springframework.beans.factory.annotation.Value;
    3. import org.springframework.context.annotation.Bean;
    4. import org.springframework.context.annotation.Configuration;
    5. import springfox.documentation.builders.ApiInfoBuilder;
    6. import springfox.documentation.builders.PathSelectors;
    7. import springfox.documentation.builders.RequestHandlerSelectors;
    8. import springfox.documentation.service.ApiInfo;
    9. import springfox.documentation.spi.DocumentationType;
    10. import springfox.documentation.spring.web.plugins.Docket;
    11. import springfox.documentation.swagger2.annotations.EnableSwagger2;
    12. import java.text.SimpleDateFormat;
    13. import java.util.Date;
    14. @Configuration
    15. @EnableSwagger2
    16. public class SwaggerConfig {
    17. @Value("${spring.swagger2.enabled}")
    18. private Boolean enabled;
    19. @Bean
    20. public Docket createRestApi() {
    21. return new Docket(DocumentationType.SWAGGER_2)
    22. .apiInfo(apiInfo())
    23. .enable(enabled)
    24. .select()
    25. .apis(RequestHandlerSelectors.basePackage("docker")) //你自己的package
    26. .paths(PathSelectors.any())
    27. .build();
    28. }
    29. public ApiInfo apiInfo() {
    30. return new ApiInfoBuilder()
    31. .title("Java" + "\t" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()))
    32. .description("docker-compose")
    33. .version("1.0")
    34. .termsOfServiceUrl("https://www.baidu.com/")
    35. .build();
    36. }
    37. }

    六、entities类

    1.User

    1. package docker.entities;
    2. import javax.persistence.Column;
    3. import javax.persistence.GeneratedValue;
    4. import javax.persistence.Id;
    5. import javax.persistence.Table;
    6. import java.util.Date;
    7. @Table(name = "t_user")
    8. public class User {
    9. @Id
    10. @GeneratedValue(generator = "JDBC")
    11. private Integer id;
    12. /**
    13. * 用户名
    14. */
    15. private String username;
    16. /**
    17. * 密码
    18. */
    19. private String password;
    20. /**
    21. * 性别 0=女 1=男
    22. */
    23. private Byte sex;
    24. /**
    25. * 删除标志,默认0不删除,1删除
    26. */
    27. private Byte deleted;
    28. /**
    29. * 更新时间
    30. */
    31. @Column(name = "update_time")
    32. private Date updateTime;
    33. /**
    34. * 创建时间
    35. */
    36. @Column(name = "create_time")
    37. private Date createTime;
    38. /**
    39. * @return id
    40. */
    41. public Integer getId() {
    42. return id;
    43. }
    44. /**
    45. * @param id
    46. */
    47. public void setId(Integer id) {
    48. this.id = id;
    49. }
    50. /**
    51. * 获取用户名
    52. *
    53. * @return username - 用户名
    54. */
    55. public String getUsername() {
    56. return username;
    57. }
    58. /**
    59. * 设置用户名
    60. *
    61. * @param username 用户名
    62. */
    63. public void setUsername(String username) {
    64. this.username = username;
    65. }
    66. /**
    67. * 获取密码
    68. *
    69. * @return password - 密码
    70. */
    71. public String getPassword() {
    72. return password;
    73. }
    74. /**
    75. * 设置密码
    76. *
    77. * @param password 密码
    78. */
    79. public void setPassword(String password) {
    80. this.password = password;
    81. }
    82. /**
    83. * 获取性别 0=女 1=男
    84. *
    85. * @return sex - 性别 0=女 1=男
    86. */
    87. public Byte getSex() {
    88. return sex;
    89. }
    90. /**
    91. * 设置性别 0=女 1=男
    92. *
    93. * @param sex 性别 0=女 1=男
    94. */
    95. public void setSex(Byte sex) {
    96. this.sex = sex;
    97. }
    98. /**
    99. * 获取删除标志,默认0不删除,1删除
    100. *
    101. * @return deleted - 删除标志,默认0不删除,1删除
    102. */
    103. public Byte getDeleted() {
    104. return deleted;
    105. }
    106. /**
    107. * 设置删除标志,默认0不删除,1删除
    108. *
    109. * @param deleted 删除标志,默认0不删除,1删除
    110. */
    111. public void setDeleted(Byte deleted) {
    112. this.deleted = deleted;
    113. }
    114. /**
    115. * 获取更新时间
    116. *
    117. * @return update_time - 更新时间
    118. */
    119. public Date getUpdateTime() {
    120. return updateTime;
    121. }
    122. /**
    123. * 设置更新时间
    124. *
    125. * @param updateTime 更新时间
    126. */
    127. public void setUpdateTime(Date updateTime) {
    128. this.updateTime = updateTime;
    129. }
    130. /**
    131. * 获取创建时间
    132. *
    133. * @return create_time - 创建时间
    134. */
    135. public Date getCreateTime() {
    136. return createTime;
    137. }
    138. /**
    139. * 设置创建时间
    140. *
    141. * @param createTime 创建时间
    142. */
    143. public void setCreateTime(Date createTime) {
    144. this.createTime = createTime;
    145. }
    146. }

    2.UserDTO

    1. package docker.entities;
    2. import io.swagger.annotations.ApiModel;
    3. import io.swagger.annotations.ApiModelProperty;
    4. import lombok.AllArgsConstructor;
    5. import lombok.Data;
    6. import lombok.NoArgsConstructor;
    7. import java.io.Serializable;
    8. import java.util.Date;
    9. @NoArgsConstructor
    10. @AllArgsConstructor
    11. @Data
    12. @ApiModel(value = "用户信息")
    13. public class UserDTO implements Serializable {
    14. @ApiModelProperty(value = "用户ID")
    15. private Integer id;
    16. @ApiModelProperty(value = "用户名")
    17. private String username;
    18. @ApiModelProperty(value = "密码")
    19. private String password;
    20. @ApiModelProperty(value = "性别 0=女 1=男 ")
    21. private Byte sex;
    22. @ApiModelProperty(value = "删除标志,默认0不删除,1删除")
    23. private Byte deleted;
    24. @ApiModelProperty(value = "更新时间")
    25. private Date updateTime;
    26. @ApiModelProperty(value = "创建时间")
    27. private Date createTime;
    28. /**
    29. * @return id
    30. */
    31. public Integer getId() {
    32. return id;
    33. }
    34. /**
    35. * @param id
    36. */
    37. public void setId(Integer id) {
    38. this.id = id;
    39. }
    40. /**
    41. * 获取用户名
    42. *
    43. * @return username - 用户名
    44. */
    45. public String getUsername() {
    46. return username;
    47. }
    48. /**
    49. * 设置用户名
    50. *
    51. * @param username 用户名
    52. */
    53. public void setUsername(String username) {
    54. this.username = username;
    55. }
    56. /**
    57. * 获取密码
    58. *
    59. * @return password - 密码
    60. */
    61. public String getPassword() {
    62. return password;
    63. }
    64. /**
    65. * 设置密码
    66. *
    67. * @param password 密码
    68. */
    69. public void setPassword(String password) {
    70. this.password = password;
    71. }
    72. /**
    73. * 获取性别 0=女 1=男
    74. *
    75. * @return sex - 性别 0=女 1=男
    76. */
    77. public Byte getSex() {
    78. return sex;
    79. }
    80. /**
    81. * 设置性别 0=女 1=男
    82. *
    83. * @param sex 性别 0=女 1=男
    84. */
    85. public void setSex(Byte sex) {
    86. this.sex = sex;
    87. }
    88. /**
    89. * 获取删除标志,默认0不删除,1删除
    90. *
    91. * @return deleted - 删除标志,默认0不删除,1删除
    92. */
    93. public Byte getDeleted() {
    94. return deleted;
    95. }
    96. /**
    97. * 设置删除标志,默认0不删除,1删除
    98. *
    99. * @param deleted 删除标志,默认0不删除,1删除
    100. */
    101. public void setDeleted(Byte deleted) {
    102. this.deleted = deleted;
    103. }
    104. /**
    105. * 获取更新时间
    106. *
    107. * @return update_time - 更新时间
    108. */
    109. public Date getUpdateTime() {
    110. return updateTime;
    111. }
    112. /**
    113. * 设置更新时间
    114. *
    115. * @param updateTime 更新时间
    116. */
    117. public void setUpdateTime(Date updateTime) {
    118. this.updateTime = updateTime;
    119. }
    120. /**
    121. * 获取创建时间
    122. *
    123. * @return create_time - 创建时间
    124. */
    125. public Date getCreateTime() {
    126. return createTime;
    127. }
    128. /**
    129. * 设置创建时间
    130. *
    131. * @param createTime 创建时间
    132. */
    133. public void setCreateTime(Date createTime) {
    134. this.createTime = createTime;
    135. }
    136. @Override
    137. public String toString() {
    138. return "User{" +
    139. "id=" + id +
    140. ", username='" + username + '\'' +
    141. ", password='" + password + '\'' +
    142. ", sex=" + sex +
    143. '}';
    144. }
    145. }

    七、mapper类

    1.UserMapper

    1. package docker.mapper;
    2. import docker.entities.User;
    3. import tk.mybatis.mapper.common.Mapper;
    4. public interface UserMapper extends Mapper {
    5. }

    2.UserMapper.xml

    在此处创建UserMapper.xml

    9ba908d6b9c84f21afd9bd011962c04e.png

    1. mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    2. <mapper namespace="docker.mapper.UserMapper">
    3. <resultMap id="BaseResultMap" type="docker.entities.User">
    4. <id column="id" jdbcType="INTEGER" property="id" />
    5. <result column="username" jdbcType="VARCHAR" property="username" />
    6. <result column="password" jdbcType="VARCHAR" property="password" />
    7. <result column="sex" jdbcType="TINYINT" property="sex" />
    8. <result column="deleted" jdbcType="TINYINT" property="deleted" />
    9. <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
    10. <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
    11. resultMap>
    12. mapper>

    八、service类

    1. package docker.service;
    2. import docker.entities.User;
    3. import docker.mapper.UserMapper;
    4. import lombok.extern.slf4j.Slf4j;
    5. import org.slf4j.Logger;
    6. import org.slf4j.LoggerFactory;
    7. import org.springframework.beans.factory.annotation.Autowired;
    8. import org.springframework.data.redis.core.RedisTemplate;
    9. import org.springframework.data.redis.core.ValueOperations;
    10. import org.springframework.stereotype.Service;
    11. import org.springframework.web.bind.annotation.PathVariable;
    12. import javax.annotation.Resource;
    13. import java.util.concurrent.TimeUnit;
    14. @Service
    15. @Slf4j
    16. public class UserService {
    17. public static final String CACHE_KEY_USER = "user:";
    18. @Resource
    19. private UserMapper userMapper;
    20. @Resource
    21. private RedisTemplate redisTemplate;
    22. /**
    23. * addUser
    24. *
    25. * @param user
    26. */
    27. public void addUser(User user) {
    28. //1 先插入mysql并成功
    29. int i = userMapper.insertSelective(user);
    30. if (i > 0) {
    31. //2 需要再次查询一下mysql将数据捞回来并ok
    32. user = userMapper.selectByPrimaryKey(user.getId());
    33. //3 将捞出来的user存进redis,完成新增功能的数据一致性。
    34. String key = CACHE_KEY_USER + user.getId();
    35. redisTemplate.opsForValue().set(key, user);
    36. }
    37. }
    38. /**
    39. * findUserById
    40. *
    41. * @param id
    42. * @return
    43. */
    44. public User findUserById(Integer id) {
    45. User user = null;
    46. String key = CACHE_KEY_USER + id;
    47. //1 先从redis里面查询,如果有直接返回结果,如果没有再去查询mysql
    48. user = (User) redisTemplate.opsForValue().get(key);
    49. if (user == null) {
    50. //2 redis里面无,继续查询mysql
    51. user = userMapper.selectByPrimaryKey(id);
    52. if (user == null) {
    53. //3.1 redis+mysql 都无数据
    54. //你具体细化,防止多次穿透,我们规定,记录下导致穿透的这个key回写redis
    55. return user;
    56. } else {
    57. //3.2 mysql有,需要将数据写回redis,保证下一次的缓存命中率
    58. redisTemplate.opsForValue().set(key, user);
    59. }
    60. }
    61. return user;
    62. }
    63. }

    九、controller类

    1. package docker;
    2. import org.springframework.boot.SpringApplication;
    3. import org.springframework.boot.autoconfigure.SpringBootApplication;
    4. import tk.mybatis.spring.annotation.MapperScan;
    5. @SpringBootApplication
    6. @MapperScan("docker.mapper") //import tk.mybatis.spring.annotation.MapperScan;
    7. public class DockerBootApplication
    8. {
    9. public static void main(String[] args)
    10. {
    11. SpringApplication.run(DockerBootApplication.class, args);
    12. }
    13. }

    十、打成jar包并上传

    fde851c088d744c795490044eeaf1ed1.png

    直接双机,在打包完成后上传至Linux,记得单独开一个目录来进行存放。 

    f93e1102d91e40b59d4e86983d2cbefd.png


    十一、编写Dockerfile

    在刚刚用来存放jar包的目录下新建Dockerfile文件,注意文件名大小写。

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

    427bf4fec60a4717aeab328673b1a3f4.png


    十二、构建镜像

    注意最后的空格和点

    docker build -t van_docker:1.6 .

    430d2ee486a24daca77b94e6643e548f.png

    构建成功。


    不使用Compose

    有compose不用就有点类似于有idea不用,偏偏要用记事本写代码

    一、mysql容器实例

    docker run -p 3306:3306 --name mysql57 --privileged=true -v /jardata/mysql/conf:/etc/mysql/conf.d -v /jardata/mysql/logs:/logs -v /jardata/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=你的密码 -d mysql:5.7

    老规矩,别忘了ps看一眼 

    0f8e8f13fe674caa9cc6cb023ba8f458.png

    然后咱们进入容器看看:

    1. docker exec -it mysql57 bash
    2. mysql -uroot -p

    8e15af97a7a54b67a48955be8a97800a.png

    然后我们需要开始建库建表,把之前的东西给扔进去:

    1. create database dbtest;
    2. use dbtest;

    接着将之前的那一大段sql复制进去:

    27607a01e2dc4975be83440544207ca1.png

    表结构创建成功 


    二、redis容器实例

    docker run  -p 6379:6379 --name redis608 --privileged=true -v /app/redis/redis.conf:/etc/redis/redis.conf -v /app/redis/data:/data -d redis:6.0.8 redis-server /etc/redis/redis.conf

     ps看一眼:

    9e6e66f25b2941a7abc248158b848cdc.png

    进入容器:

    docker exec -it redis608 bash

    3076c48e7bca4a7099979415de72b12d.png

    这时候的mysql和redis都还是空的,而且都已经创建成功


    三、微服务

    注意自己的实际ID

    docker run -d -p 6001:6001 965861d1a066

    7402b5836a48428893edb8738986246b.png

    到了这里才算是把这三个玩意儿都起起来,但是这只是三个而已。实际的生产环境里有很大的概率会是几十个,要是这样一个一个起真的有点折寿


    swagger测试

    一、验证写操作

    这里要注意自己的真实IP:

    http://192.168.150.30:6001/swagger-ui.html#/user-controller

    13347185a0c645cc8d2450b75a0320a1.png

    点击右侧的Try it now ,然后点击弹出来的Execute

    a6e41b512c084364bf912280174e8bb9.png

    6dc4391537e145d1a6bd559c179d9d6e.png

     这里是发送了一个post请求

    95efef851f924e4b8e419be4f808490d.png

    然后咱们返回到mysql查询一下看看:

    52a22025a7fa4a9a8fd4417da0d8916b.png

    接着去redis看看:

    dfdca8c1a07e41ec895d1dbe0fa295f9.png

    这里的写操作已经验证成功。 


    二、验证读操作

    点击get里面的Try it now

    7454580b57294ab1a05a1b97567211f0.png

    我们这里查找一下1号记录,然后点击Execute 

    91277f21046847f3914d40f817fa32a8.png

    往下看结果

    f6d2c6467ede432d8bcd7ec297b254c0.png

    全部查询成功,到这里读操作也完成了。 


    存在的问题

    咱们这里没有使用compose也成功达到了目的,但是存在着以下问题:

    先后顺序要求固定,先mysql+redis才能启动微服务

    过多的run 

    容器间的启停或宕机,有可能导致IP地址对应容器实例变化,映射出错,这时候就只能写死IP,要么通过服务调用 


    使用Compose

    本篇的重点到这里才刚刚开始

    一、编写docker-compose.yml文件

    在之前上传jar包的目录下创建yml文件

    vim docker-compose.yml
    

    ceac02f8d5254f659d50a7534f3bb9c6.png

    将以下内容复制进去: 

    1. version: "3"
    2. services:
    3. #微服务
    4. microService:
    5. image: van_docker:2.0
    6. #镜像
    7. container_name: ms01
    8. #容器名称
    9. ports:
    10. #端口映射
    11. - "6001:6001"
    12. volumes:
    13. #容器数据卷
    14. - /app/microService:/data
    15. networks:
    16. #网络模式
    17. - van_net
    18. depends_on:
    19. #依赖关系
    20. - redis
    21. - mysql
    22. redis:
    23. #redis
    24. image: redis:6.0.8
    25. #镜像
    26. ports:
    27. #端口映射
    28. - "6379:6379"
    29. volumes:
    30. #容器数据卷
    31. - /app/redis/redis.conf:/etc/redis/redis.conf
    32. - /app/redis/data:/data
    33. networks:
    34. #网络模式
    35. - van_net
    36. command: redis-server /etc/redis/redis.conf
    37. mysql:
    38. #mysql
    39. image: mysql:5.7
    40. #镜像
    41. environment:
    42. #环境
    43. MYSQL_ROOT_PASSWORD: 'zxcvbn0131'
    44. MYSQL_ALLOW_EMPTY_PASSWORD: 'no'
    45. MYSQL_DATABASE: 'dbtest'
    46. MYSQL_USER: 'van'
    47. MYSQL_PASSWORD: 'zxcvbn0131'
    48. ports:
    49. #端口映射
    50. - "3306:3306"
    51. volumes:
    52. #容器数据卷
    53. - /app/mysql/db:/var/lib/mysql
    54. - /app/mysql/conf/my.cnf:/etc/my.cnf
    55. - /app/mysql/init:/docker-entrypoint-initdb.d
    56. networks:
    57. #网络模式
    58. - van_net
    59. command: --default-authentication-plugin=mysql_native_password #解决外部无法访问
    60. networks:
    61. #网络模式
    62. van_net:

    二、修改微服务项目

    1.修改yml

    复制以下内容,并覆盖粘贴(这里只是把原先的IP地址改成了服务名):

    1. server.port=6001
    2. # ========================alibaba.druid相关配置=====================
    3. spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
    4. spring.datasource.driver-class-name=com.mysql.jdbc.Driver
    5. spring.datasource.url=jdbc:mysql://mysql:3306/dbtest?useUnicode=true&characterEncoding=utf-8&useSSL=false
    6. spring.datasource.username=root
    7. spring.datasource.password=自己的密码
    8. spring.datasource.druid.test-while-idle=false
    9. # ========================redis相关配置=====================
    10. spring.redis.database=0
    11. spring.redis.host=redis
    12. spring.redis.port=6379
    13. spring.redis.password=
    14. spring.redis.lettuce.pool.max-active=8
    15. spring.redis.lettuce.pool.max-wait=-1ms
    16. spring.redis.lettuce.pool.max-idle=8
    17. spring.redis.lettuce.pool.min-idle=0
    18. # ========================mybatis相关配置===================
    19. mybatis.mapper-locations=classpath:mapper/*.xml
    20. mybatis.type-aliases-package=docker.entities
    21. # ========================swagger=====================
    22. spring.swagger2.enabled=true

    接着就跟之前一样,打包jar包,然后上传,替换掉原先的jar包。

    Dockerfile这里就不用进行修改了,然后重建一个镜像出来:

    docker build -t van_docker:2.0 .

    37ab4caaf8fd4eab84cf0b93fead5943.png

    然后把之前的三个容器直接停掉:

    docker rm -f 1e071bfa04a3 c4855d7f87fd 426eac422e84
    

    af08c4eaec2c4841b45f3de2dcc7a2ff.png

     把之前构建的的1.6版本也给删了:

    docker rmi -f 965861d1a066
    

    fad60ac5f50a4888aa8ada464d83d5bf.png

    接着要开始使用之前提到的常用命令了(建议在yml文件的目录下执行):

    运行一个看看有没有问题:

    docker-compose config -q

    82c092717de24e808dc886a59acc51d5.png

     只要没有其它的任何提示,就代表操作没有问题。接下来开始正式启动:

    docker-compose up -d
    

     效果如下:

    40c7c4bf07124a44947e787fa820e43f.png

    我们可以顺便去看一眼docker的网络:

    ec5e5d19dfc140ed8c78d23c54773806.png

    可以看到它在我们刚刚创建的(写在了docker-compose.yml里面)van_net网络模式前面加上了前缀。ps看一眼:

    350e5c4c0d4a4451af8267c8ee7eba65.png

    进入mysql容器看一眼:

    docker exec -it 0fd561357e08 bash

    737d619c6cba41c79b89912666ee8ba7.png

    重建一次该表,再进去redis看一眼:

    1. docker exec -it 04a23c342f44 bash
    2. redis-cli
    3. keys *

    1b82919f16714a88b810693a42100c56.png

    可以看到现在咱们的mysql和redis都是空的,开始重新进行测试。


    三、再次进行swagger测试

    这里需要注意自己的真实IP,再次访问进行测试:

    http://192.168.150.30:6001/swagger-ui.html#/user-controller

    写入数据

    ea6db65731b049209966281d38cc5ca9.png

    0fb76fc18ee64fd1a3efe768bcd99379.png

    成功拿到数据,数据写入成功。

    88ca36d5335b43d89bc95537da68a9a1.png

    成功读取。 


    四、关停

    docker-compose stop
    

    0645ebd9302844ecac760fc4aacc72db.png


    案例演示结束。

  • 相关阅读:
    PLSQL远程连接数据库
    基于蒙特卡洛的大规模电动汽车充电行为分析(Matlab代码实现)
    基于SpringBoot的篮球论坛系统
    DHorse v1.4.2 发布,基于 k8s 的发布平台
    数据结构:线性表
    动态库和静态库
    CSP-J-2016-海港
    python使用memory_profiler分析代码运行内存占用
    【软考-软件设计师精华知识点笔记】第十一章 法律法规与标准化
    招聘| 嵌入式軟件(单片机)工程师
  • 原文地址:https://blog.csdn.net/Trollz/article/details/126223361