springcloud之eureka集群

简介:springcloud微服务架构的笔记。第一章,使用Eureka微服务发现与注册测试。

环境版本:

maven:3.6.3

jdk:1.8.0_151

Eureka简介:

Eureka是Netflix(网飞公司)开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。SpringCloud将它集成在其子项目spring-cloud-netflix中,以实现SpringCloud的服务发现功能。

Eureka包含两个组件:Eureka Server和Eureka Client。

Eureka Server提供服务注册服务,各个节点启动后,会在Eureka Server中进行注册,这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到。

Eureka Client是一个java客户端,用于简化与Eureka Server的交互,客户端同时也就是一个内置的、使用轮询(round-robin)负载算法的负载均衡器。

项目结构:

项目简介:

  • cloud-api-commons主要是抽离出实体类,后期方便各模块进行调用。减少代码的冗余。
  • cloud-provider-payment8001cloud-provider-payment8002作为微服务的提供者。
  • cloud-consumer-order80作为微服务的消费者。
  • cloud-eureka-server7001cloud-eureka-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
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
<modules>
<module>cloud-api-commons</module>
<module>cloud-provider-payment8001</module>
<module>cloud-provider-payment8002</module>
<module>cloud-consumer-order80</module>
<module>cloud-eureka-server7001</module>
<module>cloud-eureka-server7002</module>
</modules>

<!-- 统一管理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.2.2-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.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.SR1</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>
<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>
<version>2.2.2.RELEASE</version>
<configuration>
<fork>true</fork>
<addResources>true</addResources>
</configuration>
</plugin>
</plugins>
</build>

公用api模块:

后面各模块引用时记得在他们的pom中加入依赖:

1
2
3
4
5
<dependency>
<groupId>org.example</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</dependency>

服务提供者模块:

分为3层,dao/service/controller层,记得写接口是一个好习惯。。。

这三层的代码没有特别之处。主启动类上记得加上:

1
@EnableEurekaClient  //表示该主启动类作为eureka的client进行注册

pom主要是:

1
2
3
4
5
6
7
8
9
10
11
<!-- eureka-client客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--实体类的api公用依赖-->
<dependency>
<groupId>org.example</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</dependency>

这里主要介绍配置文件的写法:

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: 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&serverTimezone=UTC
username: root
password: root
druid:
validation-query: select 1
test-while-idle: true


mybatis:
mapperLocations: classpath:mapper/*.xml
type-aliases-package: com.aaron.springcloud.entities

eureka:
client:
register-with-eureka: true #表示是否将自己注册进eureka
fetch-registry: true # 表示自己端不是注册中心
service-url:
defaultZone: http://localhost:7001/eureka,http://localhost:7002/eureka #集群版
# defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka #集群版,配置本地host映射

两个服务提供者可以在eureka中注册一样的服务名,因为后期order模块可以使用常量写死。方便做负载均衡。

服务消费者模块:

自写配置类,做一个负载均衡,这也是eureka自带的:

1
2
3
4
5
6
7
8
@Configuration
public class ApplicationContextConfig {
@Bean
@LoadBalanced
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}

服务消费者的重点在于controller模块:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@RestController
@Slf4j
public class OrderController {
public static final String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE"; //这个就是eureka注册里面的大写

@Autowired
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);
}
}

可以看到将服务提供者一侧的url写死,这里就是其在eureka中注册的名,全大写。使用RestTemplate进行调用。

Eureka模块:

首先主启动类的注解:@EnableEurekaServer注意!!!

主要在yml配置文件处:

1
2
3
4
5
6
7
8
9
10
11
12
server:
port: 7001

eureka:
instance:
hostname: eureka7001.com #eureka服务端的实例名称
client:
register-with-eureka: false #表示不向注册中心注册自己
fetch-registry: false #false表示自己端就是注册中心
#设置与eureka server交互地址,查询服务和注册服务都需要依赖该地址,这里写依赖的兄弟server主机
service-url:
defaultZone: http://localhost:7002/eureka/ # 集群版就是指向其他的主机

项目至此大致介绍了各模块的重点,但是其中的细节问题可能需要自己去摸索。项目的启动顺序也需要注意下:依次启动eureka,payment模块,order模块。

测试时可以看到实现了eureka自带的轮询负载。

补充:

Eureka的web界面修饰:

修改主机名和显示服务主机IP在配置文件中配置即可。

1
2
3
#  instance:
# instance-id: payment8001 # 修改服务主机名
# prefer-ip-address: true # 显示服务主机IP地址

主要修改的是如下的信息:

服务发现discovery:

对于注册进eureka里面的微服务,可以通过服务发现来获得该服务的信息。

使用方法主要是一个注解和一个注解标签:

1
2
@Resource
privet DiscoveryClient discoverClient;

还需要在主启动类上添加:@EnableDiscoveryClient

Eureka自我保护:

也就是服务界面的这句话:

自我保护简介:

1
2
3
4
Eureka的自我保护机制用最通俗的语言说就是:好死不如赖活着。
长时间没有访问、检测不到心跳,或者修改实例名称,eureka启动自我保护机制.即:某一个时刻,某一个微服务不可用了,eureka不会立即清理,依旧会对该微服务的信息进行保存.

一句话:某时刻某一个微服不可用了,eureka不会立刻清理,依旧会对改微服的信息进行保存。

关闭这个很简单,配置里添加:

1
2
server: 
enable-self-preservation: false

也可以设置eureka心跳检测与续约时间.

  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!

请我喝杯咖啡吧~

支付宝
微信