十一、Docker搭建部署SpringCloud微服务项目Demo(二)

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
云原生网关 MSE Higress,422元/月
注册配置 MSE Nacos/ZooKeeper,118元/月
简介: 十一、Docker搭建部署SpringCloud微服务项目Demo
3.4 抽取公共模块

上面两个微服务会有重复代码,抽取公共部分包含项目一些公共的类以及jar包

Department

package com.ylc;
import java.io.Serializable;
import java.util.Date;
/**
 * @author yanglingcong
 * 部门类
 */
public class Department implements Serializable {
    private static final long serialVersionUID = 279210942586979318L;
    private Integer id;
    /**
     * 部门名称
     */
    private String name;
    /**
     * 创建时间
     */
    private Date createdAt;
    private Employee employee;
    public Employee getEmployee() {
        return employee;
    }
    public void setEmployee(Employee employee) {
        this.employee = employee;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Date getCreatedAt() {
        return createdAt;
    }
    public void setCreatedAt(Date createdAt) {
        this.createdAt = createdAt;
    }
}

Employee

package com.ylc;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.io.Serializable;
import java.util.Date;
/**
 * (Employee)实体类
 * @author yanglingcong
 */
public class Employee implements Serializable {
    private static final long serialVersionUID = -87055454147065054L;
    private String id;
    private String name;
    /**
     * 生日
     */
    private Date birthday;
    /**
     * 工资
     */
    private String salary;
    /**
     * 部门信息
     */
    @JsonProperty("department_id")
    private Integer departmentId;
    private Department department;
    public Department getDepartment() {
        return department;
    }
    public void setDepartment(Department department) {
        this.department = department;
    }
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Date getBirthday() {
        return birthday;
    }
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
    public String getSalary() {
        return salary;
    }
    public void setSalary(String salary) {
        this.salary = salary;
    }
    public Integer getDepartmentId() {
        return departmentId;
    }
    public void setDepartmentId(Integer departmentId) {
        this.departmentId = departmentId;
    }
}

pom文件

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <!-- 确认继承关系 -->
    <parent>
        <!--父工程 gropuId-->
        <groupId>com.ylc</groupId>
        <!--父工程 artifactId-->
        <artifactId>springcloud-dockerDemo</artifactId>
        <!--父工程 版本-->
        <version>1.0-SNAPSHOT</version>
    </parent>
    <artifactId>ems-employess</artifactId>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <!--web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--nacos-service-discovery-client-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--druid mysql mybatis-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.6</version>
        </dependency>
        <!--mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.23</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.0</version>
        </dependency>
        <!--远程调用openfegin-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.10.1</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.3.4.RELEASE</version>
                <configuration>
                    <fork>true</fork>
                    <addResources>true</addResources>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

公共模块搭建很简单就两个类,然后在其他模块引用公共模块

<dependencies>
        <!--公共模块-->
        <dependency>
            <groupId>com.ylc</groupId>
            <artifactId>ems-commons</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

到此就完成了

3.5.测试

通过查询员工信息,然后远程调用部门信息

远程接口

@FeignClient("DEPARTMENTS")
public interface DepartmentClient {
    //部门详细
    @GetMapping("/department/{id}")
     Department detail(@PathVariable("id") Integer id);
}

1、接口定义

/**
 *  查询员工以及部门的详细信息
 * @return List<Employee>
 */
 List<Employee> queryAll();

2、实现类

@Override
public List<Employee> queryAll() {
    List<Employee> employees=employeeDao.queryAll();
    employees.forEach(emp->{
        Integer departmentid=emp.getDepartmentId();
        Department detail = departmentClient.detail(departmentid);
        emp.setDepartment(detail);
    });
    return employees;
}

3、调用方法

//员工列表
    @GetMapping
    public List<Employee> employees() {
        return employeeService.queryAll();
    }

4、测试localhost:8085/employee

3.6 搭建网关子模块

1、开启服务注册发现

@SpringBootApplication
@EnableDiscoveryClient
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }
}

2、网关配置

spring:
  cloud:
    gateway:
      routes: # 用来配置网关路由规则
        - id: employee_route
          uri: lb://EMPLOYESS
          predicates:
            - Path=/ems/employee
          filters:
            - StripPrefix=1
        - id: department_route
          uri: lb://DEPARTMENTS
          predicates:
            - Path=/ems/department
          filters:
            - StripPrefix=1

3、bootstrap.yml

server.port=8888
spring.application.name=GATEWAY
spring.cloud.nacos.server-addr=121.43.33.150:8848
spring.cloud.nacos.config.server-addr=121.43.33.150:8848
spring.cloud.nacos.discovery.server-addr=121.43.33.150:8848
spring.cloud.nacos.config.enabled=false

4、通过网关访问成功

至此整个项目流程就打通了

部署

1.本地测试

1、打包之前每个项目都需要有springboot的打包插件,没有的话要在项目中引入

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

安装之后出现这个就可以了

2、先对父项目进行清理(clean)再打包(Package),common公共模块是没主启动类的,这时候把父项目的pom文件的该插件注释调就行了。

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

全部打包完成

3、先在本地测试jar是否成功

运行员工模块

运行部门模块

运行网关模块

都成功之后本地访问http://localhost:8888/ems/employee

到这里都没有问题说明本地测试通过了

2.编写Dockerfile

docker中需要有JDK1.8的镜像,安装JDK

docker pull openjdk:8

在idea中编写员工模块Dockerfile

FROM openjdk:8
ENV APP_HOME=/apps
WORKDIR $APP_HOME
COPY ./ems-employess-1.0-SNAPSHOT.jar ./employess.jar
EXPOSE 8086
ENTRYPOINT ["java","-jar"]
CMD ["employess.jar"]

部门模块Dockerfile

FROM openjdk:8
ENV APP_HOME=/apps
WORKDIR $APP_HOME
COPY ./ems-departments-0.0.1-SNAPSHOT.jar ./departments.jar
EXPOSE 8085
ENTRYPOINT ["java","-jar"]
CMD ["departments.jar"]

网关模块Dockerfile

FROM openjdk:8
ENV APP_HOME=/apps
WORKDIR $APP_HOME
COPY ./ems-gateway-1.0-SNAPSHOT.jar ./gateway.jar
EXPOSE 8888
ENTRYPOINT ["java","-jar"]
CMD ["gateway.jar"]

然后在idea 中登录docker所在服务器

3.Dockerfile文件上传

然后把项目的文件上传到服务自己建的ems文件夹中

4.编写docker-compose.yml

直接利用dockerfile文件的路径打包成镜像,最后编排运行

version: "3.8"
networks:
  ems:
volumes:
  data:
services:
  employee:
    build:
      context: ./employee
      dockerfile: Dockerfile
    ports:
      - "8085:8085"
    networks:
      - ems
  department:
    build:
      context: ./department
      dockerfile: Dockerfile
    ports:
      - "8086:8086"
    networks:
      - ems
  gateway:
    build:
      context: ./gateway
      dockerfile: Dockerfile
    ports:
      - "8888:8888"
    networks:
      - ems
  nacos:
    image: nacos/nacos-server:1.3.1
    ports:
      - "8848:8848"
    environment:
      - "MODE=standalone"
    networks:
      - ems
  mysql:
    image: mysql
    ports:
      - "3306:3306" #只写一个端口随机使用宿主机一个端口进行容器端口映射
    environment:
      - "MYSQL_ROOT_PASSWORD=root"
      - "MYSQL_DATABASE=ems"
    volumes:
      - data:/var/lib/mysql
      #- ./ems.sql:/docker-entrypoint-initdb.d/ems.sql
    networks:
      - ems

5.项目启动

在服务器ems文件夹中输入

docker-compose up -d department
docker-compose up -d employee
docker-compose up -d gateway

报错

有个服务报错:Error: Invalid or corrupt jarfile employess.jar

检查了好几遍,重新打包上传还是这样,最后进目录查看发现jar包每次都没有上传完整

文件大小明显不对,因为打包错了里面没有主启动类,我在打包之前就删除这些,添加进来然后重新运行 mvn install即可

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

这下正常了

再次运行因为之前构建的镜像还在,即便重新上传还是运行的之前构建的,没有效果,所以的删除之前构建过的错误镜像,三个都运行成功

部署成功!

总结

还有很多可以优化的地方,因为本节是着重演示部署流程,细节方面就没有优化了

这就是一整个部署的大概流程,但每次项目代码如果有更改,又需要手动重新生成镜像然后在服务器重新运行,还是不太方便,后续会出Jenkins+Docker自动化部署SpringCloud,实现代码提交自动进行编译打包上传并部署,简化在部署方面的操作。

项目细节难免有纰漏之处,附项目地址:https://gitee.com/yanglingcong/spring-cloud-docker

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
14天前
|
关系型数据库 MySQL Docker
《docker高级篇(大厂进阶):5.Docker-compose容器编排》包括是什么能干嘛去哪下、Compose核心概念、Compose使用三个步骤、Compose常用命令、Compose编排微服务
《docker高级篇(大厂进阶):5.Docker-compose容器编排》包括是什么能干嘛去哪下、Compose核心概念、Compose使用三个步骤、Compose常用命令、Compose编排微服务
75 24
|
16天前
|
关系型数据库 MySQL Docker
《docker高级篇(大厂进阶):5.Docker-compose容器编排》包括是什么能干嘛去哪下、Compose核心概念、Compose使用三个步骤、Compose常用命令、Compose编排微服务
《docker高级篇(大厂进阶):5.Docker-compose容器编排》包括是什么能干嘛去哪下、Compose核心概念、Compose使用三个步骤、Compose常用命令、Compose编排微服务
94 6
|
24天前
|
Java 应用服务中间件 Docker
将基于 Spring 的 WAR 应用程序部署到 Docker:详尽指南
将基于 Spring 的 WAR 应用程序部署到 Docker:详尽指南
29 2
|
1月前
|
Java Linux Docker
什么是 Docker?如何将 Spring Boot 应用程序部署到 Docker?
什么是 Docker?如何将 Spring Boot 应用程序部署到 Docker?
43 3
|
1月前
|
机器学习/深度学习 数据采集 Docker
Docker容器化实战:构建并部署一个简单的Web应用
Docker容器化实战:构建并部署一个简单的Web应用
|
1月前
|
监控 安全 持续交付
构建高效的微服务架构:从设计到部署
构建高效的微服务架构:从设计到部署
25 1
|
1月前
|
安全 持续交付 Docker
微服务架构和 Docker 容器化部署的优点是什么?
微服务架构和 Docker 容器化部署的优点是什么?
|
1月前
|
持续交付 开发者 Docker
掌握Docker容器化技术,加速软件开发与部署
掌握Docker容器化技术,加速软件开发与部署
51 0
|
1月前
|
设计模式 Java API
微服务架构演变与架构设计深度解析
【11月更文挑战第14天】在当今的IT行业中,微服务架构已经成为构建大型、复杂系统的重要范式。本文将从微服务架构的背景、业务场景、功能点、底层原理、实战、设计模式等多个方面进行深度解析,并结合京东电商的案例,探讨微服务架构在实际应用中的实施与效果。
132 6
|
1月前
|
设计模式 Java API
微服务架构演变与架构设计深度解析
【11月更文挑战第14天】在当今的IT行业中,微服务架构已经成为构建大型、复杂系统的重要范式。本文将从微服务架构的背景、业务场景、功能点、底层原理、实战、设计模式等多个方面进行深度解析,并结合京东电商的案例,探讨微服务架构在实际应用中的实施与效果。
51 1