image-20230801103322932

img

Eureka

基础知识

什么是注册服务与发现?

  • consumer 买房的人
  • Eureka 房产服务中心 办理业 we
  • provider 房产商

image-20230801103637874

两个组件

  • server 科技园
  • client 科技园里的公司

image-20230801103944677

单机 Eureka 构建步骤

搭建服务

建 model

  • 名称: cloud-euraka-server7001

改 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
<dependencies>
<!--eureka-server-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<!-- 引入自己定义的api通用包,可以使用Payment支付Entity -->
<dependency>
<groupId>com.cyt.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</dependency>
<!--boot web actuator-->
<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>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>

写 yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
server:
port: 7001

eureka:
instance:
hostname: eureka7001.com #eureka服务端的实例名称
client:
register-with-eureka: false #false表示不向注册中心注册自己。
fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
service-url:
#集群指向其它eureka
#defaultZone: http://eureka7002.com:7002/eureka/
#单机就是7001自己
defaultZone: http://eureka7001.com:7001/eureka/
#server:
#关闭自我保护机制,保证不可用服务被及时踢除
#enable-self-preservation: false
#eviction-interval-timer-in-ms: 2000
1
2
3
4
5
6
7
8
9
10
11
server:
port: 7001

eureka:
instance:
hostname: localhost #eureka服务端的实例名称
client:
register-with-eureka: false #false表示不向注册中心注册自己。
fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

主启动

1
2
3
4
5
6
7
@SpringBootApplication
@EnableEurekaServer // 表示自己是Eureka服务中心
public class EurekaMain7001 {
public static void main(String[] args) {
SpringApplication.run(EurekaMain7001.class, args);
}
}

访问 7001

image-20230801105531291

单机注册 8001 服务

image-20230801105814828

改 pom

1
2
3
4
5
<!--eureka-client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

改 yml

1
2
3
4
5
6
7
8
eureka:
client:
# 表示自己是否注册进EurekaServer 默认为true
register-with-eureka: true
#是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetch-registry: true
service-url:
defaultZone: http://localhost:7001/eureka

主启动

1
2
3
4
5
6
7
@SpringBootApplication
@EnableEurekaClient // 注册EurekaClient
public class PaymentMain8001 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain8001.class, args);
}
}

启动测试

  • 启动 8001
  • 查看实例

image-20230801111228628

==集群环境构建==

  • 原理
  • 互相注册,相互守望

image-20230801112333557

搭建服务

建 model

  • cloud-euraka-server7002

改 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
<dependencies>
<!--eureka-server-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<!-- 引入自己定义的api通用包,可以使用Payment支付Entity -->
<dependency>
<groupId>com.cyt.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</dependency>
<!--boot web actuator-->
<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>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>

写 yml

  • 7002
1
2
3
4
5
6
7
8
9
10
11
12
13
14
server:
port: 7002

eureka:
instance:
hostname: eureka7002.com #eureka服务端的实例名称
client:
register-with-eureka: false #false表示不向注册中心注册自己。
fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
service-url:
#集群指向其它eureka
defaultZone: http://eureka7001.com:7001/eureka/
#单机就是自己
#defaultZone: http://eureka7002.com:7002/eureka/
  • 7001
1
2
3
4
5
6
7
8
9
10
11
12
13
server:
port: 7001

eureka:
instance:
hostname: eureka7001.com #eureka服务端的实例名称
# hostname: localhost #eureka服务端的实例名称
client:
register-with-eureka: false #false表示不向注册中心注册自己。
fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
service-url:
#集群指向其它eureka
defaultZone: http://eureka7002.com:7002/eureka/

修改映射配置

image-20230801113121983

1
2
3
4
######SpringCloud2023.8.1#########
127.0.0.1 eureka7001.com
127.0.0.1 eureka7002.com
127.0.0.1 eureka7003.com

启动测试

  • 2 指向 1

image-20230801114157975

注册微服务

改 yml

1
2
3
4
5
6
7
8
9
10
11
eureka:
client:
# 表示自己是否注册进EurekaServer 默认为true
register-with-eureka: true
#是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetch-registry: true
service-url:
#单机版
# defaultZone: http://localhost:7001/eureka
#集群版
defaultZone: http://eureka7001.com:7001/eureka, http://eureka7002.com:7002/eureka

支付微服务集群 8002

改 yml

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
server:
port: 8002

spring:
application:
name: cloud-payment-service
datasource:
type: com.alibaba.druid.pool.DruidDataSource # 当前数据源操作类型
driver-class-name: com.mysql.cj.jdbc.Driver # mysql驱动包
url: jdbc:mysql://localhost:3306/db2019?useUnicode=true&characterEncoding=utf-8&useSSL=false
username: root
password: cyt

eureka:
client:
# 表示自己是否注册进EurekaServer 默认为true
register-with-eureka: true
#是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetch-registry: true
service-url:
#单机版
# defaultZone: http://localhost:7001/eureka
#集群版
defaultZone: http://eureka7001.com:7001/eureka, http://eureka7002.com:7002/eureka

mybatis:
mapperLocations: classpath:mapper/*.xml
type-aliases-package: com.cyt.springcloud.entities # 所有Entity别名类所在包

==负载均衡==

  1. 修改 80 模块 controller访问支付模块地址
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class OrderController {
// public static final String PAYMENT_URL = "http://localhost:8001"; 单机版,写死
public static final String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE";

@Resource
private RestTemplate restTemplate;

@GetMapping("/consumer/payment/create")
public CommonResult<Payment> create(Payment payment) {
return restTemplate.postForObject(PAYMENT_URL + "/payment/create", payment, CommonResult.class);
}

@GetMapping("/consumer/payment/get/{id}")
public CommonResult<Payment> getPayment(@PathVariable("id") Long id) {
return restTemplate.getForObject(PAYMENT_URL + "/payment/get/" + id, CommonResult.class);
}
}
  1. 修改 config.ApplicationContextConfig
  • @LoadBalanced 注解
1
2
3
4
5
6
7
8
9
@Configuration
public class ApplicationContextConfig {

@Bean
@LoadBalanced // 赋予RestTemplate负载均衡能力
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}

actuator 微服务信息完善

主机名称:服务名称修改

改 yml

  • 改 8001 8002 服务 yml
1
2
3
eureka:
instance:
instance-id: payment8001
1
2
3
eureka:
instance:
instance-id: payment8002

对比

  • 修改前

image-20230801184943481

  • 修改后

image-20230801185014759

访问信息有 IP 信息提示

改 yml

1
2
3
eureka:
instance:
prefer-ip-address: true # 访问路径可以显示IP地址

对比

  • 修改后
  • 左下角

image-20230801185625441

服务发现 Discover

image-20230801224210265

添加 controller 映射路径

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// discovery配置信息对外暴露
@GetMapping(value = "/payment/discovery")
public Object discovery() {
List<String> services = discoveryClient.getServices();
for (String service : services) {
log.info("**discovery: {}", service);
}
log.info("*---------------*");
List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
for (ServiceInstance instance : instances) {
log.info(instance.getServiceId() + "\t" + instance.getHost()
+ "\t" + instance.getPort() + "\t" + instance.getUri());
}
return this.discoveryClient;
}

==@EnableDiscoveryClient==

  • 修改启动类
1
2
3
4
5
6
7
8
@SpringBootApplication
@EnableEurekaClient // 注册EurekaClient
@EnableDiscoveryClient // 允许服务发现
public class PaymentMain8001 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain8001.class, args);
}
}

Eureka 自我保护

故障现象

image-20230801232458717

导致原因

  • 作用:防止网络延时等问题误删调微服务实例

image-20230801233030494

image-20230801232903727

如何禁止自我保护

修改集群 7001

1
2
3
4
5
eureka:
server:
# 关闭自我保护机制,保证不可用服务被及时踢除
enable-self-preservation: false
eviction-interval-timer-in-ms: 2000

修改服务 8001

1
2
3
4
5
6
7
8
eureka:
instance:
instance-id: payment8001
prefer-ip-address: true # 访问路径可以显示IP地址
# Eureka客户端向服务端发送心跳时间间隔,单位为妙(默认30s)
lease-renewal-interval-in-seconds: 1 # 改为1s
#Eureka服务端在收到最后一次心跳后等待时间上限,单位为秒(默认是90秒),超时将别除服务
lease-expiration-duration-in-seconds: 2

Zoonkeeper

注册中心

image-20230802110148906

步骤

image-20230802175604925

建 model

  • cloud-provider-payment8004

改 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
<dependencies>
<!-- SpringBoot整合Web组件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency><!-- 引入自己定义的api通用包,可以使用Payment支付Entity -->
<groupId>com.cyt.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</dependency>
<!-- SpringBoot整合zookeeper客户端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
<!--先排除自带的zookeeper3.5.3-->
<exclusions>
<exclusion>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--添加zookeeper3.4.9版本-->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.9</version>
</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>

写 yml

1
2
3
4
5
6
7
8
9
10
server:
port: 8004

# 服务别名---注册zoonkeeper到注册中心
spring:
application:
name: cloud-provider-payment
cloud:
zookeeper:
connect-string: 139.186.5.203:2181

controller

1
2
3
4
5
6
7
8
9
10
11
12
@RestController
@SuppressWarnings({"all"})
@Slf4j
public class PaymentController {
@Value("${server.port}")
private String ServerPort;

@RequestMapping("/payment/zk")
public String paymentzk() {
return "springcloud with zoonkeeper: " + ServerPort + "\t" + UUID.randomUUID().toString();
}
}

测试

image-20230802175741233

consul

简介

image-20230815103841212

安装并运行

consul agent -dev

image-20230815104318351

服务提供者

建 module

  • cloud-providerconsul-payment8006

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
<dependencies>
<!-- 引入自己定义的api通用包,可以使用Payment支付Entity -->
<dependency>
<groupId>com.cyt.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</dependency>
<!--SpringCloud consul-server -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<!-- SpringBoot整合Web组件 -->
<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>
<!--日常通用jar包配置-->
<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>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>RELEASE</version>
<scope>test</scope>
</dependency>
</dependencies>

yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
###consul服务端口号
server:
port: 8006

spring:
application:
name: consul-provider-payment

####consul注册中心地址
cloud:
consul:
host: localhost
port: 8500
discovery:
#hostname: 127.0.0.1
service-name: ${spring.application.name}

启动类

1
2
3
4
5
6
7
@SpringBootApplication
@EnableDiscoveryClient
public class PaymentMain8006 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain8006.class, args);
}
}

业务类 controller

1
2
3
4
5
6
7
8
9
10
11
@RestController
@Slf4j
public class PaymentController {
@Value("${server.port}")
private String ServerPort;

@RequestMapping("/payment/consul")
public String paymentConsul() {
return "springcloud with consul: " + ServerPort + "\t" + UUID.randomUUID().toString();
}
}

测试

image-20230815110525872

服务消费者

建 module

  • cloud-consumerconsul-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
<dependencies>
<!--SpringCloud consul-server -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<!-- SpringBoot整合Web组件 -->
<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>
<!--日常通用jar包配置-->
<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>

yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
###consul服务端口号
server:
port: 80

spring:
application:
name: cloud-consumer-order
####consul注册中心地址
cloud:
consul:
host: localhost
port: 8500
discovery:
#hostname: 127.0.0.1
service-name: ${spring.application.name}

启动类

1
2
3
4
5
6
7
8
@SpringBootApplication
@EnableDiscoveryClient
public class OrderConsulMain80 {
public static void main(String[] args) {
SpringApplication.run(OrderConsulMain80.class, args);
}

}

配置 bean

1
2
3
4
5
6
7
8
9
@Configuration
public class ApplicationContextConfig {

@Bean
@LoadBalanced // 赋予RestTemplate负载均衡能力
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}

controller

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@SuppressWarnings({"all"})
@RestController
@Slf4j
public class OrderConsulController {
// public static final String PAYMENT_URL = "http://localhost:8001"; 单机版,写死
public static final String INVOKE_URL = "http://consul-provider-payment";

@Resource
private RestTemplate restTemplate;

@GetMapping("/consumer/payment/consul")
public String paymentInfo() {
String res = restTemplate.getForObject(INVOKE_URL + "/payment/consul", String.class);
return res;
}
}

测试

image-20230815112105792

访问测试地址

image-20230815112059407

三个注册中心异同点

image-20230815113159811

cap

  • 分布式 p 一定保证

image-20230815112637710

image-20230815113003408