sentinel用于对请求的流量控制,熔断降级的管控
实现原理:通过拦截器对配置了限流规则的接口或者代码块进行限流和熔断降级处理
代码整合
流程原理:目的微服务暴露8719端口,控制台可根据8719的接口获取埋点的信息(若该端口被已经被占用,则会开启8719自增未被占用的端口),控制台设置规则并将规则发送到目的微服务,目的微服务在进行每次访问的时候被其拦截器拦截,根据规则来流量控制
开启控制台
控制台用于获取要控制的微服务的埋点,以及给每个埋点设置规则
整合sentinel
依赖
1 2 3 4 5
| <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> <version>2.1.2.RELEASE</version> </dependency>
|
xml配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| spring: application: name: sentinel cloud: sentinel: transport: #配置sentinel控制台的ip和端口 dashboard: localhost:8080 heartbeat-interval-ms: 500 #懒加载标志 默认是false eager: true filter: #配置是否对controller进行默认控制,默认是true enabled: true feign: sentinel: #feign开启sentinel限流,默认为false,且只需在FeignClient注解中配置属性 fallback就行 enabled: true
|
自定义配置类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler; import com.alibaba.csp.sentinel.slots.block.BlockException; import com.alibaba.fastjson.JSON; import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.PrintWriter; import java.util.HashMap; import java.util.Map;
@Component public class SentinelExceptionHandler implements BlockExceptionHandler { public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws Exception { Map<String,Object> map = new HashMap<String, Object>(); map.put("code", 500); map.put("mesg", "流量控制,请求失败"); map.put("data",""); String jsonString = JSON.toJSONString(map);
httpServletResponse.setStatus(500); httpServletResponse.setCharacterEncoding("utf-8"); httpServletResponse.setContentType("text/html;charset=utf-8"); PrintWriter out = httpServletResponse.getWriter(); out.print(jsonString); out.flush(); out.close(); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.RequestOriginParser; import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
@Component public class SentinelRequestOriginParser implements RequestOriginParser {
public String parseOrigin(HttpServletRequest httpServletRequest) { String token = httpServletRequest.getHeader("token"); return "stopUser"; } }
|
controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| import com.alibaba.csp.sentinel.Entry; import com.alibaba.csp.sentinel.SphU; import com.alibaba.csp.sentinel.Tracer; import com.alibaba.csp.sentinel.annotation.SentinelResource; import com.alibaba.csp.sentinel.context.ContextUtil; import com.alibaba.csp.sentinel.slots.block.BlockException; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
@RestController @RequestMapping("/ces") public class DemoController {
@GetMapping("ces") @SentinelResource(value = "ces") public String ces(){ return "1111"; }
@GetMapping("manual") public String ManualSentinelDo(){
ContextUtil.enter("manual","stopUser"); Entry entry = null; try { entry = SphU.entry("manual");
String date = new Date().toString(); return date;
} catch (BlockException e) { e.printStackTrace(); return "熔断降级处理..."; } catch (Exception e) { e.printStackTrace(); Tracer.trace(e); }finally { if(entry != null){ entry.exit(); } ContextUtil.exit(); } return "result"; } }
|
其它
注: