Eureka用于服务的注册与发现,跟zookeeper类似。
添加依赖
<?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.3.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>eureka</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>eureka</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR9</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</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-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
</project>
spring cloud版本跟spring boot版本是有对应关系的,如果版本不匹配,会出现一堆ClassNotFound和MethodNotFound异常。好多初学者满怀信心的学习spring cloud,结果被一堆版本兼容问题劝退了,多可惜啊。这是官网关于它们对应版本的表格:
左边是spring cloud依赖版本,右边是spring boot依赖版本。
启动类
package com.example.eureka;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@EnableEurekaServer
@SpringBootApplication
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
}
}
注意要加上@EnableEurekaServer注解。然后run主函数。若没有报错,且启动之后可以正常访问管理控制台(如果没更改端口的话,默认是8080端口,例如http://localhost:8080就可以访问到控制台),说明启动成功。
自我注册
每个Eureka Server同样也是一个Eureka Client,它会注册到其他Eureka Server,需要提供其他成员的URL给它才行。如果只有一个Eureka Server,也就是说是单机版,会打印很多日志,比如下面这些:
2020-11-19 23:32:46.574 WARN 9252 --- [nfoReplicator-0] c.n.discovery.InstanceInfoReplicator : There was a problem with the instance info replicator
com.netflix.discovery.shared.transport.TransportException: Cannot execute request on any known server
单机版
如果是单机版,不想看到那么多warn日志,可以增加如下配置:
eureka:
instance:
hostname: localhost
client:
register-with-eureka: false #不用注册到其他Eureka Server
fetch-registry: false #不需要去注册中心获取其他服务的地址
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
server:
port: 8761
集群版
通过让多个Eureka Server实例之间互相注册,能够实现Eureka Server的高可用,以及能让它更容易从故障中恢复过来。下面是有2个Eureka Server实例的配置文件:
---
spring:
profiles: peer1
eureka:
instance:
hostname: peer1
client:
service-url:
defaultZone: http://peer2:8762/eureka/
server:
port: 8761
---
spring:
profiles: peer2
eureka:
instance:
hostname: peer2
client:
service-url:
defaultZone: http://peer1:8761/eureka/
server:
port: 8762
上面用到了hostname,所以需要在/etc/hosts文件里做一下映射。如下:
127.0.0.1 peer1
127.0.0.1 peer2
运行时需要指定哪个profile生效,如果是打包成jar包运行,需要加上--spring.profiles.active
参数,
例如java -jar eureka-server-1.0.0.jar --spring.profiles.active=peer1
。如果是在基于Intellij IDEA的开发环境运行,右键编辑启动类的配置,然后操作如下:
运行两个Eureka Server,访问http://localhost:8761/, 可以看到peer1多了一个discover server副本peer2。同样,peer1也是peer2的副本。
鉴权
要对注册到Eureka Server的客户端进行鉴权的话,首先要添加spring security依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
虽然spring security有默认的用户名和密码,但是建议自定义用户名和密码,完整配置如下:
---
spring:
profiles: peer1
security:
user:
name: peer1
password: 123456
application:
name: myapp
eureka:
instance:
hostname: peer1
client:
service-url:
defaultZone: http://peer2:123456@peer2:8762/eureka/
server:
port: 8761
---
spring:
profiles: peer2
security:
user:
name: peer2
password: 123456
application:
name: myapp
eureka:
instance:
hostname: peer2
client:
service-url:
defaultZone: http://peer1:123456@peer1:8761/eureka/
server:
port: 8762
此时Eureka Server还无法互相注册成功。官网说:默认情况下,当spring security在类路径时,它将要求向应用程序的每个请求都发送一个有效的CSRF令牌。Eureka客户端通常不会拥有有效的跨站点请求伪造(CSRF)令牌,您需要对/Eureka/**端点禁用此要求。所以还需要增加一个配置类才行:
package com.example.eureka;
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;
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().ignoringAntMatchers("/eureka/**");
super.configure(http);
}
}
OK,大功告成。