ruoyi框架源码阅读之--redis配置

2023-11-20

redis配置



前言

redis的配置信息,记录一下,也可以拿来就用

一、引入依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

二、配置信息

spring:
  redis:
    # 地址
    host: localhost
    # 端口,默认为6379
    port: 6379
    # 数据库索引
    database: 0
    # 密码
    password: 
    # 连接超时时间
    timeout: 10s
    lettuce:
      pool:
        # 连接池中的最小空闲连接
        min-idle: 0
        # 连接池中的最大空闲连接
        max-idle: 8
        # 连接池的最大数据库连接数
        max-active: 8
        # #连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1ms

三、序列化文件

redis会乱码,就需要序列化,这里是序列化文件,可以直接拿来用
package com.ruoyi.framework.config;

import java.nio.charset.Charset;

import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONReader;
import com.alibaba.fastjson2.JSONWriter;

/**
 * Redis使用FastJson序列化
 * redis直接存中文会乱码,就需要序列化一下,这里是序列化的配置文件,在RedisConfig里面调用进行真正的序列化
 */
public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T> {
    public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");

    private Class<T> clazz;

    public FastJson2JsonRedisSerializer(Class<T> clazz) {
        super();
        this.clazz = clazz;
    }

    @Override
    public byte[] serialize(T t) throws SerializationException {
        if (t == null) {
            return new byte[0];
        }
        return JSON.toJSONString(t, JSONWriter.Feature.WriteClassName).getBytes(DEFAULT_CHARSET);
    }

    @Override
    public T deserialize(byte[] bytes) throws SerializationException {
        if (bytes == null || bytes.length <= 0) {
            return null;
        }
        String str = new String(bytes, DEFAULT_CHARSET);

        return JSON.parseObject(str, clazz, JSONReader.Feature.SupportAutoType);
    }
}

四、redis配置文件

package com.ruoyi.framework.config;

import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * redis配置
 *
 * @author ruoyi
 */
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {

    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);

        // FastJson2JsonRedisSerializer对所有对象序列化
        FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class);

        // 使用StringRedisSerializer来序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(serializer);

        // Hash的key也采用StringRedisSerializer的序列化方式
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(serializer);

        template.afterPropertiesSet();
        return template;
    }

    // redis接口限流,好东西啊,
    @Bean
    public DefaultRedisScript<Long> limitScript() {
        DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();
        redisScript.setScriptText(limitScriptText());
        redisScript.setResultType(Long.class);
        return redisScript;
    }

    /**
     * 限流脚本,脚本的意思就是获取传进来的 count time,根据传进来的 ip-类名-方法名 这个类型的key获取对应的数据current。和现有的count比,大就返回current。没有的话就给current+1,
     * 然后判断这个current是不是第一次出现,就是他的值是不是1,是的话说明是刚创建的,就给他搞个过期时间(传进来参数的默认值是120s)。不是就直接返回current。
     */
    private String limitScriptText() {
        return "local key = KEYS[1]\n" +
                "local count = tonumber(ARGV[1])\n" +
                "local time = tonumber(ARGV[2])\n" +
                "local current = redis.call('get', key);\n" +
                "if current and tonumber(current) > count then\n" +
                "    return tonumber(current);\n" +
                "end\n" +
                "current = redis.call('incr', key)\n" +
                "if tonumber(current) == 1 then\n" +
                "    redis.call('expire', key, time)\n" +
                "end\n" +
                "return tonumber(current);";
    }
}

五、redis工具类

package com.ruoyi.common.core.redis;

import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;

/**
 * spring redis 工具类
 *
 * @author ruoyi
 **/
@Component
public class RedisCache {
    @Autowired
    public RedisTemplate redisTemplate;

    /**
     * 缓存基本的对象,Integer、String、实体类等
     *
     * @param key   缓存的键值
     * @param value 缓存的值
     */
    public <T> void setCacheObject(final String key, final T value) {
        redisTemplate.opsForValue().set(key, value);
    }

    /**
     * 缓存基本的对象,Integer、String、实体类等
     *
     * @param key      缓存的键值
     * @param value    缓存的值
     * @param timeout  时间
     * @param timeUnit 时间颗粒度
     */
    public <T> void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit) {
        redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
    }

    /**
     * 设置有效时间
     *
     * @param key     Redis键
     * @param timeout 超时时间
     * @return true=设置成功;false=设置失败
     */
    public boolean expire(final String key, final long timeout) {
        return expire(key, timeout, TimeUnit.SECONDS);
    }

    /**
     * 设置有效时间
     *
     * @param key     Redis键
     * @param timeout 超时时间
     * @param unit    时间单位
     * @return true=设置成功;false=设置失败
     */
    public boolean expire(final String key, final long timeout, final TimeUnit unit) {
        return redisTemplate.expire(key, timeout, unit);
    }

    /**
     * 获取有效时间
     *
     * @param key Redis键
     * @return 有效时间
     */
    public long getExpire(final String key) {
        return redisTemplate.getExpire(key);
    }

    /**
     * 判断 key是否存在
     *
     * @param key 键
     * @return true 存在 false不存在
     */
    public Boolean hasKey(String key) {
        return redisTemplate.hasKey(key);
    }

    /**
     * 获得缓存的基本对象。
     *
     * @param key 缓存键值
     * @return 缓存键值对应的数据
     */
    public <T> T getCacheObject(final String key) {
        ValueOperations<String, T> operation = redisTemplate.opsForValue();
        return operation.get(key);
    }

    /**
     * 删除单个对象
     *
     * @param key
     */
    public boolean deleteObject(final String key) {
        return redisTemplate.delete(key);
    }

    /**
     * 删除集合对象
     *
     * @param collection 多个对象
     * @return
     */
    public boolean deleteObject(final Collection collection) {
        return redisTemplate.delete(collection) > 0;
    }

    /**
     * 缓存List数据
     *
     * @param key      缓存的键值
     * @param dataList 待缓存的List数据
     * @return 缓存的对象
     */
    public <T> long setCacheList(final String key, final List<T> dataList) {
        Long count = redisTemplate.opsForList().rightPushAll(key, dataList);
        return count == null ? 0 : count;
    }

    /**
     * 获得缓存的list对象
     *
     * @param key 缓存的键值
     * @return 缓存键值对应的数据
     */
    public <T> List<T> getCacheList(final String key) {
        return redisTemplate.opsForList().range(key, 0, -1);
    }

    /**
     * 缓存Set
     *
     * @param key     缓存键值
     * @param dataSet 缓存的数据
     * @return 缓存数据的对象
     */
    public <T> BoundSetOperations<String, T> setCacheSet(final String key, final Set<T> dataSet) {
        BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key);
        Iterator<T> it = dataSet.iterator();
        while (it.hasNext()) {
            setOperation.add(it.next());
        }
        return setOperation;
    }

    /**
     * 获得缓存的set
     *
     * @param key
     * @return
     */
    public <T> Set<T> getCacheSet(final String key) {
        return redisTemplate.opsForSet().members(key);
    }

    /**
     * 缓存Map
     *
     * @param key
     * @param dataMap
     */
    public <T> void setCacheMap(final String key, final Map<String, T> dataMap) {
        if (dataMap != null) {
            redisTemplate.opsForHash().putAll(key, dataMap);
        }
    }

    /**
     * 获得缓存的Map
     *
     * @param key
     * @return
     */
    public <T> Map<String, T> getCacheMap(final String key) {
        return redisTemplate.opsForHash().entries(key);
    }

    /**
     * 往Hash中存入数据
     *
     * @param key   Redis键
     * @param hKey  Hash键
     * @param value 值
     */
    public <T> void setCacheMapValue(final String key, final String hKey, final T value) {
        redisTemplate.opsForHash().put(key, hKey, value);
    }

    /**
     * 获取Hash中的数据
     *
     * @param key  Redis键
     * @param hKey Hash键
     * @return Hash中的对象
     */
    public <T> T getCacheMapValue(final String key, final String hKey) {
        HashOperations<String, String, T> opsForHash = redisTemplate.opsForHash();
        return opsForHash.get(key, hKey);
    }

    /**
     * 获取多个Hash中的数据
     *
     * @param key   Redis键
     * @param hKeys Hash键集合
     * @return Hash对象集合
     */
    public <T> List<T> getMultiCacheMapValue(final String key, final Collection<Object> hKeys) {
        return redisTemplate.opsForHash().multiGet(key, hKeys);
    }

    /**
     * 删除Hash中的某条数据
     *
     * @param key  Redis键
     * @param hKey Hash键
     * @return 是否成功
     */
    public boolean deleteCacheMapValue(final String key, final String hKey) {
        return redisTemplate.opsForHash().delete(key, hKey) > 0;
    }

    /**
     * 获得缓存的基本对象列表
     *
     * @param pattern 字符串前缀
     * @return 对象列表
     */
    public Collection<String> keys(final String pattern) {
        return redisTemplate.keys(pattern);
    }
}

六、redis接口限流–注解实现

package com.ruoyi.framework.aspectj;

import java.lang.reflect.Method;
import java.util.Collections;
import java.util.List;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.stereotype.Component;
import com.ruoyi.common.annotation.RateLimiter;
import com.ruoyi.common.enums.LimitType;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.ip.IpUtils;

/**
 * 限流处理
 */
@Aspect  // 把这个类加入到容器中,然后再添加上注解就可以就可以看成是一个切面容器。
@Component
public class RateLimiterAspect {
    private static final Logger log = LoggerFactory.getLogger(RateLimiterAspect.class);

    // 引入redis模板
    private RedisTemplate<Object, Object> redisTemplate;

    // 引入redis限流脚本
    private RedisScript<Long> limitScript;

    // 这玩意没用到,啥玩意,还有上面的两个为啥不从容器里面拿?
    @Autowired
    public void setRedisTemplate1(RedisTemplate<Object, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    // 这玩意没用到
    @Autowired
    public void setLimitScript(RedisScript<Long> limitScript) {
        this.limitScript = limitScript;
    }

    // 方法之前用 @RateLimiter 修饰的方法,再执行之前会调用这个方法模块
    @Before("@annotation(rateLimiter)")
    public void doBefore(JoinPoint point, RateLimiter rateLimiter) throws Throwable {
        // 获取注解里面的参数,可能是自定义参数,要不就是默认参数
        int time = rateLimiter.time();
        int count = rateLimiter.count();

        // 获取限流的 ip-类名-方法名
        String combineKey = getCombineKey(rateLimiter, point);

        // emm,说白了这样获取的list中,有切只有一个值,多一个少一个都报错
        List<Object> keys = Collections.singletonList(combineKey);
        try {
            // 带着脚本文件去执行,获取到数量。脚本中写法一般来说不会返回null,写了保险点吧
            Long number = redisTemplate.execute(limitScript, keys, count, time);
            if (StringUtils.isNull(number) || number.intValue() > count) {
                throw new ServiceException("访问过于频繁,请稍候再试");
            }
            log.info("限制请求'{}',当前请求'{}',缓存key'{}'", count, number.intValue(), combineKey);
        } catch (ServiceException e) {
            throw e;
        } catch (Exception e) {
            throw new RuntimeException("服务器限流异常,请稍候再试");
        }
    }

    // 获取限流的 ip-类名-方法名
    public String getCombineKey(RateLimiter rateLimiter, JoinPoint point) {
        StringBuffer stringBuffer = new StringBuffer(rateLimiter.key());

        // 如果限流类型是ip,那就把IP也加进去
        if (rateLimiter.limitType() == LimitType.IP) {
            stringBuffer.append(IpUtils.getIpAddr()).append("-");
        }
        // 获取被注解标注的方法信息
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();

        // 获取方法所在的类对象
        Class<?> targetClass = method.getDeclaringClass();
        stringBuffer.append(targetClass.getName()).append("-").append(method.getName());
        return stringBuffer.toString();
    }
}

七、redis接口限流–注解代码

package com.ruoyi.common.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.enums.LimitType;

/**
 * 限流注解
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RateLimiter
{
    /**
     * 限流key
     */
    public String key() default CacheConstants.RATE_LIMIT_KEY;

    /**
     * 限流时间,单位秒
     */
    public int time() default 60;

    /**
     * 限流次数
     */
    public int count() default 100;

    /**
     * 限流类型
     */
    public LimitType limitType() default LimitType.DEFAULT;
}

总结

应该可以拿来直接用,使用脚本限流也可以,限流用的不多的情况下方便一点,不过 一般来说nginx、getway限流好一些吧。Hystrix也不错。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ruoyi框架源码阅读之--redis配置 的相关文章

  • 将 Uri 转换为字符串以及将字符串转换为 Uri

    我正在开发一些应用程序 它允许从 SD 卡中选择图像 将其保存到数据库中并为 ImageView 设置该值 我需要知道将 uri 转换为字符串以及将字符串转换为 uri 的方法 现在我使用了 Uri 的 getEncodedPath 方法
  • 如何从二维数组中仅打印单个列?

    我正在编写这个程序 我必须只打印二维数组的一列 而不是两者 for int i 0 i lt sjf length i for int j 0 j lt sjf i length j System out printf 5d 4s sjf
  • 如何通过双击图标来执行JAVA程序?

    我写了一个java程序 现在我想在没有 IDE Eclipse 等的情况下打开我的控制台 java 应用程序 只需双击桌面上的可执行版本即可 我已将 java 项目导出为 Runnable JAR 文件 但无法打开 当我尝试使用cmd打开应
  • 可以使用注解进行代码注入吗?

    我意识到这可能是一个已经被提出和回答的问题 但请耐心等待 我想知道是否可以使用注释将代码注入到类编译时 典型的示例是为对象的成员生成 getter 和 setter 这并不完全是我所需要的 但它可以说明基本思想 现在在互联网上我得到的基本答
  • 正则表达式查找两个字符之间的内部匹配

    环境 Java 我想匹配两个字符串之间的字符 这是一个例子 foo
  • 在 Spring Security 中创建自定义 PostAuthorize 方法

    我正在尝试创建一个自定义方法 用于预 后授权调用 如下所示 public class CustomLSecurityExpressionHandler extends DefaultMethodSecurityExpressionHandl
  • 从java应用程序发送电子邮件时出现异常:中继被拒绝

    我们正在使用 Spring Mail 从 java 应用程序发送电子邮件 org springframework mail javamail JavaMailSenderImpl Spring电子邮件配置是
  • Java Swing 自定义形状(2D 图形)

    我需要绘制自定义形状 现在 当用户单击面板上的几个点时 我使用多边形创建一个形状 public void mouseClicked MouseEvent e polygon addPoint e getX e getY repaint 但我
  • Bean 属性不可读或具有无效的 getter 方法

    因此 我的任务是为注册表路由编写一个简单的 Web 应用程序 使用 Spring MVC 所以我有 路线 类 我想在其中保留起点 终点和中间点列表 但我不明白如何将值从 jsp 放入列表 例如使用 jstl 所以我决定解析一个字符串 pub
  • 如何将多个值存储到一个键(java)

    我搜索一个可以存储多个键值对的数据结构 数据基本上是这样的 1 value 1 2 value 2 于是我想到了使用HashMap 遗憾的是 这对我不起作用 因为一个键可能会出现多个值 在上面的例子中 1 value 2 可能是另一个条目
  • 如何用Java捕获音频数据

    我想访问我的麦克风用 Java 录制的音频数据 我该怎么做呢 我的目标是保存录制的音频数据并同时向用户播放 如果您不需要 JMF 中的任何附加功能 我会避免使用它 因为开发已经停止 最后一个版本是 2004 年 它与 Java 6 存在兼容
  • 在同一个容器但不同的耳朵中使用本地EJB

    我正在尝试在同一个 Glassfish 但不同的耳朵中使用本地 EJB 但是Glassfish找不到本地EJB或者无法消费 我读到了这个 根据 JavaEE 教程 Local bean 的客户端 必须在与其访问的企业 bean 相同的 JV
  • Jlist 自定义渲染器

    我正在尝试添加一个我猜你会称其为列表中每个项目的子列表 我构建了一个自定义渲染器 它提供以下输出 正如你所看到的 有些东西不对劲 我没能找到问题的答案 我猜我需要更改面板布局中的某些内容才能获得正确的结果 但不知道是什么 https i s
  • Java 8 中函数类型全等 lambda 表达式的用法

    我对 的定义和用法感到困惑 Stream collect Supplier
  • 使用 testcontainer 作为 Dockerfile 的一部分运行测试

    我的 dockerfile 看起来像这样 FROM maven 3 jdk 11 slim COPY pom xml COPY src src RUN mvn clean install 这意味着构建的一部分是单元测试的执行 一些单元测试使
  • 是否有适合 Java 1.4 和 SE (Swing) 应用程序的优秀 DI 框架?

    我正在寻找一个适用于在 JDK 1 4 下运行的 Java SE Swing 应用程序的依赖注入框架 有没有我可以使用的推荐 DI 框架 Guice 和其他基于注释的框架已经退出 我不想搞乱像 Retroweaver 这样的东西 另外 Sp
  • JavaFX颜色选择器的语言

    有没有办法改变语言ColorPicker的文本 例如 自定义颜色 当前颜色 新颜色 色相 饱和度 亮度 不透明度 保存 使用 取消 编辑 以下答案适合那些需要更多内容的人exotic语言 如果您使用其中之一 de es fr it ja k
  • Java 需要一个 FileSet 包/类

    任何人都可以建议 Java 中的 FileSet 包 类吗 我所说的 FileSet 是指文件和目录的集合以及正则表达式支持的包含和排除规则 类似于 Apache Ant 谢谢 Apache 公共 IO文件工具 http commons a
  • 无法以联觉方式绘制像素、Pi 数

    我想将 pi 数字的每个数字打印为彩色像素 因此 我得到一个带有 pi 数字的输入 然后将其解析为一个列表 每个节点包含一个数字 我知道 稍后我将使用一个数组 但我从来没有把它画到屏幕上 有人能帮我看看我错在哪里吗 import java
  • Java中不同格式的字符串解析为日期

    我想转换String to Date以不同的格式 例如 我从用户那里得到 String fromDate 19 05 2009 i e dd MM yyyy format 我想转换这个fromDate作为日期对象 yyyy MM dd fo

随机推荐

  • pip相关命令

    查看当前pip源 pip config list 更改pip源 pip config set global index url 清华源网址 升级pip python m pip install upgrade pip 安装模块 pip in
  • vue3中路由的使用

    路由是什么 vue中的路由是用来管理页面切换或跳转的一种方式 Vue Router是vue官方的路由管理器 1 Vue Router的安装 需要先弄好npm npm install vue router 4 s 在安装完成之后 开始尝试简单
  • BT蓝牙协议 — HFP/HSP的关联与区别

    一 前言 有时 我们能看到有的蓝牙产品标明支持HFP HSP 而有的产品却只标注了支持HFP 那么HFP or HSP是什么呢 又有什么样的关系呢 二 HSP协议 HSP Headset Profile 耳机模式 仅实现了最基本的通话操作
  • c语言判断一个数是否为偶数

    include
  • 图解五种磁盘调度算法, FCFS, SSTF, SCAN, C-SCAN, LOOK

    一 FCFS 调度 先来先服务 磁盘调度的最简单形式当然是先来先服务 FCFS 算法 虽然这种算法比较公平 但是它通常并不提供最快的服务 例如 考虑一个磁盘队列 其 I O 请求块的柱面的顺序如下 98 183 37 122 14 124
  • 华为OD机试 Python 【TLV解析】

    题目 题目简述 你收到了一串由两端设备传递的TLV格式的消息 现在你需要根据这串消息生成一个对应的 tag length valueOffset 列表 详细说明 这串消息其实是由许多小组成的 每一小组里包含了tag length value
  • win可以上网,但是右下方显示“无internet链接“

    使用了下面链接的方法 成功解决 Win10可以联网但右下角显示无法连接到Internet怎办 首先 打开控制面板 control 右上角 将查看方式切换为小图标 调整计算机的设置下 找到并点击网络和共享中心 网络和共享中心窗口 左侧点击更改
  • 苹果鼠标win10不能滑动_解决WIN10使用苹果鼠标滚轮不能使用的问题

    这个花费了蛮多时间却解决不了 网上流行各种各样的尝试 还有很多的安装包 都试了一遍 无一解决 绝望的时候 看到有个网友发的云盘链接 感谢 花小柏 一安装即可使用 太感谢了 最后也分享给大家 链接 https pan baidu com s
  • Linux运维脚本

    20200911 这里记录一些平时使用的脚本 免密登陆什么的 免密登陆 bin bash f root ssh id rsa pub ssh keygen t rsa P f root ssh id rsa gt dev null expe
  • 【2023版】最新stable diffusion安装教程,一键安装,永久使用,stable diffusion下载安装教程!

    关于现在非常红火的AI绘画 很多感兴趣的人不知道如何入手 如果你的电脑配置足够好 那么不要犹豫 让我来教你如何在本地电脑全免费运行当下最强大的AI绘画工具 Stable Diffusion 吧 一 Stable Diffusion 是什么
  • cmake Targets:CMake如何构建简单的Target

    CMake有三个基本命令 用于定义CMake Target 分别是 add executable 构建exe add library 构建库 add custom target 自定义构建目标在camke构建阶段运行的 add execut
  • go 进阶 go-zero相关: 七. 拦截器与熔断拦截器

    目录 一 拦截器的基础使用 1 服务端拦截器 2 客户端拦截器 二 拦截器底层底层执行原理 三 go zero默认添加的拦截器 客户端 1 熔断器拦截器 BreakerInterceptor 服务端 一 拦截器的基础使用 在go zero
  • 设计模式-享元模式

    一 概念 如果在一个系统中存在多个相同的对象 那么只需要共享一份对象的拷贝 而不必为每一次使用都创建新的对象 目的是提高系统性能 上面的概念乍一听好像单例模式其实不是 单例模式只保存一个对象 但是这里可以有很多个不同对象 但是每个对象只有一
  • ChatGPT火了,将给网络安全行业带来什么影响?

    ChatGPT是一个基于人工智能的聊天机器人 它是使用OpenAI的GPT技术构建的 能够根据用户输入的语言自动生成响应 ChatGPT可以回答各种问题 提供建议和支持 以及进行闲聊和娱乐等 它旨在为用户提供一个方便 快捷 智能的交互方式
  • 蓝桥杯-稍大的字符串

    题目 标题 稍大的串 串可以按照字典序进行比较 例如 abcd 小于 abdc 如果给定一个串 打乱组成它的字母 重新排列 可以得到许多不同的串 在这些不同的串中 有一个串刚好给定的串稍微大一些 科学地说 它是大于已知串的所有串中最小的串
  • filter函数的用法_动态数组函数系列5

    FILTER函数是筛选函数 就是在源数据中按照我们的条件筛选出我们想要的数据 除了常规的数据筛选 还可以进行多条件的 且 或者 或 的筛选 下面我们来看看这个FILTER函数怎么用 如果不想看文字 直接拉到最后看视频吧 FILTER函数语法
  • 属性,服务,事件

    属性 即设备支持的可读和 或可设置的参数功能 以一个灯为例 灯的开关就可以定义为一个属性 用户可以读取该属性的当前数值来得知灯的开关状态 也可以通过对该属性进行设置来打开或者关闭这个灯 服务 如果设备的某个功能只能设置 不能获取 那么可以将
  • 微服务系统硬件要求_全面解析微服务系统监控分层,啃透服务治理核心!

    架构师 JiaGouX 我们都是架构师 架构未来 你来不来 前言 监控 是微服务治理的一个重要环节 监控系统的完善程度直接影响到我们微服务质量的好坏 我们的微服务在线上运行时 有没有一套完善的监控体系能去了解到它的健康情况 这对整个系统的可
  • 【NPS 服务器搭建】2. 客户端完全手册

    场景 内网机器需要提供远程访问 如SSH 环境 1 一台独立ip的VPS 如阿里云服务器 2 一台内网的主机 windows linux 步骤 1 服务端中 新建客户端 2 服务端中 新建通道 2 1 点击进入通道管理 2 2 新增通道 1
  • ruoyi框架源码阅读之--redis配置

    redis配置 文章目录 redis配置 前言 一 引入依赖 二 配置信息 三 序列化文件 四 redis配置文件 五 redis工具类 六 redis接口限流 注解实现 七 redis接口限流 注解代码 总结 前言 redis的配置信息