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(); }
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