Eureka, Ribbon, Feign introduction and use of

About Eureka

Eureka is a sub-module of Netflix, it is one of the core modules. Eureka is a REST-based services, for location services, the intermediate layer in order to achieve the cloud service discovery and failover, without the need to modify the configuration file service call. Functions like the registry Dubbo, such as Zookeeper.

Spring Cloud to provide service registry to manage the micro-services information, to solve the following problems:

  • Micro-ip and port management services
    separate back-end large-scale infrastructure front, the service layer is split into a lot of micro-services, front-end interface to provide remote call back would need to know the server's ip address and port of registry helps us manage ip and port those servers .
  • Micro-service state management
    micro service is real-time reporting their status, the registry unified management of these micro-state of the service, there will be kicked out of the service in question a list of services , clients get services that are available to be called

Eureka realizes the functions of service management, service delivery and client, the server is Eureka service registry, client services to micro Eureka complete the registration services and discovery. Eureka Server and Eureke Client diagram:
Here Insert Picture Description

  • Eureka Server is the server responsible for managing information and the status of each micro-services node
  • Eureka Client deployment program on micro-services, remote access Eureka Server will register itself in Eureka Server
  • When the micro-micro-services needs to call another service to obtain service call address from Eureka Server, the remote call

Build Eureka Server

JDK8

Stand-alone environment to build

1 Create maven sub-projects (Eureka server)
2 add-dependent
parent project:

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring‐cloud‐dependencies</artifactId>
	<version>Finchley.SR1</version>
	<type>pom</type>
	<scope>import</scope>
</dependency>

Sub-projects:

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

3 startup class
mainly @EnableEurekaServercomment

@EnableEurekaServer//标识这是一个Eureka服务
@SpringBootApplication
public class GovernCenterApplication {
	public static void main(String[] args) {
		SpringApplication.run(GovernCenterApplication.class, args);
	}
}

4 Configuration

server:
  port: 50101
eureka:
  client:
    registerWithEureka: false #服务注册,是否将自己注册到Eureka服务中
    fetchRegistry: false #服务发现,是否从Eureka中获取注册信息
    serviceUrl: #Eureka客户端与Eureka服务端的交互地址,高可用状态配置对方的地址,单机状态配置自己的地址(如果不配置则默认本机8761端口)
     defaultZone: http://localhost:50101/eureka/
  server:
    enable‐self‐preservation: false #禁用自我保护模式
    eviction‐interval‐timer‐in‐ms: 60000 #服务注册表清理间隔(单位毫秒,默认是60*1000)

Parameter Description:

  • registerWithEureka: service registration, whether to register their services to Eureka
  • Needs to be set to true when you need to find the target service to be called from Eureka in: fetchRegistry
  • serviceUrl.defaultZone: interactive address Eureka Eureka client and server-side, high-availability configuration status of each other's addresses, configure single state their address (if not the default configuration of the machine 8761 port)
  • enable-self-preservation: self-protection mechanisms . Eureka Server has a self-protection mode, Eureka Server service will protect the information in the registry, do not write off any service instance, that when the micro-services were no longer reported health status, does not remove the service from the registry. When it receives the heart rate restored to above the threshold, the Eureka Server node will automatically exit the self-protection mode. This value is set to true, Eureka server enter the protection mode
  • eviction-interval-timer-in-ms: failure to clean up the node intervals, this period will be reported if the node does not receive the node removed from the list of services in

After starting Eureka Server, can be accessed through the browser localhost: 50101 Eureka view of information:
Here Insert Picture Description

High availability environment to build

If it is a stand-alone environment, Eureka Server is down, that among micro-services would not be able to call up. So configure multiple Eureka Server each other mutually registered, micro-services need to connect two Eureka Server registration, when one of them died Eureka Server will not affect the registration and discovery services to ensure high system availability.

Here implemented on a loom, with two different analog ports availability

1 profiles

server:
  port: ${PORT:50101} #服务端口
spring:
  application:
    name: govern-center #指定服务名
eureka:
  client:
    registerWithEureka: true #服务注册,是否将自己注册到Eureka服务中
    fetchRegistry: true #服务发现,是否从Eureka中获取注册信息
    serviceUrl: #Eureka客户端与Eureka服务端的交互地址,高可用状态配置对方的地址,单机状态配置自己(如果不配置则默认本机8761端口)
     defaultZone:  ${EUREKA_SERVER:http://eureka02:50102/eureka/}
  server:
    enable‐self‐preservation: false #是否开启自我保护模式
    eviction‐interval‐timer‐in‐ms: 60000 #服务注册表清理间隔(单位毫秒,默认是60*1000)
  instance:
    hostname: ${EUREKA_DOMAIN:eureka01}

2 IDEA配置
-DPORT=50101 -DEUREKA_SERVER=http://eureka02:50102/eureka/ -DEUREKA_DOMAIN=eureka01
Here Insert Picture Description
-DPORT=50102 -DEUREKA_SERVER=http://eureka01:50101/eureka/ -DEUREKA_DOMAIN=eureka02
Here Insert Picture Description
分别启动eureka01和eureka02,浏览器访问http://localhost:50101/
Here Insert Picture Description
浏览器访问http://localhost:50102/
Here Insert Picture Description

服务注册

将微服务注册到Eureka Server中

1 在微服务中添加依赖(作为Eureka Client)

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring‐cloud‐starter‐netflix‐eureka‐client</artifactId>
</dependency>

2 配置yml

server:
  port: 3000
spring:
  application:
    name: service-manage
eureka:
  client:
    registerWithEureka: true #服务注册开关
    fetchRegistry: true #服务发现开关
    serviceUrl: #Eureka客户端与Eureka服务端进行交互的地址,多个中间用逗号分隔
      defaultZone: ${EUREKA_SERVER:http://localhost:50101/eureka/,http://localhost:50102/eureka/}
  instance:
    prefer-ip-address:  true  #将自己的ip地址注册到Eureka服务中
    ip-address: ${IP_ADDRESS:127.0.0.1}
    instance-id: ${spring.application.name}:${server.port} #指定实例id

3 在微服务启动类上添加注解@EnableEurekaClient,表示它是一个Eureka的客户端
4 刷新Eureka Server
Here Insert Picture Description
截止这里,已经搭建了Eureka Server高可用环境以及微服务(Eureka Client)向Eureka Server的注册功能。

客户端负载均衡器Ribbon

远程调用即微服务之间相互调用的工作流程为(微服务A调用微服务B):

  1. A、B微服务将自己注册到注册中心
  2. A从注册中心获取B的服务地址
  3. A远程调用B

第二步中,B服务可能部署在多个节点上,因此还需要用到客户端负载均衡器

简介和配置

Ribbon是一个基于HTTP、TCP的客户端负载均衡器。消费方从服务注册中心获知有哪些地址可用,然后再从这些地址中选择一个合适的服务器。客户端负载均衡与服务端负载均衡的区别在于客户端要维护一份服务列表,Ribbon从Eureka Server获取服务列表,Ribbon根据负载均衡算法(如轮询)直接请求到具体的微服务。

使用Ribbon(微服务A调用微服务B)
1 在这个地方,设置两个微服务B,类似上面高可用性Eureka的设置
B01

server:
  port: ${PORT:3000} #服务端口

B02

server:
  port: ${PORT:3001} #服务端口

Here Insert Picture Description
2 微服务A和微服务B注册到Eureka Server中
3 在微服务A中添加ribbon依赖
因为要远程调用,选择使用okhttp提供的RestTemplate

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring‐cloud‐starter‐ribbon</artifactId>
</dependency>
<dependency>
	<groupId>com.squareup.okhttp3</groupId>
	<artifactId>okhttp</artifactId>
</dependency>

4 配置微服务A

ribbon:
	MaxAutoRetries: 2 #最大重试次数,当Eureka中可以找到服务,但是服务连不上时将会重试
	MaxAutoRetriesNextServer: 3 #切换实例的重试次数
	OkToRetryOnAllOperations: false #对所有操作请求都进行重试,如果是get则可以,如果是post,put等操作没有实现幂等的情况下是很危险的,所以设置为false
	ConnectTimeout: 5000 #请求连接的超时时间
	ReadTimeout: 6000 #请求处理的超时时间

5 启动B01和B02服务
6 在A服务器的启动类中定义RestTemplate,并使用@LoadBalanced注解

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

7 测试

//负载均衡调用
@Test
public void testRibbon() {
	//服务id
	String serviceId = "SERVICE‐MANAGE";
	for(int i=0;i<3;i++){
		//通过服务id调用
		返回值 = restTemplate.getForEntity("调用B服务的接口url", 返回值类型(XX.class);
		返回值2 = 返回值.getBody();
	}
}

三次调用B服务的接口,会轮询地调用B01和B0服务。

Ribbon核心组件IRule

IRule:根据特点算法从服务列表中选取一个要访问的服务,即Ribbon的负载均衡算法。
负载均衡算法:

  • RoundRobinRule:轮询(默认算法)
  • RandomRule:随机
  • AvailabilityFilteringRule:会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务、并发的连接数量超过阈值的服务,然后对剩余的服务列表按照轮询策略进行访问
  • WeightedResponseTimeRule:根据平均响应时间计算所有服务的权重,响应时间越快,权重越大,被选中的概率越高,刚启动时,如果统计信息不足,则使用RoundRobinRule策略,等统计信息足够,会切换到WeightedResponseTimeRule
  • RetryRule:先按照RoundRobinRule的策略获取服务,如果某个服务获取失败次数达到阈值,则后续请求不会再访问该方法
  • BestAvailableRule:会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务
  • ZoneAvoidanceRule:复合判断server所在区域的性能和server的可用性选择服务器

在A服务器的启动类中添加方法,指定轮询算法:

@Bean
public IRule myRule() {
	return new RandomRule();
}

Feign

简介和配置

Feign是一个声明式Web Service客户端,使用Feign能让编写Web Service客户端更加简单,它的使用方法是定义一个接口,然后在上面添加注解,同时也支持JAX-RS标准的注解。Feign也支持可拔插式的编码器和解码器。Spring Cloud对Feign进行了封装,使其支持了Spring MVC标准注解和HttpMessageConverters。Feign可以与Eureka和Ribbon组合使用以支持负载均衡。

1 在A服务中添加依赖

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring‐cloud‐starter‐openfeign</artifactId>
</dependency>
<dependency>
	<groupId>com.netflix.feign</groupId>
	<artifactId>feign‐okhttp</artifactId>
</dependency>

2 定义Feign接口

@FeignClient(value = "SERVICE-MANAGE") //指定远程调用的服务名
public interface ServerAClient {
    //根据页面id查询页面信息,远程调用cms请求数据
    @GetMapping("远程调用的uri")
    public 返回值类型 find(参数);
}

3 启动类添加@EnableFeignClients注解,启动类启动的时候会扫描带@FeignClient注解的接口,并生成此接口的代理
对象
4 测试

@SpringBootTest
@RunWith(SpringRunner.class)
public class TestFeign {
    @Autowired
    ServerAClient serverAClient ; //接口代理对象,由Feign生成代理对象

    @Test
    public void testRibbon(){
        //发起远程调用
        返回值类型 返回值= serverAClient.find(测试);
    }
}

这样,就能在A服务中调用B服务的接口,不需要注入RestTemplate

Feign工作原理原理

  • 启动类添加@EnableFeignClients注解,Spring会扫描标记了@FeignClient注解的接口,并生成此接口的代理
    对象
  • @FeignClient指定了B服务名称,Feign会从注册中心获取B服务列表,并通过负载均衡算法进行服务调用
  • 在接口方法中使用注解@GetMapping或者其他注解,指定调用的url,Feign将根据url进行远程调用

服务熔断Hystrix

多个微服务之间调用的时候,假设微服务A调用微服务B和微服务C,微服务B和微服务C又调用其它的微服务,这就是“扇出”。如果扇出的链路上某个微服务的调用响应时间过长或者不可用,对微服务A的调用就会占用越来越多的资源,进而引起系统崩溃,这就是“雪崩效应”。

Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统里,徐国依赖不可避免的会调用失败,比如超时、异常等,Hystrix能保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。

“断路器”本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个符合预期的、可处理的备选响应(FallBack),而不是长时间的等待或者抛出调用方法无法处理的异常,这样就保证了服务调用方的线程不会被长时间、不必要地占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩。

熔断机制是应对雪崩效应的一种微服务链路保护机制。当扇出链路的某个微服务不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回响应想。当检测到该节点微服务调用响应正常后恢复调用链路。在SpringCloud框架里,熔断机制通过Hystrix实现。Hystrix会监控微服务间调用的状况,当失败的调用到一定阈值,缺省是5s内20次调用失败就会启动熔断机制。

服务熔断配置
在微服务上引入依赖:

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

在微服务方法上加上注解:

@RequestMapping(value = "/dept/get/{id}", method = RequestMethod.GET)
//一旦调用服务方法失败并抛出了错误信息后,会自动调用@HystrixCommand标注好的fallbackMethod调用类中的指定方法
@HystrixCommand(fallbackMethod = "processHystrix_Get")
public String get(@PathVariable("id") Long id)
{
	//调用业务方法

	if (XXX) {
		throw new RuntimeException("null");
	}

	return "xxx";
}
public String processHystrix_Get(@PathVariable("id") Long id)
{
	return "没有没有对应的信息";
}

在启动类上加上注解@EnableCircuitBreaker

Eureka和Zookeeper比较

【注:本节内容来自尚硅谷周阳老师,有几个小细节我进行了改动】

著名的CAP理论提出,一个分布式系统不可能同时满足C(一致性)、A(可用性)和P(分区容错性)。由于分区容错性在分布式系统中必须要保证,因此只能在A和C之间进行权衡(A和C无法同时满足)。
Eureka和Zookeeper重要区别就是Zookeeper保证的是CP、Eureka保证的是AP。

Zookeeper保证CP

当向注册中心查询服务列表时,我们可以容忍注册中心返回的是几分钟以前的注册信息,但不能接受服务直接down调不可用,也就是说,服务注册功能对可用性的要求要高于一致性。但是Zookeeper会出现服务直接down调不可用的情况,Zookeeper使用了主从结构(部署多个注册服务中心,主节点称为Leader,从节点称为Follower),当Leader因为网络故障与其他节点失去联系时,剩余节点会重写进行Leader选举。问题在于,选举Leader的时间太长,30~120s,且选举期间整个Zookeeper集群是不可用的,这就导致在选举期间注册服务瘫痪。在云部署的环境下,因网络问题是的Zookeeper集群失去Leader节点是较大概率会发生的,虽然服务能够最终恢复,但是漫长的选举时间导致的注册长期不可用是不能容忍的。【但是Zookeeper使用主从结构,保证了数据的一致性】

Eureka保证AP

Eureka在设计时优先保证可用性。Eureka各个节点是平等的,几个节点挂掉不会影响正常节点的工作,剩余的节点依然可以提供注册和查询服务。Eureka的客户端在向某个Eureka注册时,如果发现连接失败,则会自动切换至其他节点,只要有一台Eureka还在,就能保证注册服务可用(保证可用性)只不过查询到的信息可能不是最新的(不保证强一致性)。除此之外,Eureka还有一种自我保护机制,如果在15分钟内超过85%的节点都没有正常的心跳,那么Eureka就认为客户端与注册中心出现了故障,此时会出现以下几种情况:

  • Eureka不再从注册列表中移除因为长时间没有收到心跳而应该过期的服务
  • Eureka仍然能够接受新服务的注册和查询请求,但是不会被同步到其他节点上(即保证当前节点依然可用)
  • 网络稳定时,当前实例新的注册信息会被同步到其他节点中

因此,Eureka可以很好的应对因网络故障导致部分节点失去联系的情况,而不会像Zookeeper那样使整个注册服务瘫痪。

Published 243 original articles · 87 won praise · views 70000 +

Guess you like

Origin blog.csdn.net/IT_10/article/details/104026137