1 项目地址 笔记地址
项目地址:yangxiaozhuo/springcloud (github.com)
笔记博客地址:blog.yangxiaobai.top 或 杨小白の博客 - Dream big and dare to fail (yangxiaozhuo.github.io)
2 零基础微服务框架理论入门
2.1 什么是微服务
2.2 分布式微服务架构-落地维度
服务调用
服务降级
服务注册与发先
服务熔断
负载均衡
服务消息队列
服务网关
配置中心管理
自动化构建部署
服务监控
全链路追踪
服务定时任务
调度操作
2.3 SpringCloud 简介
SpringCloud=分布式微服务架构的站式解决方案,是多种微服务架构落地技术的集合体,俗称微服务全家桶
Spring Cloud中文网-官方文档中文版 包含的技术


SpringCloud主流的技术栈

技术与解决内容对应关系

3.Boot和Cloud版本选型
boot的版本命名用的数字,cloud用的字母表示

4.Cloud组件停更说明
服务注册中心
× Eureka(停更不停用)
√ Zookeeper (见dubbo笔记)
√ Consul
√ Nacos(重点,百万级注册并发)
服务调用
服务调用2
服务降级
× Hystrix
√ resilience4j
√ sentienl(重点)
服务网关
服务配置
服务总线
Spring Cloud中文文档(https://www.bookstack.cn/read/spring-cloud-docs/docs-translate.md)
5.父工程Project空间新建
约定>配置>编码
字符编码 - Settings - File encoding
注解生效激活 - Settings - Annotation Processors
Java编译版本选8
File Type过滤 - Settings - File Type
6父工程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 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
| <?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.yxz.springcloud</groupId> <artifactId>springcloud</artifactId> <version>1.0-SNAPSHOT</version> <packaging>pom</packaging>
<modules> <module>cloud-provider-payment8001</module> </modules>
<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>5.1.47</mysql.version> <druid.version>1.1.16</druid.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>2.2.2.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.SR1</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>2.1.0.RELEASE</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>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>${log4j.version}</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lombok.version}</version> <optional>true</optional> </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>
|
7 DependencyManagement和Dependencies
Maven使用dependencyManagement
元素来提供了一种管理依赖版本号的方式。
通常会在一个组织或者项目的最顶层的父POM中看到dependencyManagement
元素。
使用pom.xml中的dependencyManagement
元素能让所有在子项目中引用个依赖而不用显式的列出版本量。
Maven会沿着父子层次向上走,直到找到一个拥有dependencyManagement
元素的项目,然后它就会使用这个dependencyManagement
元素中指定的版本号。
这样做的好处就是:如果有多个子项目都引用同一样依赖,则可以避免在每个使用的子项目里都声明一个版本号,这样当想升级或切换到另一个版本时,只需要在顶层父容器里更新,而不需要一个一个子项目的修改;另外如果某个子项目需要另外的一个版本,只需要声明version就可。
dependencyManagement
里只是声明依赖,并不实现引入,因此子项目需要显示的声明需要用的依赖。
如果不在子项目中声明依赖,是不会从父项目中继承下来的;只有在子项目中写了该依赖项,并且没有指定具体版本,才会从父项目中继承该项,并且version和scope都读取自父pom。
如果子项目中指定了版本号,那么会使用子项目中指定的jar版本。
IDEA右侧旁的Maven插件有Toggle ' Skip Tests' Mode
按钮,这样maven可以跳过单元测试
父工程创建完成执行mvn : install
将父工程发布到仓库方便子工程继承。
8 支付模块构建(上)
创建微服务模块套路
建Module
改POM
写YML
主启动
业务类
1.建名为cloud-provider-payment8001的Maven工程
2.改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
| <?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>springcloud</artifactId> <groupId>com.yxz.springcloud</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>
|
3.改yml文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| server: port: 8001
spring: application: name: cloud-payment-service datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: org.gjt.mm.mysql.Driver url: jdbc:mysql://localhost:3306/db2019?useUnicode=true&characterEncoding=utf-8&useSSL=false username: root password: 123456
mybatis: mapperLocations: classpath:mapper/*.xml type-aliases-package: com.atguigu.springcloud.entities
logging: level: com : debug
|
4.主启动类
1 2 3 4 5 6 7 8 9 10 11 12
| package com.yxz.springcloud;
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication public class PaymentMain8001 { public static void main(String[] args) { SpringApplication.run(PaymentMain8001.class, args); } }
|
9支付模块构建(中)
建sql表
entities
dao
service
controller
1.sql语句
1 2 3 4 5 6 7 8
| use db2019; CREATE TABLE `payment` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', `serial` varchar(200) DEFAULT '', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
insert into payment value (31,"aaabbb01")
|
2.CommonResult返回类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| 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,message,null); } }
|
实体类Payment:
1 2 3 4 5 6 7 8 9 10 11 12 13
| 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; }
|
3.PaymentDao接口
1 2 3 4 5 6 7 8 9 10 11
| import com.yxz.springcloud.entities.Payment; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param;
@Mapper public interface PaymentDao { public int create(Payment payment);
public Payment getPaymentById(@Param("id") Long id); }
|
mybatis映射文件,路径为resources/mapper/PaymentMapper.xml
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
| <?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.yxz.springcloud.dao.PaymentDao">
<resultMap id="BaseResultMap" type="com.yxz.springcloud.entities.Payment"> <id property="id" column="id" jdbcType="BIGINT"/> <result property="serial" column="serial" jdbcType="VARCHAR"/> </resultMap>
<sql id="Base_Column_List"> id,serial </sql>
<!-- parameterType不写全类名会爆红,但是不影响使用--> <insert id="create" parameterType="com.yxz.springcloud.entities.Payment" useGeneratedKeys="true" keyProperty="id" > insert into payment(serial) values (#{serial}); </insert>
<select id="getPaymentById" parameterType="Long" resultMap="BaseResultMap"> select * from payment where id = #{id}; </select>
</mapper>
|
4.Service
PaymentService接口
1 2 3 4 5 6 7 8 9 10
| import com.yxz.springcloud.entities.Payment; import org.apache.ibatis.annotations.Param;
public interface PaymentService {
public int create(Payment payment);
public Payment getPaymentById(@Param("id") Long id); }
|
PaymentServiceImpl实现类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| import com.yxz.springcloud.dao.PaymentDao; import com.yxz.springcloud.entities.Payment; import com.yxz.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); } }
|
5.controller层 (这里我用来restful风格)
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
| import com.yxz.springcloud.entities.CommonResult; import com.yxz.springcloud.entities.Payment; import com.yxz.springcloud.service.impl.PaymentServiceImpl; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@Slf4j @RestController @RequestMapping("/payment") public class PaymentController {
@Resource private PaymentServiceImpl paymentService;
@PostMapping() 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("/{id}") public CommonResult getById(@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); } } }
|
10 支付模块构建(下)
postman测试


11. 开启热部署
(笔记本用户本人不建议开启)
1.添加依赖
1 2 3 4 5 6
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency>
|
2.添加插件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <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.设置
File -> Settings(New Project Settings->Settings for New Projects) ->Complier
下面项勾选
Automatically show first error in editor
Display notification on build completion
Build project automatically
Compile independent modules in parallel
键入Ctrl + Shift + Alt + / ,打开Registry,勾选:
12.消费者订单模块(上)
创建微服务模块套路
建Module
改POM
写YML
主启动
业务类
1. 建module
创建名为cloud-consumer-order80的maven工程。
2. 改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
| <?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>springcloud</artifactId> <groupId>com.yxz.springcloud</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>
|
3. 写yml
1 2 3 4 5 6
| server: port: 80
logging: level: com : debug
|
4.主启动类
1 2 3 4 5 6 7 8 9 10
| import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication public class MainApp80 { public static void main(String[] args) { SpringApplication.run(MainApp80.class, args); } }
|
5.业务类
5.1 实体类(复制payment工程的)
5.2controller
我这里使用了restful风格
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
| import com.yxz.springcloud.entities.CommonResult; import com.yxz.springcloud.entities.Payment; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate;
@RequestMapping("/consumer/payment") @RestController @Slf4j public class OrderController {
public static final String PAYMENT_URL = "http://localhost:8001";
@Autowired private RestTemplate restTemplate;
@GetMapping("/create") public CommonResult<Payment> create(Payment payment) { return restTemplate.postForObject(PAYMENT_URL + "/payment", payment, CommonResult.class); }
@GetMapping("/get/{id}") public CommonResult<Payment> getPayment(@PathVariable("id") Long id) { return restTemplate.getForObject(PAYMENT_URL + "/payment/"+id, CommonResult.class); } }
|
5.3 配置类
1 2 3 4 5 6 7 8 9 10 11 12 13
| import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate;
@Configuration public class ApplicationConfig {
@Bean public RestTemplate getRestTemplate() { return new RestTemplate(); } }
|
6.测试
localhost/consumer/payment/get/31

localhost/consumer/payment/create?serial=aaa

13消费者订单模块(下)
localhost/consumer/payment/create?serial=aaa
虽然返回成功,但是观测数据库中新加了一个null的值
这是因为在在loud-provider-payment8001工程的PaymentController
中没有添加@RequestBody
注解。
1 2 3 4 5
| public class PaymentController { @PostMapping() public CommonResult create(@RequestBody Payment payment) { ···· }
|
通过修改idea的workspace.xml的方式来快速打开Run Dashboard窗口
打开工程路径下的.idea文件夹的workspace.xml
在<component name="RunDashboard">
中修改或添加以下代码
重启idea
1 2 3 4 5 6
| <option name="configurationTypes"> <set> <option value="SpringBootApplicationConfigurationType"/> </set> </option>
|
14 工程重构
发现cloud-consumer-order80与cloud-provider-payment8001中都有重复的entities实体类,这样我们将公共部分(包括工具类等)抽离出来作为一个新的工程,其他微服务模块在pom模块中引用即可。
1.新建 - cloud-api-common
2.修改pom
导入了hutool-all工具包
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
| <?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>springcloud</artifactId> <groupId>com.yxz.springcloud</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>
|
3.移入entities
将cloud-consumer-order80和cloud-provider-payment8001的包移入cloud-api-commons工程下
4.maven clean、maven install
5. 改造80和8001
删除entities包
引入cloud-api-commons依赖
1 2 3 4 5
| <dependency> <groupId>com.yxz.springcloud</groupId> <artifactId>cloud-api-commons</artifactId> <version>${project.version}</version> </dependency>
|
6.测试
localhost/consumer/payment/get/31
http://localhost/consumer/payment/create?serial=bbb
没有问题
到此已经学习完cloud课程的13%内容,和前四章节的内容
