SpringCloud微服务,euraka、feign、hystrix组件学习

SpringCloud

1 eureka

1.1 eureka基本概念在这里插入图片描述

eureka主要包含两个组件:Eureka Server 和 Eureka Client.

eureka server(注册中心),提供了三个功能:

1、服务注册
服务提供者启动时,会通过 Eureka Client 向 Eureka Server 注册信息,Eureka Server 会存储该服务的信息,Eureka Server 内部有二层缓存机制来维护整个注册表

2、提供注册表
服务消费者在调用服务时,如果 Eureka Client 没有缓存注册表的话,会从 Eureka Server 获取最新的注册表

3、同步状态
Eureka Client 通过注册、心跳机制和 Eureka Server 同步当前客户端的状态

Eureka Client:注册中心客户端
Eureka Client 会拉取、更新和缓存 Eureka Server 中的信息。因此当所有的 Eureka Server 节点都宕掉,服务消费者依然可以使用缓存中的信息找到服务提供者,但是当服务有更改的时候会出现信息不一致

Register: 服务注册
服务的提供者,将自身注册到注册中心,服务提供者也是一个 Eureka Client。当 Eureka Client 向 Eureka Server 注册时,它提供自身的元数据,比如 IP 地址、端口,运行状况指示符 URL,主页等

Renew: 服务续约
Eureka Client 会每隔 30 秒发送一次心跳来续约。 通过续约来告知 Eureka Server 该 Eureka Client 运行正常,没有出现问题。 默认情况下,如果 Eureka Server 在 90 秒内没有收到 Eureka Client 的续约,Server 端会将实例从其注册表中删除

Eviction 服务剔除
当 Eureka Client 和 Eureka Server 不再有心跳时,Eureka Server 会将该服务实例从服务注册列表中删除,即服务剔除

Cancel: 服务下线
Eureka Client 在程序关闭时向 Eureka Server 发送取消请求。 发送请求后,该客户端实例信息将从 Eureka Server 的实例注册表中删除。该下线请求不会自动完成,它需要调用以下内容:

DiscoveryManager.getInstance().shutdownComponent()

GetRegisty: 获取注册列表信息
Eureka Client 从服务器获取注册表信息,并将其缓存在本地。客户端会使用该信息查找其他服务,从而进行远程调用。该注册列表信息定期(每30秒钟)更新一次。每次返回注册列表信息可能与 Eureka Client 的缓存信息不同,Eureka Client 自动处理

Remote Call: 远程调用
当 Eureka Client 从注册中心获取到服务提供者信息后,就可以通过 Http 请求调用对应的服务;服务提供者有多个时,Eureka Client 客户端会通过 Ribbon 自动进行负载均衡

1.2 编写eureka server

(1)引入依赖

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

(2)编写启动类,在启动类上添加@EnableEurekaServer注解

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

(3)编写配置文件

#应用名
spring.application.name=security
#端口号
server.port=8333
#主机名
eureka.instance.hostname=server2
#eureka server 地址
eureka.client.service-url.defaultZone=http://localhost:8333/eureka/
#是否开启自我保护
eureka.server.enableSelfPreservation=false
#是否将自己注册到eureka server
eureka.client.register-with-eureka=false
#是否从eureka server获取注册信息
eureka.client.fetch-registry=false

eureka.client.register-with-eureka=false:表示本应用是一个注册中心,当搭建eureka集群时,将此值改为true,与其他注册中心相互注册。

eureka.client.service-url.defaultZone:与eureka server交互的地址,查询服务和注册服务都需要这个地址。

eureka.client.fetch-registry:是否从其他节点获取注册信息,默认为true,因为此节点为单节点,所以不需要从其他节点获取信息,所以设置为false.

查看注册好之后的ui界面:http://localhost:8333/
在这里插入图片描述

这便是定义好的注册中心,从界面中可以看出,现在没有实例注册进去。

1.3 编写eureka client

(1)引入依赖

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

(2)编写启动类,在启动类上添加@EnableEurekaClient注解

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

(3)编写配置文件

#注册到eureka server的应用名
spring.application.name=client-1
#端口号
server.port=8340
#将自己的ip注册到eureka server,若为false,则注册的为hostname
eureka.instance.prefer-ip-address=true
#注册到eureka server(eureka server的地址)
eureka.client.service-url.defaultZone = http://localhost:8333/eureka/

现已将服务名为client-1的微服务注册到地址为http://localhost:8333/eureka/的注册中心中,进去http://localhost:8333/eureka/此地址,UI端显示为:
在这里插入图片描述

从图中可以看出服务名为client-1,端口号为8340的微服务已注册到注册中心中。

1.4 eureka的高可用(eureka集群)
1.4.1 eureka集群框架及概念在这里插入图片描述

​ 图中由三个Eureka Server组成一个集群

​ 从图中可以看出 Eureka Server 集群相互之间通过 Replicate 来同步数据,相互之间不区分主节点和从节点,所有的节点都是平等的。在这种架构中,节点通过彼此互相注册来提高可用性,每个节点需要添加一个或多个有效的 serviceUrl 指向其他节点。

​ 如果某台 Eureka Server 宕机,Eureka Client 的请求会自动切换到新的 Eureka Server 节点。当宕机的服务器重新恢复后,Eureka 会再次将其纳入到服务器集群管理之中。当节点开始接受客户端请求时,所有的操作都会进行节点间复制,将请求复制到其它 Eureka Server 当前所知的所有节点中

1.4.2 集群之间相互注册

首先:

eureka.client.register-with-eurekaeureka.client.fetch-registry的值都改为true,或者不进行配置,因为默认为true。

配置如下:

第一个eureka server将前文配置修改,将其注册到另外两个eureka server中:

#应用名
spring.application.name=security
#端口号
server.port=8233
#主机名
eureka.instance.hostname=server2
#eureka server 地址
eureka.client.service-url.defaultZone=http://server3:8333/eureka/
#是否开启自我保护
#eureka.server.enableSelfPreservation=false
#是否将自己注册到eureka server
eureka.client.register-with-eureka=true
#是否从eureka server获取注册信息
eureka.client.fetch-registry=true

进入http://localhost:8333/可以看到:
在这里插入图片描述

可以发现server2的服务已经注册http://localhost:8333/的注册中心中

再查看http://localhost:8233/:
在这里插入图片描述

同样,可以发现server3的服务已经注册http://localhost:8233/的注册中心中

两个注册中心已经相互注册成为一个小集群。

1.5 微服务之间调用

注册两个微服务至注册中心:client-1,service。如图所示:
在这里插入图片描述

service作为服务提供者,client-1作为服务调用者。

服务调用者代码为:

编写服务调用者的controller代码为:

@RestController
@RequestMapping("/client")
public class UserController {
   
    @Autowired
    private RestTemplate restTemplate;
    @GetMapping("/getUser")
    public List<User> getUser(){
   
      List<User> userList =           restTemplate.getForObject("http://localhost:8336/services/getUser",List.class);
      return userList;
    }
}

restTemplate.getForObject(“http://localhost:8336/services/getUser”,List.class);方法解析:

public <T> T getForObject(URI url, Class<T> responseType)

url:服务提供者的接口地址

编写服务提供者的代码:

controller:

@Slf4j
@RestController
@RequestMapping("/services")
public class UserController {
   
    @Autowired
    private UserService userService;
    
    @RequestMapping("/getUser")
    public List<User> getUser() {
   
        return userService.getUser();
    }

。。。省略service 与dao代码

用postman测试工具测试服务调用者接口:http://localhost:8340/client/getUser
在这里插入图片描述

通过服务调用者调用服务提供者接口方法成功,并返回数据。

1.6 eureka的自我保护

​ 默认情况下,如果 Eureka Server 在一定的 90s 内没有接收到某个微服务实例的心跳,会注销该实例。但是在微服务架构下服务之间通常都是跨进程调用,网络通信往往会面临着各种问题,比如微服务状态正常,网络分区故障,导致此实例被注销。固定时间内大量实例被注销,可能会严重威胁整个微服务架构的可用性。为了解决这个问题,Eureka 开发了自我保护机制,Eureka Server 在运行期间会去统计心跳失败比例在 15 分钟之内是否低于 85%,如果低于 85%,Eureka Server 即会进入自我保护机制

触发自我保护机制时会有如下提示:
在这里插入图片描述

Eureka Server 进入自我保护机制,会出现以下几种情况:
(1) Eureka 不再从注册列表中移除因为长时间没收到心跳而应该过期的服务
(2)Eureka 仍然能够接受新服务的注册和查询请求,但是不会被同步到其它节点上(即保证当前节点依然可用)
(3) 当网络稳定时,当前实例新的注册信息会被同步到其它节点中

如果想关闭自我保护模式则需配置:

#是否开启自我保护
eureka.server.enableSelfPreservation=false

1.7 服务剔除与恢复

服务剔除:
在这里插入图片描述

服务恢复:
在这里插入图片描述

服务恢复时修改如上两个位置即可。

1.8 eureka的健康检查
1.8.1 查看服务信息
@GetMapping("/instance")
    public List<ServiceInstance> showInfo(){
   
        return this.discoveryClient.getInstances("service");
    }

进入接口:http://localhost:8340/client/instance

在这里插入图片描述

可以查看服务的具体信息。

1.8.2 健康检查

配置属性:

management.endpoint.health.show-details=always
eureka.client.healthcheck.enabled=true

进入接口:http://localhost:8340/actuator/health
在这里插入图片描述

可以查看服务的健康状态及注册表中的实例。

2 Ribbon

2.1 概念及框架

​ Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,它基于Netflix Ribbon实现。Spring Cloud Ribbon虽然只是一个工具类框架,它不像服务注册中心、配置中心、API网关那样需要独立部署,但是它几乎存在于每一个Spring Cloud构建的微服务和基础设施中。因为微服务间的调用,API网关的请求转发等内容,实际上都是通过Ribbon来实现的。

通过Spring Cloud Ribbon的封装,在微服务架构中使用客户端负载均衡调用非常简单,只需要如下两步:

​ ▪️服务提供者只需要启动多个服务实例并注册到一个注册中心或是多个相关联的服务注册中心。

​ ▪️服务消费者直接通过调用被@LoadBalanced注解修饰过的RestTemplate来实现面向服务的接口调用。

ribbon与eureka配合使用架构图:
在这里插入图片描述

2.2 服务调用者整合ribbon

(1)引入依赖

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

(2)修改配置类

为RestTemplate加上@LoadBalanced注解

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
   
        return new RestTemplate();
    }

(3)修改controller代码

    @GetMapping("/getUser")
    public List<User> getUser(){
   
      List<User> userList =
              restTemplate.getForObject("http://service/services/getUser",List.class);
      return userList;
    }

将微服务的地址改为:http://service/services/getUser,使用service代替原本的localhost:8336(原因后面讲)

(4)测试

在这里插入图片描述

启动2个或多个服务提供者实例,启动此ribbon实例,进入接口可以发现每一次的服务调用都以轮询的方式调用服务提供者实例。说明负载均衡策略成功。

2.3 自定义ribbon配置
2.3.1 使用java代码自定义配置

(1)定义负载均衡策略为随机分配

    @Bean
    public IRule ribbonRule(){
   
        return  new RandomRule();
    }

(2)在启动类中加载此配置文件

@RibbonClient(name = "service",configuration = RestTemplateConfig.class)
public class EurekaClientApplicationclientApplication {
   
    public static void main(String[] args) {
   
        SpringApplication.run(EurekaClientApplicationclientApplication.class, args);
    }

(3)定义接口,检查调用的是哪个接口

@GetMapping("/userInstance")
    public  void userInstance(){
   
        ServiceInstance serviceInstance = loadBalancerClient.choose("service");  System.out.println(serviceInstance.getServiceId()+serviceInstance.getHost()+serviceInstance.getPort());
    }

(3)在postman中多次调用服务调用者接口http://localhost:8340/client/getUser,及http://localhost:8340/client/userInstance接口可以看出:
在这里插入图片描述

从图中可以看出调用服务提供者已变成随机调用。

2.3.2 使用属性自定义配置

上节使用代码自定义的配置在配置文件中使用属性配置便可做到,这种方式也更方便。配置为:

service.ribbon.NFLoadBalancerRuleClassName=com
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值