docker-compose + spring boot + mysql + redis + nginx 发布web应用: part 1

Posted bear129

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了docker-compose + spring boot + mysql + redis + nginx 发布web应用: part 1相关的知识,希望对你有一定的参考价值。

-----**  原创 **------

docker的使用现在越来越多,但多个容器的话,还要一个个的安装,比较麻烦。相比于k8s的“厚重”,docker-compose相对要简单得多。这里是一篇使用docker-compose,对spring boot应用进行一个集群(2个docker)发布的过程。

1. 前言
 
  架构:spring boot使用nginx作为反向代理,redis作为缓存,mysql作为数据库,全部docker化。
  环境:开发使用win 10笔记本, eclipse ide, maven. 这个是大家平时使用的。当然也有用idea的。
        发布环境:百度云的一个ecs, 1核2G. centos 7.x

  本篇是第一部分,主要是spring boot应用。 第二部分看这里

2. spring boot的小应用
 
  一般情况下, spring boot应用都会用到redis, mysql。
  本例中redis是作为一个api调用的计数器,mysql有一个表,存储docker-compose命令及其描述(部分,为boot应用提供数据是主要功能)

  好了,先来个项目结构图

 技术图片

   然后直接上各种代码:没有行号,方便复制粘贴,  : )

  1) pom.xml

<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>
    <groupId>ex.dockercompose</groupId>
    <artifactId>compose-demo</artifactId>
    <version>1.0</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.1.RELEASE</version>
    </parent>
    
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>
    
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        
         <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <fork>true</fork>
                    <mainClass>ex.dockercompose.DemoApplication</mainClass>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

        </plugins>
    </build>
    
</project>

 

  2) DemoApplication.java

@SpringBootApplication
public class DemoApplication {
    
    public static void main(String... args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

 

  3) RedisConfig.java

@Configuration
public class RedisConfig {

    @Autowired
    private RedisConnectionFactory connectionFactory;

    @Bean
    public RedisTemplate<String, Integer> redisTemplate() {
        RedisTemplate<String, Integer> redisTemplate = new RedisTemplate<>();
        RedisSerializer<String> stringSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(stringSerializer);
        redisTemplate.setConnectionFactory(connectionFactory);
        
        return redisTemplate;
    }
}

 

  4) CommandController.java

@RestController
public class CommandController {

    @Autowired
    private CommandService commandService;
    
    @GetMapping("/commands")
    @ResponseBody
    public List<Command> getCommands() {
        
        return commandService.getCommands();
    }
}

 

  5) RedisController.java

@RestController
public class RedisController {
    
    @Autowired
    private RedisTemplate<String, Integer> redisTemplate;

    @GetMapping("/redis")
    @ResponseBody
    public String getValue(HttpServletRequest request) {
        String localAddress = request.getLocalAddr();
        
        Integer counter = redisTemplate.opsForValue().get("counter");
        if(counter == null) {
            counter = 0;
        }
        
        counter++;
        redisTemplate.opsForValue().set("counter", counter);
        
        return localAddress + " => " + counter;
    }
}

 

  6) CommandDao.java

@Mapper
public interface CommandDao {

    @Select("select id, command, description from command order by id")
    List<Command> getCommands();
}

  7) Command.java

public class Command {
    private int id;
    private String command;
    private String description;
    
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return command;
    }
    public void setName(String name) {
        this.command = name;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
}

 

  8) CommandService.java

@Service
public class CommandService {

    @Autowired
    private CommandDao commandDao;
    
    public List<Command> getCommands() {
        return commandDao.getCommands(); 
    }
}

 

  9) application-compose.yml    (mysql是指docker-compose.yml里的mysql服务名)

server.port: 10101

spring:
  datasource:
    url: jdbc:mysql://mysql:3306/compose?serverTimezone=GMT%2B8
    username: boot
    password: boot123
    
  redis:
    host: redis
    port: 6379
    password: redis123
    

 

  10) application-dev.yml  (本地开发时用)

server.port: 10101

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/compose?serverTimezone=GMT%2B8
    username: root
    password: 

  redis:
    host: 127.0.0.1
    port: 6379
    password: redis123

 

  11) application.yml  (开发时用)

 spring.profiles.active: dev 

 

  12) build.bat  这个文件稍加说明一下:使用这个脚本,是为了方便。只要鼠标双击这个文件即可在同一文件夹里生成 jar文件。

                       如果不用这个脚本,要在pom.xml所在目录, cmd里运行 mvn package, 生成的jar会在 target 文件夹里,喜欢用哪个自己选。

del targetcompose-demo-1.0.jar
call mvn package
copy targetcompose-demo-1.0.jar .
pause

 

  13) compose.sql   初始化数据库用,这个在第二部分讲

-- ----------------------------
-- Create database
-- ----------------------------
DROP DATABASE IF EXISTS compose;
CREATE DATABASE compose DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;

use compose;

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for command
-- ----------------------------
DROP TABLE IF EXISTS `command`;
CREATE TABLE `command` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `command` varchar(30) DEFAULT NULL,
  `description` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of command
-- ----------------------------
INSERT INTO `command` VALUES (‘1‘, ‘build‘, ‘Build or rebuild services‘);
INSERT INTO `command` VALUES (‘2‘, ‘bundle‘, ‘Generate a Docker bundle from the Compose file‘);
INSERT INTO `command` VALUES (‘3‘, ‘config‘, ‘Validate and view the Compose file‘);
INSERT INTO `command` VALUES (‘4‘, ‘create‘, ‘Create services‘);
INSERT INTO `command` VALUES (‘5‘, ‘down‘, ‘Stop and remove containers,  networks, images, and volumns‘);
INSERT INTO `command` VALUES (‘6‘, ‘events‘, ‘Receivve real time events from containers‘);
INSERT INTO `command` VALUES (‘7‘, ‘exec‘, ‘Excecute a command in a running container‘);
INSERT INTO `command` VALUES (‘8‘, ‘help‘, ‘Get help on a command‘);

 

  14) docker-compose.yml   第三部分讲

version: ‘3‘
 
services:
  nginx: 
    image: nginx:1.15
    volumes:
      - ./:/etc/nginx/conf.d
    ports:
      - 80:80
      - 443:443
    links:
      - spring-boot-1
      - spring-boot-2
    depends_on:
      - spring-boot-1
      - spring-boot-2
      
  mysql:
    image: mysql:5.7
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_HOST: ‘%‘
      MYSQL_ROOT_PASSWORD: root123
      MYSQL_DATABASE: compose
      MYSQL_USER: boot
      MYSQL_PASSWORD: boot123
   
  redis:
    image: redis
    container_name: my_redis
    command: redis-server --requirepass redis123
    ports:
      - "6379:6379"
       
  spring-boot-1:
    image: compose-demo:1.0
    # build: .
    # ports:
    #   - "10101:10101"
    expose:
      - "10101"
    restart: always

    depends_on:
      - mysql
      - redis

  spring-boot-2:
    image: compose-demo:1.0
    # build: .
    expose:
      - "10101"
    restart: always

    depends_on:
      - mysql
      - redis
       
    
volumes:
  db_data:

 

  15) Dockerfile

FROM java:8
COPY compose-demo-1.0.jar compose-demo-1.0.jar
ENV JAVA_OPTS=""
ENTRYPOINT exec java $JAVA_OPTS -Dspring.profiles.active=compose -jar compose-demo-1.0.jar 

 

  16) nginx.conf

upstream boots {
    server spring-boot-1:10101;
    server spring-boot-2:10101;
}

server {
    listen 80;
    charset utf-8;
    access_log off;

    location / {
        proxy_pass http://boots;
        proxy_set_header Host $host:$server_port;
        proxy_set_header X-Forwarded-Host $server_name;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

 

3. 测试

  先用compose.sql 生成相应的数据库。 然后本地运行一下。

 

4. 打包

    为了

 

好了,本篇基本上是boot应用相关。 docker相关的部分在第二部分中讲解。

   

以上是关于docker-compose + spring boot + mysql + redis + nginx 发布web应用: part 1的主要内容,如果未能解决你的问题,请参考以下文章

docker-compose - 外部化 spring application.properties

spring cloud 与 docker-compose构建微服务

如何为 MongoDB 和 Spring Boot 定义主机名到 docker-compose.yml

使用docker-compose时无法访问docker容器内的spring-boot rest-endpoint

使用 docker-compose 无法在同一网络中连接 mysql 和 spring boot

docker-compose 发布 spring cloud