项目测试代码地址: https://github.com/liangxifeng833/springcloud/tree/master/parent
parent 父模块 pom.xml
加入依赖
<!-- Hystrix断路器 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-boot-starter-netflix-hystrix</artifactId>
</dependency>
api-order-service-impl 项目开启Hystric断路器
- 因为是订单服务调用会员服务,所以修改
application.yml
:### 开启Hystrix断路器 feign: hystrix: enabled: true
- 修改服务启动文件
MemberApplication.java
新增开启服务保护功能注解@EnableHystrix
:package order.service; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.cloud.netflix.hystrix.EnableHystrix; import org.springframework.cloud.openfeign.EnableFeignClients; @SpringBootApplication //@EnableEurekaClient 将当前服务注册到Eureka @EnableEurekaClient //使用feign客户端调用远程http服务 @EnableFeignClients //开启服务保护功能 @EnableHystrix public class OrderApplication extends SpringBootServletInitializer { public static void main(String[] args) { SpringApplication.run(OrderApplication.class, args); } @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(OrderApplication.class); } }
- 在
OrderServiceImpl.java
中添加具有Hystric断路器
功能的对外方法
;import api.common.base.BaseApiService; import api.common.base.ResponseBase; import api.member.entity.User; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; import order.service.IOrderService; import order.service.feign.MemberServiceFeign; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * 订单服务controller 实现order-service项目中的接口 */ @RestController public class OrderServiceImpl extends BaseApiService implements IOrderService { @Autowired private MemberServiceFeign memberServiceFeign; @RequestMapping("/orderToMember") @Override public String orderToMember(String name) { User user = memberServiceFeign.getMember(name); return user==null ? "找不到用户信息" : user.toString(); } //没有解决服务雪崩效应 @RequestMapping("/orderToMemberUserInfo") @Override public ResponseBase orderToMemberUserInfo() { return memberServiceFeign.getUserInfo(); } /** * 解决服务雪崩效应 * @HystrixCommand 默认开启服务隔离(使用线程隔离方式): * 比如:以下orderToMemberUserInfoHystrix()方法被线程池hystrix-OrderServiceImpl处理 * 以下orderInfo()方法被线程池hystrix-OrderServiceImpl处理 * 默认开启服务降级执行,本例执行方法是:"orderToMemberUserInfoHystrixFallback" * 默认开启服务熔断机制 * fallbackMethod()方法的作用是:服务降级执行 * @return */ @HystrixCommand(fallbackMethod = "orderToMemberUserInfoHystrixFallback") @RequestMapping("/orderToMemberUserInfoHystrix") public ResponseBase orderToMemberUserInfoHystrix() { //输出:orderToMemberUserInfoHystrix-线程池名称:hystrix-OrderServiceImpl-1 System.out.println("orderToMemberUserInfoHystrix-线程池名称:"+Thread.currentThread().getName()); return memberServiceFeign.getUserInfo(); } public ResponseBase orderToMemberUserInfoHystrixFallback() { return setResultSuccess("返回一个友好的提示:服务降级,服务器忙,请稍后重试!"); } //订单服务接口 @RequestMapping("/orderInfo") @Override public ResponseBase orderInfo() { //输出:orderInfo-线程池名称:http-nio-8103-exec-7 System.out.println("orderInfo-线程池名称:"+Thread.currentThread().getName()); return setResultSuccess(); } }
- 访问带熔断的接口: http://127.0.0.1:8103/orderToMemberUserInfoHystrix,注意:该接口有
1.5秒
的延时, 因为hystrix默认超时时间=1秒
,所以这里超时了, 返回结果是fallback函数的友好提示: (熔断起作用了
){"rtnCode":200,"msg":"处理成功","data":"返回一个友好的提示:服务降级,服务器忙,请稍后重试!"}
- 此时如果关闭
hystrix
的超时设置, 修改application.yml
, 这里只是为了测试禁用掉超时时间,正常情况下我们把超时时间设置为5~10
秒即可.hystrix.command.default.execution.timeout.enabled=false
- 再次访问带服务熔断的接口http://127.0.0.1:8103/orderToMemberUserInfoHystrix,会正常返回服务内容: (因为hystrix超时时间已经关闭了), 返回结果:
{"rtnCode":200,"msg":"处理成功","data":"调用会员服务接口成功..."}
- 如果
同时2万个并发
访问带熔断的接口: http://127.0.0.1:8103/orderToMemberUserInfoHystrix, 该接口只处理10个
请求,便终止提示友好信息; 因为Hystrix默认熔断阈值=10
,超过该值便终止请求.但是此时其他http://127.0.0.1:8103/orderInfo
接口依然可以正常
访问,因为他们不在同一个线程池
中.
使用类的方式实现fallback
服务降级
- 在
api-order-service-impl
项目中的order.server
目录下新增fallback
包,且新增服务降级类MemberServiceFallback
package order.service.fallback;
import api.common.base.BaseApiService;
import api.common.base.ResponseBase;
import api.member.entity.User;
import order.service.feign.MemberServiceFeign;
import org.springframework.stereotype.Component;
/**
* 服务降级类
* 订单order服务访问会员member服务的时候
* 如果服务超时或者服务雪崩效应出现,会自动实现服务降级
*/
@Component
public class MemberServiceFallback extends BaseApiService implements MemberServiceFeign {
@Override
public User getMember(String name) {
return null;
}
//服务降级的友好提示
@Override
public ResponseBase getUserInfo() {
return setResultError("服务器忙,请稍后重试!--以类的方式写的服务降级");
}
}
- 在
api-order-service-impl
项目中修改MemberServiceFeign
, 在@FeignClient
注解中新增fallback=MemberServiceFallback.class
指定服务降级类,目的是在订单服务访问会员服务的还是,如果出现超时或者雪崩时,会返回MemberServiceFallback
服务降级类中对应方法的友好提示结果
package order.service.feign;
import api.member.service.IMemberServcie;
import order.service.fallback.MemberServiceFallback;
import org.springframework.cloud.openfeign.FeignClient;
/**
* 使用feign客户端调用远程会员服务接口
* 该接口继承会员服务api-member-service中的IMemberService接口
* 就不需要重复写接口了
* fallback目的是指定服务降级类
*/
@FeignClient(value = "app-member",fallback = MemberServiceFallback.class)
public interface MemberServiceFeign extends IMemberServcie {
}
- 在
api-order-service-impl
项目中修改订单访问会员实现类OrderServiceImpl
,新增orderToMemberUserInfoHystrixDemo02
方法(Hystrix第二种写法,使用类方式实现服务降级):
/**
* Hystrix第二种写法,使用类方式实现服务降级
* @return
*/
@RequestMapping("/orderToMemberUserInfoHystrix_demo02")
public ResponseBase orderToMemberUserInfoHystrixDemo02() {
//输出:orderToMemberUserInfoHystrix-线程池名称:hystrix-OrderServiceImpl-1
System.out.println("orderToMemberUserInfoHystrix-线程池名称:"+Thread.currentThread().getName());
return memberServiceFeign.getUserInfo(); //getUserInfo()有1.5秒的延时
}
- 此时修改
application.yml
文件,开启hystrix
超时时间,默认1秒, 注释掉.
### 禁用hystrix超时时间,默认1秒
#hystrix:
# command:
# default:
# execution:
# timeout:
# enabled: true
- 访问:http://127.0.0.1:8103/orderToMemberUserInfoHystrix_demo02,因为请求中
getUserInfo()有1.5秒的延时
超过了hystrix超时时间1秒
, 返回结果就是服务降级类中getUserInfo()
返回的友好提示语:
image.png
网友评论