gateway中记录请求和响应的时间

package com.lvhao.filters;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**

*/
@Component
public class CommonFilter implements GlobalFilter {

@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

    ServerHttpRequest request = exchange.getRequest().mutate().

            build();
    System.out.println("请求开始");
    return chain.filter(exchange.mutate().request(request).build()).then(Mono.fromRunnable(()->{
        System.out.println("1111111111111请求结束拉  ");
    }));
}

}

https://blog.csdn.net/github_38924695/article/details/105049708
在这里插入代码片

在这里插入图片描述

项目的基本介绍  
应用微服务
gateway网关
nginx
prometheus 普罗米修斯  应用服务的监控
nacos 注册配置中心
skywalking 做链路追踪  
oss 存储

限流一定是你所有项目开发完毕后 最终要做的事情  而不是一开始做的事情
普罗米修斯  做监控  监控你的服务发现是否有问题 如果有问题及时告警
通知运维或者开发人员去解决问题,业务系统的性能监控

skywalking 一次请求进来经过的所有组件 他全会帮你可视化展示出来
oss 做图片上传
数据库分库分表 使用Mycat  mycat做关系型数据库集群    . (Tidb  分布式数据库 原生的支持分布式场景 并发能力强一些) 
canal监听我们数据的Binlog 然后同步到redis中
		这样我们不用考虑我们数据是否一致的问题,我们吧数据写进mysql 中,然后canal会自动监听mysql的变动 然后吧数据写入redis中
		


在这里插入图片描述

gateway 允许跨域的访问  因为前端项目和gateway 不是一个端口了
跨域配置在网关上  配置跨域  网关中配置限流信息, 如何在微服务中拿到真实的ip

在这里插入图片描述

#########> 网关核心的功能就是过滤器
package cn.wolfcode.filters;

import cn.wolfcode.common.constants.CommonConstants;
import cn.wolfcode.redis.CommonRedisKey;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * 定义全局过滤器,功能如下:
 * 1.把客户端真实IP通过请求同的方式传递给微服务
 * 2.在请求头中添加FEIGN_REQUEST的请求头,值为0,标记请求不是Feign调用,而是客户端调用
 * 3.刷新Token的有效时间
 */
@Component
public class CommonFilter implements GlobalFilter {
    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        /**
         * pre拦截逻辑
         * 在请求去到微服务之前,做了两个处理
         * 1.把客户端真实IP通过请求同的方式传递给微服务
         * 2.在请求头中添加FEIGN_REQUEST的请求头,值为0,标记请求不是Feign调用,而是客户端调用
         */
        ServerHttpRequest request = exchange.getRequest().mutate().
                /*在过滤器中拿到ip*/
                header(CommonConstants.REAL_IP,exchange.getRequest().getRemoteAddress().getHostString()).
                header(CommonConstants.FEIGN_REQUEST_KEY,CommonConstants.FEIGN_REQUEST_FALSE).
                build();
        return chain.filter(exchange.mutate().request(request).build()).then(Mono.fromRunnable(()->{
            /**
             * post拦截逻辑
             * 在请求执行完微服务之后,需要刷新token在redis的时间
             * 判断token不为空 && Redis还存在这个token对于的key,这时候需要延长Redis中对应key的有效时间.
             * 没有带token 不会走这里
             */
            String token,redisKey;
            if(!StringUtils.isEmpty(token =exchange.getRequest().getHeaders().getFirst(CommonConstants.TOKEN_NAME))
                    && redisTemplate.hasKey(CommonRedisKey.USER_TOKEN.getRealKey(token))){
                // 我给key 许时间  每次续30分钟
                String s  = CommonRedisKey.USER_TOKEN.getRealKey(token);
                redisTemplate.expire(s  , CommonRedisKey.USER_TOKEN.getExpireTime(), CommonRedisKey.USER_TOKEN.getUnit());
            }
        }));
    }
}
Springcache的使用 
缓存的加载流程 一般如果我们的数据做缓存的话,怎么做的加载
三层缓存框架

在这里插入图片描述

加依赖pom

在这里插入图片描述

注解实现这一套操作,@EnableCaching 来实现
既可以使用redis 也可以采用gava
SpringCache+redis
我第一次@Cacheable 的时候  会走数据库查询 ,第二次就不会走了, 因为我加了缓存
我通过这个方式我存储在redis中就会产生一个key

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

我们存储在了redis 中了,我只需要加一个注解 就可以了  这就是Springcache的基本使用
我们默认redis 中设置30分钟
###################################################
我们还要维护一致性问题  数据库改变了  怎么删除redis
@cacheable 实现数据的缓存  我们看到的效果就是 第一次执行的时候执行sql
  {缓存时间 一致性时间 比方说我们配置了半个小时有效的
//
cacheConfig 配置了缓存默认的有效时间 30分钟
30分钟内 如果用户发生修改了 就会导致数据不一致
mysql和redis数据不一致的场景


双写 更新mysql 就把redis也更新了
删除 先删除redis  再更新数据库  cache

在这里插入图片描述

呢我如果30分钟不到的话,我执行了updateInfo (delete缓存)
我再执行userInfo  我缓存查不到就的从db中查询了 (select db) 然后放缓存

将用户信息和账号密码信息分开
redis+token 实现分布式session  更新session时间  在网关层面后置拦截刷新这个时间
#每访问一次都会刷新一次  每次访问一次  我都会刷新这个时间
# 秒杀需求分析

在这里插入图片描述

我们基于秒杀场次做秒杀  我们第一个要实现的就是秒杀列表 基于场次划分 比如说2点到5点
我们的表结构设计  秒杀场次====>秒杀商品

秒杀信息和商品信息是分开的 所以现在我们要怎么做
拆成2个服务 一般不能连表查询
我定时任务 我要把每天0时 我把今天要缓存的场次 以及秒杀信息 我先缓存下来
 秒杀要做缓存库存预热

基于场次--->找到对应秒杀场次的商品-->商品详情

商品可以在普通的订单详情页来购买,也可能在秒杀商品详情页购买
不同点,也就是要有一个秒杀商品信息(价格  秒杀商品)
t_seckill_product 秒杀商品信息
接下来我们要实现我们的秒杀信息
##>>秒杀流程

在这里插入图片描述

@RequireLogin  判断是否登录  注解实现是否已经登录

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

基础下单操作   如何利用jmeter来完成压力测试 我们要模拟抢购流程

在这里插入图片描述

show processList 查询正在运行的线程 /或者连接数
########>>>>>>>>..
我们目前遇到的问题
1.qps 不高
2.存在线程安全的问题 超卖 , 以及1个用户多个线程去测试 可以测试重复下单的问题

我们分析我们的接口问题,安全 我肯定不让他出现超卖的问题以及我们是不允许重复下单的
先分析一下这个问题是怎么产生的  秒杀整体流程

在这里插入图片描述

多线程秒杀情况

在这里插入图片描述

我们可以加sy锁

在这里插入图片描述

但是这个锁的话 目前可以实现但是颗粒度 太大了
 因为全锁住了   
>加锁的粒度能小就小  锁粒度太大会导致qps 降低的  影响程序整体性能 因为此时是秒杀场景

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值