Spring Cloud Eureka

简单的微服务架构

简单的微服务架构图中最中间的就是服务注册与发现,与之对应的就是Spring Cloud Eureka 是基于Netflix Eureka做了二次封装,由Eureka Server 注册中心和Eureka Client服务注册组成。

Eureka 两个组件:

  • Eureka Server 注册中心(供服务注册的服务器,维持Eureka Client的心跳连接,监控系统中各个微服务的监控状态)
  • Eureka Client 服务注册(简化与服务器的交互,作为轮询负载均衡器,并提供故障切换支持)

Eureka Server 注册中心

注册中心好比老师手中的点名册,上面记录了班上所有同学的名字,在它点名的时候就掏出名单。到了微服务这注册中心也是类似的,它记录着这里所有应用的信息和状态,应用名称、在哪台服务器上、目前是不是正常工作….

IDEA构建Eureka服务端项目

IDEA新建项目

选择 Spring Initializr ,这里如果网络不好可能不能跳到下一步,这个时候需要科学上网或者设置代理
IDEA新建项目

Discovery

选择Cloud Discovery这一栏 选择右侧Eureka Server,上面可以选择Spring Boot版本
Cloud Discovery

项目结构

EurekaApplication类作为项目启动类,resources目录是项目的配置文件目录,application.properties项目的配置文件可以修改成yml文件,pom.xml是maven的配置文件
项目结构

选择依赖版本

打开网站spring
spring.io
选择PROJECTS,找到项目Spring Cloud点击打开
Spring Cloud
拉到网站下方找到Spring Cloud版本参照表,第一行是Spring Cloud对应版本,其它集成相关的主项目版本。因为我们用的Spring Boot版本是2.0.2.RELEASE,所以我们在其他依赖选择也要对应相对的版本,以下标红的依赖版本作为项目的开发依赖版本。
Release train contents

maven依赖管理

选择依赖版本中我们找到了各个依赖项目所需要的版本,现在在pom.xml文件中做版本控制,在properties标签中新增spring-cloud-netflix.version标签,写入相应版本2.0.0.RC2,在spring-cloud.version标签处修改Spring Cloud版本为Finchley.BUILD-SNAPSHOT,把spring-cloud-starter-netflix-eureka-server都bamboo修改成Netflix的版本。

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
<?xml version="1.0" encoding="UTF-8"?>
<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.wenqi</groupId>
<artifactId>eureka</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>eureka</name>
<description>Demo project for Spring Boot</description>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<!--修改spring cloud的版本-->
<spring-cloud.version>Finchley.BUILD-SNAPSHOT</spring-cloud.version>
<!--新增netflix版本-->
<spring-cloud-netflix.version>2.0.0.RC2</spring-cloud-netflix.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
<!--添加version标签,写入Netflix的版本-->
<version>${spring-cloud-netflix.version}</version>
</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>

<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>


</project>

启动项目

IDEA右上角点击启动项目,发现控制台有错误信息,并且浏览器访问localhost:8080找不到eureka监控界面
project start error

设置注册中心注解

找不到eureka监控见面的原因是还需要在启动的主类EurekaApplication上添加EnableEurekaServer这个注解,加了EnableEurekaServer才表示这个项目有eureka注册中心这个功能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.wenqi.eureka;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);

}
}

注册中心监控简介

启动项目访问http://localhost:8080/,会发现注册中心已经启动。**System Status注册中心的状态,DS Replicas是高可用注册中心集群的情况,Instances currently registered with Eureka是要注册到注册中心的应用,General Info 系统信息,其中registered-replicas**是注册地址

解决控制台一直报错

控制台一直报错,这是因为eureka这个项目是个server端同时也是一个client端,它需要找一个注册中把自己给注册上去。
eureka server start error

修改application.properties文件为yml格式,设置eureka Service url,eureka服务端不用显示到服务应用列表中所有设置eureka的register-with-eurekafalse,设置应用名和端口。

1
2
3
4
5
6
7
8
9
10
11
spring:
application:
name: eureka
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
register-with-eureka: false
fetch-registry: false
server:
port: 8761

eureka打包运行

在项目目录运行mvn clean package进行打包,ls -al target找到jar包,运行nohup java -jar target/eureka-0.0.1-SNAPSHOT.jar > /dev/null 2>&1 &启动项目至为后台。ps -ef |grep eureka查看eureka进程。
nohup java

Eureka Client的使用

新建client项目

第一步同Service项目一致,第二步选择Discovery的时候选择Eureka Discovery,新版需要选择web
eureka client discovery

配置注册中心

修改application.properties文件为yml格式,设置eureka Service url。新版本不用添加EnableDiscoveryClient注解。

1
2
3
4
5
6
7
8
9
spring:
application:
name: client
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
# instance:
# hostname: clientName

访问http://localhost:8761/eureka/,发现应用已经注册上去了,可以在eureka配置文件中添加**instance.hostname**配置连接
eureka client registered

Eureka高可用

eureka是单台服务器,假如eureka服务挂掉了这么办?那后续的一些操作都做不了了,所以在正式生产环境中我们需要实现eureka高可用。

Eureka互相注册

eureka服务端起三个实例,两联相互注册。然后client端都注册到三个 eureka中
eureka service配置,两两相互注册

1
2
3
4
5
6
7
8
9
10
11
12
13
spring:
application:
name: eureka
eureka:
client:
service-url:
defaultZone: http://localhost:8762/eureka/,http://localhost:8763/eureka/
register-with-eureka: false
fetch-registry: false
# server:
# enable-self-preservation: false
#server:
# port: 8761

client配置文件,都注册到三个注册中心上

1
2
3
4
5
6
7
8
9
spring:
application:
name: client
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/, http://localhost:8762/eureka/,http://localhost:8762/eureka/
# instance:
# hostname: clientName

最终实现相互注册,而且服务都注册到了注册中心中
eureka ds

Eureka总结

  • @EnableEurekaServer@EnableEurekaClient分别启动Eureka的注册中心和client ,@EnableEurekaClient在高版本中不用注解

  • eureka有心跳检测机制,如果在系统运行过程中某个服务挂了,也就是在规定的时间内没有发送心跳信号,就会被eureka自动剔除。还有健康检查、负载均衡等功能

  • eureka的高可用,生产环境上建议至少两天以上,将注册中心分别注册到其它注册中心上

  • 分布式系统中,服务注册中心是最重要的基础部分

    分布式下服务注册的地位和原理

    分布式系统中为什么需要服务发现?

    假如最简单的情况只有A和B两个服务,这个时候A要调用B,这好办A里面配置一下B的地址不久行了?但是B变成分布式的了,A怎么找多节点的B呢?如果B服务有上百个上千个我们还继续写配置吗?B的数量还会变,例如根据浏览的大小调整服务的数量,宁一方面机器可能会挂。总而言之B服务的数量在动态的变化,这个时候再在A里面写配置文件显然不可靠。
    分布式多服务场景
    这个时候必然就会出现一个角色叫做注册中心,B启动的时候就把信息上班到注册中心里,不管B启用了多少个实例都把信息提交到注册中心,这个时候A想调用B,直接跟注册中心说我要B服务就可以了。
    注册中心
    注册中心是分布式系统最重要的基础部分,提供服务的状态。不论用不用eureka承担分布式系统中这一块职责的组件都应该高可用也级别上采用集群的方案,因为如果这一块挂掉了,那所有的应用都会成为无头苍蝇不知道找谁。

服务发现的两种方式

  • 客户端发现 (客户的发现的有点是简单明了,不需要代理的介入,同时客户端是知道所有可用服务的地址。缺点是客户端自己得实现逻辑把服务端挑出来) eureka采用的是客户端发现。

  • 服务端发现 (优点:代理的介入服务端和注册中心对于客户端是不可见的,只需要找代理发一个请求就可以了) Nginx、Zookeeper、Kubernetes采用服务端发现

思考

微服务的特点:异构
  • 不同的开发语言

  • 不同类型的数据库

Spring Cloud的服务调用方式
  • REST or RPC
  • Node.js的eureka-js-client