Spring Cloud Eureka-学习笔记
Spring Cloud
微服务概念
微服务组件示意图
核心问题
- 服务很多客户端怎么访问
- 这么多服务如何通信
- 如何治理
- 服务崩溃怎么解决
注册中心
介绍
介你麻痹
学习顺序
CAP原则
A 可用性、C 一致性、P 分布式
Availability 可用性
Partition-Tolerance 分区容错性
Consistency 一致性
CP 效率低(牺牲可用性)
AP 牺牲一致性 (有脏数据)
CA 牺牲横向可扩容
对比
Eureka
架构原理
- 注册中心 Eureka Server
- 之间相互同步 Replicate
- 应用服务
- 注册 Registry
- 定时心跳机制 Renew
- 下线 Cancel
- 获取其他微服务信息 Get Registry
- 客户端服务 Client
- Get Registry
- Make Remote Call
角色
- Server 注册中心
- Service Provider 服务提供者
- 注册、重新注册、清除 Register/Renew/Cancel
- Servcie Consumer 服务消费者
- 负载均衡的调用 Remote Call
- 拉取服务地址 Get Registery
调用顺序
搭建入门
需求
查看spring cloud要求的环境版本 https://spring.io/projects/spring-cloud#learn
官方提到需要的spring Boot版本是
Supported Boot Version: 2.4.6
查看spring boot最新版本 “https://spring.io/projects/spring-boot#learn"
查看spring boot 的需求 https://docs.spring.io/spring-boot/docs/current/reference/html/
https://docs.spring.io/spring-boot/docs/current/reference/html/getting-started.html#getting-started
- Maven 3.5+
- JDK 8+
- Tomcat 9.0+
搭建文档要到官方照xml
从官方找到maven依赖
建立eureka demo项目和eureka server 模块
参考文档:
spring eureka:https://docs.spring.io/spring-cloud-netflix/docs/current/reference/html/
maven :https://mvnrepository.com/search?q=spring+cloud+eureka+netflix
demo maven pom.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
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
<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>org.akachi</groupId>
<artifactId>eurekademo</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>server</module>
</modules>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<spring.cloud-version>Hoxton.SR8</spring.cloud-version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.5</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>eureka server pom.xml
创建一个基础eureka demo 的server 选择spring boot Web 、 Spring Cloud starter eureka server
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
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.akachi</groupId>
<artifactId>eurekademo</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>com.example</groupId>
<artifactId>server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>server</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
<spring-cloud.version>2020.0.4</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</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>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>application.yml 配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24server:
port: ${SERVICE_PORT:8761}
spring:
jpa:
database-platform: org.hibernate.dialect.MySQL8Dialect
show-sql: true
hibernate:
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
application:
name: eurekademo-server
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 123456
url: jdbc:mysql://localhost:4306/eurekademo
eureka:
instance:
hostname: localhost
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/参考资料:https://docs.spring.io/spring-cloud-netflix/docs/3.0.3/reference/html/#netflix-eureka-client-starter
单节点环境下 register-with-eureka: false
fetch-registry: false
自己不要给自己注册。会报错
通过
http://${eureka.instance.hostname}:${server.port}/eureka/
能够访问到eureka
需要在EurekaServerApplication类头上添加一个注解 @EanbleEurekaServer
看到这个界面入门案例久搭建成功了
搭建集群版的注册中心
要注意我再这里用了Run/Debug Configuration 来启动多个相互注册的eureka而不是建立多个项目。
需要服务注册中心相互注册所以需要从新配置
18761>18762>18763
修改内容包含
1 | register-with-eureka: true # 将自己注册到注册中心 默认 true |
yml
1 | server: |
ip+端口作为名字注册
加入配置
1 | eureka: |
也可以无视继续使用
开发一个 provider
- pom.xml
1 |
|
- yml
1 | server: |
- 开发一个商品接口
问题:
- 不是所有的eureka集群上都有服务
- eureka会出现自我保护机制的红字
eureka的保护机制
eureka是通过renew、心跳包进行连接的。
90秒也就是3次没有收到心跳包就会剔除掉微服务。
eureka有可能会怀疑自己的网络出现故障,会提示自己可能出现网络问题。
就是说在所有服务中有25%的服务无法连接eureka就会认为可能是自己网络出现问题。需要我们去手动排查网络并且,他会保留微服务。
可以在配置文件中关闭自我保护
1 | eureka: |
开发一个 consumer
yml
1 | server: |
大体配置与product相同,注意
1 | eureka: |
编写代码调用远程接口
编写远程调用代码
1 | package org.akachi.eurekademo.order.controller; |
问题:
注入RestTemplate not found
1
2
3
4
public RestTemplate restTemplate() {
return new RestTemplate();
}通过创建rest
LoadBalancerClient 负载均衡器
1 |
|
@LoadBalancer 负载均衡
通过注解负载均衡
1 | private void getProductsByLoadBalancerRestTemplate(OrderDto order) { |
可以直接通过服务名负载均衡调用
优雅停服
在product 添加actuator依赖
1
2
3
4
5<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>2.5.5</version>
</dependency>查看是否成功
1
http://localhost:18180/actuator
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16{
"_links": {
"self": {
"href": "http://localhost:18180/actuator",
"templated": false
},
"health": {
"href": "http://localhost:18180/actuator/health",
"templated": false
},
"health-path": {
"href": "http://localhost:18180/actuator/health/{*path}",
"templated": true
}
}
}在配置文件中打開 shutdown端点
1
2
3
4
5
6
7
8management:
endpoints:
web:
exposure:
include: shutdown
endpoint:
shutdown:
enabled: true打開shutdown请求后就可以通过访问服务请求下线服务
http://localhost:18180/actuator/shutdown
亲求后服务会被优雅停止
1
2
3{
"message": "Shutting down, bye..."
}
安全
配置maven
在所有相关节点中加入
在 eureka server中的pom.xml中加入
1
2
3
4
5<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>2.5.5</version>
</dependency>在eureka server中application.yml加入
1
2
3
4
5spring:
security:
user:
name: root
password: 123456在所有需要連接的節點中加入 root:123456@
1
2
3server:
client:
defaultZone: http://root:123456@${eureka.server.hostname}:${eureka.server.port}/eureka/加入账号名与密码
过滤CSRF服务
禁用防御机制
添加一個WebSecurityConfig
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18package org.akachi.server.config;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
/**
* @Author akachi
* @Email zsts@hotmail.com
* @Date 2021/10/21 15:14
*/
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
protected void config(HttpSecurity http) throws Exception{
super.configure(http);
http.csrf().ignoringAntMatchers("/eureka/**");
}
}如果修改完之服務重啓能夠正常访问那感谢
Ribbon负载均衡
什么是Ribbon
ribbon不是需要独立部署的微服务。几乎所有的微服务都需要用到ribbon。
Ribbon提供了微服务的负载均衡。
负载均衡的不同方案区别
集中式
进程式
Ribbon负载均衡策略
轮询
RoundRobinRule
响应时间权重策略
WegihtedResponseTimeRule
响应时间越小轮询到的可次数越少
随机
RandomRule
最少并发数
BestAvailableRule
选择正在请求中的并发数最小的provider,除非这个provider在熔断。
重试策略
RetryRule
首先轮询、如果不可用再替换其他服务。
可用性敏感策略
AvailabilityFilteringRule
过滤掉不可用的provider或者过滤掉比较忙的
区域敏感性策略
ZoneAvoidanceRule
以区域为考察的可用性敏感策略
入门案例
如果想要方便的一次性启动一堆服务可以通过这里
- 启动多个Product port 分别为18181,18182,18183
- 返回端口来判断访问的是谁
- 直接调用/order/list 查看返回是否是轮询
设置负载均衡策略
添加maven cloud 2.5.5 中默认不包含
pom.xml
1
2
3
4
5
6
7
8
9
10<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-ribbon</artifactId>
<version>2.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>com.netflix.ribbon</groupId>
<artifactId>ribbon-loadbalancer</artifactId>
<version>2.3.0</version>
</dependency>在OrderApplication中加入代码
1
2
3
4
public RandomRule randomRule(){
return new RandomRule();
}org.akachi.config.LoadBalanced.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24package org.akachi.config;
import com.netflix.loadbalancer.IRule;
import org.akachi.eurekademo.order.config.TestRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @Author akachi
* @Email zsts@hotmail.com
* @Date 2021/10/22 0:19
*/
public class LoadBalanced {
public IRule ribbonRule() {
// return new RoundRobinRule(); //轮询
// return new WeightedResponseTimeRule(); //加权权重
// return new RetryRule(); //带有重试机制的轮训
// return new RandomRule(); //随机
return new TestRule(); //自定义规则
}
}
设置某个微服务的负载均衡策略
失败了下次再试
点对点直连
删除pom.xml引用 spring-cloud-starter-netflix-eureka-client
添加pom.xml引用spring-cloud-starter-netflix-ribbon
注释application.yml中的eureka相关内容
增加相关配置
1
2
3
4
5
6
7eurekademo-service-product: #服务名称(注意大小写) restTemplate.exchange
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #随机策略
listOfServers: http://localhost:18182,http://localhost:18181,http://localhost:18180
ribbon:
eureka:
enable: false