微服务注册中心之 Eureka
eureka 搭建集群
版本说明
Spring Boot 2.1.7.RELEASE
spring-cloud-starter-netflix-eureka-server Finchley.SR2
spring-boot-starter-security 2.1.7.RELEASE
pom.xml 文件
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.online.taxi.eureka</groupId>
<artifactId>eureka</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>eureka</name>
<description>Demo project for Spring Boot</description>
<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.version>Finchley.SR2</spring-cloud.version>
</properties>
<dependencies>
<!-- eureka 服务端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<!-- 安全认证 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>
</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>
</project>
搭建单节点
单节点搭建非常简单,引入上面的依赖,然后编写配置文件
application.yml
#单节点,正确
#应用名称及验证账号
server:
port: 7900
spring:
application:
name: eureka
security:
user:
# eureka登陆账号密码
name: root
password: root
eureka:
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://root:root@localhost:7900/eureka/
server:
#关闭自我保护
enable-self-preservation: false
#清理间隔时间
eviction-interval-timer-in-ms: 5000
启动类添加注解
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
import com.netflix.eureka.registry.InstanceRegistry;
import com.netflix.eureka.registry.PeerAwareInstanceRegistry;
import com.netflix.eureka.registry.PeerAwareInstanceRegistryImpl;
@EnableEurekaServer // eureka服务端启动注解
@SpringBootApplication
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
}
}
这样单节点就构建完成了。
但是单节点一般来说仅仅是个人开发时使用,因为单节点容易出现问题,当该节点因为网络或者其他情况不可用时,其他服务之间的调用就会出现问题。
因此注册中心都是搭建集群来使用。
eureka集群搭建
pom文件启动类还是与单机时没有任何区别,唯有配置文件需要更改
为了演示,这里我们仅仅只建立一个项目,但是启动三次,模拟三个节点的高可用集群,配置文件如下
#高可用3个节点,正确。
#应用名称及验证账号
spring:
application:
name: eureka
security:
user:
name: root
password: root
logging:
level:
root: info
eureka:
server:
# 设置 eureka server同步失败的等待时间 默认 5分 , 在这期间,它不向客户端提供服务注册信息
wait-time-in-ms-when-sync-empty: 0
client:
serviceUrl:
defaultZone: http://root:root@localhost:7901/eureka/,http://root:root@localhost:7902/eureka/,http://root:root@localhost:7903/eureka/
---
spring:
profiles: 7901
server:
port: 7901
eureka:
instance:
hostname: eureka-7901
---
spring:
profiles: 7902
server:
port: 7902
eureka:
instance:
hostname: eureka-7902
---
spring:
profiles: 7903
server:
port: 7903
eureka:
instance:
hostname: eureka-7903
怎样在一个项目中启动三次服务,这个看截图
点击左上角的 “+” ,添加springboot启动项,Name是启动项名称,build and run 下,前者是jdk,后者选择服务启动类,最后在 Active profiles 分别填写对应的 profiles 即可
这样集群就搭建完成了
关闭csrf
需要注意的是,搭建集群时,若引入spring security后,需要关闭csrf,不然会一只报注册失败
关闭csrf代码如下
import org.springframework.context.annotation.Configuration;
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;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// 关闭csrf
// http.csrf().disable();
/*
* 默认情况下添加SpringSecurity依赖的应用每个请求都需要添加CSRF token才能访问,Eureka客户端注册时并不会添加,所以需要配置/eureka/**路径不需要CSRF token。
*/
http.csrf().ignoringAntMatchers("/eureka/**");
// 开启认证支持HttpBasic
http.authorizeRequests().anyRequest().authenticated().and().httpBasic();
}
}
eureka 多节点注意事项
问题:eureka server间 设置peer。A->B,B->C,C->A,结果注册信息并不同步。
看例子:
依次启动7901,7902,7903。
启动成功,注册api-driver ->7901
发现只有7901和7902有 api-driver而 7903没有。
简单说:api-driver向 7901注册,7902将api-driver同步到7902,但是不会同步到7903。后面源码会讲到。
多节点建议:设置A->B,A->C其他类似。尽量不要跨 eureka节点。一对多,面面对到。
讲解下图。前置概念peer。清除流程。
功能点:
peer启动:
1、拉取它的peer的注册表。
2、把自己注册到peer上。
3、完成2之后,2中的peer会把它同步到,2中peer的peer。
eureka集群复制流程图
Eureka 原理
-
本质:存储了每个客户端的注册信息。EurekaClient从EurekaServer同步获取服务注册列表。通过一定的规则选择一个服务进行调用。
-
Eureka架构图
Eureka架构图
- 详解
- 服务提供者:是一个eureka client,向Eureka Server注册和更新自己的信息,同时能从Eureka Server注册表中获取到其他服务的信息。
- 服务注册中心:提供服务注册和发现的功能。每个Eureka Cient向Eureka Server注册自己的信息,也可以通过Eureka Server获取到其他服务的信息达到发现和调用其他服务的目的。
- 服务消费者:是一个eureka client,通过Eureka Server获取注册到其上其他服务的信息,从而根据信息找到所需的服务发起远程调用。
- 同步复制:Eureka Server之间注册表信息的同步复制,使Eureka Server集群中不同注册表中服务实例信息保持一致。
- 远程调用:服务客户端之间的远程调用。
- 注册:Client端向Server端注册自身的元数据以供服务发现。
- 续约:通过发送心跳到Server以维持和更新注册表中服务实例元数据的有效性。当在一定时长内,Server没有收到Client的心跳信息,将默认服务下线,会把服务实例的信息从注册表中删除。
- 下线:Client在关闭时主动向Server注销服务实例元数据,这时Client的服务实例数据将从Server的注册表中删除。
- 获取注册表:Client向Server请求注册表信息,用于服务发现,从而发起服务间远程调用。
如果让我们自己做,该如何做 ?
客户端:
拉取注册表
从注册表选一个
调用
服务端:
写个web server。
功能:
1、定义注册表:
Map<name,Map<id,InstanceInfo>>。
2、别人可以向我注册自己的信息。
3、别人可以从我这里拉取他人的注册信息。
4、我和我的同类可以共享注册表。
eureka是用:jersey实现,也是个mvc框架。
我们可以自己写个spring boot web实现。