1.描述
1.1Hystrix如何解决服务器雪崩效应的?
服务降级、服务隔离、服务熔断。
服务降级:
在高并发情况下,防止客户端一直等待,使用服务器降级方式(返回一个友好的提示,不会去处理请求,调用fallback本地方法) 目的:提高用户体验
应用场景:
秒杀------当前请求认识过多,请稍后重试。
(查看tomcat7配置文件,发现最大的线程数是150,如果没有线程来处理客户端请求的时候,不应该让用户一直转圈等待)
服务熔断:
服务熔断目的就为了保护服务,在高并发的情况下,如果请求达到了一定的极限,如果服务超出规定的上线后,会自动开启保护服务功能,使用服务降级方式返回一个友好的提示。服务熔断机制和服务降级是配套使用的。
服务隔离:
线程池和信号量隔离
采用服务隔离机制 线程池隔离:每个服务接口都有自己独立的线程池,每个线程池互不影响,缺点:CPU占用率非常高(只有核心的接口才采用线程池隔离)。
2.Hystrix使用
2.1 pom.xml
<!--hystri 熔断器aa-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
2.2 application.yml
##设置feign超时时间
ribbon:
##指的是创建连接所用的时间,适用于网络状况正常的情况下,两端所用的时间,默认是1s
ReadTimeout: 3000
##指的是创建连接后从服务器读取可用资源所用的时间
ConnectTimeout: 3000
##开启Hystrix断路器
feign:
hystrix:
enabled: true
##禁止hystrix超时时间,默认是1秒,不加这个访问一定会进失败方法,增加后就可以调用成功
hystrix:
command:
default:
execution:
timeout:
enabled: false
2.3 controller类
package com.fqyd.api.service.impl;
import com.fqyd.api.entity.User;
import com.fqyd.api.feign.MemberServiceFeign;
import com.fqyd.api.service.IOrderService;
import com.fqyd.util.BaseDataResult;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* Description:
* Author: wude
* Date: 2019/7/25 17:39
* Modified By:
*/
@RestController
public class OrderServiceImpl implements IOrderService {
@Autowired
private MemberServiceFeign memberServiceFeign;
@RequestMapping("getOrder")
@Override
public String orderToMember(String name) {
User user = memberServiceFeign.getMember(name);
if(user == null){
return "没有找到信息";
}
return user.toString();
}
@RequestMapping("/orderToMemberUserInfo")
@Override
public BaseDataResult orderToMemberUserInfo() {
System.out.println("没有做隔离:线程名称:"+Thread.currentThread().getName());
return memberServiceFeign.getUserInfo();
}
@HystrixCommand(fallbackMethod ="orderToMemberUserInfoHystrixFallback")
@RequestMapping("/orderToMemberUserInfoHystrix")
public BaseDataResult orderToMemberUserInfoHystrix() {
System.out.println("测试线程隔离:线程名称:"+Thread.currentThread().getName());
return memberServiceFeign.getUserInfo();
}
@RequestMapping("/orderToMemberUserInfoHystrix2")
public BaseDataResult orderToMemberUserInfoHystrix2() {
System.out.println("测试线程隔离:线程名称2:"+Thread.currentThread().getName());
return memberServiceFeign.getUserInfo();
}
public BaseDataResult orderToMemberUserInfoHystrixFallback() {
return new BaseDataResult(1,"服务器正忙,请稍后重试!","");
}
}
2.4 启动类
package com.fqyd;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* Description:
* Author: wude
* Date: 2019/7/25 16:49
* Modified By:
*/
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
@EnableHystrix //开启熔断器
public class OrderServiceImplApplication {
public static void main(String[] args) {
SpringApplication.run(OrderServiceImplApplication.class,args);
}
}
2.5 fallback统一接口
package com.fqyd.api.fallback;
import com.fqyd.api.entity.User;
import com.fqyd.api.feign.MemberServiceFeign;
import com.fqyd.util.BaseDataResult;
import org.springframework.stereotype.Component;
/**
* Description:
* Author: wude
* Date: 2019/10/16 10:10
* Modified By:
*/
@Component
public class MemberServiceFeignFallback extends BaseDataResult implements MemberServiceFeign {
@Override
public User getMember(String name) {
return null;
}
@Override
public BaseDataResult getUserInfo() {
return new BaseDataResult(1,"服务器正忙!","");
}
}
2.6 MemberServiceFeign
package com.fqyd.api.feign;
import com.fqyd.api.entity.User;
import com.fqyd.api.fallback.MemberServiceFeignFallback;
import com.fqyd.api.service.IMemberService;
import org.springframework.cloud.openfeign.FeignClient;
/**
* Description:
* Author: wude
* Date: 2019/8/1 10:35
* Modified By:
*/
@FeignClient(value = "fqyd-member",fallback = MemberServiceFeignFallback.class)
public interface MemberServiceFeign extends IMemberService {
}
3.测试和分析
通过现场名称可以看出,是做了隔离的,tomcat的线程一般都是http-nip-XXX格式。
服务的熔断和降级,通过jmeter工具循环2w次,发现,控制台只打印了4次
fallback有两种方式,第一种是在需要设置的方法以上增加
@HystrixCommand(fallbackMethod ="orderToMemberUserInfoHystrixFallback")
第二种是类方式实现:增加一个类MemberServiceFeignFallback,MemberServiceFeign增加fallback参数。
两种方式有什么区别?
增加了hystrix的注解,该线程就不是nio-8080 tomcat的对应线程勒,而是隔离的一个线程。采用第一种方式,整个方法是一个线程,而第二种,标识1和标识2是独立的两个线程,一般都是采用第二种方式实现。
如果你热衷技术,喜欢交流,欢迎加入我们!