美文网首页SpringBoot
Spring Boot的容器化改造

Spring Boot的容器化改造

作者: 樂浩beyond | 来源:发表于2018-05-21 19:28 被阅读246次

    Spring Boot的容器化改造

    目前最流行的容器引擎:Docker,微服务领域最热门的框架Spring Boot, 两强联手会产生什么样的化学反应呢?

    最近偶然看到了纯洁的微笑的这篇文章,是一篇不错的入门docker文章,决定自己动手实践一下,纯洁的微笑这篇文章里用的是JPA操作数据库,我这里做了改动,用的是MyBatis框架操作数据库,docker-compose 文件也做了改动,这篇文章会把自己遇到的坑记录下来。文末会给出整个项目地址。

    Spring Boot

    使用Spring Boot 搭建一个web服务,在数据库中记录每个访问者的ip 和访问次数,并且返回给前端展示。

    依赖包

    主要依赖Spring boot web框架、Mysql驱动和MyBatis框架。

        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </dependency>
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>1.1.1</version>
            </dependency>
        </dependencies>
    

    核心代码

    Controller 层主要负责对接收到请求进行判断,操作数据库记录ip 和访问次数。

    @RestController
    public class VisitorController {
    
        @Autowired
        private VisitorMapper visitorMapper;
    
        @RequestMapping("/")
        public String index(HttpServletRequest request) {
            String ip=request.getRemoteAddr();
            Visitor visitor = visitorMapper.getOne(ip);
    
            if(visitor==null){
                visitor=new Visitor();
                visitor.setIp(ip);
                visitor.setTimes(1);
                visitorMapper.insert(visitor);
            }else {
                visitor.setTimes(visitor.getTimes()+1);
                visitorMapper.update(visitor);
            }
    
            return "I have been seen ip "+visitor.getIp()+" "+visitor.getTimes()+" times.";
        }
    }
    

    MyBatis的Mapper 负责操作数据库。

    @Mapper
    @Component(value = "visitorMapper")
    public interface VisitorMapper {
    
        @Select("SELECT * FROM visitor WHERE ip =#{ip}")
        Visitor getOne(String ip);
    
        @Update("UPDATE visitor SET ip=#{ip} ,times=#{times} WHERE ip =#{ip}")
        void update(Visitor visitor);
    
        @Insert("INSERT INTO visitor(ip,times) VALUES(#{ip},#{times})")
        void insert(Visitor visitor);
    }
    

    容器化改造

    首先看一下目录结构。DockerCompose是Spring Boot的项目工程文件,docker-compose.yaml是描述如何构建服务。nginx 里是关于nginx的配置。mysql 是mount到容器里的文件,下面会具体介绍。

    image.png

    docker-compose.yaml

    docker-compose.yaml 与纯洁的微笑里的文件相比做了些许改动,下面具体说明。

    version: '3'
    services:
      nginx:
       container_name: v-nginx
       build: ./nginx
       restart: always
       ports:
       - 80:80
       - 443:443
       volumes:
       - ./nginx/conf.d:/etc/nginx/conf.d
    
      mysql:
       container_name: v-mysql
       image: mysql/mysql-server:5.7
       volumes:
       - ./mysql/data:/var/lib/mysql
       environment:
        MYSQL_DATABASE: test
        MYSQL_ROOT_PASSWORD: root
        MYSQL_ROOT_HOST: '%'
       ports:
       - "3306:3306"
       restart: always
    
      app:
        restart: always
        build: ./DockerCompose
        working_dir: /DockerCompose
        volumes:
          - ./DockerCompose:/DockerCompose
          - ~/.m2:/root/.m2
        expose:
          - "8080"
        depends_on:
          - nginx
          - mysql
        command: mvn clean spring-boot:run -Dspring-boot.run.profiles=docker
    

    改动一:nginx
    在纯洁的微笑里nginx里并没有build: ./nginx,而是直接用image:nginx:1.13基础镜像。

    关于build的定义:

    服务除了可以基于指定的镜像,还可以基于一份 Dockerfile,在使用 up 启动之时执行构建任务,这个构建标签就是 build,它可以指定 Dockerfile 所在文件夹的路径。

    因为nginx:1.13基础镜像并不能满足我的在容器中使用vim命令的需求,所以在这里重新构建了一个镜像。使用apt-get安装vim,可以方便在nginx容器中使用vim命令。

    nginx目录下的Dockerfile:


    image.png

    改动二:mysql
    纯洁的微笑在结束运行容器之后,并没有保存数据库中的表,这是因为每次启动容器都会在宿主机中创建一个新的数据卷,所以只要一直是使用同一个数据卷,就不会有数据丢失的问题。可以具体参照这篇文章
    关于volumes的定义:

    挂载一个目录或者一个已存在的数据卷容器,可以直接使用 [HOST:CONTAINER] 这样的格式

    在Spring Boot 项目的同级目录下创建一个mysql/data目录,挂载完成之后,进入data目录,可以看到有test目录对应到数据库中的test

    image.png

    进入到test目录中,看到visitor命名的文件,就是对应到数据库中visitor表,这两种后缀是InnoDB引擎的存储方式。

    image.png
    除了上面两处改动,其他关键字的说明如下:
    • version: '3': 表示使用第三代语法来构建 docker-compose.yaml 文件。
    • services: 用来表示 compose 需要启动的服务,我们可以看出此文件中有三个服务分别为:nginx、mysql、app。
    • container_name: 容器名称
    • environment: 此节点下的信息会当作环境变量传入容器,此示例中 mysql 服务配置了数据库、密码和权限信息。
    • ports: 表示对外开放的端口
    • restart: always 表示如果服务启动不成功会一直尝试。
    • volumes: 加载本地目录下的配置文件到容器目标地址下
    • depends_on:可以配置依赖服务,表示需要先启动 depends_on 下面的服务后,再启动本服务。
    • command: mvn clean spring-boot:run -Dspring-boot.run.profiles=docker: 表示以这个命令来启动项目,-Dspring-- boot.run.profiles=docker表示使用 application-docker.properties文件配置信息进行启动。

    docker compose 的书写规则可以参照Docker Compose 配置文件详解

    Nginx配置

    Nginx没有改动,需要注意的一点是proxy_pass http://app:8080这块要使用app,必须要和compose中的service 名称对应。不熟悉Nginx配置的同学可以参考Nginx配置文章

    server {
            listen 80;
            charset utf-8;
            access_log off;
    
            location / {
            proxy_pass http://app:8080;
            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;
            }
    
            location /static {
            access_log   off;
            expires      30d;
    
            alias /app/static;
        }
    }
    

    部署与运行

    docker-compose up -d:以后端运行的方式启动容器

    image.png

    docker ps:查看正在运行的所有容器

    image.png

    docker-compose down: 关闭项目中的所有容器

    image.png

    运行结果:


    image.png

    总结

    使用Docker可以解决部署中的环境问题,不必再去一个个安装配置Mysql 、Nginx,安装配置完在和Spring Boot联调,非常麻烦。写个docker-compose.yaml文件,docker会帮你搞定这一切。即使是部署新的一个环境,docker也能帮你完美的避开安装配置的坑。


    示例代码:GitHub地址

    相关文章

      网友评论

        本文标题:Spring Boot的容器化改造

        本文链接:https://www.haomeiwen.com/subject/bomqjftx.html