【SpringCloud】SpringCloud基础教程(2)
前言:
本文内容:Rest学习环境搭建:服务提供者、服务消费者、Eureka:什么是Eureka
推荐免费SpringCloud基础教程视频:【狂神说Java】SpringCloud最新教程IDEA版_哔哩哔哩_bilibili
Rest学习环境搭建:服务提供者
环境搭建介绍
-
我们会使用
Dept
部门模板做一个微服务通用案例Consumer
消费者(Client
)通过Rest
调用Provider
提供者(Server
)提供的服务 -
巩固Spring,SpringMVC,Mybatis,Maven等知识
一个父工程带着多个子模块
MiCroServiceCloud父工程(Project)下带有3个子模块(Module)
- microservicecloud-api(封装的整体entity接口/公共配置等)
- microservicecloud-provider-dept-8001(服务提供者)
- microservicecloud-consumer-dept-80(服务消费者)
环境搭建
-
新建一个普通
Maven
项目springcloud
-
在
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
<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.jokerdig</groupId>
<artifactId>springcloud</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 打包方式-->
<packaging>pom</packaging>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<!-- 版本控制-->
<junit.version>4.13</junit.version>
<lombok.version>1.18.24</lombok.version>
<log4j.version>1.2.17</log4j.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- springcloud-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- springboot-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.3.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- 数据库+数据源-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.22</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.8</version>
</dependency>
<!-- springboot启动器-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
<!-- logback-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
<!-- log4j-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<!-- junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<!-- lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project> -
新建数据库
db01
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24create database db01;
use db01;
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
DROP TABLE IF EXISTS `dept`;
CREATE TABLE `dept` (
`deptno` bigint(0) NOT NULL AUTO_INCREMENT,
`dname` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`db_source` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
PRIMARY KEY (`deptno`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '部门表' ROW_FORMAT = Dynamic;
INSERT INTO `dept`(`dname`,`db_source`) VALUES ('开发部', DATABASE());
INSERT INTO `dept`(`dname`,`db_source`) VALUES ('生产部', DATABASE());
INSERT INTO `dept`(`dname`,`db_source`) VALUES ('研发部', DATABASE());
INSERT INTO `dept`(`dname`,`db_source`) VALUES ('人事部', DATABASE());
INSERT INTO `dept`(`dname`,`db_source`) VALUES ('运维部', DATABASE());
SET FOREIGN_KEY_CHECKS = 1; -
新建一个
Maven
的Module
,springcloud-api
-
在
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
<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.jokerdig</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>springcloud-api</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<!-- 当前module需要的依赖-->
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project> -
新建
com.jokerdig.springcloud.pojo
包,在包下新建Dept
实体类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
27package com.jokerdig.springcloud.pojo;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* @author Joker大雄
* @data 2022/8/3 - 10:16
**/
// 链式写法 安卓开发中有大量的链式写法
// 实体类序列化
public class Dept implements Serializable {
private Long deptno;// 主键
private String dname;
// 数据存在哪个数据库的字段 微服务,一个服务对应一个数据库
private String db_source;
public Dept(String dname) {
this.dname = dname;
}
} -
新建一个
Maven
的Module
,springcloud-provider-dept-8001
-
在
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
<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.jokerdig</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>springcloud-provider-dept-8001</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<!-- 需要实体类 配置api-->
<dependency>
<groupId>com.jokerdig</groupId>
<artifactId>springcloud-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<!-- 数据库+数据源-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
<!-- mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<!-- test-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!-- web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- jetty-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<!-- 热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
</project> -
resources
下新建mapper
文件夹,mybatis-config.xml
配置文件和application.yaml
配置文件application
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17server:
port: 8001
# mybatis配置
mybatis:
type-aliases-package: com.jokerdig.springcloud.pojo
config-location: classpath:mybatis/mybatis-config.xml
mapper-locations: classpath:mybatis/mapper/*.xml
# spring配置
spring:
application:
name: springcloud-provider-dept
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/db01?useSSL=true&serverTimezone=UTC
username: root
password: 123456mybatis-config
1
2
3
4
5
6
7
8
9
10
<configuration>
<settings>
<!-- 开启缓存-->
<setting name="cacheEnabled" value="true"/>
</settings>
</configuration> -
新建包
com.jokerdig.springcloud.mapper
,在包下新建DeptMapper
接口1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22package com.jokerdig.springcloud.mapper;
import com.jokerdig.springcloud.pojo.Dept;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* @author Joker大雄
* @data 2022/8/3 - 11:14
**/
public interface DeptMapper {
// 添加
public boolean addDept(Dept dept);
// 查询
public Dept queryById(Long id);
// 查询所有
public List<Dept> queryAll();
} -
在
resources/mybatis/mapper
下新建DeptMapper.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<mapper namespace="com.jokerdig.springcloud.mapper.DeptMapper">
<insert id="addDept" parameterType="Dept">
insert into db01.dept(dname,db_source) values(#{dname},DATABASE())
</insert>
<select id="queryById" parameterType="Long" resultType="Dept">
select * from db01.dept where deptno = #{deptno}
</select>
<select id="queryAll" resultType="Dept">
select * from db01.dept
</select>
</mapper> -
新建包
com.jokerdig.springcloud.service
,在包下新建DeptService
接口和DeptServiceImpl
实现类DeptService
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19package com.jokerdig.springcloud.service;
import com.jokerdig.springcloud.pojo.Dept;
import java.util.List;
/**
* @author Joker大雄
* @data 2022/8/3 - 11:23
**/
public interface DeptService {
// 添加
public boolean addDept(Dept dept);
// 查询
public Dept queryById(Long id);
// 查询所有
public List<Dept> queryAll();
}DeptServiceImpl
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
35package com.jokerdig.springcloud.mapper;
import com.jokerdig.springcloud.pojo.Dept;
import com.jokerdig.springcloud.service.DeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author Joker大雄
* @data 2022/8/3 - 11:24
**/
public class DeptServiceImpl implements DeptService {
DeptMapper deptMapper;
public boolean addDept(Dept dept) {
return deptMapper.addDept(dept);
}
public Dept queryById(Long id) {
return deptMapper.queryById(id);
}
public List<Dept> queryAll() {
return deptMapper.queryAll();
}
} -
新建包
com.jokerdig.springcloud.controller
,在包下新建DeptController
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
35package com.jokerdig.springcloud.controller;
import com.jokerdig.springcloud.pojo.Dept;
import com.jokerdig.springcloud.service.DeptService;
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.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* @author Joker大雄
* @data 2022/8/3 - 11:29
**/
// 提供Restful服务
public class DeptController {
private DeptService deptService;
public boolean addDept(Dept dept){
return deptService.addDept(dept);
}
public Dept get({ Long id)
return deptService.queryById(id);
}
public List<Dept> queryAll(){
return deptService.queryAll();
}
} -
在
springcloud
包下新建DeptProvider_8001
主启动类1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16package com.jokerdig.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author Joker大雄
* @data 2022/8/3 - 11:34
**/
// 启动类
public class DeptProvider_8001 {
public static void main(String[] args) {
SpringApplication.run(DeptProvider_8001.class,args);
}
} -
在右侧的
Maven
栏中父工程的Lifecycle
下运行clean
和install
-
运行主启动,在浏览器测试数据是否可以获取
1
[{"deptno":1,"dname":"开发部","db_source":"db01"},{"deptno":2,"dname":"生产部","db_source":"db01"},{"deptno":3,"dname":"研发部","db_source":"db01"},{"deptno":4,"dname":"人事部","db_source":"db01"},{"deptno":5,"dname":"运维部","db_source":"db01"}]
Rest学习环境搭建:服务消费者
-
新建一个
Maven
的Module
,springcloud-consumer-dept-80
-
在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
<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.jokerdig</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>springcloud-consumer-dept-80</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<!-- 实体类+web-->
<dependencies>
<dependency>
<groupId>com.jokerdig</groupId>
<artifactId>springcloud-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
</project> -
resources
下新建application.yaml
1
2server:
port: 80 -
在
com.jokerdig.springcloud.controller
包下新建DeptConsumerController
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
44package com.jokerdig.springcloud.controller;
import com.jokerdig.springcloud.pojo.Dept;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
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;
import java.util.List;
/**
* @author Joker大雄
* @data 2022/8/3 - 15:10
**/
public class DeptConsumerController {
// 消费者不会有service
// RestTemplate 供我们调用
// {url,实体:Map,Class<T> responseType}
private RestTemplate restTemplate; // 提供多种边界访问远程HTTP服务方法,简单的RestFul服务模板
private static final String REST_URL_PREFIX="http://localhost:8001";
// 添加
public boolean add(Dept dept){
return restTemplate.postForObject(REST_URL_PREFIX+"/dept/add/",dept,Boolean.class);
}
// 通过id查询
public Dept get({ Long id)
return restTemplate.getForObject(REST_URL_PREFIX+"/dept/get/"+id,Dept.class);
}
// 查询
public List<Dept> queryAll(){
return restTemplate.getForObject(REST_URL_PREFIX+"/dept/list",List.class);
}
} -
在
com.jokerdig.springcloud.config
包下新建ConfigBean
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18package com.jokerdig.springcloud.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/**
* @author Joker大雄
* @data 2022/8/3 - 15:14
**/
public class ConfigBean {
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
} -
在
springcloud
包下新建DeptConsumer_80
主启动类1
2
3
4
5
6
7
8
9
10
11
12
13
14
15package com.jokerdig.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author Joker大雄
* @data 2022/8/3 - 15:28
**/
public class DeptConsumer_80 {
public static void main(String[] args) {
SpringApplication.run(DeptConsumer_80.class,args);
}
} -
分别启动提供者和消费者的主启动类,进行测试
1
[{"deptno":1,"dname":"开发部","db_source":"db01"},{"deptno":2,"dname":"生产部","db_source":"db01"},{"deptno":3,"dname":"研发部","db_source":"db01"},{"deptno":4,"dname":"人事部","db_source":"db01"},{"deptno":5,"dname":"运维部","db_source":"db01"}]
Eureka:什么是Eureka
什么是Eureka
-
Eureka
[juˈriːkə]
-
Eureka是基于REST(Representational State Transfer)服务,主要以AWS云服务为支撑,提供服务发现并实现负载均衡和故障转移。称此服务为Eureka服务。
-
Netflix在设计Eureka时,遵循的时AP原则
原理讲解
-
Eureka的基本架构
- SpirngCloud封装了NetFlix公司开发的Eureka模块来实现服务注册和发现(类比zookeeper)
- Eureka采用C-S架构设计,EurekaServer作为服务注册功能的服务器,也是服务注册中心
- 而系统中的其他微服务,使用Eureka的客户端连接到EurekaServer并维持心跳链接,维护人员可以通过EurekaServer监控系统中各个微服务是否正常运行,例如Zuul可以通过EurekaServer来发现系统中其他微服务,并执行相关逻辑
- Eureka包含了两个组件:
Eureka Server
和Eureka Client
Eureka Server
提供服务注册与发现Eureka Client
是一个Java客户端,用于简化Eureka Server的交互
三大角色
- Eureka Server:提供服务注册与发现
- Eureka Providert:将自身服务注册到Eureka中,从而使消费方能够找到
- Service Consumer:服务消费方从Eureka中获取注册服务列表,从而找得到消费服务
整合Eureka
-
在父工程继续新建Module,
springcloud-eureka-7001
-
在
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
<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.jokerdig</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>springcloud-eureka-7001</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<!-- eureka-->
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<!-- 热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
</project> -
在
resources
下新建application.yaml
1
2
3
4
5
6
7
8
9
10
11
12server:
port: 7001
# eureka配置
eureka:
instance:
hostname: localhost #服务端实例名称
client:
register-with-eureka: false # 是否向eureka注册中心注册自己
fetch-registry: false # 如果为false 则表示自己为注册中心
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ -
新建
com.jokerdig.springcloud
包,在包下新建EurekaServer_7001
主启动类1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17package com.jokerdig.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
/**
* @author Joker大雄
* @data 2022/8/3 - 16:08
**/
// 开启EurekaServer
public class EurekaServer_7001 {
public static void main(String[] args) {
SpringApplication.run(EurekaServer_7001.class,args);
}
} -
运行测试