所有代码发布在 [https://github.com/hades0525/leyou]
Day03
2019年1月18日
11:45
Springcloud
Hystrix(一种保护机制/熔断器)
- Hystrix是Netflix开源的一个延迟和容错库,用于隔离访问远程服务、第三方库,防止出现级联失败。
- 雪崩问题:微服务中调用关系复杂,如果一个调用异常,请求阻塞,导致其他服务都不可用,形式雪崩效应。
- Hystrix解决雪崩问题两个手段:
- 线程隔离
- 服务熔断
线程隔离,服务降级(消费者方):
-
- 把各个线程隔离开,线程池满了后,会优先保证核心服务,非核心服务不可用或弱可用
- 请求故障时,不会阻塞或无线等待,至少返回一个执行结果
- 触发服务降级的情况
- 线程池满
- 请求超时
使用:
-
- 引入依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency> |
-
- 启动类上添加注解 @@EnableCircuitBreaker
- 后期注解过多,使用组合注解@springCloudApplication
- 启动类上添加注解 @@EnableCircuitBreaker
代替3个注解
@EnableCircuitBreaker @EnableDiscoveryClient @SpringBootApplication |
-
- 编写降级逻辑
- 降级逻辑方法必须和正常逻辑方法参数和返回值一致
- 编写降级逻辑
@GetMapping("{id}") @HystrixCommand(fallbackMethod="queryByIdFallBcak") Public String queryById(@PathVariable("id")Longid){ Stringurl="http://user-service/user/"+id; Stringuser=restTemplate.getForObject(url,String.class); returnuser; } Public String queryByIdFallBcak(Longid){ return"对不起,服务器太拥挤"; } |
-
- 设置通用的fallback
在consumer调用类上@DefaultProperties(defaultFallback="defalutFallBcak")
Public String defalutFallBcak(){ return"对不起,服务器太拥挤"; } |
在启用的方法上添加@Hystrix即可
-
- 自定义超时时长
- 配置一个方法的
- 自定义超时时长
@HystrixCommand(commandProperties={ @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="3000") }) |
-
- 全局配置
hystrix: command: default: isolation: thread: timeoutInMilliseconds:3000 |
-
- 针对一个服务或方法
hystrix: command: 服务名/方法: isolation: thread: timeoutInMilliseconds:3000
|
服务熔断(Circuit Breaker):
- 服务降级的等待时长过长,降低了并发效率,所以用熔断器。
- 熔断器3个状态
@HystrixCommand(commandProperties={
@HystrixProperty(name="circuitBreaker.requestVolumeThreshold",value="10"),
@HystrixProperty(name="circuitBreaker.sleepWindowInMilliseconds",value="10000"),
@HystrixProperty(name="circuitBreaker.errorThresholdPercentage",value="60"),
})
一般要自定义控制超时的时长,不修改熔断的设置。
Feign:
-
- 作用:把远程请求隐藏,伪装成和contrller一样
- 省略代码,伪装成controller
- 作用:把远程请求隐藏,伪装成和contrller一样
Stringurl="http://user-service/user/"+id; Stringuser=restTemplate.getForObject(url,String.class); |
-
- 引入依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> |
-
- 启动类注解 @EnableFeignClients
- 编写接口
@FeignClient("user-service") public interface UserClient{ @GetMapping("user/{id}") User queryById(@PathVariable("id") Long id); } |
-
- 直接调用
@Autowired private UserClient userClient;
@GetMapping("{id}") public User queryById(@PathVariable("id")Longid){ return userClient.queryById(id); } |
-
- feign已经实现了ribbon和hystrix
- feign配置ribbon
- feign已经实现了ribbon和hystrix
user-service: ribbon: ConnectTimeout: 250 # 连接超时时间(ms) ReadTimeout: 1000 # 通信超时时间(ms) OkToRetryOnAllOperations: true # 是否对所有操作重试 MaxAutoRetriesNextServer: 1 # 同一服务不同实例的重试次数 MaxAutoRetries: 1 # 同一实例的重试次数 |
-
- feign配置hystrix(默认关闭)
- 开启熔断
- feign配置hystrix(默认关闭)
feign: hystrix: enabled: true # 开启Feign的熔断功能 |
-
- 定义一个类实现接口UserClient
@Component public class UserClientFallback implements UserClient{ @Override public UserqueryById(Longid){ User user = new User(); user.setUser_name("未知用户"); return user; } } |
-
- 接口上注解添加熔断类
@FeignClient(value="user-service",fallback=UserClientFallback.class)
zuul:微服务网关
服务网关统一向外系统提供REST API的过程中,除了具备服务路由、均衡负载功能之外,它还具备了权限控制等功能。为微服务架构提供了前门保护的作用,同时将权限控制这些较重的非业务逻辑内容迁移到服务路由层面,使得服务集群主体能够具备更高的可复用性和可测试性。
使用:新建一个网关module
-
- 引入依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> |
-
- 启动类
@EnableZuulProxy @SpringBootApplication publicclassGatewayApplication{ publicstaticvoidmain(String[]args){ SpringApplication.run(GatewayApplication.class); } } |
-
- 配置application.yml
server: port: 10010 spring: application: name: gateway eureka: #添加eureka配置 client: service-url: defaultZone: http://127.0.0.1:10087/eureka zuul: #设置映射配置 routes: user-service: /user/** #访问url:http://127.0.0.1:10010/user/user/1 ignored-services: #设置不能访问的服务 - consumer-service |
-
- 过滤器(zuul的核心就是一系列的过滤器)
- ZuulFilter是过滤器的顶级父类,4个最重要的方法
- 过滤器(zuul的核心就是一系列的过滤器)
public abstract ZuulFilter implements IZuulFilter{
abstract public String filterType();//过滤器类型
abstract public int filterOrder();//过滤器顺序(优先级)
boolean shouldFilter();// 是否需要执行过滤器
Object run() throws ZuulException;// 具体的业务逻辑 } |
-
- 过滤器类型
|
-
- 自定义过滤器
public class LoginFilter extends ZuulFilter { @Override public String filterType() { return FilterConstants.PRE_TYPE; } @Override public int filterOrder() { return FilterConstants.PRE_DECORATION_FILTER_ORDER - 1; } @Override public boolean shouldFilter() { return true; } @Override public Object run() throws ZuulException { //获取请求上下文 RequestContext ctx = RequestContext.getCurrentContext(); //获取request HttpServletRequest request = ctx.getRequest(); //获取请求参数 String token = request.getParameter("access-token"); //判断是否存在 if(StringUtils.isBlank(token)){ //不存在,未登录,则拦截 ctx.setSendZuulResponse(false); //状态码403,禁用 ctx.setResponseStatusCode(HttpStatus.FORBIDDEN.value()); } return null; } } |
-
- 负载均衡和熔断
ribbon真正的默认超时时长是原有时长(连接时长+通信时长)的2倍
hystrix超时时长应该大于ribbon的真正超长时长
-
- Zull的高可用
- 启动多个zuul服务,注册到eureka形式集群,内部访问自动负载均衡
- 外部访问时,无法 通过erreka实现负载均衡,通过使用其他网关,如nginx对zuul进行代理
- Zull的高可用
其他的springcloud组件
- spring-cloud-config:统一配置中心。配置统一放到git。拉取配置列表
- spring-cloud-bus:消息总线(activitiMQ或kafaka实现)。
- 当git有新的提交时,会通过调用配置中心定义好的hook(接口)拉取git上的配置,通过消息总线,向所有微服务推送配置更新的通知,微服务自动拉取最新的配置,并且不重启,自动生效。
- spring-cloud-hystrix-dashboard:容错统计,图形化界面
- spring-cloud-sleuth:链路追踪(结合zipkin),体现各个微服务之间的调用关系