十一、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
相关文章
|
9天前
|
传感器 监控 安全
智慧工地云平台的技术架构解析:微服务+Spring Cloud如何支撑海量数据?
慧工地解决方案依托AI、物联网和BIM技术,实现对施工现场的全方位、立体化管理。通过规范施工、减少安全隐患、节省人力、降低运营成本,提升工地管理的安全性、效率和精益度。该方案适用于大型建筑、基础设施、房地产开发等场景,具备微服务架构、大数据与AI分析、物联网设备联网、多端协同等创新点,推动建筑行业向数字化、智能化转型。未来将融合5G、区块链等技术,助力智慧城市建设。
|
1月前
|
搜索推荐 NoSQL Java
微服务架构设计与实践:用Spring Cloud实现抖音的推荐系统
本文基于Spring Cloud实现了一个简化的抖音推荐系统,涵盖用户行为管理、视频资源管理、个性化推荐和实时数据处理四大核心功能。通过Eureka进行服务注册与发现,使用Feign实现服务间调用,并借助Redis缓存用户画像,Kafka传递用户行为数据。文章详细介绍了项目搭建、服务创建及配置过程,包括用户服务、视频服务、推荐服务和数据处理服务的开发步骤。最后,通过业务测试验证了系统的功能,并引入Resilience4j实现服务降级,确保系统在部分服务故障时仍能正常运行。此示例旨在帮助读者理解微服务架构的设计思路与实践方法。
101 17
|
1月前
|
监控 JavaScript 数据可视化
建筑施工一体化信息管理平台源码,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
智慧工地云平台是专为建筑施工领域打造的一体化信息管理平台,利用大数据、云计算、物联网等技术,实现施工区域各系统数据汇总与可视化管理。平台涵盖人员、设备、物料、环境等关键因素的实时监控与数据分析,提供远程指挥、决策支持等功能,提升工作效率,促进产业信息化发展。系统由PC端、APP移动端及项目、监管、数据屏三大平台组成,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
|
1月前
|
Java 关系型数据库 数据库
微服务SpringCloud分布式事务之Seata
SpringCloud+SpringCloudAlibaba的Seata实现分布式事务,步骤超详细,附带视频教程
76 1
|
1月前
|
人工智能 安全 Java
微服务引擎 MSE:打造通用的企业级微服务架构
微服务引擎MSE致力于打造通用的企业级微服务架构,涵盖四大核心内容:微服务技术趋势与挑战、MSE应对方案、拥抱开源及最佳实践。MSE通过流量入口、内部流量管理、服务治理等模块,提供高可用、跨语言支持和性能优化。此外,MSE坚持开放,推动云原生与AI融合,助力企业实现无缝迁移和高效运维。
|
2月前
|
运维 监控 持续交付
微服务架构解析:跨越传统架构的技术革命
微服务架构(Microservices Architecture)是一种软件架构风格,它将一个大型的单体应用拆分为多个小而独立的服务,每个服务都可以独立开发、部署和扩展。
555 36
微服务架构解析:跨越传统架构的技术革命
|
2月前
|
Java 开发者 微服务
从单体到微服务:如何借助 Spring Cloud 实现架构转型
**Spring Cloud** 是一套基于 Spring 框架的**微服务架构解决方案**,它提供了一系列的工具和组件,帮助开发者快速构建分布式系统,尤其是微服务架构。
301 69
从单体到微服务:如何借助 Spring Cloud 实现架构转型
|
3月前
|
JavaScript Java API
深入解析微服务的架构设计与实践
深入解析微服务的架构设计与实践
56 0
|
3月前
|
消息中间件 供应链 架构师
微服务如何实现低耦合高内聚?架构师都在用的技巧!
本文介绍了微服务的拆分方法,重点讲解了“高内聚”和“低耦合”两个核心设计原则。高内聚强调每个微服务应专注于单一职责,减少代码修改范围,提高系统稳定性。低耦合则通过接口和消息队列实现服务间的解耦,确保各服务独立运作,提升系统的灵活性和可维护性。通过领域建模和事件通知机制,可以有效实现微服务的高效拆分和管理。
87 7
|
3月前
|
设计模式 Java API
微服务架构演变与架构设计深度解析
【11月更文挑战第14天】在当今的IT行业中,微服务架构已经成为构建大型、复杂系统的重要范式。本文将从微服务架构的背景、业务场景、功能点、底层原理、实战、设计模式等多个方面进行深度解析,并结合京东电商的案例,探讨微服务架构在实际应用中的实施与效果。
214 6