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

Eureka包含Server、Client两部分

  • Eureka Server  接收服务注册、保存各服务节点的信息
  • Eureka Client   即各服务节点,内置负载均衡器Ribbon。

Eureka的架构


Eureka Server

Maven创建父子工程,新建子模块eureka-server。

Eureka和ZK不同,ZK是安装软件作为注册中心,Eureka是自己写一个服务作为注册中心。

(1)创建时勾选 Spring Cloud Discovery -> Eureka Server

也可以手动加eureka server的依赖:

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

(2)引导类上加  @EnableEurekaServer

(2)配置文件可以使用.properties,但springcloud官方使用yml,我们也使用yml,重命名一下

server:
port: 8761 eureka:
instance:
   #设置为所在机器的主机名(域名)或者ip地址,如果是主机名上线时需要在dns上注册
hostname: 127.0.0.1
client:
#不注册到其它Eureka Server上,表示这是一个Eureka Server
registerWithEureka: false
#不从其它Eureka Server上拉取、同步注册信息,表示这是单机版的Eureka Server
fetchRegistry: false
serviceUrl:
#这个Eureka Server的注册中心地址,服务都会注册到这个地址
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

如果要搭建Eureka Server集群,将上面2个false改为true

(4)启动,127.0.0.1:8761 访问Eureka Server的控制台

ip是运行Eureka Server的机器的ip,port是上面配置文件中的port


新建子模块order-service作为服务提供者

每一个服务都是Eureka Client

(1)创建时勾选 Developer Tools -> Lombok,Web -> Spring Web,Spring Cloud Discovery -> Eureka Discovery Client

也可以手动加eureka client依赖:

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

(2)引导类上加@EnableEurekaClient (非必需)

@EnableEurekaClient是eureka的注解,也可以换为@EnableDiscoveryClient(springcloud的注解)

也可以不加,因为项目的classpath中有Eureka Client的依赖 spring-cloud-starter-netflix-eureka-client 时,启动应用时会自动在引导类上加 @EnableEurekaClient。

(3)配置文件

server:
port: 8771 spring:
application:
#服务名称
name: order-service eureka:
client:
#注册中心地址,如果
serviceUrl:
defaultZone: http://127.0.0.1:8761/eureka/

如果是Eureka Server集群,多个url之间逗号分隔。不必写全部的Eureka Server,写一部分即可。

注册时只注册到第一个Eureka Server,Eureka Server之前会相互同步数据,后面的url都是备胎,第一个故障才会使用第二个,以此类推。

(4)实体类、controller

@Getter
@Setter
public class Order implements Serializable{
private Long id;
//.....
private Long userId;
}
@Controller
@RequestMapping("/api/v1/order")
public class OrderController { @RequestMapping("/list/{user_id}")
@ResponseBody
public List<Order> findOrdersByUserId(@PathVariable("user_id") Long userId){
//模拟
ArrayList<Order> orders = new ArrayList<>();
Order order = new Order();
order.setId(1L);
order.setUserId(userId);
orders.add(order);
return orders;
} }

把pojo对象转换为作为json传输时不需要序列化,但有些场景可能要用到序列化,最好加上。

v1表示api版本,此处只是模拟一下,并没有写在service层。


新建子模块user-service作为服务消费者

(1)创建时依然勾选 Developer Tools -> Lombok,Web -> Spring Web,Spring Cloud Discovery -> Eureka Discovery Client

(2)引导类上加@EnableEurekaClient (非必需)

(3)配置文件

server:
port: 8781 spring:
application:
#服务名称
name: user-service eureka:
client:
#注册中心地址,如果
serviceUrl:
defaultZone: http://127.0.0.1:8761/eureka/

(4)实体类、controller

@Getter
@Setter
public class Order implements Serializable{
private Long id;
//.....
private Long userId;
}
@Controller
@RequestMapping("/api/v1/user")
public class UserController {
@Resource
private RestTemplate restTemplate; @RequestMapping("order/{user_id}")
@ResponseBody
public List<Order> findOrdersByUserId(@PathVariable("user_id") Integer userId){
List orders = restTemplate.getForObject("http://order-service/api/v1/order/list/" + userId, List.class);
return orders;
} }

SpringCloud重复代码多,如果要使用其它服务中的实体类、工具类,得Copy过来,也可以把公共要用的代码放在一个单独的子模块中,打包成jar,引入。

(4)引导类

消费者要使用RestTemplate这个Bean,需要自己创建

@SpringBootApplication
public class UserServiceApplication { @Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
} public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
} }

启动order-service、user-service,地址栏输入127.0.0.1:8781/api/v1/user/order/1  看到显示json数据,说明调用成功。


RestTemplate

RestTemplate用于以restful方式远程调用服务。

常用方法:

   //参数:远程服务接口,返回值类型(目标类型)
List orders = restTemplate.getForObject("http://order-service/api/v1/order/list/" + userId, List.class); //url中的参数可以使用+号拼接,也可以使用占位符{1},{2}...,在目标类型后面写参数值(Object...)
List orders = restTemplate.getForObject("http://order-service/api/v1/order/list/{1}" + userId, List.class,1); //可以用map来传递数据,服务提供者接收map中的键值对时,要以@PathVariable的方式来接收
HashMap<String, Object> map = new HashMap<>();
map.put("user_id", 1);
List orders = restTemplate.getForObject("http://order-service/api/v1/order/list/" + userId, List.class,map); //可以不使用restful方式来传递参数,用?user_id=1这种方式也行,但需要修改下服务提供者的

xxxForObject(),get是查询,put是新建,post是更新,delete是删除,用法都差不多。

上面服务的url我写的是服务名order-service,在引导类中创建RestTemplate这个Bean时要加@LoadBalanced,这样拿到该服务节点列表后才会使用负载均衡器Ribbon来确定使用哪个服务节点。

url可以直接写ip:port (不推荐),http://127.0.0.1:8771/api/v1/order/list/,这样是直接调用某一个服务节点,服务消费者、提供者直连,不从Eureka Server获取节点列表,不需要加@LoadBalanced。


Eureka Server的服务保护

Eureka Server默认开启了服务保护,停掉某个服务,Eureka Server控制台会用一段红色文字提示:这个服务节点进入了保护模式。

服务的自我保护模式:

Eureka Server在90s内都未收到某个服务节点的心跳包时,会开启为期15min的心跳检测,这期间不会把该服务节点的信息从服务注册列表中删除。

如果15min内实际收到该节点的心跳数占应接收心跳数的比值小于0.85(默认值0.85,可设置),就认为是该服务节点与Eureka Server之间的网络故障导致的心跳包丢失,该服务节点本身没有问题,保留该节点的注册信息;如果比值大于0.85,就认为是该服务节点自身出了问题,从服务注册列表中删除该服务节点的信息。

造成的问题:该服务节点可能出问题了,但依然被当做正常节点使用。

项目上线时一般也不关闭服务保护,公司的项目,服务节点的数量往往成百上千,如果关闭服务保护,网络不稳定时(网络波动、延迟、断线等)会导致大量的服务反复注册、删除、再注册,会降低程序性能。开启服务保护,某些服务节点故障时,无非就是注册列表中有少量无效节点,不一定会调用集群中的这些无效节点,就算调用了无效节点不能正确处理请求,用户刷新几次,转发给集群中正常的节点处理就ok了。

开发、调试时可以关闭Eureka Server的服务保护,快速清理掉无效节点:

eureka:
server:
#关闭Eureka Server的服务保护
enableSelfPreservation: false

Eureka Client的缓存机制

Eureka|ZK Client都会缓存Eureka|ZK Server返回的服务节点列表,缓存一直有效,直到此Client下线。

消费者调用服务时都是先从本地缓存中找有没有该服务的节点列表,没有才会从Eureka|ZK Server获取该服务的节点列表。

ZK Client通过订阅来监听ZK Server上服务节点列表的变化,Eureka Client通过轮询来确定缓存的服务节点列表是否有更新,有更新|变化时会自动从ZK|Eureka Server上获取服务节点列表的更新。

即便Eureka|ZK Server集群的所有节点都宕机,服务消费者依然可以调用服务提供者(以前调用过,有缓存)。


SpringCloud也可以使用其它的服务发现组件,比如ZK、Consul,但对Eureka的支持最好。

SpringCloud Netflix Eureka的更多相关文章

  1. SpringCloud学习笔记(三、SpringCloud Netflix Eureka)

    目录: 服务发现简介 SpringCloud Netflix Eureka应用 Eureka高可用 Eureka源码分析 >>> Eureka Client初始化(客户端定时获取服务 ...

  2. SpringCloud Netflix Eureka(服务注册/发现)

    ⒈Eureka是什么? Eureka是Netflix的一个子模块,也是核心模块之一,Eureka是一个基于REST的服务,用于定位服务以实现云端中间层服务发现和故障转移,服务注册与发现对于微服务架构来 ...

  3. Spring-cloud & Netflix 源码解析:Eureka 服务注册发现接口 ****

    http://www.idouba.net/spring-cloud-source-eureka-client-api/?utm_source=tuicool&utm_medium=refer ...

  4. SpringCloud系列——Eureka 服务注册与发现

    前言 Eureka是一种基于REST(具像状态传输)的服务,主要用于AWS云中定位服务,以实现中间层服务器的负载平衡和故障转移.本文记录一个简单的服务注册与发现实例. GitHub地址:https:/ ...

  5. SpringCloud Netflix Ribbon(负载均衡)

    ⒈Ribbon是什么? Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡工具. Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负 ...

  6. java框架之SpringCloud(3)-Eureka服务注册与发现

    在上一章节完成了一个简单的微服务案例,下面就通过在这个案例的基础上集成 Eureka 来学习 Eureka. 介绍 概述 Eureka 是 Netflix 的一个子模块,也是核心模块之一.Eureka ...

  7. Spring Cloud Netflix Eureka源码导读与原理分析

    Spring Cloud Netflix技术栈中,Eureka作为服务注册中心对整个微服务架构起着最核心的整合作用,因此对Eureka还是有很大的必要进行深入研究. 本文主要分为四部分,一是对项目构建 ...

  8. springcloud之eureka配置——eureka.instance

    1.在springcloud中服务的 Instance ID 默认值是: ${spring.cloud.client.hostname}:${spring.application.name}:${sp ...

  9. SpringCloud之Eureka集群

    前面我们介绍了SpringCloud注册中心Eureka,但是存在一个单点故障的问题,一个注册中心远远不能满足实际的生产环境,现在我们介绍一下如何搭建一个Eureka集群. 一:集群环境搭建 我们先建 ...

随机推荐

  1. PGET,一个简单、易用的并行获取数据框架

    使用场景 当我们的服务收到一个请求后,需要大量调用下游服务获取业务数据,然后对数据进行转换.计算后,响应给请求方. 如果我们采用串行获取下游数据,势必会增加响应时长,降低接口的qps.如果是并行获取下 ...

  2. centos6离线安装apache2.4

    在/usr/local中新建文件夹 Apache2.4,将httpd安装包放入该文件夹, 解压:tar xvf httpd-2.4.41.tar.gz 进入httpd-2.4.41文件夹中,对Apac ...

  3. Luogu4316 | 绿豆蛙的归宿 (期望DP)

    题目背景 随着新版百度空间的上线,Blog宠物绿豆蛙完成了它的使命,去寻找它新的归宿. 题目描述 给出一个有向无环图,起点为1终点为N,每条边都有一个长度,并且从起点出发能够到达所有的点,所有的点也都 ...

  4. 【巨杉数据库SequoiaDB】巨杉Tech | 巨杉数据库数据高性能数据导入迁移实践

    SequoiaDB 一款自研金融级分布式数据库产品,支持标准SQL和分布式事务功能.支持复杂索引查询,兼容 MySQL.PGSQL.SparkSQL等SQL访问方式.SequoiaDB 在分布式存储功 ...

  5. tk(三)按钮的事件绑定

    (三)按钮的事件绑定 ==1.普通的Button绑定事件== (1)说明: Button 使用 command=功能函数 来绑定 Button(win, text="确定", co ...

  6. vuejs在解析时出现闪烁的原因及防止闪烁的方法

    原因: 在使用vuejs.angularjs开发时,经常会遇见在如Chrome这类能够快速解析的浏览器上出现表达式({{ express }} ),或者是模块(div)的闪烁.对于这个问题由于Java ...

  7. linux - mysql - 卸载:RPM包安装方式的MySQL卸载

    (1)检查是否安装了MySQL组件 [root@DB-Server init.d]# rpm -qa | grep -i mysql MySQL-devel-5.6.23-1.linux_glibc2 ...

  8. java通过浏览器请求头(User-Agent)获取访问者设备信息以及系统版本

    个人博客 地址:http://www.wenhaofan.com/article/20181125220342 在开发AutuBlog项目时需要做后台的登录记录,想起浏览器的User-Agent,于是 ...

  9. jdbc url的若干参数

    参数名称 参数说明 缺省值 最低版本要求 user 数据库用户名,用于连接数据库 无 所有版本 password 用户密码(用于连接数据库) 无 所有版本 useUnicode 是否使用Unicode ...

  10. Linq To Sqlite使用心得

    若要使用Linq To Sqlite类库,可以安装Devart Linq Connect Model,如图: 新建这个Model就可以和Linq To Sql一样使用Linq模型,下载地址:https ...