SpringCloud——Eureka解释以及使用

Posted *^O^*—*^O^*

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringCloud——Eureka解释以及使用相关的知识,希望对你有一定的参考价值。

什么是注册中心

注册中心可以说是微服务架构的“通讯录”,记录了服务和服务地址的映射关系,在分布式架构中,所有的服务都会注册在注册中心里,当服务需要调用其它服务的时候,就到注册中心找寻服务的地址,进行调用。

为什么需要注册中心

注册中心不仅承担着服务的注册以及地址映射,还需要完成以下功能:

  • 服务注册后,如何别别的服务所发现
  • 服务宕机后,如何及时下线
  • 服务如何进行有效的水平扩展
  • 服务发现时,如何进行路由
  • 服务异常时,如何进行降级
  • 注册中心如何实现自身的高可用

Eureka注册中心的三种角色

Server
通过Register, Get, Renew 等接口提供服务的注册和发现
Consumer
服务调用方,通过Eureka Server获取服务列表,消费服务
Provider
服务提供方,把自身的服务实例注册到Eureka Server中

  1. 实例化服务
  2. 将服务注册到注册中心
  3. 注册中心收录服务
  4. 从注册中心获取服务列表
  5. 基于负载均衡算法从地址列表选择一个服务地址进行服务调用
  6. 定期发送心跳
  7. 检查没有定期发送心跳的服务并在一定的时间内剔除服务从服务列表中

Eureka 入门案例

server
build.gradle.kts

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins 
    id("org.springframework.boot") version "2.3.7.RELEASE"
    id("io.spring.dependency-management") version "1.0.10.RELEASE"
    kotlin("jvm") version "1.3.72"
    kotlin("plugin.spring") version "1.3.72"


group = "com"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_1_8

repositories 
    mavenCentral()

dependencies 
    implementation("org.springframework.boot:spring-boot-starter-web")
    implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
    implementation("org.jetbrains.kotlin:kotlin-reflect")
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
    testImplementation("org.springframework.boot:spring-boot-starter-test") 
        exclude(group = "org.junit.vintage", module = "junit-vintage-engine")
    
// https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-dependencies
    implementation("org.springframework.cloud:spring-cloud-dependencies:Hoxton.SR12")
// https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-eureka-server
    implementation("org.springframework.cloud:spring-cloud-starter-netflix-eureka-server:2.2.10.RELEASE")




tasks.withType<Test> 
    useJUnitPlatform()


tasks.withType<KotlinCompile> 
    kotlinOptions 
        freeCompilerArgs = listOf("-Xjsr305=strict")
        jvmTarget = "1.8"
    

application.yml

server:
  port: 8761

spring:
  application:
    name: eureka-server

  freemarker:
    prefer-file-system-access: false

eureka:
  instance:
    hostname: localhost
#    是否使用ip地址注册,在多个注册中心节点时使用
#    prefer-ip-address: true
#    instance-id: $spring.cloud.client,ip-address:$server.port
  client:
    register-with-eureka: false #是否将服务注册到注册中心
    fetch-registry: false
    service-url:
      defaultZone: http://$eureka.instance.hostname:$server.port/eureka/

在启动类还要加上@EnableEurekaServer注解,不然无法访问页面
Consumer
build.gradle.kts

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins 
    id("org.springframework.boot") version "2.3.7.RELEASE"
    id("io.spring.dependency-management") version "1.0.10.RELEASE"
    kotlin("jvm") version "1.3.72"
    kotlin("plugin.spring") version "1.3.72"


group = "com"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_1_8

configurations 
    compileOnly 
        extendsFrom(configurations.annotationProcessor.get())
    


repositories 
    mavenCentral()


dependencies 
    implementation("org.springframework.boot:spring-boot-starter-web")
    implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
    implementation("org.jetbrains.kotlin:kotlin-reflect")
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
    compileOnly("org.projectlombok:lombok")
    annotationProcessor("org.projectlombok:lombok")
    testImplementation("org.springframework.boot:spring-boot-starter-test") 
        exclude(group = "org.junit.vintage", module = "junit-vintage-engine")
    
    // https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-dependencies
    implementation("org.springframework.cloud:spring-cloud-dependencies:Hoxton.SR12")
    // https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-eureka-client
    implementation("org.springframework.cloud:spring-cloud-starter-netflix-eureka-client:2.2.10.RELEASE")


tasks.withType<Test> 
    useJUnitPlatform()


tasks.withType<KotlinCompile> 
    kotlinOptions 
        freeCompilerArgs = listOf("-Xjsr305=strict")
        jvmTarget = "1.8"
    


application.yml

server:
  port: 9091
spring:
  application:
    name: service-consumer

  freemarker:
    prefer-file-system-access: false

eureka:
#  instance:
#    prefer-ip-address: true
#    instance-id: $spring.cloud.client,ip-address:$server.port
  client:
    register-with-eureka: false
    registry-fetch-interval-seconds: 10 #表示client多久去服务器拉取注册信息,默认是30秒
    service-url:
      defaultZone: http://localhost:8761/eureka/

restTemplateConfig

import org.springframework.cloud.client.loadbalancer.LoadBalanced
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.web.client.RestTemplate

@Configuration
class RestTemplateConfig 
    @Bean
    @LoadBalanced //负载均衡注解
    fun restTemplate(): RestTemplate 
        return RestTemplate()
    

测试接口

package com.service_consumer.controller


import org.springframework.beans.factory.annotation.Autowired
import org.springframework.core.ParameterizedTypeReference
import org.springframework.http.HttpMethod
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.client.RestTemplate

@RestController
@RequestMapping("/order")
class OrderController 

    @Autowired
    lateinit var restTemplate: RestTemplate

    @GetMapping
    fun getOrderById(id:Int):String
        return "id:$id  $selectProductListByLoadBalancerAnnotation()"
    
    fun selectProductListByLoadBalancerAnnotation(): String? 
        class ListOfPeople : ParameterizedTypeReference<String>()
        var respeonse: ResponseEntity<String> = restTemplate.exchange(
                "http://service-provider/product/test",
                HttpMethod.GET,
                null,
                ListOfPeople()
        )
        return respeonse.body
    

Provider
bulid.gradle.kts

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins 
    id("org.springframework.boot") version "2.3.7.RELEASE"
    id("io.spring.dependency-management") version "1.0.10.RELEASE"
    kotlin("jvm") version "1.3.72"
    kotlin("plugin.spring") version "1.3.72"


group = "com"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_1_8

repositories 
    mavenCentral()


dependencies 
    implementation("org.springframework.boot:spring-boot-starter-web")
    implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
    implementation("org.jetbrains.kotlin:kotlin-reflect")
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
    testImplementation("org.springframework.boot:spring-boot-starter-test") 
        exclude(group = "org.junit.vintage", module = "junit-vintage-engine")
    
    // https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-dependencies
    implementation("org.springframework.cloud:spring-cloud-dependencies:Hoxton.SR12")
    // https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-eureka-client
    implementation("org.springframework.cloud:spring-cloud-starter-netflix-eureka-client:2.2.10.RELEASE")

    implementation ("org.projectlombok:lombok:1.18.24")


tasks.withType<Test> 
    useJUnitPlatform()


tasks.withType<KotlinCompile> 
    kotlinOptions 
        freeCompilerArgs = listOf("-Xjsr305=strict")
        jvmTarget = "1.8"
    


application.yml

server:
  port: 7070
spring:
  application:
    name: service-provider

  freemarker:
    prefer-file-system-access: false

eureka:
  instance:
    prefer-ip-address: true
    instance-id: $spring.cloud.client,ip-address:$server.port
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

测试接口


import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

@RestController
@RequestMapping("/product")
class ProductController 

    @GetMapping("/test")
    fun selectAll():String
        return "hello"
    

结果展示

Eureka 优雅停服

配置优雅停服之后,将不需要Eureka Server中配置关闭自我保护。
需要添加依赖 actuator

// https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-actuator
implementation("org.springframework.boot:spring-boot-starter-actuator:2.7.0")

management:
  endpoints:
    web:
      exposure:
        include: shutdown #开启shutdown端点访问
  endpoint:
    shutdown:
      enabled: true  #开启shutdown 实现优雅停服

然后使用post发送请求
http://localhost:7070/actuator/shutdown
该节点的服务就会停掉

Eureka 安全认证

在配置中心中添加,需要添加如下依赖

// https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-security
implementation("org.springframework.boot:spring-boot-starter-security:2.6.8")

spring:
  security:
    user:
      name: root
      password: 123456

将配置文件的地址,前面加上root:123456@

    service-url:
      defaultZone: http://root:123456@localhost:8761/eureka/

再启动之后,每次访问需要输入用户名和密码

过滤CSRF

在添加安全配置之后,注册中心节点不能互相构建,需要过滤CSRF

Eureka 自我保护

一般情况下,服务在注册之后,会每隔30秒发送心跳包,Eureka通过心跳来判断服务是否健康,同时会定期删除超过90秒没有发送心跳的服务。

如果因为网络故障原因导致的删除,就需要另外进行处理
Eureka Server 在运行期间会去统计心跳失败比例在15分钟之内是否低于85%,如果低于,则会将这些实例保护起来,让这些实例不会过期,同时提示一个警告,这种算法叫做Eureka Server的自我保护模式,默认是开启的,可以通过application.yml文件中修改

  server:
    enable-self-preservation: true
    eviction-interval-timer-in-ms: 60000

以上是关于SpringCloud——Eureka解释以及使用的主要内容,如果未能解决你的问题,请参考以下文章

springcloud—— eureka本地集群搭建以及实现微服务的负载均衡调用

SpringCloud系列四:Eureka 服务发现框架(定义 Eureka 服务端Eureka 服务信息Eureka 发现管理Eureka 安全配置Eureka-HA(高可用) 机制Eur(代码片段

springcloud--eureka服务治理深入浅出

SpringCloud系列之三---Ribbon负载均衡使用

SpringCloud:如何使用Eureka进行服务治理?

F版本SpringCloud 5—Eureka集群和自我保护机制