一文让你搞懂Sentinel 的搭建、使用以及原理

转载:https://mp.weixin.qq.com/s?__biz=Mzg3Mjk3OTA4OA==&mid=2247484243&idx=1&sn=7011f471fad70679dfc89505f186d36e&chksm=cee64cacf991c5baf3b32559f86500a7c12aaa25cf7df6e8ed8b575f612650b1218cb686d89a&cur_album_id=2973104649560178694&scene=189#wechat_redirect

在这里插入图片描述
在这里插入图片描述

java -jar sentinel-dashboard-1.8.1.jar

如果你需要修改默认的配置端口,可以使用以下命令:

java -Dserver.port=8090 -jar sentinel-dashboard-1.8.1.jar

在这里插入图片描述
启动成功后访问http://localhost:8080页面,就可以看到sentinel的控制台了,输入默认的用户名和密码 sentinel
在这里插入图片描述

一开始进来是空白的,这时候他没有监控到任何的服务,因为这时候我们还没有整合到项目中。

在这里插入图片描述
在这里插入图片描述

<!--sentinel-->
<dependency>
    <groupId>com.alibaba.cloud</groupId> 
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

在这里插入图片描述

server:
  port: 8082
spring:
  cloud: 
    sentinel:
      transport:
        dashboard: localhost:8080

在这里插入图片描述

打开浏览器,访问http://localhost:8088/order/102,这样才能触发sentinel的监控。

然后再访问sentinel的控制台,查看效果:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

@GetMapping("/update")
    public String update() {
    return "更新库存成功";
}

@GetMapping("/select")
    public String select() {
    return "查询库存成功";
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

public void queryGoods(){
    System.out.println("查询商品");
}

在这里插入图片描述

@GetMapping("/query")
public String queryOrder() {
    // 查询商品
    orderService.queryGoods();
    // 查询订单
    System.out.println("查询订单");
    return "查询订单成功";
}

在这里插入图片描述

@GetMapping("/save")
public String saveOrder() {
    // 查询商品
    orderService.queryGoods();
    // 查询订单
    System.err.println("新增订单");
    return "新增订单成功";
}

在这里插入图片描述

@SentinelResource("goods")
public void queryGoods(){
   System.out.println("查询商品");
}

在这里插入图片描述

spring:
  cloud:
    sentinel:
      web-context-unify: false # 关闭context整合

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1)标记资源

给order-service中的OrderController中的/order/{orderId}资源添加注解:

@SentinelResource("hot")
@GetMapping("{orderId}")
public Order queryOrderByUserId(@PathVariable("orderId") Long orderId) {
        // 根据id查询订单并返回
        return orderService.queryOrderById(orderId);
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

feign:
  sentinel:
    enabled: true # 开启feign对sentinel的支持

在这里插入图片描述

package cn.itcast.feign.fallback;
import cn.itcast.feign.client.UserFeignClient;
import cn.itcast.feign.pojo.User;
import feign.hystrix.FallbackFactory;
import lombok.extern.log4j.Log4j2;
@Log4j2
public class UserClientFallback implements FallbackFactory<UserFeignClient> {
    @Override
    public UserFeignClient create(Throwable cause) {
        log.error("UserClientFallback create fallback err:{}",cause.getMessage());
        /*降级的方法,queryById调用异常后的兜底方案*/
        return new UserFeignClient() {
            @Override
            public User queryById(Long id) {
                return new User();
            }
        };
    }
}

在这里插入图片描述

package cn.itcast.feign.config;
import cn.itcast.feign.fallback.UserClientFallback;
import feign.Logger;
import org.springframework.context.annotation.Bean;
public class DefaultFeignConfiguration {
    @Bean
    public UserClientFallback setUserClientFallback(){
        return new UserClientFallback();
    }
}

在这里插入图片描述

package cn.itcast.feign.client;
import cn.itcast.feign.fallback.UserClientFallback;
import cn.itcast.feign.pojo.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@FeignClient(value = "user-service", fallbackFactory = UserClientFallback.class)
public interface UserFeignClient {
    @GetMapping("/user/{id}")
    User queryById(@PathVariable("id") Long id);
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package cn.itcast.user.service;
import cn.itcast.user.mapper.UserMapper;
import cn.itcast.user.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;
    public User queryById(Long id) {
        //模拟如果id为103的请求为慢查询 
        if(id == 3){
            try {
                Thread.sleep(60);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return userMapper.findById(id);
    }
}

在这里插入图片描述

3)测试

在浏览器访问:http://localhost:8082/order/103,快速刷新5次,可以发现:

第一次正常响应

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package cn.itcast.user.service;
import cn.itcast.user.mapper.UserMapper;
import cn.itcast.user.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;

    public User queryById(Long id) {
        //模拟代码执行异常
        if(id == 3){
           throw new RuntimeException("模拟代码执行异常!!!");
        }

        return userMapper.findById(id);
    }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

public interface RequestOriginParser {
    /**
* 从请求request对象中获取origin,获取方式自定义
*/
    String parseOrigin(HttpServletRequest request);
}

在这里插入图片描述

package cn.itcast.order.sentinel;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.RequestOriginParser;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import javax.servlet.http.HttpServletRequest;

@Component
public class HeaderOriginParser implements RequestOriginParser {
    @Override
    public String parseOrigin(HttpServletRequest request) {
        // 1.获取请求头
        String origin = request.getHeader("origin");
        // 2.非空判断
        if (StringUtils.isEmpty(origin)) {
            origin = "blank";
        }
        return origin;
    }
}

在这里插入图片描述

spring:
  cloud:
    gateway:
      default-filters:
        - AddRequestHeader=origin,gateway

在这里插入图片描述
在这里插入图片描述

public interface BlockExceptionHandler {
    /**
     * 处理请求被限流、降级、授权拦截时抛出的异常:BlockException
     */
    void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception;
}

在这里插入图片描述
在这里插入图片描述

package cn.itcast.order.sentinel;

import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
public class SentinelExceptionHandler implements BlockExceptionHandler {
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
        String msg = "未知异常";
        int status = 429;

        if (e instanceof FlowException) {
            msg = "请求被限流了";
        } else if (e instanceof ParamFlowException) {
            msg = "请求被热点参数限流";
        } else if (e instanceof DegradeException) {
            msg = "请求被降级了";
        } else if (e instanceof AuthorityException) {
            msg = "没有权限访问";
            status = 401;
        }

        response.setContentType("application/json;charset=utf-8");
        response.setStatus(status);
        response.getWriter().println("{\"msg\": " + msg + ", \"status\": " + status + "}");
    }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值