文章目录
- 1.首先在**SpringCloud官网**中查看依赖版本号
- 2.创建主Maven项目:
- 在pom文件中引入依赖
- 3.再在这个Maven项目中创建子模块(子模块也是Maven)
- (1)创建一个数据库db01和表dept
- (2)创建实体类dept(注意:**每个实体类都要进行序列化**【实现Serializable接口】)
- (3)创建服务提供者:
- (4)创建服务消费者:
- (5)创建eureka服务注册中心
- (6)对服务提供者进行Eureka配置
- 自我保护机制:
- (7)建立Eureka集群
SpringCloud官网
SpringCloud中文文档
Maven依赖仓库
1.首先在SpringCloud官网中查看依赖版本号
查看对应的SpringBoot版本号。
(SpringCloud依赖于SpringBoot,所以一个SpringCloud项目必须引入SpringBoot)
2.创建主Maven项目:
在pom文件中引入依赖
<!-- 统一管理jar包版本 -->
<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>
<!-- 子模块继承之后,提供作用:锁定版本+子modlue不用写groupId和version -->
<dependencyManagement>
<dependencies>
<!--spring boot 2.3.2-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.3.2.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--spring cloud Hoxton.SR1-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR11</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>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>
<!--SpringBoot启动器-->
<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>
3.再在这个Maven项目中创建子模块(子模块也是Maven)
三个子模块:
(1)创建一个数据库db01和表dept
(2)创建实体类dept(注意:每个实体类都要进行序列化【实现Serializable接口】)
什么是链式写法:
//正常情况下:
Dept dept=new Dept();
dept.setDeptno(1);
dept.setDeptname("11");
//链式写法:
dept.setDeptno(1).setDeptname("11");
Dept类
@Data
@NoArgsConstructor
@Accessors(chain = true) //链式写法
public class Dept implements Serializable {
/**
* 主键
*/
private Long deptno;
private String deptname;
/**
* 这个数据存在哪个数据库的字段中
* 微服务 一个服务对应一个数据库
* 同一个信息可能存在不同的数据库中
*/
private String db_source;
public Dept(String deptname) {
this.deptname = deptname;
}
}
pom文件:
<artifactId>springcloud-api</artifactId>
<!--当前的module自己需要的依赖,如果父依赖中已经配置了,则不需要再写了-->
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
(3)创建服务提供者:
pom文件:
<dependencies>
<!--需要拿到实体类,所以要配置api module-->
<dependency>
<groupId>com.atguigu.springcloud</groupId>
<artifactId>springcloud-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--druid-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
</dependency>
<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>
application.yml配置文件:
server:
port: 8001
mybatis:
type-aliases-package: com.springcloud.pojo
mapper-locations: classpath:mybatis/mapper/*.xml
config-location: classpath:mybatis/mybatis-config.xml
spring:
datasource:
url: jdbc:mysql://localhost:3306/db01?useUnicode=true&characterEncoding=UTF-8&useSSL=false
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--<settings>-->
<!--<setting name="cacheEnabled" value="true"/>-->
<!--</settings>-->
</configuration>
DeptMapper.xml
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.springcloud.dao.DeptDao">
<insert id="addDept" parameterType="Dept">
insert into dept (deptname,db_source)
values (#{deptname},DATABASE())
</insert>
<select id="findById" resultType="Dept" parameterType="Long">
select * from dept where deptno=#{id};
</select>
<select id="findAll" resultType="Dept" >
select * from dept;
</select>
</mapper>
DeptController
@RestController
public class DeptController {
@Autowired
private DeptService deptService;
@PostMapping("/dept/add")
public boolean addDept(Dept dept){
return deptService.addDept(dept);
}
@GetMapping("/dept/get/{id}")
public Dept get(@PathVariable("id") Long id){
return deptService.findById(id);
}
@GetMapping("/dept/list")
public List<Dept> getAll(){
return deptService.findAll();
}
}
dao、service省略…
启动类:
@SpringBootApplication
public class DeptProvide_8001 {
public static void main(String[] args) {
SpringApplication.run(DeptProvide_8001.class,args);
}
}
(4)创建服务消费者:
消费者没有service层
pom文件:
<!--实体类外部-->
<dependencies>
<dependency>
<groupId>com.atguigu.springcloud</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>
DeptConsumerController:
@RestController
public class DeptConsumerController {
//消费者 没有Service层
//RestTemplate....供我们直接调用 注册到Spring中
// url,实体:Map,Class<T> responseType
@Autowired
private RestTemplate restTemplate;//提供多种便携访问远程http服务的方法,简单的Restful服务模板
private static final String REST_URL_PREFIX="http://localhost:8001";
@RequestMapping("/consumer/dept/get/{id}")
public Dept get(@PathVariable("id") Long id){
return restTemplate.getForObject(REST_URL_PREFIX+"/dept/get/"+id,Dept.class);
}
@RequestMapping("/consumer/dept/add")
public boolean add(Dept dept){
return restTemplate.postForObject(REST_URL_PREFIX+"/dept/add",dept,Boolean.class);
}
@RequestMapping("/consumer/dept/list")
public List<Dept> findAll(){
return restTemplate.getForObject(REST_URL_PREFIX+"/dept/list",List.class);
}
}
ConfigBean:
@Configuration
public class ConfigBean {
@Bean
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
启动类:
@SpringBootApplication
public class DeptConsumer_80 {
public static void main(String[] args) {
SpringApplication.run(DeptConsumer_80.class,args);
}
}
application.yml文件:
server:
port: 80
(5)创建eureka服务注册中心
Eureka:
Eureka是Netflix的一个子模块,Eureka是基于Rest的服务,它是一个注册中心(让服务在启动时注册进去)
Eureka是C-S模式(Client-Server)
它有两个组件,一个是Eureka Client,一个是Eureka Server
Eureka Server:提供服务发现的能力,各个微服务启动时,会通过Eureka Client向Eureka Server进行注册自己的信息(例如网络信息),Eureka Server会存储该服务的信息。
Eureka Client:是一个Java客户端,用于简化与Eureka Server的交互。
微服务启动后,会周期性地向Eureka Server发送心跳(默认周期为30秒)以续约自己的信息。如果Eureka Server在一定时间内没有接收到某个微服务节点的心跳,Eureka Server将会注销该微服务节点(默认90秒)
pom文件:
<artifactId>springcloud-eureka-7001</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
application.yml配置类
server:
port: 7001
eureka:
instance:
hostname: localhost #Eureka服务端的实例名称
client:
register-with-eureka: false #表示是否向eureka注册中心注册自己
fetch-registry: false #false表示自己为注册中心
service-url: #监控页面
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
启动类:
@SpringBootApplication
@EnableEurekaServer //服务端的启动类
public class EurekaServer_7001 {
public static void main(String[] args) {
SpringApplication.run(EurekaServer_7001.class,args);
}
}
注意:
SpringBoot、SpringCloud、eureka的版本号要对应
我使用的版本号分别是
SpringBoot:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.3.2.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
SpringCloud:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR11</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Eureka:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
然后浏览器访问 http://localhost:7001/ 会显示:
(6)对服务提供者进行Eureka配置
在springcloud-provider-dept-8001模块中:
在pom文件中导入eureka依赖:
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
修改application.yml配置文件
spring:
datasource:
url: jdbc:mysql://localhost:3306/db01?useUnicode=true&characterEncoding=UTF-8&useSSL=false
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
application:
name: springcloud-provider-dept
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/
instance:
instance-id: springcloud-provider-dept-8001 #修改eureka上默认描述信息
在启动类上添加注解@EnableEurekaClient
@SpringBootApplication
@EnableEurekaClient //在服务器启动后自动注册到eureka中
public class DeptProvide_8001 {
public static void main(String[] args) {
SpringApplication.run(DeptProvide_8001.class,args);
}
}
先启动EurekaServer,也就是eureka-7001模块
再启动EurekaClient,也就是springcloud-provider-dept-8001模块
然后访问http://localhost:7001/
过一段时间会出现警告:
这是Eureka的自我保护机制。
自我保护机制:
某时刻某个微服务不可用了,Eureka不会立刻清理,依旧会对微服务的信息进行保存。
默认情况下,如果Eureka Server在一定时间内(默认90秒)没有接收到某个微服务实例的心跳,Eureka Server将会移除该实例。但是当网络分区故障发生时,微服务与Eureka Server之间无法正常通信,而微服务本身是正常运行的,此时不应该移除这个微服务,所以引入了自我保护机制。
Eureka Server自动进入自我保护机制,此时会出现以下几种情况:
1、Eureka Server不再从注册列表中移除因为长时间没收到心跳而应该过期的服务。
2、Eureka Server仍然能够接受新服务的注册和查询请求,但是不会被同步到其它节点上,保证当前节点依然可用。
3、当网络稳定时,当前Eureka Server新的注册信息会被同步到其它节点中。
关闭自我保护机制:
在application.yml配置文件中:
可以关闭自我保护机制,但是不推荐关闭
server:
enable-self-preservation: false #关闭自我保护机制(不推荐关闭)
监控信息的完善:
在springcloud-provider-dept-8001模块pom文件中导入依赖:
<!--完善监控信息-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
在application.yml文件中进行配置:
info:
app.name: zsy-springcloud
company.name: blog.zzz.com
跳转结果:
获取注册微服务的一些信息:
在springcloud-provider-dept-8001模块中:
DeptController:
//获取一些配置的信息,得到具体的微服务
@Autowired
private DiscoveryClient discoveryClient;
//注册进来的微服务 获取一些消息
@GetMapping(value = "/dept/discovery")
public Object discovery(){
// 获取微服务列表的清单
List<String> service=discoveryClient.getServices();
System.out.println("discovery=>services:"+service);
// 得到一个具体的微服务信息
List<ServiceInstance> instances=discoveryClient.getInstances("SPRINGCLOUD-PROVIDER-DEPT");
for(ServiceInstance instance:instances){
System.out.println(
instance.getHost()+"\t"+
instance.getPort()+"\t"+
instance.getUri()+"\t"+
instance.getServiceId()
);
}
return this.discoveryClient;
}
访问这个接口:
(7)建立Eureka集群
这三个模块的各种配置都相同(pom文件、application.yml、启动类)
修改hosts文件:
修改application.yml文件:
7001:
defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
7002:
7003:
同时启动7001,7002,7003
这样就相当于建立了一个Eureka集群
作用:例如7001崩了,可以使用7002/7003
修改服务提供者application.yml文件
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/