当前位置: 首页 > news >正文

SpringCloud-Hystrix

一、介绍

(1)避免单个服务出现故障导致整个应用崩溃。
(2)服务降级:服务超时、服务异常、服务宕机时,执行定义好的方法。(做别的)
(3)服务熔断:达到熔断条件时,服务禁止被访问,执行定义好的方法。(不做了)
(4)服务限流:高并发场景下的一大波流量过来时,让其排队访问。(排队做)

二、构建项目

(1)pom.xml

<dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><dependency><groupId>com.wsh.springcloud</groupId><artifactId>cloud-api-common</artifactId><version>1.0-SNAPSHOT</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies>

(2)编写application.yml文件

server:port: 8001spring:application:name: cloud-provider-hystrix-paymentdatasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: org.gjt.mm.mysql.Driverurl: jdbc:mysql://localhost:3306/springcloud?useUnicode=true&characterEncoding=utf-8&useSSL=falseusername: rootpassword: wsh666eureka:client:register-with-eureka: truefetch-registry: trueservice-url:defaultZone: http://eureka1.com:7001/eurekainstance:instance-id: hystrixPayment8001prefer-ip-address: true

(3)启动类PaymentHystrixMain8001

package com.wsh.springcloud;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;/*** @ClassName PaymentHystrixMain8001* @Description: TODO* @Author wshaha* @Date 2023/10/14* @Version V1.0**/
@SpringBootApplication
@EnableEurekaClient
public class PaymentHystrixMain8001 {public static void main(String[] args) {SpringApplication.run(PaymentHystrixMain8001.class, args);}
}

(4)编写PaymentService

package com.wsh.springcloud.service;import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;/*** @ClassName PaymentService* @Description: TODO* @Author wshaha* @Date 2023/10/14* @Version V1.0**/
@Service
@Slf4j
public class PaymentService {public String test1(Integer id){return "test1: " + Thread.currentThread().getName() + " " + id;}public String test2(Integer id){try {Thread.sleep(3000);} catch (Exception e){}return "test2: " + Thread.currentThread().getName() + " " + id;}
}

(5)编写PaymentController

package com.wsh.springcloud.controller;import com.wsh.springcloud.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;/*** @ClassName PaymentController* @Description: TODO* @Author wshaha* @Date 2023/10/14* @Version V1.0**/
@Slf4j
@RequestMapping("/payment")
@RestController
public class PaymentController {@Autowiredprivate PaymentService paymentService;@GetMapping("/test1/{id}")public String test1(@PathVariable("id") Integer id){return paymentService.test1(id);}@GetMapping("/test2/{id}")public String test2(@PathVariable("id") Integer id){return paymentService.test2(id);}
}

(6)运行
在这里插入图片描述

三、 服务降级配置

(1)方式一(一旦方法出现异常或超时了,会调用@HystrixCommand的降级方法)

注:@EnableCircuitBreaker用于启动断路器,支持多种断路器,@EnableHystrix用于启动断路器,只支持Hystrix断路器

a、PaymentService编写降级方法,配置注解@HystrixCommand

@Service
@Slf4j
public class PaymentService {public String test1(Integer id){return "test1: " + Thread.currentThread().getName() + " " + id;}@HystrixCommand(fallbackMethod = "test2fallback", commandProperties = {@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000")})public String test2(Integer id){try {Thread.sleep(3000);} catch (Exception e){}return "test2: " + Thread.currentThread().getName() + " " + id;}public String test2fallback(Integer id){return "test2fallback: " + id;}
}

b、启动类开启断路器

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

c、运行
在这里插入图片描述
(2)方式二(配置全局使用的降级方法)
a、使用@DefaultProperties,注意全局降级方法的参数列表为空

@Slf4j
@RequestMapping("/payment")
@RestController
@DefaultProperties(defaultFallback = "defaultFallbacktest")
public class PaymentController {@Autowiredprivate PaymentService paymentService;@GetMapping("/test1/{id}")public String test1(@PathVariable("id") Integer id){return paymentService.test1(id);}@GetMapping("/test2/{id}")@HystrixCommandpublic String test2(@PathVariable("id") Integer id){return paymentService.test2(id);}public String defaultFallbacktest(){return "defaultFallbacktest";}
}

b、编写PaymentService

@Service
@Slf4j
public class PaymentService {public String test1(Integer id){return "test1: " + Thread.currentThread().getName() + " " + id;}//    @HystrixCommand(fallbackMethod = "test2fallback", commandProperties = {
//            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000")
//    })public String test2(Integer id){
//        try {
//            Thread.sleep(3000);
//        } catch (Exception e){
//
//        }int i = 1 / 0;return "test2: " + Thread.currentThread().getName() + " " + id;}
//    public String test2fallback(Integer id){
//        return "test2fallback: " + id;
//    }
}

c、运行
在这里插入图片描述
(3)方式三,feign调用其他服务时,可以利用实现类对应降级方法
a、pom.xml增加依赖

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

b、application.yml增加

feign:hystrix:enabled: true

c、编写远程调用接口FeignTestService

@Component
@FeignClient(value = "CLOUD-PAYMENT-SERVICE", fallback = FeignTestServiceImpl.class)
public interface FeignTestService {@GetMapping("/payment/test")public CommonResult<String> test();
}

d、编写降级方法类FeignTestServiceImpl

@Component
public class FeignTestServiceImpl implements FeignTestService{@Overridepublic CommonResult<String> test() {return new CommonResult(444, "", "error");}
}

e、编写Controller

@Slf4j
@RequestMapping("/payment")
@RestController
//@DefaultProperties(defaultFallback = "defaultFallbacktest")
public class PaymentController {@Autowiredprivate PaymentService paymentService;@Autowiredprivate FeignTestService feignTestService;@GetMapping("/test1/{id}")public String test1(@PathVariable("id") Integer id){return paymentService.test1(id);}@GetMapping("/test2/{id}")
//    @HystrixCommandpublic String test2(@PathVariable("id") Integer id){return paymentService.test2(id);}
//    public String defaultFallbacktest(){
//        return "defaultFallbacktest";
//    }@GetMapping("/test")public CommonResult<String> test(){return feignTestService.test();}
}

f、运行
在这里插入图片描述

四、服务熔断配置

(1)服务先降级,然后熔断,后面尝试恢复
(2)在规定时间内,接口访问量超过设置阈值,并且失败率大于等于设置阈值
(3)例子

@Service
@Slf4j
public class PaymentService {@HystrixCommand(fallbackMethod = "test1fallback", commandProperties = {@HystrixProperty(name = "circuitBreaker.enabled", value = "true"),//开启断路器@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),//请求次数阈值@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"),//规定时间内@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60")//失败率阈值})public String test1(Integer id){int i = 1 / id;return "test1: " + Thread.currentThread().getName() + " " + id;}public String test1fallback(Integer id){return "test1fallback: " + id;}//    @HystrixCommand(fallbackMethod = "test2fallback", commandProperties = {
//            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000")
//    })public String test2(Integer id){
//        try {
//            Thread.sleep(3000);
//        } catch (Exception e){
//
//        }int i = 1 / 0;return "test2: " + Thread.currentThread().getName() + " " + id;}
//    public String test2fallback(Integer id){
//        return "test2fallback: " + id;
//    }
}

五、监控界面搭建(只能监控hystrix接管的方法)

(1)编写pom.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>demo20220821</artifactId><groupId>com.wsh.springcloud</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>cloud-consumer-hystrix-dashboard9001</artifactId><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId></dependency><dependency><groupId>com.wsh.springcloud</groupId><artifactId>cloud-api-common</artifactId><version>1.0-SNAPSHOT</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
<!--        <dependency>-->
<!--            <groupId>org.springframework.boot</groupId>-->
<!--            <artifactId>spring-boot-starter-actuator</artifactId>-->
<!--        </dependency>--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies>
</project>

(2)编写application.yml

server:port: 9001spring:application:name: cloud-hystrix-dashboard

(3)编写启动类

package com.wsh.springcloud;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;/*** @ClassName HystrixDashboardMain9001* @Description: TODO* @Author wshaha* @Date 2023/10/14* @Version V1.0**/
@SpringBootApplication
@EnableHystrixDashboard
public class HystrixDashboardMain9001 {public static void main(String[] args) {SpringApplication.run(HystrixDashboardMain9001.class, args);}
}

(4)运行
在这里插入图片描述
(5)配置被监控的项目
a、pom.xml

加上探针spring-boot-starter-actuator

b、启动类加上

package com.wsh.springcloud;import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;/*** @ClassName PaymentHystrixMain8001* @Description: TODO* @Author wshaha* @Date 2023/10/14* @Version V1.0**/
@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker
@EnableFeignClients
public class PaymentHystrixMain8001 {public static void main(String[] args) {SpringApplication.run(PaymentHystrixMain8001.class, args);}@Beanpublic ServletRegistrationBean getServlet(){HystrixMetricsStreamServlet hystrixMetricsStreamServlet = new HystrixMetricsStreamServlet();ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(hystrixMetricsStreamServlet);servletRegistrationBean.setLoadOnStartup(1);servletRegistrationBean.addUrlMappings("/hystrix.stream");servletRegistrationBean.setName("HystrixMetricsStreamServlet");return servletRegistrationBean;}
}

(6)监控界面
在这里插入图片描述
在这里插入图片描述

相关文章:

SpringCloud-Hystrix

一、介绍 &#xff08;1&#xff09;避免单个服务出现故障导致整个应用崩溃。 &#xff08;2&#xff09;服务降级&#xff1a;服务超时、服务异常、服务宕机时&#xff0c;执行定义好的方法。&#xff08;做别的&#xff09; &#xff08;3&#xff09;服务熔断&#xff1a;达…...

Ansible脚本进阶---playbook

目录 一、playbooks的组成 二、案例 2.1 在webservers主机组中执行一系列任务&#xff0c;包括禁用SELinux、停止防火墙服务、安装httpd软件包、复制配置文件和启动httpd服务。 2.2 在名为dbservers的主机组中创建一个用户组&#xff08;mysql&#xff09;和一个用户&#x…...

pytorch 模型部署之Libtorch

Python端生成pt模型文件 net.load(model_path) net.eval() net.to("cuda")example_input torch.rand(1, 3, 240, 320).to("cuda") traced_model torch.jit.trace(net, example_input) traced_model.save("model.pt")output traced_model(exa…...

Unity——数据存储的几种方式

一、PlayerPrefs PlayerPrefs适合用于存储简单的键值对数据 存储的数据会在游戏关闭后依然保持&#xff0c;并且可以在不同场景之间共享&#xff0c;适合用于需要在游戏不同场景之间传递和保持的数据。 它利用key-value的方式将数据保存到本地&#xff0c;跟字典类似。然后通…...

『heqingchun-ubuntu系统下安装cuda与cudnn』

ubuntu系统下安装cuda与cudnn 一、安装依赖 1.更新 sudo apt updatesudo apt upgrade -y2.基础工具 sudo apt install -y build-essential python二、安装CUDA 1.文件下载 网址 https://developer.nvidia.com/cuda-toolkit-archive依次点击 (1)“CUDA Toolkit 11.6.2”…...

Unity AI Muse 基础教程

Unity AI Muse 基础教程 Unity AI 内测资格申请Unity 项目Package ManagerMuse Sprite 安装Muse Texture 安装 Muse Sprite 基础教程什么是 Muse Sprite打开 Muse Sprite 窗口Muse Sprite 窗口 参数Muse Sprite Generations 窗口 参数Muse Sprite Generations 窗口 画笔Muse Sp…...

pgsl基于docker的安装

1. 有可用的docker环境 &#xff0c;如果还没有安装docker&#xff0c;则请先安装docker 2. 创建pg数据库的挂载目录 mkdir postgres 3. 下载pg包 docker pull postgres 这个命令下载的是最新的pg包&#xff0c;如果要指定版本的话&#xff0c;则可以通过在后面拼接 :versio…...

idea设置某个文件修改后所在父文件夹变蓝色

idea设置某个文件修改后所在父文件夹变蓝色的方法&#xff1a; 老版idea设置方法&#xff1a; File---->Settings---->Version Control---->勾选 Show directories with changed descendants 新版idea设置方法&#xff1a; File---->Settings---->Version Co…...

代码随想录训练营二刷第五十八天 | 583. 两个字符串的删除操作 72. 编辑距离

代码随想录训练营二刷第五十八天 | 583. 两个字符串的删除操作 72. 编辑距离 一、583. 两个字符串的删除操作 题目链接&#xff1a;https://leetcode.cn/problems/delete-operation-for-two-strings/ 思路&#xff1a;定义dp[i][j]为要是得区间[0,i-1]和区间[0,j-1]所需要删除…...

秋日有感之秋诉-于光

诗&#xff1a;于光 秋风扫叶枝不舍&#xff0c; 叶落随风根欢唱。 秋日穿云不入眼&#xff0c; 云亦婆娑诉余年。...

ubuntu 22.04版本修改服务器名、ip,dns信息的操作方法

总结 1、ubuntu修改服务器名重启后生效的方法是直接修改/etc/hostname文件 2、ubuntu 22.04操作系统配置ip和dns信息&#xff0c;一般只需要使用netplan命令行工具来配置就行&#xff0c;在/etc/netplan/在目录下创建一个yaml文件就可以实现ip和dns的配置&#xff0c;当然如果…...

【微信小程序】6天精准入门(第2天:小程序的视图层、逻辑层、事件系统及页面生命周期)

一、视图层 View 1、什么是视图层 框架的视图层由 WXML 与 WXSS 编写&#xff0c;由组件来进行展示。将逻辑层的数据反映成视图&#xff0c;同时将视图层的事件发送给逻辑层。WXML(WeiXin Markup language) 用于描述页面的结构。WXS(WeiXin Script) 是小程序的一套脚本语言&am…...

速学Linux丨一文带你打开Linux学习之门

前言 如果你是刚开始学习Linux的小白同学&#xff0c;相信你已经体会到与学习一门编程语言相比&#xff0c;学习Linux系统的门槛相对较高&#xff0c;你会遇到一些困惑&#xff0c;比如&#xff1a; 为什么要学习Linux&#xff0c;学成之后我们可以在哪些领域大显身手&#xf…...

符尧:别卷大模型训练了,来卷数据吧!【干货十足】

大家好&#xff0c;我是HxShine。 今天分享一篇符尧大佬的一篇数据工程&#xff08;Data Engineering&#xff09;的文章&#xff0c;解释了speed of grokking指标是什么&#xff0c;分析了数据工程&#xff08;data engineering&#xff09;包括mix ratio&#xff08;数据混合…...

2023年中国半导体检测仪器设备销售收入、产值及市场规模分析[图]

半导体测试设备是一种用于电子与通信技术领域的电子测量仪器。随着技术发展&#xff0c;半导体芯片晶体管密度越来越高&#xff0c;相关产品复杂度及集成度呈现指数级增长&#xff0c;这对于芯片设计及开发而言是前所未有的挑战&#xff0c;随着芯片开发周期的缩短&#xff0c;…...

诊断DLL——Visual Studio安装与dll使用

文章目录 Visual Studio安装一、DLL简介二、使用步骤1.新建VS DLL工程2.生成dll文件3.自定义函数然后新建一个function.h文件,声明这个函数。4.新建VS C++ console工程,动态引用DLL编写代码,调用dll三、extern "C" __declspec(dllexport)总结Visual Studio安装 官…...

专业课138,总分390+,西工大,西北工业大学827信号与系统考研分享

数学一 考研数学其实严格意义上已经没有难度大小年之分了&#xff0c;说21年难的会说22年简单&#xff0c;说22年简单的做23年又会遭重&#xff0c;所以其实只是看出题人合不合你的口味罢了&#xff0c;建议同学不要因偶数年而畏惧&#xff0c;踏踏实实复习。资料方面跟谁就用…...

css3链接

你可以使用CSS3来自定义链接&#xff08;超链接&#xff09;的样式&#xff0c;以改变它们的外观。以下是一些用于自定义链接的常见CSS3样式规则&#xff1a; 链接的颜色: a { color: #0077b6; /* 设置链接的文字颜色 */ } 这个规则可以改变链接的文字颜色。你可以根据需要设置…...

第五章 运输层 | 计算机网络(谢希仁 第八版)

文章目录 第五章 运输层5.1 运输层协议概述5.1.1 进程之间的通信5.1.2 运输层的两个主要协议5.1.3 运输层的端口 5.2 用户数据报协议UDP5.2.1 UDP概述5.2.2 UDP的首部格式 5.3 传输控制协议TCP概述5.3.1 TCP最主要的特点5.3.2 TCP的连接 5.4 可靠传输的工作原理5.4.1 停止等待协…...

CustomTabBar 自定义选项卡视图

1. 用到的技术点 1) Generics 泛型 2) ViewBuilder 视图构造器 3) PreferenceKey 偏好设置 4) MatchedGeometryEffect 几何效果 2. 创建枚举选项卡项散列&#xff0c;TabBarItem.swift import Foundation import SwiftUI//struct TabBarItem: Hashable{ // let ico…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

7.4.分块查找

一.分块查找的算法思想&#xff1a; 1.实例&#xff1a; 以上述图片的顺序表为例&#xff0c; 该顺序表的数据元素从整体来看是乱序的&#xff0c;但如果把这些数据元素分成一块一块的小区间&#xff0c; 第一个区间[0,1]索引上的数据元素都是小于等于10的&#xff0c; 第二…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案

问题描述&#xff1a;iview使用table 中type: "index",分页之后 &#xff0c;索引还是从1开始&#xff0c;试过绑定后台返回数据的id, 这种方法可行&#xff0c;就是后台返回数据的每个页面id都不完全是按照从1开始的升序&#xff0c;因此百度了下&#xff0c;找到了…...

MODBUS TCP转CANopen 技术赋能高效协同作业

在现代工业自动化领域&#xff0c;MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步&#xff0c;这两种通讯协议也正在被逐步融合&#xff0c;形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

C++.OpenGL (10/64)基础光照(Basic Lighting)

基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...

图表类系列各种样式PPT模版分享

图标图表系列PPT模版&#xff0c;柱状图PPT模版&#xff0c;线状图PPT模版&#xff0c;折线图PPT模版&#xff0c;饼状图PPT模版&#xff0c;雷达图PPT模版&#xff0c;树状图PPT模版 图表类系列各种样式PPT模版分享&#xff1a;图表系列PPT模板https://pan.quark.cn/s/20d40aa…...

GruntJS-前端自动化任务运行器从入门到实战

Grunt 完全指南&#xff1a;从入门到实战 一、Grunt 是什么&#xff1f; Grunt是一个基于 Node.js 的前端自动化任务运行器&#xff0c;主要用于自动化执行项目开发中重复性高的任务&#xff0c;例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...

深入理解Optional:处理空指针异常

1. 使用Optional处理可能为空的集合 在Java开发中&#xff0c;集合判空是一个常见但容易出错的场景。传统方式虽然可行&#xff0c;但存在一些潜在问题&#xff1a; // 传统判空方式 if (!CollectionUtils.isEmpty(userInfoList)) {for (UserInfo userInfo : userInfoList) {…...