一、eureka简介
eureka主要用来实现服务的注册、发现,服务的调用者通过服务的标识符就可以访问到服务。参考资料一 、参考资料二 、参考资料三 、参考资料四
通过eureka,我们可以实现服务上线、下线(宕机)的动态感知,方便服务调用者。同时,eureka包含了ribbon依赖,实现了java后台程序客户端的负载均衡。
二、通过demo来学习
这次学习eureka,我们构建三个spring项目,分别是eureka注册服务项目、订单服务项目、用户服务项目。
1、eureka-service注册服务项目
(1)、项目依赖
<?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.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>eureka-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>eureka-service</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Finchley.SR2</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
(2)、application.properties配置
server.port=9090
spring.application.name=eureka-service
#指向服务注册中心的地址
eureka.client.service-url.defaultZone=http://localhost:9090/eureka
#设置服务提供者不发起注册,既自己不注册自己
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
#关闭自我保护,确保注册中心将不可用的实例删除
eureka.server.enable-self-preservation=false
#eureka server刷新readCacheMap的时间,注意,client读取的是readCacheMap,这个时间决定了多久会把readWriteCacheMap的缓存更新到readCacheMap上
#默认30s
eureka.server.responseCacheUpdateIntervalMs=3000
#eureka server缓存readWriteCacheMap失效时间,这个只有在这个时间过去后缓存才会失效,失效前不会更新,过期后从registry重新读取注册服务信息,registry是一个ConcurrentHashMap。
#由于启用了evict其实就用不太上改这个配置了
#默认180s
eureka.server.responseCacheAutoExpirationInSeconds=180
#启用主动失效,并且每次主动失效检测间隔为3s
#默认60s
eureka.server.eviction-interval-timer-in-ms=3000
#服务过期时间配置,超过这个时间没有接收到心跳EurekaServer就会将这个实例剔除
#注意,EurekaServer一定要设置eureka.server.eviction-interval-timer-in-ms否则这个配置无效,这个配置一般为服务刷新时间配置的三倍
#默认90s
eureka.instance.lease-expiration-duration-in-seconds=15
#服务刷新时间配置,每隔这个时间会主动心跳一次
#默认30s
eureka.instance.lease-renewal-interval-in-seconds=5
#eureka client刷新本地缓存时间
#默认30s
eureka.client.registryFetchIntervalSeconds=5
#eureka客户端ribbon刷新时间
#默认30s
ribbon.ServerListRefreshInterval=1000
eureka.instance.preferIpAddress=true
(3)、项目代码
我们需要在入口类上添加@EnableEurekaServer来开启eureka服务
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@EnableEurekaServer
@SpringBootApplication
public class EurekaServiceApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServiceApplication.class, args);
}
}
其实到这里eureka注册服务中心我们就已经简单搭建完成了。eureka-service服务可以自己注册自己,我们可以将eureka client 下的register-with-eureka、fetch-registry 设置成true就可以了。但控制台可能会报“Cannot execute request on any known server”错误,因为我们的eureka服务还没启动,所以可以不予理会。
2、order-service订单服务
(1)、项目依赖
<?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.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>order-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>order-service</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Finchley.SR2</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
(2)、application.properties配置
spring.application.name=order-service
server.port=8080
eureka.server.enable-self-preservation=false
#最好每个实例不同顺序,按照离自己最近的Eureka地址放到最前面
#eureka.client.serviceUrl.defaultZone=http://10.120.242.153:8211/eureka/,http://10.120.242.154:8211/eureka/
eureka.client.service-url.defaultZone=http://localhost:9090/eureka
(3)、项目代码
package com.example;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class OrderController {
@Value("${server.port}")
private int port;
@GetMapping("getOrder")
public String getOrder(){
return "获取订单信息,服务端口:"+port;
}
}
3、user-service用户系统
(1)、项目依赖
<?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.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>user-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>user-service</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Finchley.SR2</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.1.1.RELEASE</version>
</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>
</project>
(2)、application.properties配置
spring.application.name=user-service
server.port=8070
eureka.client.service-url.defaultZone=http://localhost:9090/eureka
(3)、项目代码
package com.example;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
@FeignClient("order-service")
public interface OrderServiceFeignClient {
@GetMapping("getOrder")
String getOrder();
}
package com.example;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class OpenFeignController {
@Autowired
private OrderServiceFeignClient orderServiceFeignClient;
@GetMapping("feignClientMethod")
public String feignClientMethod(){
return orderServiceFeignClient.getOrder();
}
}
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}
三、总结
到此,spring cloud eureka的简单搭建使用就完成了。
1、eureka服务集群
另外我们可以通过复制一份eureka-service项目,改一下项目端口号,将eureka-service项目配置文件中的eureka注册地址更改如下,我们就可以搭建出来一个eureka的服务集群,其实就是多个eureka服务通过各自互相注册来实现的集群。
9090端口的eureka-service配置文件配置:
#每个实例要不同顺序,离自己最近的Eureka地址放到最前面
eureka.client.serviceUrl.defaultZone=http://localhost:9091/eureka
eureka.client.register-with-eureka=true
eureka.client.fetch-registry=true
9091端口的eureka-service配置文件配置:
eureka.client.serviceUrl.defaultZone=http://localhost:9090/eureka
eureka.client.register-with-eureka=true
eureka.client.fetch-registry=true
多个eureka服务注册地址,用“逗号”分隔注册。
order-service、user-service注册eureka服务配置如下:
#每个实例要不同顺序,离自己最近的Eureka地址放到最前面
eureka.client.serviceUrl.defaultZone=http://localhost:9090/eureka,http://localhost:9091/eureka
这样我们就非常简单的实现了eureka服务的集群。
2、eureka安全认证
(1)、pom.xml添加依赖
要实现eureka的安全认证,需要通过spring-boot-starter-security来实现,所有我们首先需要添加security依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
(2)、修改配置文件
添加如下配置,设置安全认证需要的用户名及密码:
spring.security.user.name=qz
spring.security.user.password=qzpassword
在eureka注册中心url上添加认证账号和密码,另外eureka 客服端服务同样需要修改service-url,添加账号密码:
eureka.client.service-url.defaultZone=http://qz:qzpassword@localhost:8081/eureka
(3)、添加WebSecurityConfig配置类
由于CSRF是默认开启的,所以需要将其关闭,否则启动会报以下错误:
javax.ws.rs.WebApplicationException: com.fasterxml.jackson.databind.exc.MismatchedInputException: Root name 'timestamp' does not match expected ('instance') for type [simple type, class com.netflix.appinfo.InstanceInfo]
在入口类同级目录下新建WebSecurityConfig配置类,如下:
package com.example.eurekaservice.config;
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;
@EnableWebSecurity
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();//关闭csrf
super.configure(http);//开启认证
}
}
启动eureka服务,即可看到已经开启了安全认证,如下图:

(3)、补充:
CAP的特点
C:指数据的强一致性(Consistency);A:指高可用性;P:指分区容错性(集群几点、跨区域的高可用性)
eureka是AP特性。
eureka需要我们关注的点有四个:三级缓存、自动保护机制、续约、服务注册。
eureka自我保护机制
心跳失败的比例在15分钟以内低于85%的节点,Eureka server会认为这个实例出现了网络故障,正常应该直接剔除这个有问题的服务。但eureka自我保护机制就是为了减少网络抖动或者网络不稳定的情况下的误删除,那么这个服务就不会删除。
- eureka server不会剔除因为长时间没有收到心跳数据的过期服务
- eureka server仍然能够接收新的服务的注册和查询
738



被折叠的 条评论
为什么被折叠?



