首页 > 其他分享 >Hystrix熔断使用

Hystrix熔断使用

时间:2025-01-05 22:16:25浏览次数:5  
标签:String Hystrix payment eureka port 熔断 使用 id public

试想一下,你的32核,128G的机器,假设最大能抗住2000qps,这个时候内存也是飙升的。如果QPS或者TPS在大一些会发生什么,会产生OOM这种ERROR,服务直接挂掉。
于是你的客服不断收到电话投诉,那是多刺激。售后催你们的技术赶紧把有问题的业务处理下,一大堆由于服务挂掉的东西需要,回退,该状态等等等,让后GG了。
在传统的设计上,熔断或者限流设计为两种。
一种是调用方发现服务方达到最大极限了,此时不再去调用,直接给用户返回友好提示,比如网络飞了,当前网络过多请稍后重试,等提示,那就表示,被调用方达到极限了,给出的保护提示。
还有一种就是,被调用放达到极限,返回给调用方,但这样会多出很多无效请求到服务方。

 接下来上案例,用我曾经做过的订单系统为例吧。

先要准备个订单调用方:OrderFeignMain80,

配置文件:

server.port=8080

spring.application.name=cloud-consumer-feign
#向注册中心注册自己
eureka.client.register-with-eureka=true
#是否从eureka抓取自己,并不需要检索服务,单节点无所谓,集群必须设置true,才能使用ribbon负载均衡
eureka.client.fetch-registry=true
#eureka.client.service-url.defaultZone=http://localhost:7001/eureka
#集群模板                                这里修改了C:\Windows\System32\drivers\etc\hosts 人为添加了域名 eureka7001.com
eureka.client.service-url.defaultZone=http://eureka7001:7001/eureka,http://eureka7002:7002/eureka
eureka.instance.instance-id=cloud-consumer-feign
#显示IP地址
eureka.instance.prefer-ip-address=true



# ribbon的可配置部分
#处理请求的超时时间,默认为1秒
ribbon.ReadTimeout=5000
#连接建立的超时时长,默认1秒
ribbon.ConnectTimeout=5000
#ribbon.MaxAutoRetries=1 //同一台实例的最大重试次数,但是不包括首次调用,默认为1次
#ribbon.MaxAutoRetriesNextServer=0 //重试负载均衡其他实例的最大重试次数,不包括首次调用,默认为0次
#ribbon.OkToRetryOnAllOperations=false //是否对所有操作都重试,默认false
## Feign的可配置部分
#feign.hystrix.enabled=false //Feign是否启用断路器,默认为false
#feign.client.config.default.connectTimeout=10000 //Feign的连接建立超时时间,默认为10秒
#feign.client.config.default.readTimeout=60000 //Feign的请求处理超时时间,默认为60
#feign.client.config.default.retryer=feign.Retryer.Default //Feign使用默认的超时配置,在该类源码中可见,默认单次请求最大时长1秒,重试5次
logging.level.com.wangbiao.springcloud.config.FeignConfig=debug

 

使用OpenFegin开启用层服务调用

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

 

Controller和普通的没什么区别

@RestController
@RequestMapping("/payment")
@Slf4j
public class PaymentController {

    @Value("${server.port}")
    private String port;
    @Resource
    PaymentFeginService paymentFeginService;

    @GetMapping("/selectOne/{id}")
    public CommonResult selectOne(@PathVariable(name = "id") Integer id) {
        CommonResult payment = this.paymentFeginService.selectOne(id);
        if (payment != null) {
            System.out.println("111111111111");
            return new CommonResult(200, "找到了port:" + port, payment);
        }

        return new CommonResult(404, "找不到port:" + port, null);
    }

    //Hystrim >test
    @GetMapping("/timeOut/{id}")
    @HystrixCommand(fallbackMethod = "payTimeOut", commandProperties = {@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1500")})
    public String paymentTimeOut(@PathVariable("id") Integer id) {
        return paymentFeginService.paymentTimeOut(id);

    }

    public String payTimeOut(Integer id) {
        log.info("客户端调用超时打印:{}", id);
        return "客户端超时:" + Thread.currentThread().getName() + ":超时了:" + id;
    }

    @GetMapping("/timeOut")
    public CommonResult timeOut() {
        CommonResult payment = this.paymentFeginService.timeOut();
        return new CommonResult(404, "找不到port:" + port, payment);
    }

}

 服务调用层:这里要关注下

@FeignClient(value = "cloud-payment-server") 这里面是备用方的服务名称,我们采用的就是微服务
@Component
@FeignClient(value = "cloud-payment-server")
public interface PaymentFeginService {
    @GetMapping("/payment/selectOne/{id}")
     CommonResult selectOne(@PathVariable(name = "id") Integer id);

    @GetMapping("/payment/timeOut")
     CommonResult timeOut();

    @GetMapping("/payment/timeOut/{id}")
    String paymentTimeOut(@PathVariable("id") Integer id);
}

 被调用方,也及时上面的那个cloud-payment-server

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

    @Bean
    public ServletRegistrationBean getServlet() {
        HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
        registrationBean.setLoadOnStartup(1);
        registrationBean.addUrlMappings("/hystrix.stream");
        registrationBean.setName("HystrixMetricsStreamServlet");
        return registrationBean;
    }
}

 Controller:

@RestController
@RequestMapping("/payment")
@Slf4j
public class PaymentController {
    @Resource
    private PaymentService paymentService;

    @Value("${server.port}")
    private String port;

    @GetMapping("/getHystrix/{id}")
    public String payment_ok(@PathVariable("id") Integer id) {
        String result = paymentService.paymentOk(id);
        log.info(">>>>>>>>>>>>{}", result);

        return result;
    }

    @GetMapping("/timeOut/{id}")
    public String paymentTimeOut(@PathVariable("id") Integer id) {
        String result = paymentService.paymentTimeOut(id);
        log.info("<<<<<<<<{}", result);
        return result;

    }
    @GetMapping("/selectOne/{id}")
    public CommonResult selectOne(@PathVariable(name = "id") Integer id){
        return  new CommonResult(100,"测试dashboard");
    }
    //服务熔断
    @HystrixCommand(fallbackMethod ="paymentCircuitBreakFallback",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")//失败率达到多少后跳闸
    })
    @GetMapping("/circuit/{id}")
    public String paymentCircuitBreaker(@PathVariable("id")Integer id){
        if(id<0){
            throw new RuntimeException("******id不能为负数");
        }
        String sss= UUID.randomUUID().toString();
        return Thread.currentThread().getName()+"调用成功:"+sss;
    }

    @GetMapping("/timeOut")
    public CommonResult timeOut(){
        return  new CommonResult(100,"timeOut");
    }

    /**
     * 熔断  服务不可用时,返回给调用放的信息
     * @param id
     * @return
     */
    public String paymentCircuitBreakFallback(@PathVariable("id")Integer id){
        return "ID不能是负数,请稍后再试,呜呜呜"+id;
    }
    
    
    
    @GetMapping("/payment/lb")
    public String lb() {
        return  port;
    }
}

 Service:

@Slf4j
@Service
public class PaymentService {
    public String paymentOk(Integer id) {
        return "线程池:" + Thread.currentThread().getName() + ":id:" + id;
    }

    @HystrixCommand(fallbackMethod = "payTimeOutHandler", commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")})//设置3s超时后触发payTimeOutHandler给调用方
    public String paymentTimeOut(Integer id) {
        int num = 6000;
        try {
            Thread.sleep(num);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "线程池:" + Thread.currentThread().getName() + ":id:" + id;
    }

    //服务端降级
    public String payTimeOut(Integer id) {
        return "线程池:" + Thread.currentThread().getName() + ":超时了:" + id;
    }
    //服务端降级

    public String payTimeOutHandler(Integer id) {
        int a = 10 / 0;
        return "线程池:" + Thread.currentThread().getName() + ":报错" + id;
    }
}

 配置文件:

server.port=8001
#向注册中心注册自己
spring.application.name=cloud-payment-server
eureka.client.register-with-eureka=true
#自己就是注册中心,并不需要检索服务,单节点无所谓,集群必须设置true,才能使用ribbon负载均衡
eureka.client.fetch-registry=true
#注入eureka使用的唯一服务名字(unid)
eureka.instance.instance-id=hystrim8001
#显示IP地址
eureka.instance.prefer-ip-address=true
#默认实例每30秒发送一次心跳
#eureka.instance.lease-renewal-interval-in-seconds=1
#注册中心,默认90s内加收到心跳认为服务正常。大于90s认为超时
#eureka.instance.lease-expiration-duration-in-seconds=2
#单机版
#eureka.client.service-url.defaultZone=http://eureka7001:7001/eureka
#集群模板             #这里修改了C:\Windows\System32\drivers\etc\hosts 人为添加了域名 eureka7002
eureka.client.service-url.defaultZone=http://eureka7001:7001/eureka,http://eureka7002:7002/eureka
#熔断连接时间
#hystrix.config.stream.maxConcurrentConnections=500

#hystrix.dashboard.proxyStreamAllowList=http://localhost:8001
management.endpoints.web.exposure.include=*

 

标签:String,Hystrix,payment,eureka,port,熔断,使用,id,public
From: https://www.cnblogs.com/wangbiaohistory/p/18654040

相关文章

  • 使用生成式人工智能进行软件测试1使用大型语言模型增强测试
    1使用大型语言模型增强测试1.1认识人工智能工具对测试和开发的影响在过去,想要利用人工智能的个人必须具备开发、训练和部署人工智能模型的技能,或者有一个专家团队来完成这些任务,所有这些都会使在日常活动中使用人工智能成为一项昂贵而独特的工作。随着最近人工智能的进步,以及......
  • FineReport 函数使用
    1、函数概念1.1函数作用为何使用计算?通过计算,可以根据数据源中已存在的数据创建新数据,并对数据执行计算,从而进行更复杂的分析。这不仅增强了数据分析的能力,还提升了报表的灵活性和可视化效果。增强数据分析能力:基于已有数据生成新数据点,支持复杂分析。提升报表灵活性......
  • 使用 Perl 实现英文数字验证码识别
    我们将通过结合TesseractOCR和ImageMagick工具来实现图像处理和文本识别。安装依赖确保已安装以下工具和模块:TesseractOCR:用于文本识别。ImageMagick:用于图像处理。Perl模块:Image::Magick和Tesseract::OCR。在命令行中执行以下命令:bash安装TesseractOCRsudo......
  • [20250103]使用递归实现distinct功能.txt
    [20250103]使用递归实现distinct功能.txt--//生产系统遇到实际上许多条类似语句,顺便拿其中几个出来,真心不知道开发如何学计算机的。1.问题提出:SYS@127.0.0.1:9106/xtdb/xtdb2>@sql_idc29undaquszs6--SQL_ID=c29undaquszs6comefromsharedpoolselectdistinctritemfrom......
  • 6.6 Error recovery with a custom lexer 使用自定义词法分析器进行错误恢复
    https://lalrpop.github.io/lalrpop/lexer_tutorial/006_error_recovery_custom_lexer.htmlFeaturesdescribedinErrorrecoveryworkwellwiththecustomlexer,howevererrorrecoveryonlysupportsrecoveringfromparsererrors-notlexererrors.Thispagesh......
  • samba服务 使用
    SAMBA服务访问安装http://www.samba.org/#模拟window共享[root@vm~]#yum-yinstallsamba[root@vm~]#systemctlstartsmb[root@vm~]#ss-antlp|grepsmbLISTEN050*:445*:*users:(("smbd",pid=20155,fd=36))LISTEN0......
  • 程序猿,你真的会使用Typora吗?
    目录1.聊聊我和Typora的故事1.1初识typora1.2初识typora+图床1.3爱不释手2.typora进阶使用2.1你的Typora界面2.2高手的Typora界面2.3感慨3.Typora到底是什么3.1偏好设置3.2开启调试模式3.3检查元素3.4配置文件修改1.聊聊我和Typora的故事1.1初识typora我是......
  • Jekins使用手册
    在构建历史中显示构建者和分支名在构建后执行Groovy脚本来实现,参考:Jenkins在历史中展示构建者和分支名添加GroovyPostbuild:manager.addShortText(manager.getEnvVariable("BUILD_USER"))manager.addShortText(manager.build.buildVariables.get("branch"))还可以自定构建......
  • 9.类的定义与使用
    类的定义构造函数(__init__)实例变量类变量方法(实例方法)类方法(@classmethod)静态方法(@staticmethod)属性装饰器(@property)私有属性与方法继承多态方法重写super()函数类的文档字符串类的属性和方法访问控制1.类的定义:如int,list,tuple等等都是类,还可以通过class方......
  • uniapp - 详解使用高德地图在地图上实现绘制边界/点聚合/行政区域高亮等功能,Uniapp高
    效果图在uni-app手机h5网页网站/支付宝微信小程序/安卓app/苹果app/nvue等(全平台兼容)开发中,实现各端都兼容的“安装使用高德地图并实现点聚合/地图绘制边界部分高亮显示”,高德地图点聚合标记及高德地图绘制行政边界等,标点窗体信息展示,在高德地图上标点及卡片气泡框面板......