springcloud介绍euruka服务发现ribbon负载均衡feign简化hystrix容错机制

本文介绍了SpringCloud的核心组件,如Eureka实现服务发现,Ribbon进行客户端负载均衡,Feign简化服务调用,以及Hystrix提供的容错保护。通过实例展示了如何构建微服务架构,包括服务注册、服务调用和容错处理。最后提到了Zuul微服务网关的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

springcloud介绍euruka服务发现ribbon负载均衡feign简化hystrix容错机制

本文内容都是实际操作后得到的,是基本没有错误的,命名格式本次比较随意

springcloud概念:Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。Spring并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。
“微服务架构”在这几年非常的火热,以至于关于微服务架构相关的开源产品被反复的提及(比如:netflix、dubbo),Spring Cloud也因Spring社区的强大知名度和影响力也被广大架构师与开发者备受关注。

总的来说就是把一个系统分成多个比如淘宝的用户管理和商品页面各自用一些服务器部署,一个项目的各个模块可以遍布在成千上万台服务器上

eureka概念:Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。SpringCloud将它集成在其子项目spring-cloud-netflix中,以实现SpringCloud的服务发现功能。
Eureka包含两个组件:Eureka Server和Eureka Client。
Eureka Server提供服务注册服务,各个节点启动后,会在Eureka Server中进行注册,这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到。
Eureka Client是一个java客户端,用于简化与Eureka Server的交互,客户端同时也就是一个内置的、使用轮询(round-robin)负载算法的负载均衡器。
在应用启动后,将会向Eureka Server发送心跳,默认周期为30秒,如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点移除(默认90秒)。
Eureka Server之间通过复制的方式完成数据的同步,Eureka还提供了客户端缓存机制,即使所有的Eureka Server都挂掉,客户端依然可以利用缓存中的信息消费其他服务的API。综上,Eureka通过心跳检查、客户端缓存等机制,确保了系统的高可用性、灵活性和可伸缩性。

在这里插入图片描述

总的来说就是把各个服务找到结合起来

ribbon概念:Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,它基于Netflix Ribbon实现。

通过Spring Cloud的封装,可以让我们轻松地将面向服务的REST模版请求自动转换成客户端负载均衡的服务调用。

Spring Cloud Ribbon只是一个工具类框架,它不像服务注册中心、配置中心、API网关那样需要独立部署,但是它几乎存在于每一个Spring
Cloud构建的微服务和基础设施中。

因为微服务间的调用,API网关的请求转发等内容,实际上都是通过Ribbon来实现的,包括后续我们将要介绍的Feign,它也是基于Ribbon实现的工具。

所以,对Spring Cloud Ribbon的理解和使用,对于我们使用Spring Cloud来构建微服务非常重要。

总结比如淘宝的用户模块可能有同样的数千台服务器,可能你每一次访问你的主页,给你提供数据的服务器可能是不同,有的服务器压力过大就由其他的服务器给你提供服务

feign概念:Feign是Netflix开发的声明式、模板化的HTTP客户端, Feign可以帮助我们更快捷、优雅地调用HTTP API。
在Spring Cloud中,使用Feign非常简单——创建一个接口,并在接口上添加一些注解,代码就完成了。Feign支持多种注解,例如Feign自带的注解或者JAX-RS注解等。
Spring Cloud对Feign进行了增强,使Feign支持了Spring MVC注解,并整合了Ribbon和Eureka,从而让Feign的使用更加方便。
Spring Cloud Feign是基于Netflix feign实现,整合了Spring Cloud Ribbon和Spring Cloud Hystrix,除了提供这两者的强大功能外,还提供了一种声明式的Web服务客户端定义的方式。
Spring Cloud Feign帮助我们定义和实现依赖服务接口的定义。在Spring Cloud feign的实现下,只需要创建一个接口并用注解方式配置它,即可完成服务提供方的接口绑定,简化了在使用Spring Cloud Ribbon时自行封装服务调用客户端的开发量。
Spring Cloud Feign具备可插拔的注解支持,支持Feign注解、JAX-RS注解和Spring MVC的注解。

总结就是不用将服务的ip端口等手动去写到文件中,那样工作量很大

hystrix概念:在分布式系统架构中多个系统之间通常是通过远程RPC调用进行通信,也就是 A 系统调用 B 系统服务,B 系统调用 C 系统的服务。当尾部应用 C 发生故障而系统 B 没有服务降级时候可能会导致 B,甚至系统 A 瘫痪,这种现象被称为雪崩现象。所以在系统设计时候要使用一定的降级策略,来保证当服务提供方服务不可用时候,服务调用方可以切换到降级后的策略进行执行。
设计原则:资源隔离(线程池隔离和信号量隔离)机制:限制调用分布式服务的资源使用,某一个调用的服务出现问题不会影响其它服务调用。
限流机制:限流机制主要是提前对各个类型的请求设置最高的QPS阈值,若高于设置的阈值则对该请求直接返回,不再调用后续资源。
熔断机制:当失败率达到阀值自动触发降级(如因网络故障、超时造成的失败率增高),熔断器触发的快速失败会进行快速恢复。
降级机制:超时降级、资源不足时(线程或信号量)降级 、运行异常降级等,降级后可以配合降级接口返回托底数据。
缓存支持:提供了请求缓存、请求合并实现
通过近实时的统计/监控/报警功能,来提高故障发现的速度
通过近实时的属性和配置热修改功能,来提高故障处理和恢复的速度

总结就是避免服务器全部崩盘死掉,因为各个模块彼此间有依赖,一个的崩溃可能会导致其他的崩溃,所以有了这个容错机制,保证一个的崩溃不会影响到其他的服务器

项目构建

1创建microserver空的maven包当作文件夹

2在项目中添加sping modul(eureka_service)
修改application.yml文件
在启动类上添加注解@EnableEurekaServer

在这里插入图片描述

server:
  port: 8761
eureka:
  client:
#要不要去注册中心获取其他服务的地址
    fetch-registry: false
#自己就是注册中心,不用注册自己
    register-with-eureka: false

运行后打开浏览器可以访问到

在这里插入图片描述

3添加microserver_procider_user modul 使用sping初始化选择如下工具
修改application.yml配置文件
然后创建实体类
创建服务层
创建控制类
启动类添加注解@EnableDiscoveryClient
运行(运行前请确保数据库有相应的数据)

在这里插入图片描述

server:
  port: 8000
spring:
  application:
  #name不能使用_不然后面的http请求要报错,http请求中不能有_,也可能是版本问题
    name: microservice-provider-user
  jpa:
    show-sql: true
  datasource:
    url: jdbc:mysql:///test?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT
    driver-class-name: com.mysql.jdbc.Driver
    username: root
    password:
eureka:
  instance:
    prefer-ip-address: true
package com.example.proj.entity;

import lombok.Data;


import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Table;

import javax.persistence.*;

@Data
@Entity
@Table(name = "user")
public class user {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String username;

    private String password;
}


package com.example.proj.dao;

import com.example.proj.entity.user;
import org.springframework.data.jpa.repository.JpaRepository;

public interface userDao extends JpaRepository<user, Integer> {
}

package com.example.proj.controller;


import com.example.proj.dao.userDao;
import com.example.proj.entity.user;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Optional;

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private userDao dao;

    @RequestMapping("/findById/{id}")
    public user findById(@PathVariable("id") Integer id) {
        Optional<user> optional = dao.findById(id);
        if (optional.isPresent()) return optional.get();
        else return null;
    }
}

在这里插入图片描述

中间遇到了一个错误搞了一个多小时心态都给我搞崩了,没有任何报错就是访问不了,来回找问题,后面百度,尝试一番才发现是启动类的位置不对,启动类我将他放到了最外层目录下面一下就没问题了

异常This application has no explicit mapping for /error, so you are seeing this as a fallback.
在这里插入图片描述

4创建microservice_consumer_user(同样是在主结构下创建一个模块选择需要的)
修改application.yml文件
创建实体类
创建userController类实现访问逻辑
同样启动类上面要加注解@EnableDiscoveryClient

在这里插入图片描述

server:
  port: 8010
spring:
  application:
    name: microservice-consumer-user
eureka:
  instance:
    prefer-ip-address: true
package com.example.proj.microservice_consumer_user.entity;

import lombok.Data;


@Data
public class user {
    private Integer id;

    private String username;

    private String password;
}
package com.example.proj.microservice_consumer_user.controller;

import com.example.proj.microservice_consumer_user.entity.user;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
@RequestMapping("/user")
public class userController {

    @RequestMapping("/{id}")
    public user getOne(@PathVariable("id") Integer id) {
        RestTemplate restTemplate = new RestTemplate();
        return restTemplate.getForObject("http://localhost:8000/user/findById/" + id, user.class);
    }
}

在这里插入图片描述

5负载均衡实现先创建一个提供者按前面的提供者的创建一样的
生产者8001,服务名为microservice_provider_user_copy

修改application.yml文件
同样启动类需要添加依赖@EnableDiscoveryClient

server:
  port: 8001
spring:
  application:
  #端口不一样,同时这个name必须一样
    name: microservice-provide-user
  jpa:
    show-sql: true
  datasource:
    url: jdbc:mysql:///test?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: root
eureka:
  instance:
    prefer-ip-address: true

实体类中添加一句

//上面的添加在原来的提供者中,下面的添加到新的提供者中以供区分
@Transient
private String source = "EurekaProvider";
@Transient
private String source = "EurekaProviderRibbon";

测试时修改url中的端口看新的是否创建成功

准备做好了就要开始实现负载均衡了
需要现在消费者中添加pom依赖包

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

消费者启动类中添加如下代码

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

消费者controller中代码改为

package com.example.proj.microservice_consumer_user.controller;

import com.example.proj.microservice_consumer_user.entity.user;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
@RequestMapping("/user")
public class userController {

    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping("/{id}")
    public user getOne(@PathVariable("id") Integer id) {
        return restTemplate.getForObject("http://microservice-provider-user/user/findById/" + id, user.class);
    }
}

消费者实体中添加代码去匹配生产者

private String source;

一切准备就全部启动,结果如下,可以看出已经实现了

在这里插入图片描述

6使用feign来简化开发
先创建consumerfeign
勾选如下依赖

在这里插入图片描述

修改application.xml文件

server:
  port: 8020
spring:
  application:
    name: microservice-consumer-user-feign
eureka:
  instance:
    prefer-ip-address: true

创建实体类

package com.example.proj.microservice_consumer_user_feign.entity;

import lombok.Data;

@Data
public class User {
    private Integer id;

    private String username;

    private String password;

    private String source;
}

创建feign客户端

package com.example.proj.microservice_consumer_user_feign.feign;

import com.example.proj.microservice_consumer_user_feign.entity.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
@FeignClient("microservice-provider-user")
public interface UserFeignClient {
    @RequestMapping("/user/findById/{id}")
    public User findById(@PathVariable("id") Integer id);
}

创建controller类

package com.example.proj.microservice_consumer_user_feign.controller;

import com.example.proj.microservice_consumer_user_feign.entity.User;
import com.example.proj.microservice_consumer_user_feign.feign.UserFeignClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserFeignClient userFeignClient;

    @RequestMapping("/{id}")
    public User getOne(@PathVariable("id") Integer id) {
        return userFeignClient.findById(id);
    }
}

启动类添加注解@EnableFeignClients,启动测试

在这里插入图片描述

7服务C宕机,导致服务B宕机,从而导致服务A宕机,最终整个商城无法使用,所以hystrix就有用了

在这里插入图片描述

首先创建模块选择相关依赖

在这里插入图片描述

修改application.xml文件

server:
  port: 8030
spring:
  application:
    name: microservice-user-feign-hytrix
eureka:
  instance:
    prefer-ip-address: true
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

entity,feign两个模块复制前面的feignconsumer

修改controller类只是在前面feign中的controller中加了一个方法和一个注解

package com.example.proj.microservice_consumer_user_feign_hystrix.controller;

import com.example.proj.microservice_consumer_user_feign_hystrix.entity.User;
import com.example.proj.microservice_consumer_user_feign_hystrix.feign.UserFeignClient;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserFeignClient userFeignClient;

    @HystrixCommand(defaultFallback = "cannoFind")
    @RequestMapping("/{id}")
    public User getOne(@PathVariable("id")Integer id){
        return userFeignClient.findById(id);
    }
    private User cannoFind(){
        User user=new User();
        user.setId(-1);
        return  user;
    }
}

启动类上添加注解
@EnableFeignClients
@EnableCircuitBreaker
@EnableDiscoveryClient

然后运行,发现访问8030正常,然后关掉一个生产者发现另一个生产者正常一个返回这个

在这里插入图片描述
目前就这么搭建了一个项目后面会在这个给基础上加上网关zuul微服务网关

码字不易

只看不赞王八蛋

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菜鸟程序员李老板专业码代码三十年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值