Spring Boot+Mysql最简单的Docker服务编排

Docker的安装网上已经有很多资源了,在这里就不在赘述,直接进入项目

一、创建Spring Boot项目,并编写简单的计数器功能,数据记录在mysql中

项目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>

	<groupId>com.example</groupId>
	<artifactId>demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>demo</name>
	<description>Demo project for Spring Boot</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.1.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<docker.image.prefix>leo</docker.image.prefix>
		<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-jdbc</artifactId>
		</dependency>
		<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>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>

			<plugin> --Docker插件
				<groupId>com.spotify</groupId>
				<artifactId>docker-maven-plugin</artifactId>
				<version>0.4.11</version>
				<executions>
					<execution>
                        -- 当执行package命令的时候进行Docker镜像的build
						<id>build-image</id>
						<phase>package</phase>
						<goals>
							<goal>build</goal>
						</goals>
					</execution>
				</executions>

				<configuration>
                    -- 镜像名称
					<imageName>${docker.image.prefix}/${project.artifactId}</imageName>
                    -- Dockerfile所在的路径
					<dockerDirectory>src/main/docker</dockerDirectory>
					<resources>
						<resource>
							<targetPath>/</targetPath>
							<directory>${project.build.directory}</directory>
							<include>${project.build.finalName}.jar</include>
						</resource>
					</resources>
				</configuration>
			</plugin>


			<plugin>
				<groupId>org.mybatis.generator</groupId>
				<artifactId>mybatis-generator-maven-plugin</artifactId>
				<version>1.3.2</version>
				<configuration>
					<configurationFile>generator.xml</configurationFile>
					<overwrite>true</overwrite>
					<verbose>true</verbose>
				</configuration>
				<dependencies>
					<dependency>
						<groupId>mysql</groupId>
						<artifactId>mysql-connector-java</artifactId>
						<version>5.1.41</version>
					</dependency>
					<dependency>
						<groupId>org.mybatis.generator</groupId>
						<artifactId>mybatis-generator-core</artifactId>
						<version>1.3.2</version>
					</dependency>
				</dependencies>
			</plugin>
		</plugins>
	</build>
</project>

application.yml文件

spring:
  datasource:
    url: jdbc:mysql://mysql1:3306/lhz?useSSL=false -- 此处由于要链接到mysql容器中去,所以这里写的是容器的名称
    username: docker
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver
    
mybatis:
  mapper-locations: classpath*:/mapper/*/*Mapper.xml

HelloController文件

@RestController
public class HelloController {
	
	@Autowired
	private UserService userService;

	@ResponseBody
	@RequestMapping(value="hello",method=RequestMethod.GET)
	public String hello() {
		return "hello";
	}
	
	@ResponseBody
	@RequestMapping(value="hello/{userId}",method=RequestMethod.GET)
	public Integer hello(@PathVariable(value = "userId") String userId) {
		return userService.plus(userId);
	}
	
}
@Service
public class UserService {
	
	@Autowired
	private UserMapper userMapper;
	
	public Integer plus(String userId) {
		User user = userMapper.selectById(userId);
		if(user == null) {
			user = new User();
			user.setId(1);
			user.setCount(0);
			userMapper.insert(user);
			return 0;
		}
		Integer count = user.getCount();
		user.setCount(++count);
		userMapper.update(user);
		return count;
	}

}
@Mapper
public interface UserMapper {
    int insert(User record);

    List<User> selectAll();

	User selectById(String userId);

	void update(User user);
}
public class User {
    private Integer id;

    private Integer count;

    public Integer getId() {
        return id;
    }

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

    public Integer getCount() {
        return count;
    }

    public void setCount(Integer count) {
        this.count = count;
    }
}
<?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.example.demo.mapper.UserMapper" >
  <resultMap id="BaseResultMap" type="com.example.demo.domain.User" >
    <result column="id" property="id" jdbcType="INTEGER" />
    <result column="count" property="count" jdbcType="INTEGER" />
  </resultMap>
  <insert id="insert" parameterType="com.example.demo.domain.User" >
    insert into user (id, count)
    values (#{id,jdbcType=INTEGER}, #{count,jdbcType=INTEGER})
  </insert>
  <select id="selectAll" resultMap="BaseResultMap" >
    select id, count
    from user
  </select>
  <update id="update" parameterType="com.example.demo.domain.User">
  	update user set count = #{count,jdbcType=INTEGER} where id = #{id,jdbcType=INTEGER}
  </update>
  <select id="selectById" resultMap="BaseResultMap" >
    select id, count
    from user where id = #{id,jdbcType=INTEGER}
  </select>
</mapper>

到这里项目都已经创建完成,启动后访问hello/{userId}可以看到计数器增加

二、编写Dockerfile将服务的镜像和mysql的镜像生成出来

src文件夹下面新建文件夹src/main/docker/mysql

创建文件my.cnf

[mysql]
default-character-set=utf8

[mysqld]
character-set-server=utf8

schema.sql

CREATE DATABASE  IF NOT EXISTS `lhz` /*!40100 DEFAULT CHARACTER SET latin1 */;
USE `lhz`;
-- MySQL dump 10.13  Distrib 5.7.22, for Linux (x86_64)
--
-- Host: localhost    Database: lhz
-- ------------------------------------------------------
-- Server version	5.7.22-0ubuntu0.17.10.1

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Table structure for table `user`
--

DROP TABLE IF EXISTS `user`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `user` (
  `id` int(11) NOT NULL,
  `count` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

-- Dump completed on 2018-05-01 22:23:08

privileges.sql

use mysql;
select host, user from user;
-- 因为mysql版本是5.7,因此新建用户为如下命令:
create user docker identified by '123456';
-- 将docker_mysql数据库的权限授权给创建的docker用户,密码为123456:
grant all on lhz.* to docker@'%' identified by '123456' with grant option;
-- 这一条命令一定要有:
flush privileges;

setup.sh

#!/bin/bash
set -e

#查看mysql服务的状态,方便调试,这条语句可以删除
echo `service mysql status`

echo '1.启动mysql....'
#启动mysql
service mysql start
sleep 3
echo `service mysql status`

echo '2.开始导入数据....'
#导入数据
mysql < /etc/mysql/schema.sql
echo '3.导入数据完毕....'

sleep 3
echo `service mysql status`

#重新设置mysql密码
echo '4.开始修改密码....'
mysql < /etc/mysql/privileges.sql
echo '5.修改密码完毕....'

#sleep 3
echo `service mysql status`
echo 'mysql容器启动完毕,且数据导入成功'

tail -f /dev/null

Dockerfile文件

FROM mysql:5.7

VOLUME my.cnf:/etc/mysql/my.cnf mysql

#将所需文件放到容器中
ADD setup.sh /etc/mysql/setup.sh
ADD schema.sql /etc/mysql/schema.sql
ADD privileges.sql /etc/mysql/privileges.sql

EXPOSE 3306
ENV MYSQL_ALLOW_EMPTY_PASSWORD=yes
#设置容器启动时执行的命令
CMD ["sh", "/etc/mysql/setup.sh"]

至此mysql镜像所需文件完成,进入docker/mysql文件夹下执行命令

docker build -t leo/mysql .

输出如下

Sending build context to Docker daemon  8.192kB
Step 1/8 : FROM mysql:5.7
 ---> db763dfc448b
Step 2/8 : VOLUME my.cnf:/etc/mysql/my.cnf mysql
 ---> Running in c7983fbbc27e
Removing intermediate container c7983fbbc27e
 ---> 6713fe9fbd20
Step 3/8 : ADD setup.sh /etc/mysql/setup.sh
 ---> 250290ecac96
Step 4/8 : ADD schema.sql /etc/mysql/schema.sql
 ---> 0bff6bb6ccbc
Step 5/8 : ADD privileges.sql /etc/mysql/privileges.sql
 ---> 41909954766f
Step 6/8 : EXPOSE 3306
 ---> Running in c34065f6f503
Removing intermediate container c34065f6f503
 ---> a40db40e4fc6
Step 7/8 : ENV MYSQL_ALLOW_EMPTY_PASSWORD=yes
 ---> Running in d7dc727ade54
Removing intermediate container d7dc727ade54
 ---> 4ce1e5739a43
Step 8/8 : CMD ["sh", "/etc/mysql/setup.sh"]
 ---> Running in 2d24626e4b53
Removing intermediate container 2d24626e4b53
 ---> edbaec51aa90
Successfully built edbaec51aa90
Successfully tagged leo/mysql:latest

镜像创建成功

执行docker images命令可以看到我们刚才创建的镜像

下面我们来创建服务镜像,这里我们使用maven的docker插件,在上面我们都有注释。

然后我们在docker文件夹下面创建Dockerfile文件

FROM java:8
VOLUME /tmp
ADD demo-0.0.1-SNAPSHOT.jar app.jar
RUN sh -c 'touch /app.jar'
EXPOSE 8080
ENV JAVA_OPTS=""
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar" ]

然后在项目路径执行mvn clean package命令,可以看到最后面生成了我么服务的镜像

[INFO] Building image leo/demo
Step 1/7 : FROM java:8

 ---> d23bdf5b1b1b
Step 2/7 : VOLUME /tmp

 ---> Using cache
 ---> f3b25192acf9
Step 3/7 : ADD demo-0.0.1-SNAPSHOT.jar app.jar

 ---> 74b032aca919
Step 4/7 : RUN sh -c 'touch /app.jar'

 ---> Running in 4910f0d0bc10
Removing intermediate container 4910f0d0bc10
 ---> 1c3adcdb997e
Step 5/7 : EXPOSE 8080

 ---> Running in 608eca7f3c3f
Removing intermediate container 608eca7f3c3f
 ---> 75894ae6a8a4
Step 6/7 : ENV JAVA_OPTS=""

 ---> Running in 3b64b4567ac4
Removing intermediate container 3b64b4567ac4
 ---> 327ee6e1d18e
Step 7/7 : ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar" ]

 ---> Running in 057a92e82ce7
Removing intermediate container 057a92e82ce7
 ---> 15289a9089fe
ProgressMessage{id=null, status=null, stream=null, error=null, progress=null, progressDetail=null}
Successfully built 15289a9089fe
Successfully tagged leo/demo:latest

现在两个镜像都有了,我们进行服务的编排。在项目目录下创建docker-compose.yml文件

version : '2'
services:
  -- 服务名称,其他服务调用的时候就用这个名称
  mysql1:
    image: leo/mysql:latest
    volumes:
           - ./src/main/docker/mysql/my.cnf:/etc/mysql/my.cnf mysql
    environment:
       - MYSQL_ROOT_PASSWORD=123456
    ports:
       - "3307:3306"
    expose:
       - "3307"
           
  demo:
    image: leo/demo:latest
    ports:
      - "8080:8080"
    links:
        -- 连接的服务,这里连接到了mysql1
        - mysql1

  

编写完之后,在同目录下执行命令

docker-compose up

会自动开始创建容器,启动服务

demo_1    | 2018-05-02 14:35:23.603  INFO 6 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
demo_1    | 2018-05-02 14:35:23.604  INFO 6 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
demo_1    | 2018-05-02 14:35:24.048  INFO 6 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
demo_1    | 2018-05-02 14:35:24.051  INFO 6 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Bean with name 'dataSource' has been autodetected for JMX exposure
demo_1    | 2018-05-02 14:35:24.064  INFO 6 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Located MBean 'dataSource': registering with JMX server as MBean [com.zaxxer.hikari:name=dataSource,type=HikariDataSource]
demo_1    | 2018-05-02 14:35:24.352  INFO 6 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
demo_1    | 2018-05-02 14:35:24.357  INFO 6 --- [           main] com.example.demo.DemoApplication         : Started DemoApplication in 8.268 seconds (JVM running for 11.648)
mysql1_1  | 2018-05-02T14:35:28.633990Z 1 [Warning] 'user' entry 'root@localhost' ignored in --skip-name-resolve mode.
mysql1_1  | 2018-05-02T14:35:28.634029Z 1 [Warning] 'user' entry 'mysql.session@localhost' ignored in --skip-name-resolve mode.
mysql1_1  | 2018-05-02T14:35:28.634038Z 1 [Warning] 'user' entry 'mysql.sys@localhost' ignored in --skip-name-resolve mode.
mysql1_1  | 2018-05-02T14:35:28.634055Z 1 [Warning] 'db' entry 'performance_schema mysql.session@localhost' ignored in --skip-name-resolve mode.
mysql1_1  | 2018-05-02T14:35:28.634060Z 1 [Warning] 'db' entry 'sys mysql.sys@localhost' ignored in --skip-name-resolve mode.
mysql1_1  | 2018-05-02T14:35:28.634070Z 1 [Warning] 'proxies_priv' entry '@ root@localhost' ignored in --skip-name-resolve mode.
mysql1_1  | 2018-05-02T14:35:28.634095Z 1 [Warning] 'tables_priv' entry 'user mysql.session@localhost' ignored in --skip-name-resolve mode.
mysql1_1  | 2018-05-02T14:35:28.634102Z 1 [Warning] 'tables_priv' entry 'sys_config mysql.sys@localhost' ignored in --skip-name-resolve mode.
mysql1_1  | ..
mysql1_1  | MySQL Community Server 5.7.22 is started.
mysql1_1  | MySQL Community Server 5.7.22 is running.
mysql1_1  | 2.开始导入数据....
mysql1_1  | 3.导入数据完毕....
mysql1_1  | MySQL Community Server 5.7.22 is running.
mysql1_1  | 4.开始修改密码....
mysql1_1  | host	user
mysql1_1  | localhost	mysql.session
mysql1_1  | localhost	mysql.sys
mysql1_1  | localhost	root
mysql1_1  | 5.修改密码完毕....
mysql1_1  | MySQL Community Server 5.7.22 is running.
mysql1_1  | mysql容器启动完毕,且数据导入成功

启动完成,这时候我们从浏览器中访问刚才的服务地址/hello/1

可以看到计数器依旧生效,至此我们完成了一个简单的将服务运行在docker上

猜你喜欢

转载自my.oschina.net/u/1175305/blog/1805838