Spring Cloud Stream 与 Hystrix 冲突
Spring Cloud Stream conflicts with Hystrix
我有一个带有 Hystrix 和 Spring Cloud Stream 通道的 RestController :
@RestController
@RequestMapping(value = "/api/products")
@EnableBinding(ProductProcessor.class)
public class ProductUiController {
/*******
* LISTENERS
*******/
private List<Product> listenAllProducts;
private Product listenProduct;
/*******
* CHANNELS
*******/
@Autowired
@Qualifier(ProductProcessor.OUTPUT_DELETE)
private MessageChannel channel_delete;
@Autowired
@Qualifier(ProductProcessor.OUTPUT_CREATE)
private MessageChannel channel_create;
@Autowired
@Qualifier(ProductProcessor.OUTPUT_UPDATE)
private MessageChannel channel_update;
Logger logger = Logger.getLogger(ProductUiController.class);
@Autowired
RabbitTemplate rabbitTemplate;
@Autowired
RabbitAdmin rabbitAdmin;
@Autowired
private LoadBalancerClient loadBalancer;
/**
* returns all the products in the database
*
* @return
*/
@RequestMapping(method = RequestMethod.GET)
@HystrixCommand(fallbackMethod = "getAllProductsFallback")
public List<Product> getAllProducts() {
try {
ServiceInstance instance = loadBalancer.choose("product-service");
URI uri = instance.getUri();
URL obj = new URL(uri.toString() + "/products");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.getResponseCode();
} catch (MalformedURLException e) {
logger.error(e.getMessage());
} catch (IOException e) {
logger.error(e.getMessage());
}
return this.listenAllProducts;
}
/**
* Returns a specific product from product-service
*
* @param id
* @return
*/
@RequestMapping(value = "/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public Product getProduct(@PathVariable("id") Long id) {
try {
ServiceInstance instance = loadBalancer.choose("product-service");
URI uri = instance.getUri();
URL obj = new URL(uri.toString() + "/products/" + id);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
con.getResponseCode();
} catch (MalformedURLException e) {
logger.error(e.getMessage());
} catch (IOException e) {
logger.error(e.getMessage());
}
System.out.println("RETURNED PRODUCT = " + listenProduct);
return listenProduct;
}
@HystrixCommand(fallbackMethod = "addProductFallback")
@RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
public Product addProduct(@RequestBody Product product) {
logger.info("SENT VIA OUTPUT_CREATE: " + product);
channel_create.send(MessageBuilder.withPayload(product).build());
return product;
}
@HystrixCommand(fallbackMethod = "removeProductFallback")
@RequestMapping(method = RequestMethod.DELETE)
public void removeProduct(@RequestParam("id") Long id) {
logger.info("SENT VIA OUTPUT_DELETE: " + id);
this.channel_delete.send(MessageBuilder.withPayload(id).build());
}
/**************************************/
/**********LISTENERS*******************/
/**************************************/
/**
* Receiver for all products
*
* @param products
*/
@StreamListener(ProductProcessor.INPUT_GETALL)
public void listenerGetAllProducts(List<Product> products) {
logger.info("RECEIVED FROM INPUT_GETALL: " + products);
listenAllProducts = products;
}
/**
* Receiver for product
*
* @param product
*/
@StreamListener(ProductProcessor.INPUT_GET)
public void listenerGetProduct(Product product) {
logger.info("RECEIVED FROM INPUT_GET: " + product);
listenProduct = product;
}
/**************************************/
/**********FALLBACK METHODS************/
/**************************************/
/**
* Fallback method for getAllProducts
*
* @return
*/
public List<Product> getAllProductsFallback(Throwable e) {
logger.info("getAllProductsFallback");
return listenAllProducts;
}
/**
* Fallback method for addProduct
*
* @param product
* @return
*/
Product addProductFallback(Product product) {
logger.info("addProductFallback");
return null;
}
/**
* Fallback method for delete
*
* @param id
*/
void removeProductFallback(Long id) {
logger.info("removeProductFallback");
}
}
在实现中 HystrixCommand 使 getDeclaredMethod 到 ProductUiController 来查找回退方法但是@EnableBinding 从反射中隐藏了 class 方法,任何解决方法的线索?
解决方案: 将 @EnableBinding 移动到主 SpringBootApplication class.
我有一个带有 Hystrix 和 Spring Cloud Stream 通道的 RestController :
@RestController
@RequestMapping(value = "/api/products")
@EnableBinding(ProductProcessor.class)
public class ProductUiController {
/*******
* LISTENERS
*******/
private List<Product> listenAllProducts;
private Product listenProduct;
/*******
* CHANNELS
*******/
@Autowired
@Qualifier(ProductProcessor.OUTPUT_DELETE)
private MessageChannel channel_delete;
@Autowired
@Qualifier(ProductProcessor.OUTPUT_CREATE)
private MessageChannel channel_create;
@Autowired
@Qualifier(ProductProcessor.OUTPUT_UPDATE)
private MessageChannel channel_update;
Logger logger = Logger.getLogger(ProductUiController.class);
@Autowired
RabbitTemplate rabbitTemplate;
@Autowired
RabbitAdmin rabbitAdmin;
@Autowired
private LoadBalancerClient loadBalancer;
/**
* returns all the products in the database
*
* @return
*/
@RequestMapping(method = RequestMethod.GET)
@HystrixCommand(fallbackMethod = "getAllProductsFallback")
public List<Product> getAllProducts() {
try {
ServiceInstance instance = loadBalancer.choose("product-service");
URI uri = instance.getUri();
URL obj = new URL(uri.toString() + "/products");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.getResponseCode();
} catch (MalformedURLException e) {
logger.error(e.getMessage());
} catch (IOException e) {
logger.error(e.getMessage());
}
return this.listenAllProducts;
}
/**
* Returns a specific product from product-service
*
* @param id
* @return
*/
@RequestMapping(value = "/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public Product getProduct(@PathVariable("id") Long id) {
try {
ServiceInstance instance = loadBalancer.choose("product-service");
URI uri = instance.getUri();
URL obj = new URL(uri.toString() + "/products/" + id);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
con.getResponseCode();
} catch (MalformedURLException e) {
logger.error(e.getMessage());
} catch (IOException e) {
logger.error(e.getMessage());
}
System.out.println("RETURNED PRODUCT = " + listenProduct);
return listenProduct;
}
@HystrixCommand(fallbackMethod = "addProductFallback")
@RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
public Product addProduct(@RequestBody Product product) {
logger.info("SENT VIA OUTPUT_CREATE: " + product);
channel_create.send(MessageBuilder.withPayload(product).build());
return product;
}
@HystrixCommand(fallbackMethod = "removeProductFallback")
@RequestMapping(method = RequestMethod.DELETE)
public void removeProduct(@RequestParam("id") Long id) {
logger.info("SENT VIA OUTPUT_DELETE: " + id);
this.channel_delete.send(MessageBuilder.withPayload(id).build());
}
/**************************************/
/**********LISTENERS*******************/
/**************************************/
/**
* Receiver for all products
*
* @param products
*/
@StreamListener(ProductProcessor.INPUT_GETALL)
public void listenerGetAllProducts(List<Product> products) {
logger.info("RECEIVED FROM INPUT_GETALL: " + products);
listenAllProducts = products;
}
/**
* Receiver for product
*
* @param product
*/
@StreamListener(ProductProcessor.INPUT_GET)
public void listenerGetProduct(Product product) {
logger.info("RECEIVED FROM INPUT_GET: " + product);
listenProduct = product;
}
/**************************************/
/**********FALLBACK METHODS************/
/**************************************/
/**
* Fallback method for getAllProducts
*
* @return
*/
public List<Product> getAllProductsFallback(Throwable e) {
logger.info("getAllProductsFallback");
return listenAllProducts;
}
/**
* Fallback method for addProduct
*
* @param product
* @return
*/
Product addProductFallback(Product product) {
logger.info("addProductFallback");
return null;
}
/**
* Fallback method for delete
*
* @param id
*/
void removeProductFallback(Long id) {
logger.info("removeProductFallback");
}
}
在实现中 HystrixCommand 使 getDeclaredMethod 到 ProductUiController 来查找回退方法但是@EnableBinding 从反射中隐藏了 class 方法,任何解决方法的线索?
解决方案: 将 @EnableBinding 移动到主 SpringBootApplication class.