0714~oauth2Day2~RabbitMQ死信队列理解

每次把登录之后把token存入客户端,这样服务端压力小,维护简单;

oauth2登录流程:

1.前端登录请求打过来后台用工具类发送请求,请求token;

2.把token等一系列参数封装成对象返回给前端;

3.前端把token,刷新token,登陆人用户名存入localstore;

4.前端设置前置拦截器,每次发送请求的时候携带token即可;

 1.前端登录请求打过来后台用工具类发送请求,请求token;

@Override
    public JSONResult toLogin(Login login) {
        //1.拼接参数发送请求token
        String url = "http://localhost:1050/oauth/token?client_id=admin&client_secret=123456&grant_type=password&redirect_uri=http://www.baidu.com&username=%s&password=%s";
        url=String.format(url,login.getUsername(),login.getPassword());
        System.out.println(url);
        HttpRequest post = HttpUtil.createPost(url);
        HttpResponse execute = post.execute();
        //2拿到json串
        String body = execute.body();
        AccessTokenDto dto = JSONObject.parseObject(body, AccessTokenDto.class);
        //3.封装token返回给前端
        return JSONResult.success(dto);
    }

 4.前端设置前置拦截器,每次发送请求的时候携带token即可;

//axios前置拦截器,每次请求都会走这里
axios.interceptors.request.use(config => {
    //如果已经登录了,每次都把token作为一个请求头传递过程
    if (localStorage.getItem('U-TOKEN')) {
        // 让每个请求携带token--['X-Token']为自定义key 请根据实际情况自行修改
        config.headers['Authorization'] = "Bearer " + localStorage.getItem('U-TOKEN');
    }
    console.debug('config',config)
    return config
}, error => {
    // Do something with request error
    Promise.reject(error)
});

 这时已经登录成功了,但此时发送请求的时候我们会看到401,没有权限访问,是因为网关zuul里面会默认屏蔽到敏感的头部信息,我们携带的token就被屏蔽了,此时需要在zuul的yml里设置参数:

zuul:
  sensitive-headers:

 在yml里面配置完即可携带token访问了;

设置无感刷新token,每次token时间过后请求都会刷新token,再获取一个新的token和刷新的token;

//刷新token
    @Override
    public JSONResult refreshToken(String refreshToken) {
        //通过刷新的token换取新的token
        //1.拼接路径
        String url = "http://localhost:1050/oauth/token?grant_type=refresh_token&refresh_token=%s&client_id=admin&client_secret=123456";
        url=String.format(url,refreshToken);
        //2.发送请求
        HttpRequest post = HttpUtil.createPost(url);
        String body = post.execute().body();
        //if(StringUtils.hasLength(body)){
        //
        //}
        //3.封装返回
        AccessTokenDto dto = JSONObject.parseObject(body, AccessTokenDto.class);
        if(dto.getRefreshToken()==null||dto.getRefreshToken()==""){
            return JSONResult.error();
        }
        return JSONResult.success(dto);
    }

 前端无感刷新token代码:

//刷新Token
async function getNewToken() {
    var refreshToken = localStorage.getItem('R-TOKEN');
    if(refreshToken){
        return await axios({
            url: '/auth/login/refreshToken?refreshToken=' + refreshToken,
            method: 'post',
            headers: {
                'Content-Type':'application/x-www-form-urlencoded'
            }
        })
    }else{
        alert("登录失效,请重新登录");
        localStorage.clear();
        router.replace({ path:"/login" });
    }
}

   RabbitMQ死信队列?

思路导图:

 死信队列,也有交换机,也有队列,也有消费者,和普通消费者没有区别;

RabbitMQ出现死信队列的原因:

1.消费消息的时候出现异常,消息被否认,走catch,走channel.basicNack,进入死信队列;

2.当在队列存活时间超过设置的TTL时间;

3.消费消息的队列超过队列最大长度;

 1.消费消息的时候出现异常,消息被否认,走catch,走channel.basicNack,进入死信队列;

@RabbitListener(queues = {"normalQueue"})
    public void handleOrderQueue(Message message, Channel channel) throws IOException {
        System.out.println("订单消费者类,拿到消息:" + new String(message.getBody()));

        try {
            //开始处理消息
                //模拟处理消息花费时间
                //Thread.sleep(6000);
                int i = 1/0;//模拟:处理消息时发生了某种异常
            //消息处理完毕,一定要记得手动ACK
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        } catch (Exception e){
            //发生异常,进行NACK
            channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
        }
    }

 如果普通消费者出现异常,则会走catch,走死信队列消费;

RabbitListener(queues = {"deadQueue"})
    public void handleDeadQueue(Message message, Channel channel) throws IOException {
        System.out.println("拿到死信消息:" + new String(message.getBody()));
        System.out.println("properties===" + message.getMessageProperties());

        /**
         * 这里取到消息后,根据实际业务规则,进行处理即可
         */
        try {
            //模拟处理消息花费时间
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //最后手动ACK
        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
    }

 2.当在队列存活时间超过设置的TTL时间;

 /***********************************************************************************
         * 2、发送带有过期时间的订单消息到RabbitMQ
        ***********************************************************************************/
        rabbitTemplate.convertAndSend(
                "normalExchange", //普通交换机名称
                "normalRoutingKey", //正常路由键
                JSONObject.toJSONString(dto));//消息
                //new MessagePostProcessor() { //定义消息属性处理类
                //    @Override
                //    public Message postProcessMessage(Message message) throws AmqpException {
                //        MessageProperties messageProperties = message.getMessageProperties();
                //        /**
                //         * 设置过期时间TTL(单位:毫秒)
                //         * 模拟:订单5秒内还未被消费,那么就进入死信队列
                //         */
                //        messageProperties.setExpiration("500000");
                //        //设置持久化
                //        messageProperties.setDeliveryMode(MessageDeliveryMode.PERSISTENT);
                //        return message;
                //    }
                //});

 3.消费消息的队列超过队列最大长度;

@Bean
    public Queue normalQueue() {

        Map<String, Object> arguments = new HashMap<>(2);
        /**
         * 设置死信相关参数
         * x-max-length、x-dead-letter-exchange、x-dead-letter-exchange等参数是固定写法
         */
        //设置队列长度
        arguments.put("x-max-length", 2);
        // 绑定死信交换机
        arguments.put("x-dead-letter-exchange", "deadExchange");
        // 绑定死信的路由key
        arguments.put("x-dead-letter-routing-key", "deadRoutingKey");
        return new Queue("normalQueue", true, false,false, arguments);
    }

 队列存货时间过长或队列长度超过都会进入死信队列;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值