Spring Cloud 学习笔记(一) -服务治理

Spring Cloud Eureka 服务治理

服务治理可以说是SpringCloud微服务架构中最为核心核基础的模块, 它主要实现各个微服务实例的自动化注册和发现。

  • 服务注册:
    在服务框架中, 通常会构建一个注册中心,每个服务启动时向注册中心登记自己提供的服务,并将自身信息(主机,端口、协议等)告知注册中心,注册中心按照服务名分类组织服务清单。
  • 服务发现:
    在服务的框架下,服务间的调用不再通过指定具体的实例地址来实现, 而是通过服务名发起请求来实现,所以服务调用方在调用服务接口的时候,并不知道具体的服务实例位置。因此,调用方需要向服务注册中心咨询服务,并获取所有服务的实例清单。
  • Spring Cloud Eureka, 使用netfix Eureka来实现服务注册和发现, 他既包含服务端,也包含客户端组件, 服务端我们也称为服务注册中心,Eureka客户端主要处理服务的发现和注册。

搭建服务注册中心

1、 创建一个SpringBoot 工程,命名为eureka-server, 并在pom.xml中引入依赖。

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

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

2、 通过注解@EnableEurekaServer 启动一个服务注册中心提供给其他应用进行对话。
如下:

@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {

    public static void main(String[] args) {
        new SpringApplicationBuilder(EurekaServerApplication.class).web(true).run(args);
    }
}

3、 默认情况下, 该服务的注册中心也会将自己作为客户端来尝试注册自己,所以我们要禁用它的客户端注册行为,只需要在application.yml中添加以下配置:

server:
  port: 8081

eureka:
  instance:
    hostname: localhost
  client:
    register-with-eureka: false
    fetch-registry: false
  • euraka.client.register-with-enreka: 设为false,代表不向注册中心注册自己
  • eureka.client.fetch-registry : 由于注册中心的职责是维护服务实例,他并不需要去检索服务, 所以设置为false
    4、 启动应用,并访问 http://localhost:8081/ ,可以看到Eureka的信息面板,其中Instance currently registered with Eureka 栏是空的,说明该注册中心还没有注册任何服务。

注册服务提供者

在完成服务注册中心搭建之后,接下来尝试将一个既有的Springboot应用加入到Eureka的服务治理体系中去。
1、 pom.xml中增加Spring Cloud Eureka模块的依赖,如下:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Dalston.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

2、 添加/hello 请求处理接口

@RestController
public class HelloController {
    @Autowired
    private DiscoveryClient discoveryClient;

    @RequestMapping("/hello")
    public String index(){
        ServiceInstance instance = discoveryClient.getLocalServiceInstance();
        System.out.println("Hello host:"+instance.getHost()+",service_id:"+instance.getServiceId());
        return "Hello Word";
    }
}

3、 在主类中添加注解

@EnableEurekaClient
@SpringBootApplication
public class EurekaClientApplication {
    public static void main(String[] args) {
        new SpringApplicationBuilder(
                EurekaClientApplication.class)
                .web(true).run(args);
    }

}

4、配置application.yml

spring:
  application:
    name: eureka-client
server:
  port: 8083
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8081/eureka/
  • spring.application.name 属性为服务名
  • eureka.client.serviceUrl.defaultZone=http://localhost:8081/eureka/ 指定服务注册中心的地址

5、启动程序, 再次访问 http://localhost:8081/ ,可以看到Eureka的信息面板,其中Instance currently registered with Eureka 有一条注册服务信息的信息。

Ribbon 服务的发现与消费

下面尝试构建一个服务消费者,它主要有两个目标,发现服务以及消费服务。其中发现服务由eureka的客户端来完成,而服务的消费的任务是由Ribbon完成。Ribbon 是一个基于HTTP和TCP的客户端的负载均衡器。下面创建一个简单的例子:

1、 首先在8082和8083端口号下,启动eurake-client,这时候可以在注册中心界面可以看到名为enreka-cilent 下有两个实例。
2、 创建一个SpringBoot 基础工程来实现服务消费者,取名为service-ribbon,并在pom.xml中添加依赖,如下:

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

3、配置application.yml

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8081/eureka/
server:
  port: 8085
spring:
  application:
    name: service-ribbon

4、 创建应用主类,并通过@EnableDiscoveryClient 注解让该应用注入为Eureka客户端应用,以获取服务发现的能力,同时,在该类中创建RestTemplate的Spring Bean实例,并通过@LoadBalanced注解开启客户端负载均衡,如下:

@EnableDiscoveryClient
@SpringBootApplication
public class ServiceRibbonApplication {

    @Bean
    @LoadBalanced
    RestTemplate restTemplate(){
        return new RestTemplate();
    }

    public static void main(String[] args) {
        SpringApplication.run(ServiceRibbonApplication.class, args);
    }
}
@RestController
public class ConsumerController {
    @Autowired
    RestTemplate restTemplate;

    @RequestMapping("/ribbon-consumer")
    public String helloConsumer(){
        return restTemplate.getForEntity("http://EUREKA-CLIENT/hello",String.class).getBody();
    }
}

5、这是我们启动应用,再注册中心的面板上看到8085的服务已经启动,多次输入http://localhost:8085/ribbon-consumer ,会在EUREKA-CLIENT服务的8082、8083控制台交替打印日志。


Eureka详解——服务治理机制

1、 服务提供者

  • 服务注册
    “服务提供者”在启动的时候会通过发送REST请求的方式将自己注册到Eureka Server 上, 同时带上自身服务的一些元数据信息,Eureka Server 接收到这个REST请求之后,将元数据信息保存在一个双层结构的Map中,其中一层是的key是服务名,第二层的key 是具体服务的实例名
  • 服务同步
    如果两个服务提供者分别注册到两个不同的服务注册中心上, 也就是说,他们的信息分别被两个服务注册中心所维护,此时, 由于服务注册中心之间因为互相注册为服务,当服务提供者发送注册请求到一个服务注册中心时,他会将该请求转发给集群中相连的其他的注册中心, 从而实现注册中心之间的服务同步。
  • 服务续约
    再注册玩服务之后,服务提供者会维护一个心跳来告诉Eureka Server,说明这个服务正在启用。

    eureka.instance.lease-renewal-interval-in-seconds=30 定义服务续约任务的调用间隔时间
    eureka.instance.lease-expiration-duration-in-seconds=90 定义服务失效的时间

2、 服务消费者

  • 获取服务
    获取服务首先要保证 该服务已在Eureka Server中注册, 必须确保enreka.client.fetch-registry=true参数没有被修改称false, 该值默认为true

    enreka.client.fetch-registry=true 是否检索服务

    eureka.client.registry-fetch-interval-seconds = 30 修改缓存清单的更新时间

  • 服务调用
    服务消费者在获取服务清单后,通过服务名可以获得具体提供服务的实例名和该实例的元数据信息,之后,客户端可以改居自己的需求决定具体调用哪个实例,Ribbon中会默认采用轮训的方式进行调用,从而实现客户端的负载均衡。

  • 服务下线
    当服务实例进行正常关闭时,会触发一个服务下线的REST请求给Eureka Server ,告诉服务注册中心,这时服务端收到该请求后,将该服务状态设置为显现(DOWN),并把下线事件传播出去

3、 服务注册中心

  • 失效剔除
    当服务实例没有正常下线时,可能是其他原因导致服务故障,而注册中心没有收到下线请求。为了将折现无法提供服务的实例剔除,Eureka Server 在启动的时候会创建一个定时任务,默认60S将当前清单中没有续约的服务剔除掉

  • 自我保护
    Eureka Server 在运行期间,会统计心跳失败比例在15分钟之内是否会低于85%,如果低于情况(可能是网络不稳定导致),Eureka Server 会将当前实例注册信息保护起来,让这些实例不会过期,尽可能保护这些注册信息。但是,这段时间内实例若出现问题,那么客户端很容易拿到的实际已经不存在的服务实例,会出现调用失败的情况, 所以客户端必须要有容错机制,比如请求重试、断路器等机制。

4、 高可用eurake 配置

通过运行多个实例并请求他们相互注册,可以使Eureka更具弹性和可用性。事实上,这是默认的行为,所以你需要做的只是为对方添加一个有效的serviceUrl;您可以向系统添加多个对等体,只要它们至少一个边缘彼此连接,则它们将在它们之间同步注册

eureka:
  instance:
    prefer-ip-address: true
  client:
    register-with-eureka: false
    serviceUrl:
      defaultZone: http://127.0.0.1:8082/eureka/
spring:
  application:
    name: eureka-server01

-------
eureka:
  instance:
    prefer-ip-address: true
  client:
    register-with-eureka: false
    serviceUrl:
      defaultZone: http://127.0.0.1:8081/eureka/
server:
  port: 8082
spring:
  application:
    name: eureka-server02

猜你喜欢

转载自blog.csdn.net/panleiaiying/article/details/79323762