学习记录 互联网项目---2(Eureka详解,负载均衡入门)

天大地大妈咪最大 提交于 2019-12-10 10:53:17

2.4 Eureka详解

2.4.1 优化集群:高可用的注册中心

  • Eureka demo即服务的注册中心,事实上Eureka demo也可以是一个集群,形成高可用的Eureka注册中心

  • 服务同步

    • 多个Eureka Server之间也会互相注册为服务,当服务提供者注册到Eureka Server集群中的某个节点时
    • 该节点会把服务的信息同步给集群中的每个节点,从而实现数据同步
    • 因此,无论客户端访问到Eureka Server集群中的任意一个节点,都可以获取到完整的服务列表信息。
  • 搭建高可用的注册中心

  • 我们假设要搭建两条EurekaServer的集群,端口分别为:10086和10087
    • application-10086.yml

      # 端口号
      server:
        port: 10086
      # eureka的配置
      eureka:
        client:
          service-url:
            defaultZone: http://localhost:10087/eureka/
      
    • application-10087.yml

      # 端口号
      server:
        port: 10087
      # eureka的配置
      eureka:
        client:
          service-url:
            defaultZone: http://localhost:10086/eureka/
      

所谓的高可用注册中心,其实就是把EurekaServer自己也作为一个服务进行注册,这样多个EurekaServer之间就能互相发现对方,从而形成集群。因此我们做了以下修改:

  • 删除了register-with-eureka=false和fetch-registry=false两个配置。

​ 因为默认值是true,这样就会吧自己注册到注册中心了。

  • 把service-url的值改成了另外一台EurekaServer的地址,而不是自己

  • 使用SpringBoot启动加载两个配置文件

2.4.2 优化:服务提供者配置

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

  • 服务注册

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

    • 在注册服务完成以后,服务提供者会维持一个心跳(定时向EurekaServer发起Rest请求),告诉EurekaServer:“我还活着”。这个我们称为服务的续约(renew);
    eureka:
      instance:
        lease-expiration-duration-in-seconds: 10	#服务失效时间(默认90秒)
        lease-renewal-interval-in-seconds: 5	#发送心跳续约时间(默认30秒)
    
    • 这两个值在生产环境不要修改,默认即可。但是在开发时,这个值有点太长了,经常我们关掉一个服务,会发现Eureka依然认为服务在活着。所以我们在开发阶段可以适当调小

2.4.3 优化:服务消费者配置

当服务消费者启动是,会检测eureka.client.fetch-registry=true参数的值,如果为true,则会从Eureka Server服务的列表只读备份,然后缓存在本地。并且每隔30秒会重新获取并更新数据。我们可以通过下面的参数来修改

eureka:
  client:
    registry-fetch-interval-seconds: 5		#从注册中心,获得列表的间隔时间(默认30秒)

生产环境中,我们不需要修改这个值。

但是为了开发环境下,能够快速得到服务的最新状态,我们可以将其设置小一点。

2.4.4 注册中心优化:失效剔除和自我保护

  • 失效剔除

    ​ 有些时候,我们的服务提供方并不一定会正常下线,可能因为内存溢出、网络故障等原因导致服务无法正常工作。Eureka Server需要将这样的服务剔除出服务列表。因此它会开启一个定时任务,每隔60秒对所有失效的服务(超过90秒未响应)进行剔除。

    可以通过eureka.server.eviction-interval-timer-in-ms参数对其进行修改,单位是毫秒,生成环境不要修改。

  • 自我保护

    ​ 这是触发了Eureka的自我保护机制。当一个服务未按时进行心跳续约时,Eureka会统计最近15分钟心跳失败的服务实例的比例是否超过了85%。在生产环境下,因为网络延迟等原因,心跳失败实例的比例很有可能超标,但是此时就把服务剔除列表并不妥当,因为服务可能没有宕机。Eureka就会把当前实例的注册信息保护起来,不予剔除。生产环境下这很有效,保证了大多数服务依然可用

eureka:
  server:
    enable-self-preservation: false # 关闭自我保护模式(默认为打开)
    eviction-interval-timer-in-ms: 10000 # 扫描失效服务的间隔时间/毫秒(默认为60*1000ms)

3. 负载均衡

3.1 服务提供者

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

  • 步骤一:配置yml文件

  • application-8081.yml 仅配置端口号

server:
  port: 8081
  • application-8082.yml 仅配置端口号
server:
  port: 8082
  • 步骤二: 为两个yml文件配置SpringBoot启动类

  • 步骤三: 启动测试

3.2 开启负载均衡

因为Eureka中已经集成了Ribbon,所以我们无需引入新的依赖。直接修改代码:

  • 服务提供方

    • 导入RestTemplate依赖

        <dependency>
                  <groupId>org.apache.httpcomponents</groupId>
                  <artifactId>httpclient</artifactId>
                  <version>4.5.5</version>
        </dependency>
      
    • 测试数据

package com.czxy.controller;

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.servlet.http.HttpServletRequest;

/**
 * Created by liangtong.
 */
@RestController
@RequestMapping("/test")
public class TestController {
    @GetMapping
    public ResponseEntity<String> test(HttpServletRequest request){
        //  返回自己的服务器端口号
        return ResponseEntity.ok("测试数据" + request.getServerPort());
    }
}
  • 服务使用方

    • 编写配置类,配置RestTemplate实例

      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;
      
      /**
       * Created by liangtong.
       */
      @Configuration
      public class HttpConfig {
          [@Bean](https://my.oschina.net/bean)
          @LoadBalanced       //让RestTemplate支持负载均衡,也就是说支持“服务名”访问
          public RestTemplate restTemplate(){
              return new RestTemplate();
          }
      }
      
    • 步骤二:修改dao,使用RestTemplate进行远程调用时,使用“服务名”进行调用即可。

      package com.czxy.controller;
      
      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 org.springframework.web.client.RestTemplate;
      
      import javax.annotation.Resource;
      
      /**
       * Created by 澈 on 2019/12/10.
       */
      @RestController
      @RequestMapping("/data")
      public class DataController {
      
          @Resource
          private RestTemplate restTemplate;
      
          @GetMapping
          public ResponseEntity<String> dataDemo01(){
              //使用服务名进行访问
              return restTemplate.getForEntity("http://service/test",String.class);
          }
      }
      
    • 测试----未指定端口号,轮换访问两个服务器

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!