SpringCloud 微服务搭建

    科技2025-06-20  6

    博客参考学习视频: https://www.bilibili.com/video/BV18E411x7eT?from=search&seid=4388336378730572330

    一、微服务架构编码构建

    ① 约定 > 配置 > 编码

    slave会从master读取binlog来进行数据同步

    三步骤+原理图

    MySQL复制过程分成三步: 1 master将改变记录到二进制日志(binary log)。这些记录过程叫做二进制日志事件,binary log events; 2 slave将master的binary log events拷贝到它的中继日志(relay log); 3 slave重做中继日志中的事件,将改变应用到自己的数据库中。 MySQL复制是异步的且串行化的

    ② IDEA 新建project 工作空间

    1.微服务cloud 整体聚合父工程 Project

    ​ 父工程步骤:

    1) New Project

    2)聚合总工程名字和工程名字(idea 2020.2 版本)

    3)选择Maven 版本

    4)字符编码

    5) 注解生效激活

    6)Java 编译版本选择8

    File Type 过滤

    2.父工程

    <?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.oy</groupId> <artifactId>clould</artifactId> <version>1.0-SNAPSHOT</version> <modules> <module>cloud-provider-payment8001</module> </modules> <packaging>pom</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <junit.version>4.12</junit.version> <log4j.version>1.2.17</log4j.version> <lombok.version>1.16.18</lombok.version> <mysql.version>8.0.19</mysql.version> <druid.version>1.1.16</druid.version> <spring.boot.version>2.2.2.RELEASE</spring.boot.version> <spring.cloud.version>Hoxton.SR1</spring.cloud.version> <spring.cloud.alibaba.version>2.1.0.RELEASE</spring.cloud.alibaba.version> <mybatis.spring.boot.version>1.3.0</mybatis.spring.boot.version> </properties> <!--子模块继承后,提供作用:锁定版本+子module不用groupId和version--> <dependencyManagement> <dependencies> <!--springboot 2.2.2--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring.boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> <!--Spring cloud Hoxton.SR1--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring.cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> <!--Spring cloud alibaba 2.1.0.RELEASE--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>${spring.cloud.alibaba.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql.version}</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>${druid.version}</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>${mybatis.spring.boot.version}</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lombok.version}</version> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <fork>true</fork> <addResources>true</addResources> </configuration> </plugin> </plugins> </build> </project>

    3.Maven 工程落地细节复习

    Maven 中的 dependencyManagement 和 dependencies

    maven 中跳过单元测试

    4.父工程创建完成执行mvn:insall将父工程发布到仓库方便子工程继承

    二、Rest 微服务工程构建

    ① 构建步骤

    (1) cloud-provider-payment8001 微服务提供者支付Module 模块

    ​ 建cloud-provider-payment8001

    ​ 创建完成之后请回到父工程产看pom文件的变化

    1. **改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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>clould</artifactId> <groupId>com.oy</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>cloud-provider-payment8001</artifactId> <dependencies><!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter -web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter -web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter -web --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/com.alibaba/druid --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency> <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter -jdbc --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtoo ls --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter -test --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> </project> 写 YML server: port: 8001 spring: application: name: cloud-payment-service datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/db2019?useUnicode=true&characterEncoding=utf-8&useSSL=false username: root password: 6090 mybatis: mapperLocations: classpath:mapper/*.xml type-aliases-package: com.oy.springcloud.entities # 所有Entity别名类所在包

    注意:有可能在编译时会出现以下的异常

    The server time zone value ‘�й���׼ʱ��’ is unrecogni

    需要在配置文件中的datasource.url 后面添加上 serverTimezone=UTC

    url: jdbc:mysql://localhost:3306/db2019?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC 主启动类 @SpringBootApplication public class PaymentMain8001 { public static void main(String[] args) { SpringApplication.run(PaymentMain8001.class, args); } } 业务类 建表 SQL CREATE TABLE `payment` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', `serial` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '支付流水号', PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '支付表' ROW_FORMAT = Dynamic; emtities

    ​ 主实体 Payment

    package com.oy.springcloud.entities; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.io.Serializable; /** * @Author OY * @Date 2020/10/7 */ @Data @AllArgsConstructor @NoArgsConstructor public class Payment implements Serializable { private Long id; private String serial; } Json 封装 CommonResult package com.oy.springcloud.entities; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; /** * @Author OY * @Date 2020/10/7 */ @Data @AllArgsConstructor @NoArgsConstructor public class CommonResult<T> { private Integer code; private String message; private T data; public CommonResult(Integer code, String message){ this.code = code; this.message = message; } } Dao @Mapper public interface PaymentDao { public int create(Payment payment); public Payment getPaymentById(@Param("id") Long id); }

    ​ mybatis 的映射文件为 PaymentMapper.xml, 路径为 src\main\resources\mapper\ParmentMapper.xml

    PaymentMapper.xml

    <?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.oy.springcloud.dao.PaymentDao"> <!--public int create(Payment payment);--> <insert id="create" parameterType="Payment" useGeneratedKeys="true" keyProperty="id"> insert into payment(serial) values(#{serial}) </insert> <!--public Payment getPaymentById(@Param("id") Long id);--> <resultMap id="BaseResult" type="com.oy.springcloud.entitles.Payment"> <id column="id" property="id" jdbcType="BIGINT"/> <id column="serial" property="serial" jdbcType="VARCHAR"/> </resultMap> <select id="getPaymentById" parameterType="Long" resultMap="BaseResult"> select * from payment where id=#{id} </select> </mapper> Service

    ​ 接口类 PaymentService

    package com.oy.springcloud.service; import com.oy.springcloud.entities.Payment; import org.apache.ibatis.annotations.Param; public interface PaymentService { public int create(Payment payment); // 写 public Payment getPaymentById(@Param("id") Long id); // 读取 }

    ​ 实体类

    package com.oy.springcloud.service.impl; import com.oy.springcloud.dao.PaymentDao; import com.oy.springcloud.entities.Payment; import com.oy.springcloud.service.PaymentService; import org.springframework.stereotype.Service; import javax.annotation.Resource; @Service public class PaymentServiceImpl implements PaymentService { @Resource // @Autowired private PaymentDao paymentDao; @Override public int create(Payment payment){ return paymentDao.create(payment); } @Override public Payment getPaymentById(Long id){ return paymentDao.getPaymentById(id); } } controller @RestController @Slf4j public class PaymentController { @Resource private PaymentService paymentService; @PostMapping(value = "/payment/create") public CommonResult create(Payment payment) { int result = paymentService.create(payment); log.info("*****插入结果: " + result); // 成功 if (result > 0) { return new CommonResult(200, "插入数据库成功", result); } else { return new CommonResult(444, "插入数据库失败", null); } } @GetMapping(value = "/payment/get/{id}") public CommonResult getPaymentById(@PathVariable("id") Long id) { Payment payment = paymentService.getPaymentById(id); log.info("*****查询结果: " + payment); // 成功 if (payment != null) { return new CommonResult(200, "查询成功", payment); } else { return new CommonResult(444, "没 有 对 应 记 录 , 查 询 ID :"+id, null); } } }

    测试

    http://localhost:8001/payment/get/1

    postman 模拟 post

    通过修改 idea 的 workpace.xml 的方式来快速打开 Run DashBoard窗口 开启 Run DashBoard(个别版本需要)

    <option name="configurationTypes"> <set> <option value="SpringBootApplicationConfigurationType" /> </set> </option>

    注意:部分同学可能由于 idea 版本不同, 需要关闭重启

    (2) 热部署 Devtools

    Adding devtools to your project <!--https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> Adding plugin to your pom.xml // 下面这一段粘贴在父POM.xml中 <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <fork>true</fork> <addResources>true</addResources> </configuration> </plugin> </plugins> </build>

    3.Enabling automatic build

    4.Update the value of

    (3) cloud-consumer-order80 微服务消费者订单 Module模块

    ​ 建 cloud-consumer-order80

    改 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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>clould</artifactId> <groupId>com.oy</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>cloud-consumer-order80</artifactId> <dependencies> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter -web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter -web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtoo ls --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> <dependency><groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter -test --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> </project> 写YML server: port: 80 主启动 package com.oy.springcloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class OrderMain80 { public static void main(String[] args) { SpringApplication.run(OrderMain80.class, args); } } 业务类

    创建 entities(将 cloud-provider-payment8001 工程下的entities 包下的两个实体复制过来)

    RestTemplate:

    官网及使用

    ​ 官网地址:https://docs.spring.io/spring-framework/docs/5.2.2.RELEASE/javadoc-api/org/springframework/web/client/RestTemplate.html

    ​ 使用:使用restTemplate访问restful接口非常的简单的粗暴无脑。(url, reuestMap, ResponseBean.class)这三个参数分别代表REST请求地址、请求参数、HTTP响应转换成的对象类型。

    config 配置类

    package com.oy.springcloud.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate; @Configuration public class ApplicationContextConfig { @Bean public RestTemplate getRestTemplate(){ return new RestTemplate(); } } 测试 先启动 cloud-provider-payment8001再启动 cloud-consumer-order80

    http://localhost/consumer/payment/get/1

    不要忘记@RequestBody 注解,不然在测试 http://localhost/consumer/payment/create?serial=“商店003”

    (4) 工程重构

    观察问题:系统中有重复的部分

    重构

    新建 cloud-api-commons 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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>clould</artifactId> <groupId>com.oy</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>cloud-api-commons</artifactId> <dependencies> <!--https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!--https://mvnrepository.com/artifact/cn.hutool/hutool-all --> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.1.0</version> </dependency> </dependencies> </project> 在 cloud-api-commons 项目下创建 entities 的 Payment 和 CommonResult 封装类

    使用maven 命名 clean 和 install 命令,把它存储到仓库里,方便其他的项目的复用。

    对订单80 和 支付8001 分别改造, 删除各自原有的entities 文件夹, 各自黏贴 POM内容 80、8001 <dependency> <groupId>这里根据自己设置来定</groupId>// com.oy 这是我自己的,不清楚查看一下自己的仓库 <artifactId>cloud-api-commons</artifactId> <version>${project.version}</version> </dependency>

    ② 目前项目样图

    Processed: 0.011, SQL: 8