SpringCloud Netflix Eureka

2020-02-13 16:02:39来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

SpringCloud Netflix Eureka

 

Eureka是Netflix开源的服务发现组件,基于REST,SpringCloud将它集成在子项目Spring Cloud Netflix中,从而实现服务的注册、发现。

 

Eureka包含Server、Client两部分:

  • Eureka Server  接收服务注册、保存各服务节点的信息
  • Eureka Client  即各服务节点,内置Ribbon(实现负载均衡)。消费者通过Ribbon从提供该服务的节点列表中确定一个要使用的节点。

 

 


 

 

Eureka的架构

 

 

 

 

 


 

 

搭建单个Eureka Server

1、创建空项目,作为容器

因为微服务是独立的模块,单独开发部署,不建议使用父子工程。

 

 


 

 

 

2、新建模块eureka-server,作为eureka服务器

(1)pom.xml

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.4.RELEASE</version>
  </parent>

  <dependencies>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
      <version>2.2.1.RELEASE</version>
    </dependency>
  </dependencies>

 

 

(2)application.properties

### eureka server config ###
#使用的端口
server.port=9001

#服务名,eureka集群时会作为一个服务注册到其它server上
#spring.application.name=eureka-server

#这个eureka server的ip,不是预定义的key,下面要取出来用。上线时要改为真实的ip
eureka.server.ipAddress=127.0.0.1

#erueka实例名,注册到eureka server上时,这个名称就代表该服务节点。集群使用,只有一个server时可不用
#eureka.instance.instance-id=${eureka.server.ipAddress}:${server.port}

#这个eureka server的注册中心地址
eureka.client.serviceUrl.defaultZone=http://${eureka.server.ipAddress}:${server.port}/eureka/


#是否将自己作为Eureka Client注册到其它Eureka Server上,默认为true。因为只有一个eureka server,所以设置为false
eureka.client.register-with-eureka=false
#是否同步其它Eureka Server节点的数据(复制),默认为true。因为只有一个eureka server,所以设置为false
eureka.client.fetch-registry=false


#注册时以ip地址注册,默认以主机名注册。如果注册主机名,使用时还需要转换为ip,浪费时间
eureka.instance.prefer-ip-address=true


#期待心跳间隔时间,默认30s
#eureka.instance.lease-renewal-interval-in-seconds=30
#服务节点失效时间,默认为90s,即90s内没有接收到某个服务节点的心跳,就认为该节点失效
#eureka.instance.lease-expiration-duration-in-seconds=90
###调试时可把上面2个值写小些###


#是否启用服务的自我保护模式,默认为true,调试时设置为false,正式部署设置为true
eureka.server.enableSelfPreservation=false
#清理间隔,每隔60s清理一次无效节点,默认为60000(60s)
#eureka.server.eviction-interval-timer-in-ms=60000
#设置缓存过期时间。eureka集群时,要从其它server拉取数据,此设置指定拉取的数据的有效期,即每隔多少秒拉取、更新一次 #注意是缓存,是从其他server拉取的,不是本机的注册中心的节点信息,默认180s更新一次 eureka.server.response-cache-auto-expiration-in-seconds=180 #数值设置大,可用性高,因为其它server下线,本server也可以维持某些节点一段时间,但节点信息更新慢,数据一致性差

 

 

(3)引导类

@SpringBootApplication
@EnableEurekaServer  //作为Eureka Server
public class EurekaServer {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServer.class, args);
    }
}

 

启动之后,在   http://localhost:9001/ 查看eureka server的信息。

 

 


 

 

 

3、新建子模块order-server(服务提供者),作为eureka client

1、pom.xml

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.4.RELEASE</version>
  </parent>

  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
      <version>2.0.0.RELEASE</version>
    </dependency>
  </dependencies>

 

 

2、application.properties

### eureka client config###

#使用的端口
server.port=10001

#提供的服务,服务名称
spring.application.name=order-server

#注册到哪些Eureka Server的注册中心。可配置多个值,逗号隔开即可
eureka.client.serviceUrl.defaultZone=http://127.0.0.1:9001/eureka/

#本机地址,上线时要改为机器实际的ip
eureka.client.ipAddress=127.0.0.1
#eureka实例名,以ip:port的形式注册到server上
eureka.instance.instance-id=${eureka.client.ipAddress}:${server.port}

#注册节点时IP优先,默认为false——注册主机名
eureka.instance.prefer-ip-address=true

#多久发送一次心跳,默认30s,调试时可设置短些
#eureka.instance.lease-renewal-interval-in-seconds=30

 

 

3、引导类

@SpringBootApplication
@EnableEurekaClient  //作为Eureka Client
public class OrderServer {
    public static void main(String[] args) {
        SpringApplication.run(OrderServer.class, args);
    }

}

 

 

4、我们再写一个controller作为测试

@Controller
@RequestMapping("/order")
public class OrderController {

    //模拟根据用户id查找该用户的所有订单
    @GetMapping("/{user_id}")
    @ResponseBody
    public String findAllByUserId(@PathVariable Integer user_id){
        return "this is orderList of " + user_id ;
    }
}

 传递的参数写成RESTful风格。

 

 


 

 

 

4、新建子模块user-server(服务消费者),作为eureka client

1、pom.xml

都是eureka的客户端,引入的依赖和order-server的相同。

 

 

2.application.properties

都是eureka客户端,配置和order-server差不多,改一下端口号、服务名称就ok。(实际上线时还需要改ip)

 

 

3、引导类

@SpringBootApplication
@EnableEurekaClient  //作为Eureka Client
public class UserServer {
    @Bean
    @LoadBalanced  //使用Ribbon的负载均衡
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }

    public static void main(String[] args) {
        SpringApplication.run(UserServer.class, args);
    }
    
}

消费者、提供者相比,消费者要使用Ribbon的负载均衡。

 

 

4、再写一个controller作为测试

@Controller
@RequestMapping("/user")
public class UserController {
    //springcloud使用的消息是REST,通过RestTempalte来调用服务
    private RestTemplate restTemplate;

    @Autowired
    public void setRestTemplate(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    //模拟根据用户id查找用户所有订单
    @GetMapping("/order/{user_id}")
    @ResponseBody
    public String findOrdersByUserId(@PathVariable Integer user_id){
        //不写具体的ip:port,使用服务名代替,Ribbon会通过负载均衡找到该服务的合适的节点
        String orders = restTemplate.getForObject("http://order-server/order/{user_id}", String.class, user_id);
        return orders;
    }
}

参数写成RESTful风格。

启动order-server、user-server,看到已经注册到eureka-server上,即使关闭eureka的自我保护机制,服务下线后需要90s才会删除节点信息,所以有时候会看到重复的节点信息。

页面上经常 红字提示 “自我保护机制.....“,不必管。

 

地址栏输入 http://localhost:10002/user/order/1 ,显示“this is orderList of 1”,搭建成功。

 

 


 

 

 

Eureka的集群

为了提供可用性,Eureka一般都要集群。

 

1、eureka server集群

application.properties修改如下:

### eureka server config ###

#使用的端口
server.port=9001

#服务名,eureka集群时会作为一个服务注册到其它server上
spring.application.name=eureka-server
#这个eureka server的ip,上线时要改为真实的ip
eureka.server.ipAddress=127.0.0.1
#erueka实例名,以实例名注册到eureka server上。
eureka.instance.instance-id=${eureka.server.ipAddress}:${server.port}


#要写其它注册中心的地址,有多少写多少
eureka.client.serviceUrl.defaultZone=http://127.0.0.1:9002/eureka/,http://127.0.0.1:9003/eureka/


#把自己作为一个服务(eureka client)注册到其它Eureka Server上,默认就是true
eureka.client.register-with-eureka=true
#同步其它Eureka Server节点的数据(复制),默认为true
eureka.client.fetch-registry=true


#注册时优先以ip地址注册
eureka.instance.prefer-ip-address=true

#多久更新一次从其它server拉取的数据
eureka.server.response-cache-auto-expiration-in-seconds=180

##是否启用此Eureka Server的自我保护模式,默认为true,调试时设置为false,正式部署设置为true##
eureka.server.enableSelfPreservation=false
#清理间隔,每隔60s清理一次失效的节点,默认为60000
#eureka.server.eviction-interval-timer-in-ms=60000

#期待心跳间隔时间,默认30s
#eureka.instance.lease-renewal-interval-in-seconds=30
#服务节点失效时间,默认为90s,即90s内没有接收到某个服务节点的心跳,就认为该节点失效
#eureka.instance.lease-expiration-duration-in-seconds=90
###调试时可把上面2个值写小些###

要部署多少个集群,就copy多少份这个子模块,把application.properties改下就ok。

 

如果是正式部署,部署到多台机器上,需要修改副本的ip、注册中心地址;

如果是在同一台机器上测试,直接运行此模块|项目的多个实例即可,修改下端口号(包括注册中心的端口号)就ok。

 

 

 

2、eureka client集群

要部署多少个集群,就copy多少份这个子模块,把application.properties改下就ok:

#注册到哪个注册中心,需配置多个注册中心,逗号隔开
eureka.client.serviceUrl.defaultZone=http://127.0.0.1:9001/eureka/,http://127.0.0.1:9002/eureka/,http://127.0.0.1:9003/eureka/

虽然配置了多个注册中心,但只会注册到第一个,第一个下线了才会选择注册到第二个,以此类推。(后面的全是备胎)

这样做是为了提高可用性,某些注册中心挂了,也没问题。

 

如果是正式部署到多台机器,改下ip就ok;

如果是在一台机器上进行测试,在IDEA下运行多个实例,改下端口号就行。

 

 

ps:可能指定的注册中心还没上线,控制台会报错“请求失败,拒绝连接”,问题不大,等注册中心上线即可。(注意灯是绿的,仍是运行状态;如果没在运行了,那就是其它错误)

 

 


 

微服务项目的部署

将各子模块打包为jar或war(基于SpringBoot,即可打包为jar,又可打包为war),安装、部署到各台机器上即可。

 


 

 

Eureka server  服务的自我保护模式

eureka server默认是开启服务的自我保护模式的。

90s内未接受到某个服务节点的心跳,就开启为期15min的心跳检测,如果15min接收到该节点的心跳小于85%(默认值0.85,可设置),就认为是网络故障导致的,一直保留该节点的信息,依然被使用;

如果大于85%,就认为是该节点自身除了问题,删除该节点的信息。

 

造成的问题:该节点可能出问题了(成为无效节点),但依然和正常节点一样被使用,就是说返回给client的可能含有一些无效节点。

 

关闭服务保护、手动清理无效节点:(90s内没收到过心跳即为无效节点)

# 关闭服务的自我保护
eureka.server.enableSelfPreservation=false
# 清理间隔,每隔60s清理一次失效的节点
eureka.server.eviction.interval-timer-in-ms=60000

 

商业项目中不推荐关闭服务保护,因为网络不可靠很容易造成网络波动、延迟、断线。

在商业项目中,服务的数量一般是几十个、成百上千个,如果关闭服务保护,可能导致大量的服务反复注册、删除、再注册,会降低程序性能。

 

 


 

 

Eureka client的缓存机制

客户端会缓存eureka server返回的服务列表,缓存一直有效,直到此客户端下线。

第一次请求eureka server获取到服务列表后,之后调用该服务时都是从缓存中找。除非缓存的该服务的所有节点都失效,才会从server重新获取节点列表。

即便Eureka Server集群的所有节点都宕机失效,服务消费者、提供者依然能正常通信。

 

 


 

 

Eureka、ZooKeeper的对比

  • 集成情况:Dubbo只集成了ZK、未集成Eureka,SpringCloud两者都集成了,但对Eureka支持较好,对ZK支持一般。

 

  • 集群:ZK使用主从模型,一个时间点只有一个leader对外提供服务,其它follower只是实时备份leader的数据,当leader宕机时会从follower中选出一个新的leader。Eureka使用的是平等模型,每个节点都对外提供服务,需要借助网络从其它节点获取、同步数据,容易受网络故障的影响、数据一致性差。

 

  • CAP定理:ZK实现了CP、Eureka实现了AP。

  ZP同一时间只有一个leader来维护节点数据,满足数据一致性,但leader宕机到选举出新leader的这几秒、几十秒内,没有机器对外提供服务,是不可用的;

  Eureka集群之后,满足可用性,但由于存在服务的自我保护机制、不能及时同步节点信息,不满足一致性。

 

  • 跨语言:ZK支持较差
  • 支持数据存储:ZK支持,Eureka不支持
  • 监听服务端的变化:ZK通过订阅来监听,Eureka通过轮询来监听。

 


原文链接:https://www.cnblogs.com/chy18883701161/p/12295914.html
如有疑问请与原作者联系

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:什么是队列?

下一篇:什么是JWT令牌认证?