SpringCloud 学习(3) --- Eureka(二)集群,负载均衡,重试机制

[TOC]

1、配置高可用的注册中心:集群

  • 步骤一:修改核心yml文件,application.yml,只配置服务名(共享内容)
#服务名
spring:
  application:
    name: eureka_demo3
  • 步骤二:创建application-10086.yml,配置10086端口和注册路径(10087)
#端口号
server:
  port: 10086
#注册地址
eureka:
  client:
    service-url:
      defaultZone: http://localhost:10087/eureka
    register-with-eureka: true   #是否注册自己到注册中心,默认值true(可省略)
    fetch-registry: true         #是否从注册中心拉取服务列表,默认值true(可省略)
  • 步骤三:创建application-10087.yml,配置10087端口和注册路径(10086)
#端口号
server:
  port: 10087
#注册地址
eureka:
  client:
    service-url:
      defaultZone: http://localhost:10086/eureka
    register-with-eureka: true   #是否注册自己到注册中心
    fetch-registry: true         #是否从注册中心拉取服务列表
  • 步骤四:修改核心yml文件,激活10086配置,并启动程序
#服务名
spring:
  application:
    name: eureka_demo3
  profiles:
    active: 10086
  • 步骤五:修改核心yml文件,激活10087配置,并启动程序
#服务名
spring:
  application:
    name: eureka_demo3
  profiles:
    active: 10087
  • 步骤六:测试结果

2、IDEA中配置多启动

3、eureka配置详情(了解原理)

服务提供者要向EurekaServer注册服务,并且完成服务续约等工作

  • 服务注册

    服务提供者在启动时,会检测配置属性中的:eureka.client.register-with-erueka=true参数是否正确,事实上默认就是true。如果值确实为true,则会向EurekaServer发起一个Rest请求,并携带自己的元数据信息,完成注册操作。

  • 服务续约

    在注册服务完成以后,服务提供者会提供一个心跳,定时向EurekaServer发送Rest请求,告诉EurekaServer:“我还活着”,称为服务续约(renew)

eureka:
  instance:
    lease-expiration-duration-in-seconds: 90
    lease-renewal-interval-in-seconds: 30

• lease-renewal-interval-in-seconds:服务续约(renew)的间隔,默认为30秒

• lease-expiration-duration-in-seconds:服务失效时间,默认值90秒

默认:每30s,服务会向注册中心发送一次心跳,证明自己还活着,超过90秒没有发送心跳,EurekaServer会认为"你"挂了,就会从服务列表移除

3.1.1客户端的配置

#注册路径
eureka:
  client:
    service-url:
      defaultZone: http://localhost:10086/eureka
    registry-fetch-interval-seconds: 5     #从注册中心获取服务列表间隔时间
  instance:
    lease-expiration-duration-in-seconds: 10    #服务失效时间(10秒即过期)
    lease-renewal-interval-in-seconds: 5        #服务续约时间(5秒一次心跳)    

3.1.2服务端的配置

#服务名
spring:
  application:
    name: eureka_demo
#服务端配置
eureka:
  server:
    eviction-interval-timer-in-ms: 4000   #剔除失效服务间隔时间
    enable-self-preservation: false       #关闭自我保护

4、Ribbon负载均衡

4.1、Provider(服务提供者--集群)

  • 同一个名称的服务,只要提供多个实例,注册到eureka中,就可以自动形成集群。

具体操作:

  • 步骤一:创建application-8081.yml文件,并配置端口号8081

    server:
       port: 8081
    
  • 步骤二:创建application-8082.yml文件,并配置端口号8082

    server:
      port: 8082
    
  • 步骤三:为两个yml文件,分别配置启动项

  • 步骤四:启动,测试

4.2、Consumer(服务调用方--消费者)

  • pon文件

    <dependencies>
            <!--web起步依赖-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <!-- Eureka客户端 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
            <!--spring boot监控-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-actuator</artifactId>
            </dependency>
        </dependencies>
    
    • yml文件

      server:
        port: 9090
      spring:
        application:
          name: client
      eureka:
        client:
          service-url:
            defaultZone: http://localhost:10086/eureka
      
  • 启动类

    package com.czxy;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    
    
    @SpringBootApplication
    @EnableEurekaClient
    public class ClientApplication {
        public static void main(String[] args) {
            SpringApplication.run(ClientApplication.class,args);
        }
    }
    
    
  • 编写配置类,配置RestTemplate实例

package com.czxy.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;


@Configuration
public class HttpConfig {
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

  • 编写dao,请求提供方/test

package com.czxy.dao;

import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;


@Component
public class DataDao {
    @Resource
    private RestTemplate restTemplate;

    public ResponseEntity<String> data(){
        String url = "http://localhost:8081/test";
        return restTemplate.getForEntity(url,String.class);
    }
}

  • 编写controller,显示数据,对外提供接口/data

package com.czxy.controller;

import com.czxy.dao.DataDao;
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 javax.annotation.Resource;


@RestController
@RequestMapping("/data")
public class DataController {
    @Resource
    private DataDao dataDao;

    @GetMapping
    public ResponseEntity<String> data(){
        return dataDao.data();
    }
}

4.3、负载均衡

  • eureka内置ribbon,也就是说自动集成负载均衡器。
  • 负载均衡器,就是在集群环境下,选择续约的服务。

  • 步骤一:修改配置类,让RestTemplate支持"服务名"访问机制

    • 添加注解@LoadBalanced
    package com.czxy.config;
    
    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
    public class HttpConfig {
        @Bean
        @LoadBalanced       //让RestTemplate支持负载均衡,也就是说支持“服务名”访问
        public RestTemplate restTemplate(){
            return new RestTemplate();
        }
    }
    
    
  • 步骤二:修改dao,使用RestTemplate进行远程调用时,使用"服务名"进行调用即可。

    package com.czxy.dao;
    
    import org.springframework.http.ResponseEntity;
    import org.springframework.stereotype.Component;
    import org.springframework.web.client.RestTemplate;
    
    import javax.annotation.Resource;
    
    
    @Component
    public class DataDao {
        @Resource
        private RestTemplate restTemplate;
    
        public ResponseEntity<String> data(){
          //String url = "http://localhost:8081/test";
            String url = "http://service/test";
            return restTemplate.getForEntity(url,String.class);
        }
    }
    
    

4、负载均衡策略

4.1.1负载均衡策略初体验

pom,添加test依赖

<!--测试-->
<dependency>
    <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
    </dependency>

测试类

package com.czxy;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;

/**
 * @author 庭前云落
 * @Date 2019/12/10 16:53
 * @description
 */
@SpringBootTest(classes=ClientApplication.class)   //Junit和Springboot整合,将所有实例加载到spring容器
@RunWith(SpringRunner.class)    //Junit和Spring整合,将spring容器中的数据注入当前类
public class TestRibbon {

    @Resource
    private RibbonLoadBalancerClient client;

    @Test
    public void testDemo(){
        //通过"服务名" 获得对应服务实例
        for (int i = 0; i < 10; i++) {
            ServiceInstance instance = client.choose("service");
            System.out.println(instance.getHost()+":"+instance.getPort());
        }
    }
}

Provoider(提供方)yml,支持显示IP地址,并重启8081和8082

#服务名
spring:
  application:
    name: service
#注册地址
eureka:
  client:
    service-url:
      defaultZone: http://localhost:10086/eureka
  instance:
    prefer-ip-address: true   #显示IP地址

4.1.2修改策略

  • 给指定的"服务"设置策略

    服务名.ribbon.NFLoadBalancerRuleClassName=策略实现类
    
    service4:
      ribbon:
        NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule    #随机
        #NFLoadBalancerRuleClassName : com.netflix.loadbalancer.BestAvailableRule           #并发最少
        #NFLoadBalancerRuleClassName : com.netflix.loadbalancer.WeightedResponseTimeRule    #请求时间权重
    

Ribbon 中提供了 七种 负载均衡策略

策略类命名描述
RandomRule随机策略随机选择 Server
RoundRobinRule轮询策略按照顺序循环选择 Server
RetryRule重试策略在一个配置时间段内,当选择的 Server 不成功,则一直尝试选择一个可用的 Server
BestAvailableRule最低并发策略逐个考察 Server,如果 Server 的断路器被打开,则忽略,在不被忽略的 Server 中选择并发连接最低的 Server
AvailabilityFilteringRule可用过滤测试过滤掉一直连接失败,并被标记未 circuit tripped(即不可用) 的 Server,过滤掉高并发的 Server
ResponseTimeWeightedRule响应时间加权策略根据 Server 的响应时间分配权重,响应时间越长,权重越低,被选择到的几率就越低
ZoneAvoidanceRule区域权衡策略综合判断 Server 所在区域的性能和 Server 的可用性轮询选择 Server,并判定一个 AWS Zone 的运行性能是否可用,剔除不可用的 Zone 中的所有 Server

Ribbon 默认的负载均衡策略是 轮询策略

5、重试机制

  • 重试机制:服务B访问集群环境下的服务A,某一个服务A遇到故障无法访问,服务B将尝试访问其他可以使用的服务A。
  • 9090访问8081和8082
  • 如果8082宕机了
  • 9090将尝试访问8081

当访问到故障请求的时候,它会再尝试访问一次当前实例(次数由MaxAutoRetrires这个配置决定),如果不行,就换一实例进行访问,如果还是不行,再换一次实例访问(更换次数是由MaxAutoRetriesNextServer配置),如果依然不行,再返回失败信息。

如果你现在有A,B,C 3个服务,如果把A,B都停掉MaxAutoRetriesNextServer=2,则C可能没有被轮询查询的机会,如果你把MaxAutoRetriesNextServer=3,则没问题。

当用eureka做注册中心,当服务撕掉或者因为网络故障导致服务不可用时,eureka不会马上剔除这个服务,而是将它保留等待修复

pom,添加重试retry依赖

<!--重试机制-->
<dependency>
     <groupId>org.springframework.retry</groupId>
     <artifactId>spring-retry</artifactId>
</dependency>

yml,开启cloud重试机制

spring:
  cloud:
    loadbalancer:
      retry:
        enabled: true   #开启重试机制

配置当前服务的重试参数

service4:
  ribbon:
    ConnectTimeout: 250              # Ribbon的连接超时时间
    ReadTimeout: 1000                # Ribbon的数据读取超时时间
    OkToRetryOnAllOperations: true   # 是否对所有操作都进行重试
    MaxAutoRetriesNextServer: 1      # 切换实例的重试次数
    MaxAutoRetries: 1                # 对当前实例的重试次数
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值