分布式之Eureka

一、Eureka简介

Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。SpringCloud将它集成在其子项目spring-cloud-netflix中,以实现SpringCloud的服务发现功能。

  1. Eureka组件
      Eureka包含两个组件:Eureka Server和Eureka Client。

    1.1 Eureka Server
      Eureka Server提供服务注册服务,各个节点启动后,会在Eureka Server中进行注册,这样Eureka Server中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到。
      Eureka Server本身也是一个服务,默认情况下会自动注册到Eureka注册中心。
      如果搭建单机版的Eureka Server注册中心,则需要配置取消Eureka Server的自动注册逻辑。毕竟当前服务注册到当前服务代表的注册中心中是一个说不通的逻辑。
      Eureka Server通过Register、Get、Renew等接口提供服务的注册、发现和心跳检测等服务。

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

1.2 Eureka Client
  Eureka Client是一个java客户端,用于简化与Eureka Server的交互,客户端同时也具备一个内置的、使用轮询(round-robin)负载算法的负载均衡器。在应用启动后,将会向Eureka Server发送心跳,默认周期为30秒,如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点移除(默认90秒)。
  Eureka Client分为两个角色,分别是:Application Service(Service Provider)和Application Client(Service Consumer)

		<!-- Eureka-client -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
  1. Eureka和Zookeeper的不同
      ZooKeeper注册中心集群搭建后,集群中各节点呈现主从关系,集群中只有主节点对外提供服务的注册和发现功能,从节点相当于备份节点,只有主节点宕机时,从节点会选举出一个新的主节点,继续提供服务的注册和发现功能。
      Eureka Server注册中心集群中每个节点都是平等的,集群中的所有节点同时对外提供服务的发现和注册等功能。同时集群中每个Eureka Server节点又是一个微服务,也就是说,每个节点都可以在集群中的其他节点上注册当前服务。又因为每个节点都是注册中心,所以节点之间又可以相互注册当前节点中已注册的服务,并发现其他节点中已注册的服务

二、Eureka使用

  1. 搭建Eureka Server
    依赖:
		<!-- eurake-server -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>

配置文件:

server:
  port: 7001

eureka:
  instance:
    hostname: eureka7001.com # eureka服务端实例名称
  client:
    register-with-eureka: false  #false表示不向注册中心注册自己
    fetch-registry: false  # 表示当前是注册中心,不需要检索服务
    service-url:
      # 设置eureka地址,如果是单机版就写本机地址;否则写另一个注册中心的地址
      defaultZone: http://eureka7002.com:7002/eureka/
server:
  port: 7002


eureka:
  instance:
    hostname: eureka7002.com
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/

启动类上需要加注解@EnableEurekaServer

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

接口:

@RestController
@Slf4j  //日志
public class PaymentController {

    @Autowired
    private PaymentService paymentService;
    @Value("${server.port}")
    private String serverPort;

    /**
     * @Description 创建订单 
     * @Date 18:57 2020/12/23
     * @Param [serial]
     * @return void
     */
    @PostMapping(value = "payment/creatPayment")
    public CommonResult createPayment(@RequestBody Payment payment){
        int result = paymentService.creatPayment(payment);
        log.info("*************插入结果:"+ result);
        if (result > 0){
            return new CommonResult(200,"创建订单成功,serverPort:" + serverPort,result);
        }else {
            return new CommonResult(444,"创建订单失败",null);
        }
    }
    
    /**
     * @Description 查看订单列表
     * @Date 19:00 2020/12/23
     * @Param []
     * @return java.util.List<com.wn.springcloud.entities.Payment>
     */
    @GetMapping(value = "payment/payments")
    public CommonResult selectPayments(){
        List<Payment> list = paymentService.selectPayments();
        log.info("*************查询订单列表:" );
        if (list != null){
            return new CommonResult(200,"查询成功,serverPort:" + serverPort,list);
        }else {
            return new CommonResult(444,"订单为空",null);
        }
    }
    
    /**
     * @Description 查找订单
     * @Date 18:59 2020/12/23
     * @Param [id]
     * @return com.wn.springcloud.entities.Payment
     */
    @GetMapping(value = "payment/selectPaymentById/{id}")
    public CommonResult selectPaymentById(@PathVariable("id") int id){
        Payment payment = paymentService.selectPaymentById(id);
        log.info("*************查询结果:"+ payment);
        if (payment != null){
            return new CommonResult(200,"查询成功,serverPort:" + serverPort,payment);
        }else {
            return new CommonResult(444,"未查询到对应记录,查询ID:"+ id,null);
        }
    }
}
  1. 客户端使用注册中心
    2.1 provider端
    依赖:
    	<!-- Eureka-client -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    
    配置文件:
server:
  port: 8001
spring:
  application:
    name: cloud-payment-service
eureka:
  client:
    register-with-eureka: true  # 表示向注册中心注册自己
    fetch-registry: true  #是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,但是集群必须设置为true才能配合ribbon使用负载
    service-url:
      # 设置eureka地址,需要注册到多个注册中心时,地址之间用“,”隔开
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
  instance:
    instance-id: payment8001  # 在eureka显示的主机名称
    prefer-ip-address: true   # 鼠标放在主机名称上显示ip地址

启动类上加注解@EnableEurekaClient

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

2.2 consumer端
依赖、配置等同provider一致,这里主要记录一下怎么使用provider端的接口,这里为了方便直接用RestTemplate来测试调用远程微服务接口,一般是使用feign或者openfeign调用,这里不记录了

@Configuration
public class ApplicationContextConfig {

    @LoadBalanced //负载均衡
    @Bean
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}
@RestController
@Slf4j
public class OrderController {
	// "CLOUD-PAYMENT-SERVICE"是provider在注册中心显示的名称
    public static final String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE";
    @Resource
    private RestTemplate restTemplate;

    /**
     * @Description createPayment
     * @Date 14:15 2020/12/24
     * @Param [payment]
     * @return com.wn.springcloud.entities.CommonResult
     */
    @GetMapping(value = "/consumer/createPayment")
    public CommonResult create(Payment payment){
        return restTemplate.postForObject(PAYMENT_URL+"/payment/creatPayment",payment,CommonResult.class);
    }

    @GetMapping(value = "/consumer/selectPaymentById/{id}")
    public CommonResult getPayment(@PathVariable("id") int id){
        return restTemplate.getForObject(PAYMENT_URL+"/payment/selectPaymentById/"+id,CommonResult.class);
    }
}

三、服务保护模式

  1. 介绍
    默认情况下,**如果Eureka Server在一定时间内(默认90秒)没有接收到某个微服务实例的心跳,Eureka Server将会移除该实例。**但是当网络分区故障发生时,微服务与Eureka Server之间无法正常通信,而微服务本身是正常运行的,此时不应该移除这个微服务,所以引入了自我保护机制。

  2. 自我保护的机制

    默认情况下EurekaClient定时向EurekaServer端发送心跳包,如果在短时间内(默认90秒)内超过85%的客户端节点都没有正常的心跳,那么Eureka就认为客户端与注册中心出现了网络故障,Eureka Server自动进入自我保护机制,此时会出现以下几种情况:

    • Eureka Server不再从注册列表中移除因为长时间没收到心跳而应该过期的服务。

    • Eureka Server仍然能够接受新服务的注册和查询请求,但是不会被同步到其它节点上,保证当前节点依然可用。

    • 当网络稳定时,当前Eureka Server新的注册信息会被同步到其它节点中。

    因此,Eureka Server可以很好的应对因网络故障导致部分节点失联的情况,而不会像ZooKeeper那样(如果有一半不可用的情况会导致整个集群不可用而变成瘫痪)。

  3. 关闭自我保护

    • Eureka Server
eureka:
 instance:
   # 注册中心在收到最后一次心跳后等待时间(秒),默认90秒,超时将踢出服务
   lease-expiration-duration-in-seconds: 2
   # 客户端向注册中心发送心跳的时间间隔(秒),默认是30秒
   lease-renewal-interval-in-seconds: 1
- Eureka Client
eureka:

  server:
    # 禁止自我保护,默认打开
    enable-self-preservation: false
    # 将保护时间由默认的90秒修改为2000毫秒
    eviction-interval-timer-in-ms: 2000

后续补充…

### 回答1: SpringCloud和Hadoop可以配合实现分布式网盘系统,SpringCloud可以提供支撑服务,比如服务注册,服务发现,负载均衡,Hadoop则可以构建分布式文件系统,用于存储和管理文件,这样就可以实现一个分布式网盘系统。 ### 回答2: 要实现分布式网盘,可以使用Spring Cloud和Hadoop等技术来进行开发和搭建。 首先,使用Spring Cloud可以实现分布式的服务治理和微服务架构。可以使用Eureka作为服务注册与发现的中心,各个微服务将自身注册到Eureka服务器中,并通过Eureka来发现其他微服务的地址。通过使用Ribbon或Feign等负载均衡组件,可以实现对微服务的负载均衡和调用。此外,还可以使用Spring Cloud Config来统一管理配置文件,从而方便对系统进行配置和管理。 其次,使用Hadoop分布式文件系统HDFS来存储和管理网盘中的文件。HDFS的分布式特性可以将文件划分为多个块,并将这些块存储在不同的节点上,从而实现高可靠性和高性能的分布式文件存储。可以将HDFS作为网盘的底层文件系统,通过在Spring Cloud中调用HDFS提供的API,可以实现文件的上传、下载、删除和修改等功能。 在搭建分布式网盘时,可以使用Spring Cloud实现用户管理和权限控制等功能。可以通过使用Spring Security来实现用户认证和授权,保证只有合法用户可以访问网盘。可以在用户登录后,根据其身份和权限,通过HDFS提供的API来实现对文件的访问控制,例如只有拥有读权限的用户才能下载文件,只有拥有写权限的用户才能上传文件等。 此外,可以使用Spring Cloud的其他组件来实现更多的功能,例如使用Spring Cloud Stream来实现文件传输,使用Spring Cloud Task来实现定时清理和备份任务,使用Spring Cloud Sleuth来实现分布式链路追踪等。 总结来说,通过结合Spring Cloud和Hadoop等技术,可以实现分布式网盘系统,从而实现文件的分布式存储、用户管理和权限控制等功能。 ### 回答3: 要实现分布式网盘,可以结合使用Spring Cloud和Hadoop来完成。 首先,我们可以使用Spring Cloud来构建网盘的核心服务,包括用户管理、文件上传下载、文件管理等功能。通过Spring Cloud的微服务架构,可以将这些功能拆分为不同的服务,每个服务可以独立部署,并通过Spring Cloud的注册中心进行服务发现和管理。 接下来,我们可以使用Hadoop来存储和管理分布式网盘的文件。Hadoop提供了分布式文件系统HDFS,可以将大文件切分为小文件,然后分散存储在不同的HDFS节点上,实现文件的分布式存储和冗余备份。同时,Hadoop还提供了分布式计算框架MapReduce,可以用来处理大规模数据集。 在整合Spring Cloud和Hadoop时,可以通过Spring Cloud的服务调用功能来实现文件的上传和下载。当用户上传文件时,可以将文件切分为小文件后,并使用Hadoop的分布式文件系统HDFS进行存储。同时,可以使用Spring Cloud的负载均衡功能,将文件上传请求转发到不同的HDFS节点,实现负载均衡和高可用。 在文件的下载过程中,可以通过Spring Cloud将下载请求转发到对应的HDFS节点上,从而实现文件的并发下载。此外,还可以使用Hadoop的MapReduce进行文件的搜索和统计等操作,提供更多的网盘功能。 总之,结合使用Spring Cloud和Hadoop,可以实现一个分布式网盘系统,具备高可用、分布式存储和计算等优势。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值