欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Hystix熔断解决雪崩问题

程序员文章站 2022-04-28 14:17:34
1.线程隔离,服务降级(服务的消费方做降级处理) 当服务繁忙时,如果服务出现异常,不是粗暴的直接报错,而是返回一个友好的提示,虽然拒绝了用户的访问,但是会返回一个结果。 这就好比去买鱼,平常超市买鱼会额外赠送杀鱼的服务。等到逢年过节,超时繁忙时,可能就不提供杀鱼服务了,这就是服务的降级。 系统特别繁 ......

1.线程隔离,服务降级(服务的消费方做降级处理)

当服务繁忙时,如果服务出现异常,不是粗暴的直接报错,而是返回一个友好的提示,虽然拒绝了用户的访问,但是会返回一个结果。

这就好比去买鱼,平常超市买鱼会额外赠送杀鱼的服务。等到逢年过节,超时繁忙时,可能就不提供杀鱼服务了,这就是服务的降级。

系统特别繁忙时,一些次要服务暂时中断,优先保证主要服务的畅通,一切资源优先让给主要服务来使用,在双十一、618时,京东天猫都会采用这样的策略。

pom.xml

<dependency>
    <groupid>org.springframework.cloud</groupid>
    <artifactid>spring-cloud-starter-netflix-hystrix</artifactid>
</dependency>

userconsumerapplication.java


package cn.itcast.user;

import org.springframework.boot.springapplication;
import org.springframework.boot.autoconfigure.springbootapplication;
import org.springframework.cloud.client.springcloudapplication;
import org.springframework.cloud.client.circuitbreaker.enablecircuitbreaker;
import org.springframework.cloud.client.discovery.enablediscoveryclient;
import org.springframework.cloud.client.loadbalancer.loadbalanced;
import org.springframework.context.annotation.bean;
import org.springframework.http.client.okhttp3clienthttprequestfactory;
import org.springframework.web.client.resttemplate;

//@enablediscoveryclient
//@springbootapplication
//@enablecircuitbreaker //服务的熔断
@springcloudapplication //springcloudapplication可以替代上面三个
public class userconsumerdemoapplication {

@bean
@loadbalanced //负载均衡
public resttemplate resttemplate() {
// 这次我们使用了okhttp客户端,只需要注入工厂即可
return new resttemplate(new okhttp3clienthttprequestfactory());
}

public static void main(string[] args) {
springapplication.run(userconsumerdemoapplication.class, args);
}
}
 

 3.userhcontroller.java

package cn.itcast.user.controller;

import cn.itcast.user.pojo.user;
import com.netflix.hystrix.contrib.javanica.annotation.hystrixcommand;
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;
import org.springframework.web.client.resttemplate;

@restcontroller
@requestmapping("consumerh")
public class userhcontroller {
    @autowired
    private resttemplate resttemplate;

    @getmapping("{id}")
    @hystrixcommand(fallbackmethod = "queryuserbyidfallback")   //单个方法的超时返回
    public string queryuserbyid(@pathvariable("id") long id){
        string url = "http://user-service/user/" + id;
        //user user = resttemplate.getforobject(url, user.class);
        //return  user;
        string user = resttemplate.getforobject(url, string.class);
        return user;
    }

    public string queryuserbyidfallback(@pathvariable("id") long id){
        return "用户信息查询出现异常!";
//        user user = new user();
//        user.setid(id);
//        user.setnickname("用户信息查询出现异常!");
//        return user;
    }
}

==========================
配置统一超时信息
package cn.itcast.user.controller;

import cn.itcast.user.pojo.user;
import com.netflix.hystrix.contrib.javanica.annotation.defaultproperties;
import com.netflix.hystrix.contrib.javanica.annotation.hystrixcommand;
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;
import org.springframework.web.client.resttemplate;

@restcontroller
@requestmapping("consumerh")
@defaultproperties(defaultfallback = "queryuserbyidfallback")
public class userhcontroller {
@autowired
private resttemplate resttemplate;

@getmapping("{id}")
//@hystrixcommand(fallbackmethod = "queryuserbyidfallback")
@hystrixcommand
public string queryuserbyid(@pathvariable("id") long id){
string url = "http://user-service/user/" + id;
//user user = resttemplate.getforobject(url, user.class);
//return user;
string user = resttemplate.getforobject(url, string.class);
return user;
}

//public string queryuserbyidfallback(@pathvariable("id") long id){
//return "用户信息查询出现异常!";
// user user = new user();
// user.setid(id);
// user.setnickname("用户信息查询出现异常!");
// return user;
//}

public string queryuserbyidfallback(){
return "用户信息查询出现异常!";
}
}

=============================================================

package cn.itcast.user.controller;

import cn.itcast.user.pojo.user;
import com.netflix.hystrix.contrib.javanica.annotation.defaultproperties;
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.getmapping;
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("consumerh")
@defaultproperties(defaultfallback = "queryuserbyidfallback")
public class userhcontroller {
@autowired
private resttemplate resttemplate;

@getmapping("{id}")
@hystrixcommand(commandproperties = {
@hystrixproperty(name = "execution.isolation.thread.timeoutinmilliseconds",value = "3000"), //响应超时时间
@hystrixproperty(name = "circuitbreaker.requestvolumethreshold",value = "10"),
@hystrixproperty(name = "circuitbreaker.sleepwindowinmilliseconds",value = "10000"),
@hystrixproperty(name = "circuitbreaker.errorthresholdpercentage",value = "60")
})
public string queryuserbyid(@pathvariable("id") long id){
if(id % 2 ==0){
throw new runtimeexception("");
}
string url = "http://user-service/user/" + id;
string user = resttemplate.getforobject(url, string.class);
return user;
}

public string queryuserbyidfallback(){
return "用户信息查询出现异常!";
}
}