注册中心-Eureka

Eureka注册中心-介绍

又称服务中心,管理各类服务功能包括服务的注册、发现、熔断、负载、降级等。java

使用背景

  • 任何一个服务都不能直接去掉用,都须要经过注册中心来调用。经过服务中心来获取服务你不须要关注你调用的项目IP地址,由几台服务器组成,每次直接去服务中心获取可使用的服务去调用既可。
  • 因为各类服务都注册到了服务中心,就有了不少高级功能条件。
    好比几台服务提供相同服务来作客户端负载均衡(Ribbon);
    监控服务器调用成功率来作断路器(Hystrix),移除服务列表中的故障点;
    监控服务调用时间来对不一样的服务器设置不一样的权重、智能路有(Zuul)等等;

SpringCloud -Eureka注册中心

Spring Cloud 封装了 Netflix 公司开发的 Eureka 模块来实现服务注册和发现。Eureka 采用了 C-S 的设计架构。
Eureka Server 做为服务注册功能的服务器,它是服务注册中心。而系统中的其余微服务,使用 Eureka 的客户端链接到 Eureka Server,并维持心跳链接。这样系统的维护人员就能够经过 Eureka Server 来监控系统中各个微服务是否正常运行。Spring Cloud 的一些其余模块(好比Zuul)就能够经过 Eureka Server 来发现系统中的其余微服务,并执行相关的逻辑。web

Eureka由两个组件组成:Eureka服务器和Eureka客户端。spring

  • Eureka服务器用做服务注册服务器。
  • Eureka客户端是一个java客户端,用来简化与服务器的交互、做为轮询负载均衡器,并提供服务的故障切换支持。
  • Netflix在其生产环境中使用的是另外的客户端,它提供基于流量、资源利用率以及出错状态的加权负载均衡。

Eureka架构图

上图简要描述了Eureka的基本架构,由3个角色组成:服务器

一、Eureka Server架构

  • Eureka Server 做为一个独立的部署单元,以 REST API 的形式为服务实例提供了注册、管理和查询等操做。同时,Eureka Server 也为咱们提供了可视化的监控页面,能够直观地看到各个 Eureka Server 当前的运行状态和全部已注册服务的状况。

二、Service Providerapp

  • 服务提供方
  • 将自身服务注册到Eureka,从而使服务消费方可以找到

三、Service Consumer负载均衡

  • 服务消费方
  • 从Eureka获取注册服务列表,从而可以消费服务

上手-Eureka Server

1.建立一个基础的Spring Boot工程,pom中添加依赖ide

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.3.5.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<dependencies>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
   <!-- 引入Eureka-server相关jar-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka-server</artifactId>
    </dependency>
    
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Brixton.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
         </dependency>
    </dependencies>
</dependencyManagement>

2.启动代码中添加@EnableEurekaServer注解spring-boot

@SpringBootApplication
@EnableEurekaServer
public class SpringCloudEurekaApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringCloudEurekaApplication.class, args);
    }
}

3.默认设置下,该服务注册中心也会将本身做为客户端来尝试注册它本身,因此咱们须要禁用它的客户端注册行为,在application.properties添加如下配置:微服务

spring.application.name=Eureka Server

server.port=7001
#表示是否将本身注册到Eureka Server,默认为true
eureka.client.register-with-eureka=false  

#表示是否从Eureka Server获取注册信息,默认为true
eureka.client.fetch-registry=false 

#设置与Eureka Server交互的地址,查询服务和注册服务都须要依赖这个地址。默认是http://localhost:8761/eureka ;多个地址可以使用 , 分隔
eureka.client.serviceUrl.defaultZone=http://localhost:${server.port}/eureka/

application.yml形式(下面再也不给出)

eureka:
    client:
        fetch-registry: 
        register-with-eureka: false
        serviceUrl:
            defaultZone: http://localhost:${server.port}/eureka/
server:
    port: 7001
spring:
    application:
        name: Eureka Server

启动工程后,访问:http://localhost:7001/ 能够看到没有任何服务

上手-Eureka Client

建立提供服务的客户端,并向服务注册中心注册本身。实现一个RESTful API,经过传入两个参数a和b,最后返回a + b的结果

1.建立一个基础的Spring Boot工程,pom中添加依赖

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.3.5.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>Brixton.RELEASE</version>
        <type>pom</type>
        <scope>import</scope>
    </dependency>
    </dependencies>
</dependencyManagement>

2.实现/add请求处理接口,经过DiscoveryClient对象,在日志中打印出服务实例的相关内容

@RestController
public class ComputeController {

    private final Logger logger = Logger.getLogger(getClass());

    @Autowired
    private DiscoveryClient client;

    @RequestMapping(value = "/add" ,method = RequestMethod.GET)
    public Integer add(@RequestParam Integer a, @RequestParam Integer b) {
        ServiceInstance instance = client.getLocalServiceInstance();
        Integer r = a + b;
        logger.info("/add, host:" + instance.getHost() + ", service_id:" + instance.getServiceId() + ", result:" + r);
        return r;
    }

}

3.启动代码中添加@EnableDiscoveryClient注解,该注解能激活Eureka中的DiscoveryClient实现,才能实现Controller中对服务信息的输出。

@SpringBootApplication
@EnableEurekaServer
public class SpringCloudEurekaApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringCloudEurekaApplication.class, args);
    }
}

4.在application.properties添加如下配置:

#能够指定微服务的名称后续在调用的时候只须要使用该名称就能够进行服务的访问。
spring.application.name=Eureka Client   

server.port=8001    #端口
#属性对应服务注册中心的配置内容,指定服务注册中心的位置
eureka.client.serviceUrl.defaultZone=http://localhost:7001/eureka/

启动工程后,再次访问: http://localhost:7001/ 能够看到定义的服务被注册了

中止服务

1.直接停掉服务。

默认状况下,若是Eureka Server在90秒没有收到Eureka客户的续约,它会将实例从其注册表中删除。但这种作法的很差之处在于, 客户端已经中止了运行,但仍然在注册中心的列表中。 虽然经过必定的负载均衡策略或使用熔断器可让服务正常进行,但有没有方法让注册中心立刻知道服务已经下线呢?

2.为了让注册中心立刻知道服务要下线, 能够向eureka 注册中心发送delete请求

格式为 /eureka/apps/{application.name}(application的name)/划红线的地址

划红线的地址   eureka.client.instance.instance-id

下面是下线一个hello-service的例子。

下图是用postman 发送delete请求

值得注意的是,Eureka客户端每隔一段时间(默认30秒)会发送一次心跳到注册中心续约。若是经过这种方式下线了一个服务,而没有及时停掉的话,该服务很快又会回到服务列表中。

因此,能够先停掉服务,再发送请求将其从列表中移除。

http://127.0.0.1:7001/eureka/apps/config-server/WINDOWS-61L7RBP:config-server:8769

3.客户端主动通知注册中心下线

若是你的eureka客户端是是一个spring boot应用,能够经过调用如下代码通知注册中心下线。

DiscoveryManager.getInstance().shutdownComponent();

例子以下,在eureka client 中

@RestController
public class HelloController {
    @Autowired
    private DiscoveryClient client;
 
    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    public String index() {
        java.util.List<ServiceInstance> instances = client.getInstances("hello-service");       
        return "Hello World";
    }
    
    @RequestMapping(value = "/offline", method = RequestMethod.GET)
    public void offLine(){
        DiscoveryManager.getInstance().shutdownComponent();
    }   
}

GET 请求 127.0.0.1:6020/offline

相关文章
相关标签/搜索