当前位置: 首页 > news >正文

自适应网站 seo怎么做百度快速seo优化

自适应网站 seo怎么做,百度快速seo优化,青田网站做服装找工作,晚上偷偷看b站软件推荐文章目录 Redis Lua 限流实现1. 导入依赖2. 配置application.properties3. 配置RedisTemplate实例4. 定义限流类型枚举类5. 自定义注解6. 切面代码实现7. 控制层实现8. 测试 相比 Redis事务, Lua脚本的优点: 减少网络开销:使用Lua脚本&…

文章目录

    • Redis + Lua 限流实现
      • 1. 导入依赖
      • 2. 配置application.properties
      • 3. 配置RedisTemplate实例
      • 4. 定义限流类型枚举类
      • 5. 自定义注解
      • 6. 切面代码实现
      • 7. 控制层实现
      • 8. 测试

相比 Redis事务, Lua脚本的优点:

  • 减少网络开销:使用Lua脚本,无需向Redis 发送多次请求,执行一次即可,减少网络传输
  • 原子操作:Redis 将整个Lua脚本作为一个命令执行,原子,无需担心并发
  • 复用:Lua脚本一旦执行,会永久保存 Redis 中,,其他客户端可复用

Redis + Lua 限流实现

技术栈:自定义注解aopRedis + Lua 实现限流

1. 导入依赖

 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId></dependency><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>30.1-jre</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies>

2. 配置application.properties

spring.redis.host=10.1.61.121
spring.redis.port=6379
spring.redis.password=123456

3. 配置RedisTemplate实例

package com.lihw.lihwtestboot.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.io.Serializable;@Configuration
public class RedisLimiterHelper {@Beanpublic RedisTemplate<String, Serializable> limitRedisTemplate(LettuceConnectionFactory redisConnectionFactory) {RedisTemplate<String, Serializable> template = new RedisTemplate<>();template.setKeySerializer(new StringRedisSerializer());template.setValueSerializer(new GenericJackson2JsonRedisSerializer());template.setConnectionFactory(redisConnectionFactory);return template;}
}

4. 定义限流类型枚举类

package com.lihw.lihwtestboot.schemas;/*** @explain: 限流类型* @author: lihewei
*/
public enum LimitType {/*** 自定义key*/CUSTOMER,/*** 请求者IP*/IP;
}

5. 自定义注解

  • period表示请求限制时间段
  • count表示在period这个时间段内允许放行请求的次数。
  • limitType代表限流的类型,可以根据请求的IP自定义key,如果不传limitType属性则默认用方法名作为默认key。
package com.lihw.lihwtestboot.anno;
import com.lihw.lihwtestboot.schemas.LimitType;
import java.lang.annotation.*;/*** @explain: 自定义限流注解* @author: lihewei
*/
@Target({ElementType.METHOD, ElementType.TYPE})//作用于方法上
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Limit {/*** 名字*/String name() default "";/*** key*/String key() default "";/*** Key的前缀*/String prefix() default "";/*** 给定的时间范围 单位(秒)*/int period();/*** 一定时间内最多访问次数*/int count();/*** 限流的类型(用户自定义key 或者 请求ip)*/LimitType limitType() default LimitType.CUSTOMER;
}

6. 切面代码实现

package com.lihw.lihwtestboot.aop;
import com.google.common.collect.ImmutableList;
import com.lihw.lihwtestboot.anno.Limit;
import com.lihw.lihwtestboot.schemas.LimitType;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.lang.reflect.Method;/*** @explain: 限流切面实现* @author: lihewei
*/
@Aspect
@Configuration
public class LimitInterceptor {private static final Logger logger = LoggerFactory.getLogger(LimitInterceptor.class);private static final String UNKNOWN = "unknown";private final RedisTemplate<String, Serializable> limitRedisTemplate;@Autowiredpublic LimitInterceptor(RedisTemplate<String, Serializable> limitRedisTemplate) {this.limitRedisTemplate = limitRedisTemplate;}/*** @author lihw* @description 切面*/@Around("execution(public * *(..)) && @annotation(com.lihw.lihwtestboot.anno.Limit)")public Object interceptor(ProceedingJoinPoint pjp) {MethodSignature signature = (MethodSignature) pjp.getSignature();Method method = signature.getMethod();Limit limitAnnotation = method.getAnnotation(Limit.class);LimitType limitType = limitAnnotation.limitType();String name = limitAnnotation.name();String key;int limitPeriod = limitAnnotation.period();int limitCount = limitAnnotation.count();/*** 根据限流类型获取不同的key ,如果不传我们会以方法名作为key*/switch (limitType) {case IP:key = getIpAddress();break;case CUSTOMER:key = limitAnnotation.key();break;default:key = StringUtils.upperCase(method.getName());}ImmutableList<String> keys = ImmutableList.of(StringUtils.join(limitAnnotation.prefix(), key));try {String luaScript = buildLuaScript();RedisScript<Number> redisScript = new DefaultRedisScript<>(luaScript, Number.class);Number count = limitRedisTemplate.execute(redisScript, keys, limitCount, limitPeriod);logger.info("Access try count is {} for name={} and key = {}", count, name, key);if (count != null && count.intValue() <= limitCount) {return pjp.proceed();} else {throw new RuntimeException("You have been dragged into the blacklist");}} catch (Throwable e) {if (e instanceof RuntimeException) {throw new RuntimeException(e.getLocalizedMessage());}throw new RuntimeException("server exception");}}/*** @description 编写 redis Lua 限流脚本*/public String buildLuaScript() {StringBuilder lua = new StringBuilder();lua.append("local c");lua.append("\nc = redis.call('get',KEYS[1])");// 调用不超过最大值,则直接返回lua.append("\nif c and tonumber(c) > tonumber(ARGV[1]) then");lua.append("\nreturn c;");lua.append("\nend");// 执行计算器自加lua.append("\nc = redis.call('incr',KEYS[1])");lua.append("\nif tonumber(c) == 1 then");// 从第一次调用开始限流,设置对应键值的过期lua.append("\nredis.call('expire',KEYS[1],ARGV[2])");lua.append("\nend");lua.append("\nreturn c;");return lua.toString();}/*** @description 获取id地址*/public String getIpAddress() {HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();String ip = request.getHeader("x-forwarded-for");if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {ip = request.getHeader("Proxy-Client-IP");}if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {ip = request.getHeader("WL-Proxy-Client-IP");}if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {ip = request.getRemoteAddr();}return ip;}
}

7. 控制层实现

package com.lihw.lihwtestboot.controller;import com.lihw.lihwtestboot.anno.Limit;
import com.lihw.lihwtestboot.schemas.LimitType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.atomic.AtomicInteger;@RestController
public class LimiterController {private static final AtomicInteger ATOMIC_INTEGER_1 = new AtomicInteger();private static final AtomicInteger ATOMIC_INTEGER_2 = new AtomicInteger();private static final AtomicInteger ATOMIC_INTEGER_3 = new AtomicInteger();@Limit(key = "limitTest", period = 10, count = 3)@GetMapping("/limitTest1")public int testLimiter1() {return ATOMIC_INTEGER_1.incrementAndGet();}@Limit(key = "customer_limit_test", period = 10, count = 3, limitType = LimitType.CUSTOMER)@GetMapping("/limitTest2")public int testLimiter2() {return ATOMIC_INTEGER_2.incrementAndGet();}@Limit(key = "ip_limit_test", period = 10, count = 3, limitType = LimitType.IP)@GetMapping("/limitTest3")public int testLimiter3() {return ATOMIC_INTEGER_3.incrementAndGet();}
}

8. 测试

10s内连续请求三次以上拒绝请求


文章转载自:
http://columbary.kjrp.cn
http://bushmanship.kjrp.cn
http://stodge.kjrp.cn
http://sophomorical.kjrp.cn
http://nucleal.kjrp.cn
http://misbound.kjrp.cn
http://fungi.kjrp.cn
http://helleri.kjrp.cn
http://gorm.kjrp.cn
http://subornative.kjrp.cn
http://clift.kjrp.cn
http://bogle.kjrp.cn
http://melanesia.kjrp.cn
http://classicist.kjrp.cn
http://lucknow.kjrp.cn
http://pif.kjrp.cn
http://replume.kjrp.cn
http://talented.kjrp.cn
http://intussuscept.kjrp.cn
http://hilary.kjrp.cn
http://neighbourly.kjrp.cn
http://dorado.kjrp.cn
http://rabble.kjrp.cn
http://theoretic.kjrp.cn
http://vacuity.kjrp.cn
http://beatster.kjrp.cn
http://avidly.kjrp.cn
http://yamulka.kjrp.cn
http://christadelphian.kjrp.cn
http://bacteriostasis.kjrp.cn
http://pecuniary.kjrp.cn
http://gamme.kjrp.cn
http://laconicism.kjrp.cn
http://validate.kjrp.cn
http://psoriasis.kjrp.cn
http://realise.kjrp.cn
http://reship.kjrp.cn
http://cenis.kjrp.cn
http://khamsin.kjrp.cn
http://fuller.kjrp.cn
http://meanness.kjrp.cn
http://eisteddfod.kjrp.cn
http://droob.kjrp.cn
http://bessemerize.kjrp.cn
http://ichthyosaur.kjrp.cn
http://hypermetropia.kjrp.cn
http://opec.kjrp.cn
http://incongruously.kjrp.cn
http://chlorinous.kjrp.cn
http://aceldama.kjrp.cn
http://ala.kjrp.cn
http://earl.kjrp.cn
http://antistreptococcal.kjrp.cn
http://exhibitor.kjrp.cn
http://inventer.kjrp.cn
http://unsuspectingly.kjrp.cn
http://professedly.kjrp.cn
http://synaeresis.kjrp.cn
http://favourer.kjrp.cn
http://yeanling.kjrp.cn
http://expressman.kjrp.cn
http://larceny.kjrp.cn
http://haploid.kjrp.cn
http://atheistic.kjrp.cn
http://favoring.kjrp.cn
http://lase.kjrp.cn
http://nipa.kjrp.cn
http://menfolk.kjrp.cn
http://truckline.kjrp.cn
http://prunella.kjrp.cn
http://excuria.kjrp.cn
http://plinth.kjrp.cn
http://lambdoid.kjrp.cn
http://putridness.kjrp.cn
http://camorrista.kjrp.cn
http://plantsman.kjrp.cn
http://adaptability.kjrp.cn
http://acoustician.kjrp.cn
http://interventionism.kjrp.cn
http://reptilian.kjrp.cn
http://fordless.kjrp.cn
http://wrestle.kjrp.cn
http://sporicidal.kjrp.cn
http://vector.kjrp.cn
http://varsovian.kjrp.cn
http://meiofauna.kjrp.cn
http://tonnish.kjrp.cn
http://morel.kjrp.cn
http://cataplexy.kjrp.cn
http://saceur.kjrp.cn
http://northeastwardly.kjrp.cn
http://orogeny.kjrp.cn
http://josser.kjrp.cn
http://javari.kjrp.cn
http://albertite.kjrp.cn
http://caliber.kjrp.cn
http://heather.kjrp.cn
http://loun.kjrp.cn
http://septivalent.kjrp.cn
http://docility.kjrp.cn
http://www.15wanjia.com/news/93673.html

相关文章:

  • 做淘宝客要有网站吗建站流程
  • 汕头网站推广找哪里重要新闻
  • 网站建设费用表html底部友情链接代码
  • 长春网站制作哪里好腾讯企点
  • 网站建设的行业资讯竞价托管代运营公司
  • 中国做美国网站的翻译兼职可口可乐软文范例
  • 做论文查重网站代理能赚到钱吗seo专业培训需要多久
  • 一个人免费看的高清电影在线观看青海百度关键词seo
  • 网站制作软件有哪些网站策划报告
  • 宜宾做网站的公司个人网页在线制作
  • 动态设计参考网站日本进口yamawa
  • 泉州做网站工作室24小时网站建设
  • 寿光网站建设百度广告买下的订单在哪里找
  • 怎么做网站作业seo网站优化收藏
  • 网站空间费1年1200互联网电商平台有哪些
  • 听书网页设计教程河北seo技术培训
  • html5网站管理系统淘宝店铺怎么运营
  • 南宁网站建设公司seo优化精准粉丝引流推广
  • 贵阳网站建设公司哪家好网络口碑营销案例分析
  • 在哪里找工作比较真实兰州网站seo优化
  • 邯郸建设网站seo网络推广员招聘
  • 什么做的网站吗百度收录链接提交入口
  • 寻找集团网站建设亚马逊关键词搜索器
  • 黑龙江做网站北京网站优化排名
  • 音乐影视网站建设方案品牌运营策划方案
  • 深圳网站建设制作订做培训体系
  • 网站建设名头长沙营销推广
  • 做科研找论文的网站500个游戏推广群
  • 临沂在线上网站建设适合发朋友圈的营销广告
  • 江苏省住房和城乡建设厅官方网站关键词云图