springcloud-Eureka-服务注册与发现核心组件

Eureka组件

Eureka是Netfilx开源的服务发现组件,本身是一个基于rest的服务,它包含client和server两部分。

Spirng Cloud将它集成在子项目Spirng Cloud Netfilx中,从而实现服务的注册和发现

client注册到Server什么?

client注册后还会在本地做一个缓存,防止Server宕机后服务无法调用,如果提供服务的service宕机,此时调用不就出错了吗?所以要做Server的集群,后文会提到。

1.eureka中的server和client的介绍及特点

  • Eureka Server:提供服务发现的能力,各个微服务启动时,会向Eureka Server注册自己的信息例如(IP,端口号,服务名称等),Eureka会存储这些信息。
  • Eureka Client:是一个java的客户端用来简化Eureka Server的交互。
  • 微服务启动后会周期性的(默认30秒)向Eureka Server发送心跳,如果Eureka在规定的时间没有收到心跳,则会注销该实例(默认90秒)。
  • Eureka Client会缓存服务注册表中的信息。这种方式有一定的优势首先可以降低Eureka Server的压力,其次当所有的Eureka Server宕机服务调用方依然可以完成调用。

2.服务注册与服务发现

  • 服务注册:当微服务client启动时,向Eureka Server发起注册,并上报该节点的相关信息
  • 服务发现:client从Eureka Server获取注册信息,然后发起调用

3.Eureka Server开发

测试环境使用springcloud的Dalston版本。由IDEA快速构建出springboot项目,再引入相关依赖。

1.引入springcloud的相关依赖
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--eureka server-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka-server</artifactId>
        </dependency>
    </dependencies>
    <!--依赖管理,所引入的jar都是没有版本号的,全部都是Dalston版本-->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Dalston.RC1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <!--仓库-->
    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>
2.入口类的开发
//启用EurekaServer
@EnableEurekaServer
@SpringBootApplication
public class EurekaServer {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServer.class,args);
    }
}
3.配置文件
eureka.client.service-url.defaultZone=http://localhost:8761/eureka
#不能向自身注册
eureka.client.register-with-eureka=false
#关闭自我发现
eureka.client.fetch-registry=false
#本实例名称
spring.application.name=eureka
#使用端口号
server.port=8761

注意:Eureka本身既是Server又是Client,作为Server不能向自身注册,自我发现关闭。

查看Server的状态,Eureka提供了一个web界面查看当前Server上的注册实例以及其他信息

地址:http://127.0.0.1:8761/

这里忘记截图了,假装没有实例注册,将就看下

2.Eureka Client的开发

1.jar包和Server不同
       将spring-cloud-starter-eureka-server改为spring-cloud-starter-eureka
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
2.入口类
//该注解可以将client注册到以zookeeper为server的服务中心
@EnableDiscoveryClient
//该注解注册到Eureka  @EnableEurekaClient
@SpringBootApplication
public class HiApplication {

    public static void main(String[] args) {
        SpringApplication.run(HiApplication.class, args);
    }
}

3.配置文件

#指定Eureka Server的地址
eureka.client.service-url.default-zone=http://localhost:8761/eureka
server.port=8762
spring.application.name=eureka-client

3.Eureka client之间的相互调用测试

准备两个client,一个作为消费者,一个作为服务者。

服务者

1.导入相关的jar
同上Client
2.入口类同上
3.配置文件
eureka.client.service-url.default-zone=http://localhost:8761/eureka
server.port=8762
spring.application.name=eureka-provider
编写一个作为测试用的Controller
@RestController
@RequestMapping("/test")
public class TestController {

    @RequestMapping("/test1")
    public String test(String name){
        return "xixixi 8763  :"+name;
    }
}

消费者

1.jar不变
2.入口类不变
3.配置文件
eureka.client.service-url.default-zone=http://localhost:8761/eureka
server.port=8763
spring.application.name=eureka-client
4.使用java配置RestTemplate
@Configuration
public class RestTemplateConf {
    @Bean
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}

关于RestTemplate的说明:类似于HTTPClient,在程序中发起http请求,RestTemplate是对HTTPClient的封装。

5.写个简单的控制器
@RestController
@RequestMapping("/query")
public class ClientController {

    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping("/test")
    public String test(String name){
        String template = restTemplate.getForObject("http://EUREKA-PROVIDER/test/test1?name=" + name, String.class);
        return template;
    }
}

方法说明:getForObject("http://EUREKA-PROVIDER/test/test1?name=" + name, String.class); EUREKA-PROVIDER是注册过的实例名称,可以在Eureka Server的web界面看到的,大小写都可以,是有对应的映射的地址的。

6.测试

启动Eureka Server,两个Client,查看Eureka Server 中注册的实例是否有两个Client,两个则正常;

地址栏发起请求:http://localhost:8763/query/test?name=xixi

查看结果调用成功。

4.Eureka的自我保护机制

Eureka进入自我保护机制的最直接体现,是Eureka首页输出警告如图:

默认情况下,如果Eureka Server在一定时间内没有接受到服务实例的心跳,Eureka将会注销该实例(默认90秒).但是当网络分区发生故障时,微服务和Eureka Server 无法正常通信.以上行为可能变得特别危险了-因为微服务本身是健康的,此时不能注销该服务实例.

Eureka通过自我保护机制来解决这个问题,当Eureka Server在短时间丢失过多的服务实例(可能发生了网络分区的故障,那么这个节点进入自我保护模式,一旦进入此模式,Eureka Server将会保护服务注册表中的信息,不再删除服务注册表中的数据(也就是不再注销任何的服务实例),当网络故障恢复后,Eureka会自动退出自我保护模式。

综上,自我保护模式是一种应对网络故障的安全保护措施,它的架构哲学是宁可同时保留所有的微服务,也不盲目注销任何健康的微服务,使用自我保护模式可以让Eureka,更加健壮,稳定。

在springcloud中可以通过

#关闭自我保护机制  默认开启
eureka.server.enable-self-preservation=false

如果想及时剔除eureka的服务除了关闭自我保护机制外,可以调低eureka的心跳值

eureka-server服务端
配置文件中添加如下配置

#关闭保护机制,以确保注册中心将不可用的实例正确剔除
eureka.server.enable-self-preservation=false
#(代表是5秒,单位是毫秒,清理失效服务的间隔 )
eureka.server.eviction-interval-timer-in-ms=5000
客户端
配置文件中添加如下配置

# 心跳检测检测与续约时间
# 测试时将值设置设置小些,保证服务关闭后注册中心能及时踢出服务
# 配置说明
#  lease-renewal-interval-in-seconds 每间隔10s,向服务端发送一次心跳,证明自己依然”存活“
#  lease-expiration-duration-in-seconds  告诉服务端,如果我20s之内没有给你发心跳,就代表我“死”了,将我踢出掉。
eureka.instance.lease-renewal-interval-in-seconds=10
eureka.instance.lease-expiration-duration-in-seconds=20

5.client的高可用

搭建Client的集群十份简单,只需要保证实例名称一致,比如都叫做:client-provider,但是端口不能冲突。

保证端口号不一致(测试环境)
保证实例名一致!!!
示例配置
eureka.client.service-url.defaultZone=http://peer:8761/eureka
spring.application.name=eureka-provider
server.port=8764        
eureka.client.service-url.defaultZone=http://peer:8761/eureka
spring.application.name=eureka-provider
server.port=8763        
最终在Eureka Server的web界面可以看到如下一个集群

6.Eureka Server的高可用

单节点的Eureka Server 不适合线上的生产环境,Eureka Client会定时连接Eureka Server,获取服务注册表中的信息并缓存在本地,微服务消费远程API总是使用本地缓存的数据,因此一般来说既是Eureka Server发生宕机,也不会影响到服务的调用,但是如果Eureka Server宕机时某些微服务也出现了不可用的情况,Eurek Client中的缓存若不被更新,可能会影响到服务的调用,甚至影响到整个系统的高可用性,因此在生产环境会部署一个高可用的Eureka Server集群。

Eureka可以通过运行多个实例并互相注册实现高可用部署,Eureka Server实例会彼此同步信息。

Server1向Server2注册
server.port=8761
eureka.client.service-url.defaultZone=http://peer1:8765/eureka
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.instance.hostname=peer1
server.port=8762
eureka.client.service-url.defaultZone=http://peer:8761/eureka
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
spring.application.name=peer
注:peer是hosts映射本地127.0.0.1,http://peer1:8761/eureka,peer1作为Eureka复制集的名称
注意:在client注册到eureka server时 需要填写所有eureka server的地址
eureka.client.service-url.defaultZone=http://peer:8761/eureka,http://peer1:8765/eureka

7.Eureka的健康监测

服务有时候也会出现异常情况,我们也需要知道某个服务的健康状况。我们可以通过添加如下依赖,开启某个服务的健康检查。

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

我们来访问一下这个接口http://localhost:port/health,看到了一个很简短的健康报告:

{"description":"Spring Cloud Eureka Discovery Client","status":"UP"}

类似的还有

  • info 显示任意的应用信息
  • metrics 展示当前应用的指标信息 true
  • mappings 显示所有@RequestMapping路径的整理列表
  • trace 显示trace信息(默认为最新的一些HTTP请求)
  • health 展示应用的健康信息
  • beans 显示一个应用中所有Spring Beans的完整列表

这其中有一些是敏感信息,出于安全考虑,一般用户无法访问,如果内网情况下可以

eureka.client.healthcheck.enabled=true
#关掉认证(公网下的生产环境不建议,内网部署可以)
management.security.enabled=false

8.http VS rpc

应用间通信方式主要是HTTP和RPC,在微服务架构中两大配方的主角分别是:

  • Dubbo RPC框架

基于dubbo开发的应用还是要依赖周边的平台生态, 相比其它的RPC框架, dubbo在服务治理与服务集成上可谓是非常完善, 不仅提供了服务注册,发现还提供了负载均衡,集群容错等基础能力同时,还提供了面向开发测试节点的Mock和泛化调用等机制。 在spring cloud 出现之前dubbo在国内应用十分广泛,但dubbo定位始终是一个RPC框架。

  • SpringCloud 微服务框架(HTTP通信)

Spring Cloud 的目标是微服务架构下的一栈式解决方案,自dubbo复活后dubbo官方表示要积极适配到spring cloud的生态方式,比如作为springcloud的二进制通信方案来发挥dubbo的性能优势,或者通过dubbo的模块化以及对http的支持适配到Spring Cloud,但是到目前为止dubbo与spring cloud 还是不怎么兼容,spring cloud 微服务架构下微服务之间使用http的RestFul方式进行通信,Http RestFul 本身轻量易用适用性强,可以很容易跨语言,跨平台,或者与已有的系统集成。

猜你喜欢

转载自www.cnblogs.com/mzc1997/p/10252218.html