尚學(xué)堂108天總結(jié)+Hystrix

1. 什么是服務(wù)災(zāi)難性雪崩效應(yīng)

image

造成雪崩原因是什么?

image

2. 如何解決災(zāi)難性雪崩效應(yīng)

image

什么是請(qǐng)求緩存?

image

解決災(zāi)難性雪崩效應(yīng)-請(qǐng)求緩存-請(qǐng)求緩存處理

  1. @CacheConfig注解的作用是什么?
image
  1. @CacheEvict注解的作用是什么?
image

解決災(zāi)難性雪崩效應(yīng)-請(qǐng)求合并-創(chuàng)建項(xiàng)目

  1. 什么是請(qǐng)求合并?
image
  1. 請(qǐng)求合并有哪些缺點(diǎn)?
image
  1. 解決災(zāi)難性雪崩效應(yīng)-請(qǐng)求合并-請(qǐng)求合并處理
image
  1. 解決災(zāi)難性雪崩效應(yīng)-服務(wù)熔斷-服務(wù)熔斷處理

    1. 什么是服務(wù)熔斷?
image
image
  1. 解決災(zāi)難性雪崩效應(yīng)-隔離機(jī)制-線程池隔離-創(chuàng)建項(xiàng)目

  2. 什么是線程池隔離?

image
  1. 線程池隔離的優(yōu)點(diǎn)是什么?
image
  1. 解決災(zāi)難性雪崩效應(yīng)-隔離機(jī)制-線程池隔離-線程池隔離處理
image

代碼示例

請(qǐng)求緩存

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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.bjsxt</groupId>
    <artifactId>springcloud-eureka-consumer-ribbon-cache</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>springcloud-eureka-consumer</name>
    <description>Demo project for Spring Boot</description>

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

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Dalston.SR5</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
        </dependency>
        <!-- springCache -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

application.properties

spring.application.name=eureka-consumer-ribbon-cache
server.port=9010

#設(shè)置服務(wù)注冊(cè)中心地址,指向另一個(gè)注冊(cè)中心
eureka.client.serviceUrl.defaultZone=http://user:123456@eureka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/
# Redis
spring.redis.database=0
#Redis服務(wù)器地址
spring.redis.host=192.168.2.129
#Redis服務(wù)器連接端口
spring.redis.port=6379
#Redis服務(wù)器連接密碼(默認(rèn)為空)
spring.redis.password=
#連接池最大連接數(shù)(負(fù)值表示沒(méi)有限制)
spring.redis.pool.max-active=100
#連接池最大阻塞等待時(shí)間(負(fù)值表示沒(méi)有限制)
spring.redis.pool.max-wait=3000
#連接池最大空閉連接數(shù)
spring.redis.pool.max-idle=200
#連接漢最小空閑連接數(shù)
spring.redis.pool.min-idle=50
#連接超時(shí)時(shí)間(毫秒)
spring.redis.pool.timeout=600

ProductService

@CacheConfig(cacheNames={"com.bjsxt.ego.product"})
@Service
public class ProductService {

    @Autowired
    private LoadBalancerClient loadBalancerClient;// ribbon負(fù)載均衡器

    @HystrixCommand(fallbackMethod="fallback")
    public List<Product> getUsers() {
        // 選擇調(diào)用的服務(wù)的名稱
        // ServiceInstance 封裝了服務(wù)的基本信息,如 IP,端口
        ServiceInstance si = this.loadBalancerClient.choose("ego-product-provider");
        // 拼接訪問(wèn)服務(wù)的URL
        StringBuffer sb = new StringBuffer();
        // http://localhost:9001/product/findAll
        sb.append("http://").append(si.getHost()).append(":").append(si.getPort()).append("/product/findAll");
        System.out.println(sb.toString());
        // springMVC RestTemplate
        RestTemplate rt = new RestTemplate();

        ParameterizedTypeReference<List<Product>> type = new ParameterizedTypeReference<List<Product>>() {
        };

        // ResponseEntity:封裝了返回值信息
        ResponseEntity<List<Product>> response = rt.exchange(sb.toString(), HttpMethod.GET, null, type);
        List<Product> list = response.getBody();
        return list;
    }
    
    //返回托底數(shù)據(jù)的方法
    public List<Product> fallback(){
        List<Product> list = new ArrayList<>();
        list.add(new Product(-1, "我是托底數(shù)據(jù)"));
        return list;
    }
    
    //根據(jù)ID查詢商品
    @Cacheable(key="'product' + #id")
    public Product getProductById(Integer id){
        System.out.println("=========Get======"+id);
        return new Product(id, "新的商品");
    }
    
    //根據(jù)ID刪除商品
    @CacheEvict(key="'product' + #id")
    public void delProductById(Integer id){
        System.out.println("=========Del======"+id);
    }
}

ProductController

@RestController
public class ProductController {

    @Autowired
    private ProductService userService;

    @RequestMapping("/consumer")
    public List<Product> getUsers() {
        return this.userService.getUsers();
    }
    
    @RequestMapping(value="/get",method=RequestMethod.GET)
    public Product get(Integer id){
        return this.userService.getProductById(id);
    }
    
    @RequestMapping(value="/del",method=RequestMethod.GET)
    public void del(Integer id){
        this.userService.delProductById(id);
    }

}

請(qǐng)求合并

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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.bjsxt</groupId>
    <artifactId>springcloud-eureka-consumer-ribbon-batch</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>springcloud-eureka-consumer</name>
    <description>Demo project for Spring Boot</description>

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

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Dalston.SR5</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

application.properties

spring.application.name=eureka-consumer-ribbon-batch
server.port=9010
#設(shè)置服務(wù)注冊(cè)中心地址,指向另一個(gè)注冊(cè)中心
eureka.client.serviceUrl.defaultZone=http://user:123456@eureka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/

ProductControlle

@RestController
public class ProductController {

    @Autowired
    private ProductService userService;
    
    @RequestMapping("/consumer")
    public  void  getUsers() throws Exception{
        Future<Product> p1 = this.userService.getProduct(1);
        Future<Product> p2 = this.userService.getProduct(2);
        Future<Product> p3 = this.userService.getProduct(3);
        System.out.println(p1.get().toString());
        System.out.println(p2.get().toString());
        System.out.println(p3.get().toString());
    }
}

ProductService

@Service
public class ProductService {

    //利用hystrix合并請(qǐng)求  
    @HystrixCollapser(batchMethod = "batchProduct", scope = com.netflix.hystrix.HystrixCollapser.Scope.GLOBAL,  
            collapserProperties = {  
            //請(qǐng)求時(shí)間間隔在20ms之內(nèi)的請(qǐng)求會(huì)被合并為一個(gè)請(qǐng)求,默認(rèn)為10ms
            @HystrixProperty(name = "timerDelayInMilliseconds", value = "20"),
            //設(shè)置觸發(fā)批處理執(zhí)行之前,在批處理中允許的最大請(qǐng)求數(shù)。
            @HystrixProperty(name = "maxRequestsInBatch", value = "200"),  
    })  
    //consumer的controller調(diào)用的方法 該方法返回值必須要返回Future類型
    public Future<Product> getProduct(Integer id){
        System.out.println("=========="+id+"==========");
        return null;
    }
    
    @HystrixCommand
    //調(diào)用Provider服務(wù)的方法
    public List<Product> batchProduct(List<Integer> ids){
        for(Integer id:ids){
            System.out.println(id);
        }
        //假設(shè)是調(diào)用provider服務(wù)后返回的list
        List<Product> list = new ArrayList<>();
         list.add(new Product(1, "電視"));
         list.add(new Product(2, "電腦"));
         list.add(new Product(3, "冰箱"));
         list.add(new Product(4, "手電筒"));
         list.add(new Product(100,"list............"));
         System.out.println("ddddddddddddddddddddddd");
         return list;
    }
}

服務(wù)熔斷

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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.bjsxt</groupId>
    <artifactId>springcloud-eureka-consumer-ribbon-breaker</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>springcloud-eureka-consumer</name>
    <description>Demo project for Spring Boot</description>

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

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Dalston.SR5</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

application.properties

spring.application.name=eureka-consumer-ribbon-breaker
server.port=9010

#設(shè)置服務(wù)注冊(cè)中心地址,指向另一個(gè)注冊(cè)中心
eureka.client.serviceUrl.defaultZone=http://user:123456@eureka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/

ProductController

@RestController
public class ProductController {
    @Autowired
    private ProductService userService;
    
    @RequestMapping("/consumer")
    public List<Product> getUsers(@RequestParam("flag") Integer flag){
        return this.userService.getUsers(flag);
    }
}

ProductService

@Service
public class ProductService {

    @Autowired
    private LoadBalancerClient loadBalancerClient;// ribbon負(fù)載均衡器

    @HystrixCommand(fallbackMethod = "fallback",
            commandProperties = {
              //默認(rèn)20個(gè);10s內(nèi)請(qǐng)求數(shù)大于20個(gè)時(shí)就啟動(dòng)熔斷器,當(dāng)請(qǐng)求符合熔斷條件時(shí)將觸發(fā)getFallback()。
              @HystrixProperty(name=HystrixPropertiesManager.CIRCUIT_BREAKER_REQUEST_VOLUME_THRESHOLD, 

value="10"),
              //請(qǐng)求錯(cuò)誤率大于50%時(shí)就熔斷,然后for循環(huán)發(fā)起請(qǐng)求,當(dāng)請(qǐng)求符合熔斷條件時(shí)將觸發(fā)getFallback()。
              @HystrixProperty(name=HystrixPropertiesManager.CIRCUIT_BREAKER_ERROR_THRESHOLD_PERCENTAGE, 

value="50"),
              //默認(rèn)5秒;熔斷多少秒后去嘗試請(qǐng)求
              @HystrixProperty(name=HystrixPropertiesManager.CIRCUIT_BREAKER_SLEEP_WINDOW_IN_MILLISECONDS, 

value="5000"),
            })
    public List<Product> getUsers(int flag) {
        
        System.out.println(flag);
        if(flag == 1){
            throw new RuntimeException();
        }
        // 選擇調(diào)用的服務(wù)的名稱
        // ServiceInstance 封裝了服務(wù)的基本信息,如 IP,端口
        ServiceInstance si = this.loadBalancerClient.choose("ego-product-provider");
        // 拼接訪問(wèn)服務(wù)的URL
        StringBuffer sb = new StringBuffer();
        // http://localhost:9001/product/findAll
        sb.append("http://").append(si.getHost()).append(":").append(si.getPort()).append("/product/findAll");
        System.out.println(sb.toString());
        // springMVC RestTemplate
        RestTemplate rt = new RestTemplate();

        ParameterizedTypeReference<List<Product>> type = new ParameterizedTypeReference<List<Product>>() {
        };

        // ResponseEntity:封裝了返回值信息
        ResponseEntity<List<Product>> response = rt.exchange(sb.toString(), HttpMethod.GET, null, type);
        List<Product> list = response.getBody();
        return list;
    }
    //返回托底數(shù)據(jù)的方法
    public List<Product> fallback(int flag){
        List<Product> list = new ArrayList<>();
        list.add(new Product(-1, "我是托底數(shù)據(jù)"));
        return list;
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容