一、什么是服务雪崩
1.分布式系统中经常会出现某个基础服务不可用造成整个系统不可用的情况, 这种现象被称为服务雪崩效应. 为了应对服务雪崩, 一种常见的做法是手动服务降级. 而Hystrix的出现,给我们提供了另一种选择.下面这张图片讲解一下实例中雪崩效应。
二、模拟服务雪崩
1.压力测试
我使用的压力测试工具是:apache的jmeter,这是一个非常好用的给工具,我们可以通过它来达到我们的服务雪崩效应,在这块我们还要设置tomcat的最大连接数,不然我们压力测试会呈现不出来效果,下面我会把所有的工程代码贴出来,老是让你们看上篇博客,我自己看着都有点懵逼,在这个博客中我将会贴出所有的测试代码。
2.jmeter压测工具界面(在这里我模拟了1000个线程,把效果演示出来了)
三、项目代码
1.Eureka项目代码,你们还是参考我之前的博客,这个注册中心我基本上是没有修改过,博客地址:https://blog.csdn.net/chenmingxu438521/article/details/90513283
2.项目demo-service-member
2.1.pom.xml
4.0.0
org.springframework.boot
spring-boot-starter-parent
1.5.2.RELEASE
com.example
demo-service-member
0.0.1-SNAPSHOT
demo-service-member
Demo project for Spring Boot
UTF-8
UTF-8
1.8
org.springframework.cloud
spring-cloud-starter-eureka
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.springframework.cloud
spring-cloud-dependencies
Dalston.RC1
pom
import
org.springframework.boot
spring-boot-maven-plugin
spring-milestones
Spring Milestones
https://repo.spring.io/milestone
false
2.2.application.yml
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8888/eureka/
server:
port: 8763
spring:
application:
name: demo-service-member
2.3.controller
@RestController
public class MemberController {
@Value("${server.port}")
private String serverPort;
private static int count = 0;
@RequestMapping("/getMemberAll")
public List getMemberAll() {
try{
Thread.sleep(3000);
}catch (Exception e){
}
count++;
List listUser = new ArrayList();
listUser.add("zhangsan");
listUser.add("lisi");
listUser.add("cmx");
listUser.add("count"+count);
System.out.println("count:" + count);
listUser.add("serverPort:"+serverPort);
return listUser;
}
@RequestMapping("/getMemberServiceApi")
public String getMemberServiceApi(){
return "this is 会员服务工程";
}
}
2.4.启动类
@SpringBootApplication
@EnableEurekaClient
public class DemoServiceMemberApplication {
public static void main(String[] args) {
SpringApplication.run(DemoServiceMemberApplication.class, args);
}
}
3.项目demo-service-order
3.1.pom.xml
4.0.0
org.springframework.boot
spring-boot-starter-parent
1.5.2.RELEASE
com.example
demo-service-order
0.0.1-SNAPSHOT
demo-service-order
Demo project for Spring Boot
UTF-8
UTF-8
1.8
org.springframework.cloud
spring-cloud-starter-eureka
org.springframework.cloud
spring-cloud-starter-ribbon
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.springframework.cloud
spring-cloud-dependencies
Dalston.RC1
pom
import
org.springframework.boot
spring-boot-maven-plugin
spring-milestones
Spring Milestones
https://repo.spring.io/milestone
false
3.2.application.yml
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8888/eureka/
server:
port: 8764
spring:
application:
name: demo-service-order
3.3.controller
@RestController
public class OrderController {
@Autowired
private OrderMemberService orderMemberService;
@RequestMapping("/getOrderUserAll")
public List getOrderUserAll() {
System.out.println("订单服务开始调用会员服务");
return orderMemberService.getOrderUserAll();
}
@RequestMapping("/getOrderServiceApi")
public String getOrderServiceApi(){
return "this is order 服务工程";
}
}
3.4.service
@Service
public class OrderMemberService {
@Autowired
private RestTemplate restTemplate;
public List getOrderUserAll() {
return restTemplate.getForObject("http://demo-service-member/getMemberAll", List.class);
}
}
3.5.启动类
@SpringBootApplication
@EnableEurekaClient
public class DemoServiceOrderApplication {
public static void main(String[] args) {
SpringApplication.run(DemoServiceOrderApplication.class, args);
}
@Bean
//开启负载均衡
//@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
}
4.项目demo-serviceorder-fegin
4.1.pom.xml
4.0.0
org.springframework.boot
spring-boot-starter-parent
1.5.2.RELEASE
com.example
demo-serviceorder-fegin
0.0.1-SNAPSHOT
demo-serviceorder-fegin
Demo project for Spring Boot
UTF-8
UTF-8
1.8
org.springframework.cloud
spring-cloud-starter-eureka
org.springframework.cloud
spring-cloud-starter-ribbon
org.springframework.boot
spring-boot-starter-web
org.springframework.cloud
spring-cloud-starter-feign
org.springframework.boot
spring-boot-starter-test
test
org.springframework.cloud
spring-cloud-dependencies
Dalston.RC1
pom
import
org.springframework.boot
spring-boot-maven-plugin
spring-milestones
Spring Milestones
https://repo.spring.io/milestone
false
4.2.application.yml
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8888/eureka/
server:
port: 8765
tomcat:
max-threads: 50 //设置tomcat最大访问连接
spring:
application:
name: demo-serviceorder-feign
4.3.controller
@RestController
public class FeignMemberController {
@Autowired
private MemberFeign memberFeign;
@RequestMapping("/getFeignOrderByUserList")
public List getFeignOrderByUserList() {
System.out.println("order fegin 工程调用member工程");
return memberFeign.getOrderByUserList();
}
@RequestMapping("/getOrderInfo")
public String getOrderInfo(){
return "getOrderInfo";
}
}
4.4.service
@FeignClient("demo-service-member")
public interface MemberFeign {
@RequestMapping("/getMemberAll")
public List getOrderByUserList();
}
4.5.启动类
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class DemoServiceorderFeginApplication {
public static void main(String[] args) {
SpringApplication.run(DemoServiceorderFeginApplication.class, args);
}
}
5.测试产生雪崩的效果图
5.1.如下图(看红框一直在转圈,这就证明了那1000个线程压测阻塞,造成的服务雪崩的问题)
四、解决雪崩的问题
五、代码实战(使用Hystrix)
1.服务降级处理
1.1.修改demo-service-fegin项目
1.2.pom.xml(添加依赖hystrix)
org.springframework.cloud
spring-cloud-starter-hystrix
1.3.application.yml
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8888/eureka/
server:
port: 8765
tomcat:
max-threads: 50
spring:
application:
name: demo-serviceorder-feign
feign:
hystrix:
enabled: true //开启熔断
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 100000 //默认1000就会去调用fallback
1.4.fallback(项目结构)包
@Component
public class MemberFallBack implements MemberFeign {
@Override
public List getOrderByUserList() {
//服务降级处理
List list = new ArrayList();
list.add("服务发生异常...");
return list;
}
}
3.修改MemberFeign接口
@FeignClient(value = "demo-service-member",fallback = MemberFallBack.class)
public interface MemberFeign {
@RequestMapping("/getMemberAll")
public List getOrderByUserList();
}
4.效果图
六、同时也能解决了我们的雪崩效应了
1.如下图(响应很快):