微服务小记:Eureka进阶使用

494 阅读6分钟

这是我参与2022首次更文挑战的第6天,活动详情查看:2022首次更文挑战

1. 项目中使用Eureka

1.1 Eureka服务端

1.1.1 引入依赖

引入Eureka依赖时分为Spring Cloud项目中和普通项目中引入

  • 如果是Spring Cloud项目,则包含Spring Cloud版本信息,引入Eureka时不需要指定版本,而是默认跟随Spring Cloud;
  • 如果是普通项目,可以先增加Spring Cloud版本信息再引入Eureka,或者直接引入带有版本信息的Eureka依赖。
  1. 引入依赖信息,使用spring cloud控制版本信息
 <dependencies>
     <!-- eureka -->
     <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
     </dependency>
 </dependencies>
 
 <!-- Spring Cloud -->
 <dependencyManagement>
     <dependencies>
         <dependency>
             <groupId>org.springframework.cloud</groupId>
             <artifactId>spring-cloud-dependencies</artifactId>
             <version>Finchley.SR2</version>
             <type>pom</type>
             <scope>import</scope>
         </dependency>
     </dependencies>
 </dependencyManagement>
  1. 单独引入依赖信息
 <dependencies>
     <!-- eureka -->
     <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
         <version>2.2.3.RELEASE</version>
     </dependency>
 </dependencies>

1.1.2 服务端配置信息

Eureka服务端配置作为注册与发现中心,提供其他客户端注册,其本身并不需要注册和被发现。

 spring.application.name=eureka-server
 server.port=9090
 # 由于该应用为注册中心, 所以设置为false, 代表不向注册中心注册自己
 eureka.client.register-with-eureka=false
 # 由于注册中心的职责就是维护服务实例, 它并不需要去检索服务, 所以也设置为 false
 eureka.client.fetch-registry=false
  • eureka.client.register-with-eureka 配置为 false,否则启动时会把自己当作客户端向自己注册报错

1.1.3 服务端启动注解

Eureka的服务端启动时,需要在启动类中使用@EurekaServerApplication注解标注。

配置完成后,启动项目,可以通过http://localhost:9090 来访问Eureka提供的页面。

1.2 客户端

1.2.1 客户端依赖信息

客户端依赖管理与服务端相同,也分为跟随Spring Cloud版本,或自定义依赖版本。

  1. 通过spring cloud 进行版本管理
 <dependences>
     <!-- eureka client -->
     <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
     </dependency>
 </dependences>
 
 <!-- Spring Cloud -->
 <dependencyManagement>
     <dependencies>
         <dependency>
             <groupId>org.springframework.cloud</groupId>
             <artifactId>spring-cloud-dependencies</artifactId>
             <version>Finchley.SR2</version>
             <type>pom</type>
             <scope>import</scope>
         </dependency>
     </dependencies>
 </dependencyManagement>
  1. 单独管理依赖版本
 <!-- eureka -->
 <dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
     <version>2.2.3.RELEASE</version>
 </dependency>

1.2.2 客户端配置文件信息

客户端作为加入到注册中心的服务,需要发现其他服务并被其他服务发现,因此需要配置注册服务中心的地址,以及客户端自身展示的服务信息等。

 spring.application.name= eureka-client-user-service
 server.port=9095
 # eureka server 服务地址,需要将客户端注册进去
 eureka.client.serviceUrl.defaultZone=http://localhost:9090/eureka/
 # 采用IP注册
 eureka.instance.preferIpAddress=true
 # 定义实例ID格式
 eureka.instance.instance-id = ${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}

1.2.3 客户端注解

  • 客户端启动时,还需要在启动类上使用@EnableDiscoveryClient注解标注为Eureka客户端。

服务端和客户端同步状态

服务注册、拉取和缓存注册表、心跳检测和掉线判定

2. Eureka服务进阶配置

2.1 服务的注册与发现

Eureka客户端在配置完成,启动后会将自己的ip地址、端口、服务名称、运行状态等信息提供给服务端,这就是注册到服务中心。

Eureka客户端为了更方便的与其他服务通信,会定期从服务端拉取注册列表并缓存到本地,通信时通过注册表找到对应服务地址,这即是发现其他服务。

相关配置的开启关闭、拉取更新时间可以在配置文件定义

 # 是否获取注册表信息
 eureka.client.fetch-registry = true
 # 缓存注册表的间隔时间,默认30s
 eureka.client.registry-fetch-interval-seconds = 30
  • 开启获取注册表信息后,由于客户端会将注册表缓存到本地,因此服务端出现问题时,并不会影响已注册服务之间的通信

2.2 服务续约

为了保证Eureka服务的稳定,Eureka客户端可以设置开启健康检查,定期向服务端发送心跳,表示当前服务可用。

# 开启健康检查,需要引入actuator依赖
eureka.client.healthcheck.enabled=true

其中actuator依赖信息为:

<!--actuator依赖-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

心跳信息默认每隔30s向服务端发送一次,可以通过配置文件自定义客户端的心跳检测间隔。

# 表示服务续约时间(心跳检测,s)
eureka.instance.lease-renewal-interval-in-seconds = 30 

默认情况时,Eureka服务端如果在90s内没有收到客户端的心跳信息,会认为该客户端掉线,在服务注册表中剔除该客户端,掉线时间同样可以在服务注册中心自定义配置。

# 表示服务时效时间(标记掉线时间,s)
eureka.instance.lease-expiration-duration-in-seconds = 90

2.3 自我保护机制

Eureka自我保护机制就是在部分服务出现异常时,不会因为心跳检测失败而将所有服务踢出注册列表,比如网络等原因导致检测超时,Eureka服务端会标记大部分服务不可用。

  • 对于此种情况,可以通过配置设置增加判定时间或者开启服务端保护机制来保证服务存在。
# 开启保护机制,在短时间丢失过多客户端时会进入保护,不会剔除客户端服务
eureka.server.enable-self-preservation=true

# 服务端清理务间隔,默认 60000 毫秒
eureka.server.eviction-interval-timer-in-ms=5000
  • 虽然保护机制有一定的作用,但却有可能在某个服务实际宕机后仍然存在与注册列表中,因此实际使用时要衡量两种情况。

2.4 服务下线

当Eureka客户端下线时,会主动发送一条消息到服务端,告知自己下线。

Eureka分区定义:同一个分区的服务端和客户端会优先进行心跳同步

  • region:地理上的不同区域
  • zone:具体的机房

2.5 服务跳转

客户端注册到Eureka服务中心后,可以在列表中看到客户端信息,点击客户端信息列表时会跳转到指定连接,Eureka默认的跳转路径是客户端IP+Port/actuator/info,可以通过配置文件自定义跳转路径。

# 配置点击服务信息跳转路径
eureka.instance.status-page-url=localhost:8076/eureka/customer

2.6 增加账户密码验证

为保证Eureka服务地址的安全,可使用Spring-Security在Eureka服务中配置登录权限认证,配置完成后,访问Eureka服务中心配置页面时会提示登录账户后操作。

2.6.1 Spring-Security依赖信息

 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-security</artifactId>
     <version>2.6.0</version>
 </dependency>

2.6.2 自动开启验证登录

项目中添加添加依赖后,Eureka会自动与Spring-Security关联,此时登录Eureka服务页面时需要登录账户和密码,Spring-Security默认账户名是user,默认密码会在项目启动时自动生成并在控制台输出。

控制台: Using generated security password: 64d21b89-d689-40f4-8e58-1897a8f2b51e

2.6.3 自定义账户和密码

可以在配置文件中自定义登录Eureka服务(Spring-Security)的账户和密码

 # 设置登录用户名
 spring.security.user.name=admin 
 # 设置登录密码
 spring.security.user.password=123456 

2.6.4 其他安全配置

除了登录用户名和密码,还可以对Spring-Security增加其他自定义配置,如开启支持httpBastic、关闭csrf,可以使用配置类定义Spring-Security实例。

 @Configuration
 @EnableWebSecurity
 public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
     @Override
     protected void configure(HttpSecurity http) throws Exception {
         // 关闭csrf
         http.csrf().disable();
         // 支持httpBasic
         http.authorizeRequests().anyRequest().authenticated().and().httpBasic();
     }
 }

2.6.5 使用账户密码注册服务

增加Spring-Security权限配置后,客户端注册到Eureka服务中心时,需要使用用户名和密码进行登录注册,此时需要在配置文件配置Eureka服务中心时增加账户和密码配置。

 # 注册中心地址的格式变成 账户:密码@地址
 eureka.client.serviceUrl.defaultZone=http://zhangsan:123456@localhost:8761/eureka/