Spring Cloud @HystrixCommand和@CacheResult注解使用,参数配置
使用Spring Cloud时绕不开Hystrix,他帮助微服务实现断路器功能。该框架的目标在于通过控制那些访问远程系统、服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。Hystrix具备服务降级,服务熔断,线程和信号隔离,请求缓存,请求合并以及服务监控等强大功能。
关于Hystrix的介绍请参见:http://www.sohu.com/a/131568369_494947,本文部分介绍引自此文,建议先阅读此文了解Hystrix的使用场景和线程池概念。
@HystrixCommand的基础介绍请参见:http://blog.csdn.net/forezp/article/details/69934399,介绍的很详细,我这里主要说一说这个注解的各个参数的使用。
查看com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand的源代码如下:
/**
* Copyright 2012 Netflix, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.netflix.hystrix.contrib.javanica.annotation; import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; /**
* This annotation used to specify some methods which should be processes as hystrix commands.
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface HystrixCommand { /**
* The command group key is used for grouping together commands such as for reporting,
* alerting, dashboards or team/library ownership.
* <p/>
* default => the runtime class name of annotated method
*
* @return group key
*/
String groupKey() default ""; /**
* Hystrix command key.
* <p/>
* default => the name of annotated method. for example:
* <code>
* ...
* @HystrixCommand
* public User getUserById(...)
* ...
* the command name will be: 'getUserById'
* </code>
*
* @return command key
*/
String commandKey() default ""; /**
* The thread-pool key is used to represent a
* HystrixThreadPool for monitoring, metrics publishing, caching and other such uses.
*
* @return thread pool key
*/
String threadPoolKey() default ""; /**
* Specifies a method to process fallback logic.
* A fallback method should be defined in the same class where is HystrixCommand.
* Also a fallback method should have same signature to a method which was invoked as hystrix command.
* for example:
* <code>
* @HystrixCommand(fallbackMethod = "getByIdFallback")
* public String getById(String id) {...}
*
* private String getByIdFallback(String id) {...}
* </code>
* Also a fallback method can be annotated with {@link HystrixCommand}
* <p/>
* default => see {@link com.netflix.hystrix.contrib.javanica.command.GenericCommand#getFallback()}
*
* @return method name
*/
String fallbackMethod() default ""; /**
* Specifies command properties.
*
* @return command properties
*/
HystrixProperty[] commandProperties() default {}; /**
* Specifies thread pool properties.
*
* @return thread pool properties
*/
HystrixProperty[] threadPoolProperties() default {}; /**
* Defines exceptions which should be ignored.
* Optionally these can be wrapped in HystrixRuntimeException if raiseHystrixExceptions contains RUNTIME_EXCEPTION.
*
* @return exceptions to ignore
*/
Class<? extends Throwable>[] ignoreExceptions() default {}; /**
* Specifies the mode that should be used to execute hystrix observable command.
* For more information see {@link ObservableExecutionMode}.
*
* @return observable execution mode
*/
ObservableExecutionMode observableExecutionMode() default ObservableExecutionMode.EAGER; /**
* When includes RUNTIME_EXCEPTION, any exceptions that are not ignored are wrapped in HystrixRuntimeException.
*
* @return exceptions to wrap
*/
HystrixException[] raiseHystrixExceptions() default {}; /**
* Specifies default fallback method for the command. If both {@link #fallbackMethod} and {@link #defaultFallback}
* methods are specified then specific one is used.
* note: default fallback method cannot have parameters, return type should be compatible with command return type.
*
* @return the name of default fallback method
*/
String defaultFallback() default "";
}
让我们来看一下这个注解的简单应用:
package com.example.demo.service; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate; import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; @Service
public class ConsumerService { @Autowired
private RestTemplate restTemplate; @HystrixCommand(commandKey = "testCommand", groupKey = "testGroup", threadPoolKey = "testThreadKey",
fallbackMethod = "hiConsumerFallBack", ignoreExceptions = {NullPointerException.class},
threadPoolProperties = {
@HystrixProperty(name = "coreSize", value = "30"),
@HystrixProperty(name = "maxQueueSize", value = "101"),
@HystrixProperty(name = "keepAliveTimeMinutes", value = "2"),
@HystrixProperty(name = "queueSizeRejectionThreshold", value = "15"),
@HystrixProperty(name = "metrics.rollingStats.numBuckets", value = "12"),
@HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds", value = "1440")
}
)
public String hiConsumer(String id) { //SERVICE_HI是服务端的spring.application.name,并且大写,hi为服务端提供的接口
return restTemplate.getForEntity("http://SERVICE_HI/hi", String.class).getBody();
} public String hiConsumerFallBack(String id, Throwable e) {
return "This is a error";
} }
让我们来逐个介绍下@HystrixCommand注解的各个参数:
1:commandKey:配置全局唯一标识服务的名称,比如,库存系统有一个获取库存服务,那么就可以为这个服务起一个名字来唯一识别该服务,如果不配置,则默认是@HystrixCommand注解修饰的函数的函数名。
2:groupKey:一个比较重要的注解,配置全局唯一标识服务分组的名称,比如,库存系统就是一个服务分组。通过设置分组,Hystrix会根据组来组织和统计命令的告、仪表盘等信息。Hystrix命令默认的线程划分也是根据命令组来实现。默认情况下,Hystrix会让相同组名的命令使用同一个线程池,所以我们需要在创建Hystrix命令时为其指定命令组来实现默认的线程池划分。此外,Hystrix还提供了通过设置threadPoolKey来对线程池进行设置。建议最好设置该参数,使用threadPoolKey来控制线程池组。
3:threadPoolKey:对线程池进行设定,细粒度的配置,相当于对单个服务的线程池信息进行设置,也可多个服务设置同一个threadPoolKey构成线程组。
4:fallbackMethod:@HystrixCommand注解修饰的函数的回调函数,@HystrixCommand修饰的函数必须和这个回调函数定义在同一个类中,因为定义在了同一个类中,所以fackback method可以是public/private均可。
5:commandProperties:配置该命令的一些参数,如executionIsolationStrategy配置执行隔离策略,默认是使用线程隔离,此处我们配置为THREAD,即线程池隔离。参见:com.netflix.hystrix.HystrixCommandProperties中各个参数的定义。
|
注解
|
描述
|
属性
|
|
@CacheResult
|
该注解用来标记请求命令返回的结果应该被缓存,它必须与@HystrixCommand注解结合使用
|
cacheKeyMethod
|
|
@CacheRemove
|
该注解用来让请求命令的缓存失效,失效的缓存根据定义Key决定
|
commandKey,
cacheKeyMethod
|
|
@CacheKey
|
该注解用来在请求命令的参数上标记,使其作为缓存的Key值,如果没有标注则会使用所有参数。如果同事还是使用了@CacheResult和@CacheRemove注解的cacheKeyMethod方法指定缓存Key的生成,那么该注解将不会起作用
|
value
|
/**
* Copyright 2015 Netflix, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.netflix.hystrix.contrib.javanica.cache.annotation; import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; /**
* Marks a methods that results should be cached for a Hystrix command.
* This annotation must be used in conjunction with {@link com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand} annotation.
*
* @author dmgcodevil
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CacheResult { /**
* Method name to be used to get a key for request caching.
* The command and cache key method should be placed in the same class and have same method signature except
* cache key method return type, that should be <code>String</code>.
* <p/>
* cacheKeyMethod has higher priority than an arguments of a method, that means what actual arguments
* of a method that annotated with {@link CacheResult} will not be used to generate cache key, instead specified
* cacheKeyMethod fully assigns to itself responsibility for cache key generation.
* By default this returns empty string which means "do not use cache method".
*
* @return method name or empty string
*/
String cacheKeyMethod() default "";
}
- 减少重复的请求数,降低依赖服务的并发度;
- 在同一个用户请求的上下文,想同依赖服务的返回数据始终保持一致。
- 请求缓存在run()和contruct()执行之前生效,所以可以有效减少不必要的线程开销;
package com.example.demo; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate; import com.netflix.hystrix.contrib.javanica.cache.annotation.CacheResult;
import com.example.demo.entity.User;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; @Service
public class CacheResultDemo { @Autowired
private RestTemplate restTemplate; @CacheResult(cacheKeyMethod = "getUserId")
@HystrixCommand(fallbackMethod = "hiConsumerFallBack")
public User hiConsumer(String id) { //SERVICE_HI是服务端的spring.application.name,并且大写,hi为服务端提供的接口
return restTemplate.getForEntity("http://SERVICE_HI/hi", User.class).getBody();
} public String hiConsumerFallBack(String id, Throwable e) {
return "This is a error";
} public String getUserId(String id) {
return id;
} }
package com.example.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
importcom.netflix.hystrix.contrib.javanica.cache.annotation.CacheKey;
import com.example.demo.entity.User;
importcom.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
@Service
public class CacheKeyDemo {
@Autowired
private RestTemplate restTemplate;
@HystrixCommand(fallbackMethod = "hiConsumerFallBack")
public User hiConsumer(@CacheKey("id") String id) { //SERVICE_HI是服务端的spring.application.name,并且大写,hi为服务端提供的接口
return restTemplate.getForEntity("http://SERVICE_HI/hi", User.class).getBody();
} public String hiConsumerFallBack(String id, Throwable e) {
return "This is a error";
}
}
package com.example.demo; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate; import com.netflix.hystrix.contrib.javanica.cache.annotation.CacheKey;
import com.example.demo.entity.User;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; @Service
public class CacheKeyDemo2 { @Autowired
private RestTemplate restTemplate; @HystrixCommand(fallbackMethod = "hiConsumerFallBack")
public User hiConsumer(@CacheKey("id") User user) { //SERVICE_HI是服务端的spring.application.name,并且大写,hi为服务端提供的接口
return restTemplate.getForEntity("http://SERVICE_HI/hi", User.class, user.getId()).getBody();
} public String hiConsumerFallBack(String id, Throwable e) {
return "This is a error";
} }
package com.example.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
importcom.netflix.hystrix.contrib.javanica.cache.annotation.CacheKey;
importcom.netflix.hystrix.contrib.javanica.cache.annotation.CacheRemove;
import com.example.demo.entity.User;
importcom.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
@Service
public class CacheRemoveDemo {
@Autowired
private RestTemplate restTemplate;
@CacheRemove(commandKey = "getUserId")
@HystrixCommand(fallbackMethod = "hiConsumerFallBack")
public void update(@CacheKey("id") User user) { //SERVICE_HI是服务端的spring.application.name,并且大写,hi为服务端提供的接口
restTemplate.postForObject("http://SERVICE_HI/hi", user, User.class);
return;
} public String hiConsumerFallBack(String id, Throwable e) {
return "This is a error";
} public String getUserId(String id) {
return id;
}
}
Spring Cloud @HystrixCommand和@CacheResult注解使用,参数配置的更多相关文章
- spring cloud网关通过Zuul RateLimit 限流配置
目录 引入依赖 配置信息 RateLimit源码简单分析 RateLimit详细的配置信息解读 在平常项目中为了防止一些没有token访问的API被大量无限的调用,需要对一些服务进行API限流.就好比 ...
- Spring Cloud Config整合Spring Cloud Kubernetes,在k8s上管理配置
1 前言 欢迎访问南瓜慢说 www.pkslow.com获取更多精彩文章! Kubernetes有专门的ConfigMap和Secret来管理配置,但它也有一些局限性,所以还是希望通过Spring C ...
- spring cloud: zuul(二): zuul的serviceId/service-id配置(微网关)
spring cloud: zuul(二): zuul的serviceId/service-id配置(微网关) zuul: routes: #路由配置表示 myroute1: #路由名一 path: ...
- Spring Cloud gateway 七 Sentinel 注解方式使用
Sentinel 注解支持 @SentinelResource 用于定义资源,并提供可选的异常处理和 fallback 配置项. @SentinelResource 注解包含以下属性: value:资 ...
- Spring Boot 和 Spring Cloud Feign调用服务及传递参数踩坑记录
背景 :在Spring Cloud Netflix栈中,各个微服务都是以HTTP接口的形式暴露自身服务的,因此在调用远程服务时就必须使用HTTP客户端.我们可以使用JDK原生的URLConnectio ...
- spring cloud Feign 使用 @RequestLine 注解遇到的问题
package com.itmuch.cloud; import org.springframework.cloud.netflix.feign.FeignClient; import com.itm ...
- 【Spring Cloud】Spring Cloud之自定义@SpringCloudProfile注解实现@Profile注解的功能
一.为什么会想到定义@SpringCloudProfile这样的注解 首页提一下@Profile注解:它主要用与Spring Boot多环境配置中,指定某个类只在指定环境中生效,比如swagger的配 ...
- Spring Cloud(七):使用SVN存储分布式配置中心文件和实现refresh
国内很多公司都使用的svn来做代码的版本控制,我们先介绍以下如何使用svn+Spring Cloud Config来做配置中心. svn版本 同样先示例server端的代码,基本步骤一样. 1.添加依 ...
- Spring Cloud Eureka(四):Eureka 配置参数说明
Eureka Client 配置项(eureka.client.*) org.springframework.cloud.netflix.eureka.EurekaClientConfigBean 参 ...
随机推荐
- 不错的网络协议栈测试工具 — Packetdrill
Packetdrill - A network stack testing tool developed by Google. 项目:https://code.google.com/p/packetd ...
- objc一个NetConnector类示例
NetConnector是自定义的一个类,该类使用代理的方法实现异步下载特定url页面的内容. HyNetConnector.h // // HyNetConnector.h // HyNetConn ...
- web报表工具finereport常用函数的用法总结(数组函数)
ADD2ARRAY ADDARRAY(array,insertArray, start):在数组第start个位置插入insertArray中的所有元素,再返回该数组. 示例: ADDARRAY([3 ...
- Linux 系统应用编程——进程基础
一.Linux下多任务机制的介绍 Linux有一特性是多任务,多任务处理是指用户可以在同一时间内运行多个应用程序,每个正在执行的应用程序被称为一个任务. 多任务操作系统使用某种调度(shedule)策 ...
- 使用Interlocked在多线程下进行原子操作,无锁无阻塞的实现线程运行状态判断
巧妙地使用Interlocked的各个方法,再无锁无阻塞的情况下判断出所有线程的运行完成状态. 昨晚耐着性子看完了clr via c#的第29章<<基元线程同步构造>>,尽管这 ...
- python 字典dict类型合并(不能错过哦)
我要的字典的键值有些是数据库中表的字段名, 但是有些却不是, 我需要把它们整合到一起, 因此有些这篇文章.(非得凑够150个字,我也是没有办法,扯一点昨天的问题吧,话说python中的session就 ...
- ES6中Promise详解
Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果.从语法上说,Promise 是一个对象,从它可以获取异步操作的消息. Promise 提供统一的 AP ...
- JAVA堆栈的区别
1. 栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方.与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆. 2. 栈的优势是,存取速度 ...
- 全局程序集缓存GAC
GAC中的所有的Assembly都会存放在系统目录"%winroot%\assembly下面.放在系统目录下的好处之一是可以让系统管理员通过用户权限来控制Assembly的访问. 目录:C: ...
- JQuery DOM操作 、属性和CSS样式操作、其他函数
DOM操作 1.在div1内部最后追加一个节点 $("#div1").append("<img src='../01-HTML基本标签/img/Male.gif'/ ...