目前主流的服务熔断降级方案,主要有两种:springcloud的Hystrix和Alibaba的Sentinel,目前不论是从整体热度及使用体验、功能额丰富而言,Sentinel都具有绝对的优势。
为什么需要服务的熔断呢?当前的微服务架构,拥有多个服务,相互间的调用复杂,当有一台服务出现问题,导致服务无法调用,此时流量上来后,会造成整个系统的流量堆积,最终造成整个系统的不可用。所用服务的熔断是很重要的,可以维护系统的问题及可用性。
熔断主要注意两点:启动熔断和恢复熔断。
什么是服务降级呢?当系统在某个时间段迎来了流量洪峰,整个系统的压力倍增,此时为了保证核心业务的运行,可以对某些无关紧要的服务和页面进行流量限制或者停止访问,从而释放服务器的整体压力。
下面我们分别演示如何进行服务的熔断和降级。
一、Hystrix
引入依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>2.2.3.RELEASE</version>
</dependency>
加入开启熔断器的注解@EnableCircuitBreaker,我此处演示项目使用gateway演示:
/**
* 启动类
*
* @author weirx
*/
@EnableCircuitBreaker
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}, scanBasePackages = {"com.cloud.bssp.gateway"})
@EnableFeignClients(basePackages = {"com.cloud.bssp.gateway.feign"})
public class BsspGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(BsspGatewayApplication.class, args);
}
}
默认情况下FeignClient中默认情况下是禁用Hystrix的,所以如果需要在微服务中启用Hystrix的熔断功能,则需要通过配置手动开启Hystrix功能:
#开启hystrix
feign:
hystrix:
enabled: true
提供一个用户服务的feignClient,重点是属性fallbackFactory,后面配置当前feignClient的实现类。
@FeignClient(name = "bssp-user-service", path = "/user",fallbackFactory = UserClientImpl.class)
public interface UserClient {
@PostMapping("/login")
R login(@RequestBody UserDTO userDTO);
}
UserClientImpl代码如,注意增加@Component注解,否则可能会报找不到服务的错误:
/**
* @author weirx
* @date 2021/07/08 11:10
**/
@Slf4j
@Component
public class UserClientImpl implements FallbackFactory<UserClient> {
@Override
public UserClient create(Throwable throwable) {
return new UserClient() {
@Override
public R login(UserDTO userDTO) {
log.info("调用用户服务失败,对用户服务降级处理。");
return R.failed("调用用户服务失败,对用户服务降级处理");
}
};
}
}
模拟user服务宕机情况下,访问登录接口,之所以用登录接口是图方便。将user服务关闭,或者在注册中心下线处理。查看结果:
结果
Histrix提供了面板共我们直观的查看:HystrixDashboard,引入依赖,需要注意的是,尽量不要在springcloudGateway中添加dashboard,因为其依赖含有web组件,会和gateway冲突,所以下面的演示我换一个服务,这是自己踩得一个坑:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
<version>2.2.3.RELEASE</version>
</dependency>
启动类增加注解@EnableHystrixDashboard
/**
* @author weirx
* @description: 数据服务启动类
* <p>
* 注解@ServletComponentScan: 使Servlet,filter,listener 可以通过 @WebServlet,@WebFilter,@WebListener
* 等注解直接注册,无需其他代码
* @date 2020/6/17
*/
@EnableHystrixDashboard
@EnableCircuitBreaker
@SpringBootApplication
@ServletComponentScan
@EnableFeignClients
public class BsspAdminServiceApplication {
public static void main(String[] args) {
SpringApplication.run(BsspAdminServiceApplication.class, args);
}
}
访问http://localhost:8080/hystrix
hystrix-dashboard下面是我的client和fallback实现:
/**
* Description: 用户表
* Create Date: 2021-03-17T13:53:59.025
* Modified By:<br>
* Modified Date:<br>
* Why & What is modified:<br>
*
* @author weirx
* @version 1.0
*/
@FeignClient(name = "bssp-user-service", path = "/user", fallbackFactory = UserClientImpl.class)
public interface UserClient {
/**
* 分页列表
*
* @param params
* @return
*/
@PostMapping("/pageList")
R pageList(@RequestBody Map<String, Object> params);
/**
* list列表
*
* @param userDTO
* @return
*/
@PostMapping("/list")
R list(@RequestBody UserDTO userDTO);
/**
* 根据主键查询
*
* @param id
* @return
*/
@GetMapping("/info/getById")
R info(@RequestParam("id") Long id);
/**
* 新增
*
* @param userDTO
* @return
*/
@PostMapping("/save")
R save(@RequestBody UserDTO userDTO);
/**
* 更新
*
* @param userDTO
* @return
*/
@PostMapping("/update")
R update(@RequestBody UserDTO userDTO);
}
import java.util.Map;
/**
* @author weirx
* @date 2021/07/08 14:38
**/
@Component
public class UserClientImpl implements FallbackFactory<UserClient> {
@Override
public UserClient create(Throwable throwable) {
return new UserClient() {
@Override
public R pageList(Map<String, Object> params) {
return R.failed("调用用户服务失败,服务已被降级处理");
}
@Override
public R list(UserDTO userDTO) {
return R.failed("调用用户服务失败,服务已被降级处理");
}
@Override
public R info(Long id) {
return R.failed("调用用户服务失败,服务已被降级处理");
}
@Override
public R save(UserDTO userDTO) {
return R.failed("调用用户服务失败,服务已被降级处理");
}
@Override
public R update(UserDTO userDTO) {
return R.failed("调用用户服务失败,服务已被降级处理");
}
};
}
}
测试controller:
@Api(tags = "测试Hystrix")
@RestController
@RequestMapping("/test")
public class TestController {
/**
* SysMenuService
*/
@Autowired
private UserClient userClient;
/**
* list列表
* @return
*/
@GetMapping("/list")
public R list() {
return userClient.list(new UserDTO());
}
}
颜色说明:
颜色说明
现在通过dashboard监控服务,当用户服务正常启动是,我们多次访问端口看结果:
正常服务
当我们将服务关闭后访问看结果:
访问失败
下一章节演示alibaba sentinel的安装及使用过程。
网友评论