博客参考学习视频: 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.父工程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
| <?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>
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring.boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring.cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> <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 文件**
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
| <?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>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency>
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency>
<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>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> </project>
|
- 写 YML
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 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
|
注意
:有可能在编译时会出现以下的异常
The server time zone value ‘�й���ʱ��’ is unrecogni
需要在配置文件中的 datasource.url 后面添加上 serverTimezone=UTC
1
| url: jdbc:mysql://localhost:3306/db2019?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
|
- 主启动类
1 2 3 4 5 6
| @SpringBootApplication public class PaymentMain8001 { public static void main(String[] args) { SpringApplication.run(PaymentMain8001.class, args); } }
|
- 业务类
1 2 3 4 5 6 7 8 9
| 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;
|
主实体 Payment
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| package com.oy.springcloud.entities;
import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;
import java.io.Serializable;
@Data @AllArgsConstructor @NoArgsConstructor public class Payment implements Serializable { private Long id; private String serial; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| package com.oy.springcloud.entities;
import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;
@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; } }
|
1 2 3 4 5 6
| @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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <?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"> <insert id="create" parameterType="Payment" useGeneratedKeys="true" keyProperty="id"> insert into payment(serial) values(#{serial}) </insert>
<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>
|
接口类 PaymentService
1 2 3 4 5 6 7 8 9 10 11
| 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); }
|
实体类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| 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 private PaymentDao paymentDao;
@Override public int create(Payment payment){ return paymentDao.create(payment); }
@Override public Payment getPaymentById(Long id){ return paymentDao.getPaymentById(id); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| @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); } } }
|
通过修改 idea 的 workpace.xml 的方式来快速打开 Run DashBoard 窗口 开启 Run DashBoard(个别版本需要)
1 2 3 4 5
| <option name="configurationTypes"> <set> <option value="SpringBootApplicationConfigurationType" /> </set> </option>
|
注意
:部分同学可能由于 idea 版本不同, 需要关闭重启
- Adding devtools to your project
1 2 3 4 5 6 7
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency>
|
- Adding plugin to your pom.xml
1 2 3 4 5 6 7 8 9 10 11 12 13
| // 下面这一段粘贴在父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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| <?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>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
<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>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> </project>
|
- 写 YML
- 主启动
1 2 3 4 5 6 7 8 9 10 11
| 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 配置类
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 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) 工程重构
观察问题:系统中有重复的部分
重构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| <?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> <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> <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
1 2 3 4 5
| <dependency> <groupId>这里根据自己设置来定</groupId>// com.oy 这是我自己的,不清楚查看一下自己的仓库 <artifactId>cloud-api-commons</artifactId> <version>${project.version}</version> </dependency>
|
② 目前项目样图