使用docker-compose同时启动MySQL与连接MySQL的java程序

说明

docker-compose 是一个用户定义和运行多个容器的 Docker 应用程序。在 docker-compose 中你可以使用 YAML 文件来配置你的应用服务。然后,只需要一个简单的命令,就可以创建并启动你配置的所有服务。

难点

使用docker-compose启动MySQL与java程序后,java程序并不会一直等待MySQL将所需的初始化SQL文件执行完成,所以Java程序在执行过程中就会报错说连不上MySQL,就算你使用docker-compose中的depends_on来使java程序容器依赖于mysql容器也是一样没有用的,docker-compose只会判断容器是否启动成功(你可以当成是MySQL容器刚刚开机成功,还未执行SQL文件就跳到执行Java程序容器了)

快速开始

首先给出项目结构图:

使用docker-compose同时启动MySQL与连接MySQL的java程序_第1张图片

docker-mysql的配置我们沿用上一篇博客的配置详细戳-->Docker-mysql启动时自动执行SQL

为了使java程序能适应变化,我们将MySQL的连接配置写入docker-compose文件中:

docker-compose.yml

version: "2"

services:
  mymysql:
    image: mymysql:test
    container_name: mymysql
    ports:
      - "3306:3306"
    command: [
            '--character-set-server=utf8mb4',
            '--collation-server=utf8mb4_unicode_ci'
    ]
    environment:
      MYSQL_ROOT_PASSWORD: "root"
  javatest:
    image: test1jar:test
    container_name: javatest1
    depends_on:
      - mymysql
    environment:
      IP: "192.168.99.100"
      PORT: "3306"
      DRIVERCLASSNAME: "com.mysql.jdbc.Driver"
      DBNAME: "persontest"
      URL: "jdbc:mysql://192.168.99.100:3306/persontest?useSSL=false"
      USERNAME: "root"
      PASSWORD: "root"

将原来的src目录删除,新建一个model命名为Java1,更新一下pom.xml添加jdbc包,编写一个bean类,编写App.java(这里直接用JDBC操作):

pom.xml




    
        dockermysql
        cn.yunlingfly
        1.0-SNAPSHOT
    
    4.0.0

    Java1

    Java1
    
    http://www.example.com

    
        
            junit
            junit
            4.11
            test
        
    

    
        
            
                org.apache.maven.plugins
                maven-jar-plugin
                
                    target/classes/
                    
                        
                            
                            cn.yunlingfly.App
                            
                            false
                            true
                            lib/
                        
                        
                            .
                        
                    
                
            

            
                org.apache.maven.plugins
                maven-shade-plugin
                2.3
                
                    
                        package
                        
                            shade
                        
                        
                            
                                
                                    cn.yunlingfly.App
                                
                            
                               
                                
                                    *:*
                                    
                                        META-INF/*.SF
                                        META-INF/*.DSA
                                        META-INF/*.RSA
                                    
                                
                            
                        
                    
                
            
        
    

Person.java

package cn.yunlingfly;

public class Person {
    private Integer id;
    private String username;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }
}

App.java

package cn.yunlingfly;

import com.alibaba.fastjson.JSON;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/**
 * Hello world!
 */
public class App extends Thread {
    private final static String DRIVER = System.getenv("DRIVERCLASSNAME");
    private final static String URL = System.getenv("URL");
    private final static String USERNAME = System.getenv("USERNAME");
    private final static String PASSWORD = System.getenv("PASSWORD");

    public static void main(String[] args) {
        Thread app = new App();
        app.run();
    }

    private Connection getConn() {
        Connection conn = null;
        try {
            Class.forName(DRIVER);
            conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return conn;
    }

    @Override
    public void run() {
        System.out.println("[INFO]try connect...");
        int i = createConnection();
        if (i <= 36) {
            System.out.println("Successful connection...");
            selectAll();
        } else {
            System.out.println("Failed to connect");
        }
    }

    // 检查是否成功连接MySQL,尝试1min,不成功则报错
    public int createConnection() {
        boolean flag = true;
        Connection connection = null;

        try {
            Class.forName(DRIVER);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        int i = 0;
        while (flag) {
            if (i > 36) break; // 超过36次循环(3分钟)则退出程序
            System.out.println("try connect");
            try {
                connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);
                flag = false;
            } catch (Exception e) {
                i++;
                flag = true;
                try {
                    sleep(5000);    // 休息5s
                } catch (Exception e1) {
                    e1.printStackTrace();
                }
            }
        }
        return i;
    }

    private void selectAll() {
        Connection conn = getConn();
        String sql = "SELECT id,username FROM userinfo";
        Statement st;
        List list = new ArrayList<>();
        try {
            st=conn.createStatement();
            ResultSet rs = st.executeQuery(sql);
            System.out.println("============================");
            while (rs.next()) {
                Person p = new Person();
                int id = rs.getInt("id");
                String username = rs.getString("username");

                p.setId(id);
                p.setUsername(username);
                list.add(p);
            }
            System.out.println(JSON.toJSONString(list));    //输出成JSON格式
            System.out.println("============================");
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

编写Java程序的Dockerfile:

Dockerfile

# 这个是构建Java环境的dockerfile

FROM registry.saas.hand-china.com/hap-cloud/base:latest

WORKDIR /

# 将系统编码设置为c.utf-8,默认的POSIX不支持中文
ENV LANG C.UTF-8
ENV LANGUAGE C.UTF-8
ENV LC_ALL C.UTF-8

# 将子项目打包的jar包拷贝到项目根目录
COPY target/Java1-1.0-SNAPSHOT.jar /test1.jar

# 设置容器启动时执行的命令,-Dfile.encoding=utf-8
CMD ["java", "-jar", "test1.jar"]

运行结果

1 打开git bash,进入项目根目录,输入

$ ./build.sh
$ ./start.sh

start.sh运行最后可以看到如下结果,说明运行成功:

使用docker-compose同时启动MySQL与连接MySQL的java程序_第2张图片

最后ctrl+c退出,需要停止\删除容器和镜像则继续运行:

$ ./stop.sh
$ ./remove.sh

 

你可能感兴趣的:(Docker)