spring-cloud之hystrix
Hystrix是由Netflix开源的一个针对分布式系统容错处理的开源组件。
1)通过客户端库对延迟和故障进行保护和控制。(当被访问的服务或方法失败时会调用自定义的容错方法,容错方法通常都是已日志和失败提示为主,这样做使得调用发生的错误更优雅的表现出来)。
2)在一个复杂的分布式系统中停止级联故障。(例如当A服务调用B服务时,此时B服务因为其他服务的调用压力过大延迟或奔溃,那么A根据配置:过期时间,请求数量等配置触发fallback逻辑“容错逻辑”)。
3)快速失败和迅速恢复。(根据请求失败率来进行自动隔离服务,此时服务会拒绝所有请求,直到内部线程空出来在迅速恢复服务)
4)在合理的情况下回退和优雅地降级。(当请求压力大时,会将服务降级“只处理当前进程内逻辑不再接收新的请求”)
5)开启近实时监控、告警和操作控制。(提供链路追踪的仪表盘,供运维/开发推断当前配置是否合理)。
Hystrix基本操作:
例子一:
1.eureka客户端,服务端前几节有
pom.xml
<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> <parent> <groupId>cn.springcloud.book</groupId> <artifactId>ch6-1</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <artifactId>ch6-1-client-service</artifactId> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
bootstrap.yml
server:
port: 8888
spring:
application:
name: sc-client-service
eureka:
client:
serviceUrl:
defaultZone: http://${eureka.host:127.0.0.1}:${eureka.port:8761}/eureka/
instance:
prefer-ip-address: true
ClientApplication:@EnableHystrix启用Hsystrix
package cn.springcloud.book; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.netflix.hystrix.EnableHystrix; /** * @author www.springcloud.cn * */ @SpringBootApplication @EnableHystrix @EnableDiscoveryClient public class ClientApplication { public static void main(String[] args) { SpringApplication.run(ClientApplication.class, args); } }
IUserService
package cn.springcloud.book.service; public interface IUserService { public String getUser(String username) throws Exception; }
UserService:@HystrixCommand(fallbackMethod="defaultUser"),在此处执行hystrix命令,要是被修饰的方法执行失败则执行指定的方法“defaultUser”
package cn.springcloud.book.service.impl; import org.springframework.stereotype.Component; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; import cn.springcloud.book.service.IUserService; /** */ @Component public class UserService implements IUserService{ @Override @HystrixCommand(fallbackMethod="defaultUser") public String getUser(String username) throws Exception { if(username.equals("spring")) { return "This is real user"; }else { throw new Exception(); } } /** * 出错则调用该方法返回友好错误 * @param username * @return */ public String defaultUser(String username) { return "The user does not exist in this system"; } }
TestController
package cn.springcloud.book.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import cn.springcloud.book.service.IUserService; @RestController public class TestController { @Autowired private IUserService userService; @GetMapping("/getUser") public String getUser(@RequestParam String username) throws Exception{ return userService.getUser(username); } }
然后启动eureka server后启动此项目即可访问controller,可以看到当参数为:spring时返回getUser方法的:"This is real user",否则返回defaultUser方法的:"The user does not exist in this system"。
这就是hystrix在代码层展示最直观的方式。
例子二:
spring cloud feign服务间调用也集成了spring cloud hystrix,以及负载均衡 spring cloud ribbon,当调用别的服务失败时会触发fallback指定类对应的方法,fallback指定类药实现当前当前调用接口。
package cn.springcloud.book; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.netflix.hystrix.EnableHystrix; import org.springframework.cloud.openfeign.EnableFeignClients; /** * @author www.springcloud.cn */ @SpringBootApplication @EnableHystrix @EnableDiscoveryClient @EnableFeignClients public class ConsumerApplication { public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); } }
package cn.springcloud.book.service; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import cn.springcloud.book.service.impl.UserServiceFallback; @FeignClient(name = "sc-provider-service", fallback = UserServiceFallback.class) public interface IUserService { @RequestMapping(value = "/getUser",method = RequestMethod.GET) public String getUser(@RequestParam("username") String username); }
package cn.springcloud.book.service.impl; import org.springframework.stereotype.Component; import cn.springcloud.book.service.IUserService; @Component public class UserServiceFallback implements IUserService{ /** * 出错则调用该方法返回友好错误 * @param username * @return */ public String getUser(String username){ return "The user does not exist in this system, please confirm username"; } }
package cn.springcloud.book.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import cn.springcloud.book.service.IUserService; @RestController public class TestController { @Autowired private IUserService userService; @RequestMapping(value = "/getUser",method = RequestMethod.GET) public String getUser(@RequestParam("username") String username) throws Exception{ return userService.getUser(username); } }
yml配置:记得在spring cloud feign的配置中打开hystrix,否则hystrix不起作用,调用失败不会测试调用失败抛出异常后不会优雅的提示,直接会报错500.
feign:
hystrix:
enabled: true
pom.xml
<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> <parent> <groupId>cn.springcloud.book</groupId> <artifactId>ch6-2</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <artifactId>ch6-2-consumer-service</artifactId> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
要访问服务的controller,要访问的项目为一个正常的拥有controller接口的服务。如果知识单纯的被访问在不需要引入hystrix.
package cn.springcloud.book.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class TestController { @RequestMapping(value = "/getUser",method = RequestMethod.GET) public String getUser(@RequestParam("username") String username) throws Exception{ if(username.equals("spring")) { return "This is real user"; }else { throw new Exception(); } } }
hystrix统计各个服务健康状况,合并请求,隔离方式:https://weread.qq.com/web/reader/71d32370716443e271df020kd67323c0227d67d8ab4fb04
本文来自博客园,作者:~~mr.li~~,转载请注明原文链接:https://www.cnblogs.com/li-yan-long/p/15996486.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!