package com.mayikt.service.order.impl;
import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.EntryType;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.mayikt.service.order.openfeign.MemberServiceFeign;
import com.sun.org.apache.xpath.internal.CachedXPathAPI;
import lombok.extern.slf4j.Slf4j;
import org.omg.CORBA.PRIVATE_MEMBER;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
/**
* @author 蚂蚁课堂创始人-余胜军QQ644064779
* @title: OrderService
* @description: 每特教育独创第五期互联网架构课程
* @date 2020/1/921:41
*/
@RestController
@Slf4j
public class OrderService {
@Autowired
private MemberServiceFeign memberServiceFeign;
// 限流规则名称
private static final String GETORDER_KEY = "orderToMember";
private static final String getUserOrder = "getUserOrder";
/**
* 基于我们的fegin客户端形式实现rpc远程调用
*
* @return
*/
@RequestMapping("/orderFeignToMember")
public String orderFeignToMember() {
String result = memberServiceFeign.getUser(1);
return "我是订单服务调用会员服务的接口,返回结果" + result;
}
@RequestMapping("/")
public String order() {
return "订单服务";
}
@RequestMapping("/orderToMember")
public String orderToMember() {
Entry entry = null;
try {
entry = SphU.entry(GETORDER_KEY);
return "orderToMember接口";
} catch (Exception e) {
// 限流的情况就会进入到Exception
return "当前访问人数过多,请稍后重试!";
} finally {
// SphU.entry(xxx) 需要与 entry.exit() 成对出现,否则会导致调用链记录异常
if (entry != null) {
entry.exit();
}
}
}
/**
* fallback 服务降级执行本本地方法
* blockHandler 限流/熔断出现异常执行的方法
* value 指定我们的资源的名称
*
* @return
*/
@SentinelResource(value = GETORDER_KEY, blockHandler = "getOrderQpsException")
@RequestMapping("/orderToMemberSentinelResource")
public String orderToMemberSentinelResource() {
return "orderToMemberSentinelResource";
}
/**
* 被限流后返回的提示
*
* @param e
* @return
*/
public String getOrderQpsException(BlockException e) {
e.printStackTrace();
return "该接口已经被限流啦!";
}
/**
* 服务降级 限流、熔断、接口超时、接口出现异常
*/
/**
* 基于我们的控制创建规则实现限流
*
* @return
*/
@SentinelResource(value = "getOrderConsole", blockHandler = "getOrderQpsException")
@RequestMapping("/getOrderConsole")
public String getOrderConsole() {
return "getOrderConsole";
}
@SentinelResource(value = "getOrderSemaphore", blockHandler = "getOrderQpsException")
@RequestMapping("/getOrderSemaphore")
public String getOrderSemaphore() {
try {
Thread.sleep(500);
} catch (Exception e) {
}
log.info(Thread.currentThread().getName());
return "getOrderSemaphore";
}
/**
* 注意:如果没有使用 @SentinelResource注解的情况下 默认的资源名称为接口路径地址
*/
/**
* 基于我们的平均响应时间实现降级
*
* @return
*/
@SentinelResource(value = "getOrderDowngradeRtType", fallback = "getOrderDowngradeRtTypeFallback")
@RequestMapping("/getOrderDowngradeRtType")
public String getOrderDowngradeRtType() {
try {
Thread.sleep(300);
} catch (Exception e) {
}
return "正常执行我们业务逻辑";
}
public String getOrderDowngradeRtTypeFallback() {
return "执行我们本地的服务降级的方法";
}
/**
* 基于我们错误率实现服务降级
*
* @return
*/
@SentinelResource(value = "getOrderDowngradeErrorType", fallback = "getOrderDowngradeErrorTypeFallback")
@RequestMapping("/getOrderDowngradeErrorType")
public String getOrderDowngradeErrorType(int age) {
int j = 1 / age;
return "正常执行我们业务逻辑:j" + j;
}
public String getOrderDowngradeErrorTypeFallback(int age) {
return "错误率太高,展示无法访问该接口";
}
@SentinelResource(value = "getOrderSentinel", blockHandler =
"getOrderSentinelBlockHandler")
@RequestMapping("/getOrderSentinel")
public String getOrderSentinel() {
return "getOrderSentinel";
}
public String getOrderSentinelBlockHandler(BlockException e) {
return "当前访问人数过多,请稍后重试!";
}
//
// @RequestMapping("/getUserOrder")
// public String getUserOrder(Long userId) {
// Entry entry = null;
// try {
// entry = SphU.entry(getUserOrder, EntryType.IN, 1, userId);
// return "根据userId获取用户订单信息成功";
// } catch (Exception e) {
// return "您操作的比较频繁,请稍后重试!";
// } finally {
// if (entry != null) {
// entry.exit();
// }
// }
// }
// @RequestMapping("/getUserOrder")
// @SentinelResource(value = "getUserOrder")
// public String getUserOrder(Long userId) {
// return "根据userId获取用户订单信息成功";
//
// }
//
// /**
// * 秒杀接口
// *
// * @return
// */
// @RequestMapping("/seckill")
// public String seckill(Long userId) {
// Entry entry = null;
// try {
// // 对我们的userId的参数实现埋点
// entry = SphU.entry(GET_SECKULL_RESOURCE_NAME, EntryType.IN,
// 1, userId);
// return "用户秒杀成功" + userId;
// } catch (Exception e) {
// return "用户秒杀失败,您访问的频率过多。";
// } finally {
// if (entry != null) {
// entry.exit();
// }
//
// }
//
// }
//
// /**
// * 定义我们的秒杀参数限流的规则
// */
// private static final String GET_SECKULL_RESOURCE_NAME = "GET_SECKULL";
// /**
// * 提前创建限流热词规则 基于qps
// */
@RequestMapping("/seckill")
@SentinelResource(value = "seckill", blockHandler = "seckillBlockHandler"
, fallback = "seckillFallback")
public String seckill(Long userId) {
try {
return "用户秒杀成功" + userId;
} catch (Exception e) {
return "当前的访问次数过多,请稍后重试!";
}
}
public String seckillBlockHandler(Long userId) {
return "当前的访问次数过多,请稍后重试!";
}
public String seckillFallback(Long userId) {
return "当前的访问次数过多,请稍后重试!";
}
/**
* blockHandler 限流出现异常执行的方法
* fallback 服务熔断降级错误或者1.6版本以后接口出现业�