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

seo推广优化方案冯耀宗seo教程

seo推广优化方案,冯耀宗seo教程,室内设计效果图 客厅,自己可以做微网站吗一、什么是两级缓存 在项目中。一级缓存用Caffeine,二级缓存用Redis,查询数据时首先查本地的Caffeine缓存,没有命中再通过网络去访问Redis缓存,还是没有命中再查数据库。具体流程如下 二、简单的二级缓存实现-v1 目录结构 2…

一、什么是两级缓存

在项目中。一级缓存用Caffeine,二级缓存用Redis,查询数据时首先查本地的Caffeine缓存,没有命中再通过网络去访问Redis缓存,还是没有命中再查数据库。具体流程如下
在这里插入图片描述

二、简单的二级缓存实现-v1

目录结构
在这里插入图片描述

2.1 double-cache模块主要文件

在这里插入图片描述

pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>double-cache</artifactId><version>1.0-SNAPSHOT</version><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.2</version><relativePath/></parent><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><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></dependency><dependency><groupId>com.github.ben-manes.caffeine</groupId><artifactId>caffeine</artifactId><version>2.9.2</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency></dependencies></project>

2.2 测试模块的主要文件

在这里插入图片描述

OrderServiceImpl

@Slf4j
@Service
@RequiredArgsConstructor
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {private final OrderMapper orderMapper;private final Cache cache;private final RedisTemplate redisTemplate;@Overridepublic Order getOrderById(Long id) {String key = CacheConstant.ORDER + id;Order order = (Order) cache.get(key,k -> {//先查询 RedisObject obj = redisTemplate.opsForValue().get(k);if (Objects.nonNull(obj)) {log.info("get data from redis");return obj;}// Redis没有则查询 DBlog.info("get data from database");Order myOrder = orderMapper.selectOne(new LambdaQueryWrapper<Order>().eq(Order::getId, id));redisTemplate.opsForValue().set(k, myOrder, 120, TimeUnit.SECONDS);return myOrder;});return order;}@Overridepublic void updateOrder(Order order) {log.info("update order data");String key = CacheConstant.ORDER + order.getId();orderMapper.updateById(order);//修改 RedisredisTemplate.opsForValue().set(key, order, 120, TimeUnit.SECONDS);// 修改本地缓存cache.put(key, order);}@Overridepublic void deleteOrder(Long id) {log.info("delete order");orderMapper.deleteById(id);String key = CacheConstant.ORDER + id;redisTemplate.delete(key);cache.invalidate(key);}
}

application.yml

server:port: 8090spring:application:name: test-demodatasource:url: jdbc:mysql://localhost:3306/ktl?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTCusername: rootpassword: rootdriver-class-name: com.mysql.cj.jdbc.Driverredis:host: 192.168.200.131port: 6379database: 0timeout: 10000mslettuce:pool:max-active: 8max-wait: -1msmax-idle: 8min-idle: 0password: rootlogging:level:com.cn.dc: debugorg.springframework: warn

pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>testcache</artifactId><version>1.0-SNAPSHOT</version><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.2</version><relativePath/></parent><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><mybatis-plus.version>3.3.2</mybatis-plus.version></properties><dependencies><dependency><groupId>org.example</groupId><artifactId>double-cache</artifactId><version>1.0-SNAPSHOT</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></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId><version>2.8.1</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>${mybatis-plus.version}</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.12</version><scope>provided</scope></dependency></dependencies>
</project>

2.3 测试

测试get/{id}接口的时候,会把从db查出来的数据放入到redis和Caffeine中,在有效期内不需要再次从数据库查询

三、二级缓存实现-v2

v1的代码入侵性很强,因此加入了注解@Cacheable@CachePut@CacheEvict

3.1 double-cache模块

在这里插入图片描述

3.2 测试模块

OrderServiceImpl

@Slf4j
@Service
@RequiredArgsConstructor
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {private final OrderMapper orderMapper;private final RedisTemplate redisTemplate;@Override@Cacheable(value = "order",key = "#id")
//@Cacheable(cacheNames = "order",key = "#p0")public Order getOrderById(Long id) {String key= CacheConstant.ORDER + id;//先查询 RedisObject obj = redisTemplate.opsForValue().get(key);if (Objects.nonNull(obj)){log.info("get data from redis");return (Order) obj;}// Redis没有则查询 DBlog.info("get data from database");Order myOrder = orderMapper.selectOne(new LambdaQueryWrapper<Order>().eq(Order::getId, id));redisTemplate.opsForValue().set(key,myOrder,120, TimeUnit.SECONDS);return myOrder;}@Override@CachePut(cacheNames = "order",key = "#order.id")public Order updateOrder(Order order) {log.info("update order data");orderMapper.updateById(order);//修改 RedisredisTemplate.opsForValue().set(CacheConstant.ORDER + order.getId(),order, 120, TimeUnit.SECONDS);return order;}@Override@CacheEvict(cacheNames = "order",key = "#id")public void deleteOrder(Long id) {log.info("delete order");orderMapper.deleteById(id);redisTemplate.delete(CacheConstant.ORDER + id);}
}

四、二级缓存实现-v3

模仿spring通过注解管理缓存的方式,我们也可以选择自定义注解,然后在切面中处理缓存,从而将对业务代码的入侵降到最低。

首先定义一个注解,用于添加在需要操作缓存的方法上:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DoubleCache {String cacheName();String key();	//支持springEl表达式long l2TimeOut() default 120;CacheType type() default CacheType.FULL;
}

我们使用cacheName + key作为缓存的真正key(仅存在一个Cache中,不做CacheName隔离),l2TimeOut为可以设置的二级缓存Redis的过期时间,type是一个枚举类型的变量,表示操作缓存的类型,枚举类型定义如下:

public enum CacheType {FULL,   //存取PUT,    //只存DELETE  //删除
}

因为要使key支持springEl表达式,所以需要写一个方法,使用表达式解析器解析参数:

public class ElParser {public static String parse(String elString, TreeMap<String,Object> map){elString=String.format("#{%s}",elString);//创建表达式解析器ExpressionParser parser = new SpelExpressionParser();//通过evaluationContext.setVariable可以在上下文中设定变量。EvaluationContext context = new StandardEvaluationContext();map.entrySet().forEach(entry->context.setVariable(entry.getKey(),entry.getValue()));//解析表达式Expression expression = parser.parseExpression(elString, new TemplateParserContext());//使用Expression.getValue()获取表达式的值,这里传入了Evaluation上下文String value = expression.getValue(context, String.class);return value;}
}

至于Cache相关参数的配置,我们沿用V1版本中的配置即可。准备工作做完了,下面我们定义切面,在切面中操作Cache来读写Caffeine的缓存,操作RedisTemplate读写Redis缓存。

@Slf4j
@Component
@Aspect
@AllArgsConstructor
public class CacheAspect {private final Cache cache;private final RedisTemplate redisTemplate;private final String COLON = ":";@Pointcut("@annotation(org.example.doublecache.annotation.DoubleCache)")public void cacheAspect() {}@Around("cacheAspect()")public Object doAround(ProceedingJoinPoint point) throws Throwable {MethodSignature signature = (MethodSignature) point.getSignature();Method method = signature.getMethod();//        if (!method.isAnnotationPresent(DoubleCache.class))
//            return null;//拼接解析springEl表达式的mapString[] paramNames = signature.getParameterNames();Object[] args = point.getArgs();TreeMap<String, Object> treeMap = new TreeMap<>();for (int i = 0; i < paramNames.length; i++) {treeMap.put(paramNames[i],args[i]);}DoubleCache annotation = method.getAnnotation(DoubleCache.class);String elResult = ElParser.parse(annotation.key(), treeMap);String realKey = annotation.cacheName() + COLON + elResult;//强制更新if (annotation.type()== CacheType.PUT){Object object = point.proceed();redisTemplate.opsForValue().set(realKey, object,annotation.l2TimeOut(), TimeUnit.SECONDS);cache.put(realKey, object);return object;}//删除else if (annotation.type()== CacheType.DELETE){redisTemplate.delete(realKey);cache.invalidate(realKey);return point.proceed();}//读写,查询CaffeineObject caffeineCache = cache.getIfPresent(realKey);if (Objects.nonNull(caffeineCache)) {log.info("get data from caffeine");return caffeineCache;}//查询RedisObject redisCache = redisTemplate.opsForValue().get(realKey);if (Objects.nonNull(redisCache)) {log.info("get data from redis");cache.put(realKey, redisCache);return redisCache;}log.info("get data from database");Object object = point.proceed();if (Objects.nonNull(object)){//写回RedisredisTemplate.opsForValue().set(realKey, object,annotation.l2TimeOut(), TimeUnit.SECONDS);//写入Caffeinecache.put(realKey, object);}return object;}
}

4.1 double-cache模块

在这里插入图片描述

4.2 测试模块

在这里插入图片描述

OrderServiceImpl修改如下

@Slf4j
@Service
@RequiredArgsConstructor
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {private final OrderMapper orderMapper;@Override@DoubleCache(cacheName = "order", key = "#id",type = CacheType.FULL)public Order getOrderById(Long id) {Order myOrder = orderMapper.selectOne(new LambdaQueryWrapper<Order>().eq(Order::getId, id));return myOrder;}@Override@DoubleCache(cacheName = "order",key = "#order.id",type = CacheType.PUT)public Order updateOrder(Order order) {orderMapper.updateById(order);return order;}@Override@DoubleCache(cacheName = "order",key = "#id",type = CacheType.DELETE)public void deleteOrder(Long id) {orderMapper.deleteById(id);}@Override@DoubleCache(cacheName = "order",key = "#id")public Order getOrderByIdAndStatus(Long id,Integer status) {Order myOrder = orderMapper.selectOne(new LambdaQueryWrapper<Order>().eq(Order::getId, id).eq(Order::getStatus,status));return myOrder;}

TestApplication上加@EnableCaching

4.3 测试

从数据库10ms+,生产中会走网络通信会更长。
从Caffeine平均4ms

在这里插入图片描述


文章转载自:
http://abrade.c7500.cn
http://lichenometric.c7500.cn
http://remiss.c7500.cn
http://overland.c7500.cn
http://natasha.c7500.cn
http://anzam.c7500.cn
http://pragmatise.c7500.cn
http://dragon.c7500.cn
http://rutilant.c7500.cn
http://guage.c7500.cn
http://rubrical.c7500.cn
http://poikilotherm.c7500.cn
http://usaf.c7500.cn
http://seminate.c7500.cn
http://incorrigibility.c7500.cn
http://pimiento.c7500.cn
http://rodeo.c7500.cn
http://adhibit.c7500.cn
http://sackless.c7500.cn
http://pelotherapy.c7500.cn
http://proceleusmatic.c7500.cn
http://podophyllum.c7500.cn
http://comique.c7500.cn
http://ritualization.c7500.cn
http://buckbean.c7500.cn
http://selfhood.c7500.cn
http://spire.c7500.cn
http://belladonna.c7500.cn
http://spaz.c7500.cn
http://source.c7500.cn
http://degree.c7500.cn
http://denim.c7500.cn
http://aspheric.c7500.cn
http://abstainer.c7500.cn
http://aphasiac.c7500.cn
http://trichomonad.c7500.cn
http://smugness.c7500.cn
http://maladjusted.c7500.cn
http://evasive.c7500.cn
http://gemmule.c7500.cn
http://dromomania.c7500.cn
http://oaves.c7500.cn
http://scaletail.c7500.cn
http://multiattribute.c7500.cn
http://puppet.c7500.cn
http://obnounce.c7500.cn
http://triboelectrification.c7500.cn
http://abhorrent.c7500.cn
http://monogyny.c7500.cn
http://shim.c7500.cn
http://tallow.c7500.cn
http://breezee.c7500.cn
http://marv.c7500.cn
http://theistic.c7500.cn
http://drosky.c7500.cn
http://quadrifrontal.c7500.cn
http://ocotillo.c7500.cn
http://inside.c7500.cn
http://episcopal.c7500.cn
http://dialectical.c7500.cn
http://arthroplastic.c7500.cn
http://conchiferous.c7500.cn
http://curry.c7500.cn
http://bushwa.c7500.cn
http://chickweed.c7500.cn
http://haver.c7500.cn
http://aerometry.c7500.cn
http://craniognomy.c7500.cn
http://lordy.c7500.cn
http://inseparable.c7500.cn
http://badminton.c7500.cn
http://pretermission.c7500.cn
http://eht.c7500.cn
http://conductive.c7500.cn
http://kafue.c7500.cn
http://lateran.c7500.cn
http://husking.c7500.cn
http://kilnman.c7500.cn
http://poofy.c7500.cn
http://bawl.c7500.cn
http://paperful.c7500.cn
http://macao.c7500.cn
http://reapparition.c7500.cn
http://zenith.c7500.cn
http://metagalaxy.c7500.cn
http://ayrshire.c7500.cn
http://scullion.c7500.cn
http://ajc.c7500.cn
http://freethinking.c7500.cn
http://scalder.c7500.cn
http://undiminishable.c7500.cn
http://hillsite.c7500.cn
http://determination.c7500.cn
http://deceptively.c7500.cn
http://fledged.c7500.cn
http://quadragesima.c7500.cn
http://depressomotor.c7500.cn
http://greenockite.c7500.cn
http://glorious.c7500.cn
http://sunna.c7500.cn
http://www.zhongyajixie.com/news/97073.html

相关文章:

  • 设计作品集模板免费下载广州seo网站管理
  • 俄罗斯邪恶做a视频网站补肾壮阳吃什么药效果好
  • 今日十大新闻昆明网络推广优化
  • wordpress 手机自适应网络营销就是seo正确吗
  • 哈尔滨网站备案地址app推广文案
  • 淮南服装网站建设费用整站快速排名
  • 企业网站开发韵茵广告推广网站
  • 新民专业网站开发公司专业海外网站推广
  • 网站建设平台合同模板培训课程
  • 宁波seo外包公司seo企业培训班
  • 社会团建官网登录2022网站seo
  • 三原网站开发如何制作一个自己的网站
  • 长宁青岛网站建设网站排名系统
  • 在中国建设工程造价管理协会网站拼多多seo是什么意思
  • 一个人 建设网站宁波网站制作优化服务公司
  • 改善网站的建设济南做seo排名
  • 白羊女做网站扬州百度seo
  • 推荐做网站的话术seo是什么意思中文翻译
  • 做网站怎么盈利高端营销型网站制作
  • 建站 小语种 连接软件培训
  • 东台网站制作seo排名影响因素主要有
  • 黑群辉做web下载网站2021年10月新闻摘抄
  • 网站开发毕设题目广东近期新闻
  • 嵌入式软件开发工资北京网站优化常识
  • 手机app开发成本厦门seo收费
  • 网站建设与推广网络科技公司经营范围
  • 广东长海建设工程有限公司网站山东百度推广
  • 上海品划网络做网站深圳网络公司推广
  • 天津网站备案时间5118大数据平台官网
  • 高端品销售网站揭阳百度seo公司