微服务架构➖SpringCloud➖Hystrix

微服务架构➖SpringCloud➖Hystrix

关于作者

  • 作者介绍

🍓 博客主页:作者主页

🍓 简介:JAVA领域优质创作者🥇、一名在校大三学生🎓、在校期间参加各种省赛、国赛,斩获一系列荣誉 🏆、阿里云专家博主51CTO专家博主

🍓 关注我:关注我学习资料、文档下载统统都有,每日定时更新文章,励志做一名JAVA资深程序猿👨‍💻


1. 前言

什么是服务雪崩?

  1. 当用户访问A的一个接口
    • A的tomcat会给用户分配一个线程,支持用户访问
  2. A发现要完成用户的操作,需要访问B服务
  3. A去访问B
    • B的会给A分配一个线程,支持A的访问
  4. B发现需要完成A的操作,必须访问C服务,但是C挂了
    • B在访问C之前不知道C挂了,B去访问,直到超时,才知道C无法访问

结果: 因为C不可用,导致B的线程不能及时回收,从而导致A的线程也无法及时回收,导致整个服务链里面的线程池没有线程可用了。此时再有用户访问A,那么tomcat直接报503 ,服务不可用


服务雪崩的本质:线程没有及时回收。 不管是调用成功还是失败,只要线程可以及时回收,就可以解决服务雪崩

服务雪崩怎么解决?

  • 修改调用的超时时长(不推荐)

将服务间的调用超时时长改小,这样就可以让线程及时回收,保证服务可用

优点:非常简单,也可以有效的解决服务雪崩

缺点:不够灵活,有的服务需要更长的时间去处理(写库,整理数据)

  • 设置拦截器

简介

熔断器,也叫断路器!(正常情况下 断路器是关的 只有出了问题才打开)用来保护微服务不 雪崩的方法。思想和我们上面画的拦截器一样。

Hystrix 是 Netflix 公司开源的一个项目,它提供了熔断器功能,能够阻止分布式系统中出现联动故障。Hystrix 是通过隔离服务的访问点阻止联动故障的,并提供了故障的解决方案,从 而提高了整个分布式系统的弹性。微博 弹性云扩容 Docker K8。

快速入门

当有服务调用的时候,才会出现服务雪崩,所以 Hystrix 常和 OpenFeign,Ribbon 一起出现。

3.1 创建父项目 feign

3.2 创建子 module

  • project-domain 公共实体类
  • common-api 消费者接口
  • user-center 消费者
  • order-center 提供者

新建子moudle模块一定要选择 以 04-feign-project 为父项目。

pom文件的依赖关系

3.3 父项目 pom.xml

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <packaging>pom</packaging>
    <modules>
        <module>project-domain</module>
        <module>common-api</module>
        <module>user-center</module>
        <module>order-center</module>
    </modules>


    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.12.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

<!--    <packaging>pom</packaging>-->

    <groupId>org.example</groupId>
    <artifactId>04-feign-project</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <spring-boot.version>2.3.12.RELEASE</spring-boot.version>
        <spring-cloud.version>Hoxton.SR12</spring-cloud.version>
    </properties>


<!--    这里所以的依赖 子模块都会有-->
    <dependencies>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

<!--加载这里的依赖不会被直接引入该项目  只做了一个版本号的控制-->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

<!--    打包 仓库 等配置-->
<!--    <build>-->

<!--    </build>-->
</project>

3.4 子模块project-domain

Order.java

java 复制代码
package com.zmz.domain;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @ProjectName: 04-hystrix
 * @Package: com.zmz.domain
 * @ClassName: Order
 * @Author: 张晟睿
 * @Date: 2022/10/8 18:57
 * @Version: 1.0
 */

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Order {

    private Integer orderId;
    private String name;
    private Double price;
}

pom.xml

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>04-feign-project</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>project-domain</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

</project>

3.5 子模块common-api

UserOrderFeign.java

java 复制代码
package com.zmz.feign;

import com.zmz.domain.Order;
import com.zmz.feign.hystrix.UserOrderFeignHystrix;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

/**
 * @ProjectName: 04-hystrix
 * @Package: com.zmz.feign
 * @ClassName: UserOrderFeign
 * @Author: 张晟睿
 * @Date: 2022/10/8 19:04
 * @Version: 1.0
 */
@FeignClient(value="order-service", fallback = UserOrderFeignHystrix.class)
public interface UserOrderFeign {

    @GetMapping("/order/getOrderById")
    Order getOrderById(@RequestParam Integer userId);
}

UserOrderFeignHystrix.java

java 复制代码
package com.zmz.feign.hystrix;

import com.zmz.domain.Order;
import com.zmz.feign.UserOrderFeign;
import org.springframework.stereotype.Component;

/**
 * @ProjectName: 04-hystrix
 * @Package: com.zmz.feign.hystrix
 * @ClassName: UserOrderFeignHystrix
 * @Author: 张晟睿
 * @Date: 2022/10/9 9:09
 * @Version: 1.0
 */
@Component
public class UserOrderFeignHystrix implements UserOrderFeign {
    @Override
    public Order getOrderById(Integer userId) {
        return null;
    }
}

pom.xml

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>04-feign-project</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>common-api</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>project-domain</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

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

</project>

3.6 子模块order-center

OrderController.java

java 复制代码
package com.zmz.controller;

import com.zmz.domain.Order;
import com.zmz.feign.UserOrderFeign;
import org.springframework.web.bind.annotation.RestController;

/**
 * @ProjectName: 04-hystrix
 * @Package: com.zmz.controller
 * @ClassName: Order
 * @Author: 张晟睿
 * @Date: 2022/10/8 19:03
 * @Version: 1.0
 */
@RestController
public class OrderController
        implements UserOrderFeign {
    @Override
    public Order getOrderById(Integer userId) {

        Order order = Order.builder()
                .name("西红柿鸡蛋面")
                .orderId(0001)
                .price(100D).build();
        System.out.println(order);
        return order;
    }
}

OrderServiceApp.java 主启动类

java 复制代码
package com.zmz;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

/**
 * @ProjectName: 04-hystrix
 * @Package: com.zmz
 * @ClassName: OrderServiceApp
 * @Author: 张晟睿
 * @Date: 2022/10/8 19:02
 * @Version: 1.0
 */
@SpringBootApplication
@EnableEurekaClient
public class OrderServiceApp {
    public static void main(String[] args) {
        SpringApplication.run(OrderServiceApp.class, args);
    }
}

application.yml

yml 复制代码
server:
  port: 8080
spring:
  application:
    name: order-service
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka
  instance:
    hostname: localhost
    instance-id: ${eureka.instance.hostname}:${spring.application.name}:${server.port}

pom.xml

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>04-feign-project</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>order-center</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>common-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <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>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.6.0</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.3.12.RELEASE</version>
                <configuration>
                    <mainClass>com.zmz.RentCarServiceApplication</mainClass>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

3.7 子模块user-center

UserController.java

java 复制代码
package com.zmz.controller;

import com.zmz.domain.Order;
import com.zmz.feign.UserOrderFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @ProjectName: 04-hystrix
 * @Package: com.zmz.controller
 * @ClassName: UserController
 * @Author: 张晟睿
 * @Date: 2022/10/8 19:22
 * @Version: 1.0
 */
@RestController
public class UserController {

    @Autowired
    public UserOrderFeign userOrderFeign;

    @GetMapping("find")
    public Order findOrder() {
       return userOrderFeign.getOrderById(11);
    }
}

UserServiceApp.java 主启动类

java 复制代码
package com.zmz;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

/**
 * @ProjectName: 04-hystrix
 * @Package: com.zmz
 * @ClassName: UserServiceApp
 * @Author: 张晟睿
 * @Date: 2022/10/8 19:16
 * @Version: 1.0
 */
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class UserServiceApp {
    public static void main(String[] args) {
        SpringApplication.run(UserServiceApp.class, args);
    }
}

application.yml

yml 复制代码
server:
  port: 8081
spring:
  application:
    name: user-service
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka
  instance:
    hostname: localhost
    instance-id: ${eureka.instance.hostname}:${spring.application.name}:${server.port}

feign:
  hystrix:
    enabled: true  #开启熔断

pom.xml

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>04-feign-project</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>user-center</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>common-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>


        <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>
        </dependency>
    </dependencies>
</project>

小结

Hystrix是Spring Cloud生态系统中的一款强大的容错工具,用于处理分布式系统中的故障和延迟。

  1. 容错机制:Hystrix提供了诸如断路器、超时控制、线程池隔离等容错机制,以保护系统免受故障的影响。通过配置这些机制,我们可以定义对于不同的服务调用,如果出现故障或超时,应该采取的容错行为。
  2. 断路器模式:Hystrix的核心概念之一是断路器模式。通过断路器的状态监控和切换,Hystrix能够在服务调用故障超过一定阈值时,迅速切换为执行备选方案,从而避免连锁故障并提高系统的可用性。
  3. 隔离策略:Hystrix通过线程池隔离和信号量隔离两种策略,实现了对不同服务调用的隔离。线程池隔离将每个服务调用放入独立的线程池中执行,从而避免了某个服务调用的故障影响其他服务。信号量隔离则通过限制同时执行的请求数量来保护系统。
  4. 监控和度量:Hystrix提供了丰富的监控和度量功能,可以实时监控服务调用的指标、熔断器状态以及执行结果。通过集成Hystrix Dashboard和Turbine等工具,我们可以实现对服务的可视化监控和报警。
  5. 异常处理和回退:使用Hystrix时,我们可以定义回退逻辑来处理服务调用的异常情况。当服务调用失败或超时时,Hystrix将执行预定义的回退逻辑,返回一个默认值或执行备选方案,保证系统的稳定性和可用性。
相关推荐
2401_857610031 小时前
SpringBoot社团管理:安全与维护
spring boot·后端·安全
凌冰_2 小时前
IDEA2023 SpringBoot整合MyBatis(三)
spring boot·后端·mybatis
码农飞飞2 小时前
深入理解Rust的模式匹配
开发语言·后端·rust·模式匹配·解构·结构体和枚举
一个小坑货2 小时前
Rust 的简介
开发语言·后端·rust
monkey_meng3 小时前
【遵守孤儿规则的External trait pattern】
开发语言·后端·rust
Estar.Lee3 小时前
时间操作[计算时间差]免费API接口教程
android·网络·后端·网络协议·tcp/ip
Grey_fantasy4 小时前
高级编程之结构化代码
java·spring boot·spring cloud
新知图书4 小时前
Rust编程与项目实战-模块std::thread(之一)
开发语言·后端·rust
盛夏绽放4 小时前
Node.js 和 Socket.IO 实现实时通信
前端·后端·websocket·node.js
Ares-Wang4 小时前
Asp.net Core Hosted Service(托管服务) Timer (定时任务)
后端·asp.net