CGB2005-京淘13 思科 OSPF协议简单配置与分析 在一家公司呆了 10 年的程序员,最后都怎么了? 致力物联网芯片研发,奕斯伟计算获逾20亿元融资 Unity性能优化技巧 纪念首次撸出来的编程题--2020深信服软件测试岗 qml 去除标题栏后 拖动窗口和改变窗口大小 如何舒服地在图书馆用ipad入门深度学习【windows jupyter远程】 力扣Java版个人代码分享-树篇( 107. 二叉树的层次遍历 II) 第十届蓝桥杯省赛java类B组 试题 E:迷宫 (动态规划之回溯法) Unity+罗技G29方向盘+Realistic Car Controller 制作简单的模拟驾驶 2020阿里笔试题解(9.11) 起飞!这份技术点拉满的ELk+Lucene笔记,可能价值百万 好文精选整理--Redis+Nginx+设计模式+Spring全家桶+SQL+Dubbo技术 覆盖全网的微服务架构笔记,看完还不懂你来打我 技术干货:JVM架构体系与GC命令全梳理,建议收藏 跪拜,阿里P9加班到凌晨,硬肝三个月推出这份IT架构运维实践 太厉害了,华为架构师终于整理出SSM+Nginx+Redis+SQL+微服务pdf 膜拜!终于有人总结出Spring+SpringMVC+MyBatis源码层PDF了 开发1-5年的Java程序员,该学习哪些知识实现涨薪30K? 云原生景观:供应层(Provisioning)介绍 vulhub学习笔记-struts2 S2-057 Remote Code Execution Vulnerablity远程代码执行 微服务启动报 Error creating bean with name ‘eurekaAutoServiceRegistration‘ 异常 「信息安全-密码与隐藏技术」RSA加密算法的实现(CPP 实现) 单例模式线程是否安全? DDCTF2020 Writeup 迭代器模式在开源代码中的应用 微信群总是有人发广告?看我用Python写一个自动化机器人消灭他! 极光大数据持续亏损,称风控产品数据涉10亿移动端用户、包括财产消费等信息,对外投资极贷管家 揭秘英飞凌最新安全芯片解决方案:为物联网设备量身定制,小封装易开发 蒙草大数据西乌旗智慧畜牧业系统建设取得新进展 移动转售产业与大数据产业交流座谈会即将召开 19-2!62比24!湖人4大数据碾压对手,夺赛点进西决稳了 Web前端程序员每天的工作都是做什么的?有哪些是必须要做的? 四面楚歌祭利剑:华为再推鸿蒙OS,另辟蹊径进军物联网 InnoDB可重复读隔离级别是如何实现的 腾讯云物联网平台重磅升级:聚合内部能力,辅助更多产业 u校园刷课软件一键答题新视野视听说读写综合训练 css隐藏元素的几种方式及区别 display:none visibility:hidden opacity 元素隐藏 2020-09-10 使用echart完成折线图 wordpress使用memcached缓存数据提高访问速度 U校园刷课软件U校园新视野综合教程视听说答题 vue源码(十三) 数组下标改变值的响应式误区以及实现 非插件自动为WordPress关键词添加链接 SpringBoot详解(一) 从入门到入土 Mysql系列第一讲 mysql基础知识与安装 作为测试工程师,你一定要知道的数据库操作命令大全! mysql-mysql学习详记三&&数据库的备份及恢复&&多表设计&&外键约束 GROUP BY 的内在细节展示!!(不可忽略点!!)
您的位置:首页 >运维 >

CGB2005-京淘13

1 AOP实现Redis缓存服务

1.1 现有代码的分析

说明: 1.虽然在业务层service中完成了代码的实现.但是该代码不具有复用性.如果换了其他的业务则需要重新编辑. 2.由于缓存的代码写在业务层service中,所以代码的耦合性高,不方便以后的扩展. 需求: 1.能否实现代码的复用. 2.能否降低代码的耦合性.

1.2 AOP

1.2.1 AOP作用

名称:面向切面编程. 一句话总结: 在不改变原有代码的条件下,对功能进行扩展. 公式: AOP = 切入点表达式 + 通知方法.

专业术语: 1.连接点: 在执行正常的业务过程中满足了切入点表达式时进入切面的点.(织入) 多个 2.通知: 在切面中执行的具体的业务(扩展) 方法 3.切入点: 能够进入切面的一个判断 if判断 一个 4.目标方法: 将要执行的真实的业务逻辑.

1.2.2 关于通知说明

1.前置通知: 目标方法执行之前执行 2.后置通知: 目标方法执行之后执行 3.异常通知: 目标方法执行之后抛出异常时执行 4.最终通知: 不管什么时候都要执行的方法. 说明:上述的四大通知类型不能控制目标方法是否执行.一般使用上述的四大通知类型,都是用来记录程序的执行状态.

5.环绕通知: 在目标方法执行前后都要执行的通知方法. 控制目标方法是否执行.并且环绕通知的功能最为强大.

1.2.3 切入点表达式说明

1). bean(bean的id) 类名首字母小写 匹配1个类 2). within(包名.类名) 按包路径匹配类 匹配多个类 上述表达式是粗粒度的控制,按类匹配. 3).execution(返回值类型 包名.类名.方法名(参数列表)) 4).@annotation(包名.注解名) 按注解进行拦截.

1.2.4 AOPDemo复习

package com.jt.aop;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.aspectj.lang.annotation.Pointcut;import org.springframework.stereotype.Component;@Component//将对象交给spring容器管理@Aspect //标识我是一个切面public class CacheAOP {/** * AOP = 切入点表达式 + 通知方法. * * 拦截需求: *1.要求拦截itemCatServiceImpl的bean *2.拦截com.jt.service下的所有的类 *3.拦截com.jt.service下的所有类及方法 *3.1拦截com.jt.service的所有的类.返回值为int类型的.并且add开头 *的方法.并且参数一个 为String类型 *///@Pointcut(value = "bean(itemCatServiceImpl)")//@Pointcut("within(com.jt.service..*)")//拦截com.jt.service下的所有类的所有方法的任意参数类型//@Pointcut("execution(int com.jt.service..*.add*(String))")@Pointcut("execution(* com.jt.service..*.*(..))")public void pointcut(){}//定义前置通知@Before("pointcut()")public void before(){System.out.println("我是前置通知");}}

1.3 实现Redis缓存

1.3.1 需求分析

1.自定义注解CacheFind 主要被注解标识的方法,则开启缓存的实现. 2.为了将来区分业务,需要在注解中标识key属性,由使用者自行填写. 3.为了用户提供数据超时功能.

1.3.2 自定义注解

@Retention(RetentionPolicy.RUNTIME) //该注解什么时候有效@Target({ElementType.METHOD}) //对方法有效public @interface CacheFind {String key(); //该属性为必须添加int seconds() default 0;//设定超时时间 默认不超时}

1.3.3 编辑CacheAOP

package com.jt.aop;import com.jt.anno.CacheFind;import com.jt.pojo.ItemDesc;import com.jt.util.ObjectMapperUtil;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.aspectj.lang.annotation.Pointcut;import org.aspectj.lang.reflect.MethodSignature;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import redis.clients.jedis.Jedis;import java.lang.reflect.Method;import java.util.Arrays;@Component//将对象交给spring容器管理@Aspect //标识我是一个切面public class CacheAOP {//1.注入缓存redis对象@Autowiredprivate Jedis jedis;/** * 拦截@CacheFind注解标识的方法. * 通知选择: 缓存的实现应该选用环绕通知 * 步骤: *1.动态生成key用户填写的key+用户提交的参数 */@Around("@annotation(cacheFind)")public Object around(ProceedingJoinPoint joinPoint, CacheFind cacheFind){//1.如何获取用户在注解中填写的内容呢???如何获取注解对象....String key = cacheFind.key(); //前缀ITEM_CAT_PARENTID//2.如何获取目标对象的参数呢???Object[] array = joinPoint.getArgs();key += "::"+Arrays.toString(array); // "ITEM_CAT_PARENTID::[0]"//3.从redis中获取数据Object result = null;if(jedis.exists(key)){//需要获取json数据之后,直接转化为对象返回!!String json = jedis.get(key);//如何获取返回值类型MethodSignature methodSignature =(MethodSignature) joinPoint.getSignature();Class targetClass = methodSignature.getReturnType();result = ObjectMapperUtil.toObject(json,targetClass);System.out.println("AOP实现缓存的查询!!!");}else{//key不存在,应该查询数据库try {result = joinPoint.proceed();//执行目标方法,获取返回值结果String json = ObjectMapperUtil.toJSON(result);if(cacheFind.seconds()>0){ //判断是否需要超时时间jedis.setex(key, cacheFind.seconds(), json);}else{jedis.set(key,json);}System.out.println("AOP执行数据库操作!!!");} catch (Throwable throwable) {throwable.printStackTrace();throw new RuntimeException(throwable);}}return result;}/** * AOP = 切入点表达式 + 通知方法. * * 拦截需求: *1.要求拦截itemCatServiceImpl的bean *2.拦截com.jt.service下的所有的类 *3.拦截com.jt.service下的所有类及方法 *3.1拦截com.jt.service的所有的类.返回值为int类型的.并且add开头 *的方法.并且参数一个 为String类型 *///@Pointcut(value = "bean(itemCatServiceImpl)")//@Pointcut("within(com.jt.service..*)")//拦截com.jt.service下的所有类的所有方法的任意参数类型//@Pointcut("execution(int com.jt.service..*.add*(String))") /* @Pointcut("execution(int com.jt.service..*.add*(String))")public void pointcut(){}//定义前置通知@Before("pointcut()")public void before(){System.out.println("我是前置通知");}*/}

1.3.4 关于环绕通知参数的说明

问题一:连接点必须位于通知的参数的第一位. 在这里插入图片描述 否则报错信息如下: 在这里插入图片描述 问题二: 其他四大通知了类型是否可以添加ProceedingJoinPoint对象 答案: ProceedingJoinPoint 只能添加到环绕通知中. 报错如下: 在这里插入图片描述

1.3.5 关于JoinPoint方法说明

 /** * 要求: 拦截注解方法 * 打印: *1.打印目标对象的类型 *2.打印方法的参数 *3.获取目标对象的名称及方法的名称 * @param joinPoint */@Before("@annotation(com.jt.anno.CacheFind)")public void before(JoinPoint joinPoint){Object target = joinPoint.getTarget();//获取目标对象Object[] args = joinPoint.getArgs();//获取方法参数的String targetName =joinPoint.getSignature().getDeclaringTypeName(); //获取目标对象的名称//获取目标对象的类型Class targetClass = joinPoint.getSignature().getDeclaringType();//获取目标方法的名称String methodName = joinPoint.getSignature().getName();System.out.println(target);System.out.println(args);System.out.println(targetName);System.out.println(targetClass);System.out.println(methodName);}

1.4 商品列表分类实现缓存处理

说明:在业务方法中添加缓存的注解.

/** * 分析业务: 通过itemCatId获取商品分类的名称 * 1.url地址: url:"/item/cat/queryItemName", * 2.参数: {itemCatId:val}, * 3.返回值: 商品分类名称String */@RequestMapping("/queryItemName")@CacheFind(key="ITEM_CAT_NAME")public String findItemCatName(Long itemCatId){return itemCatService.findItemCatNameById(itemCatId);}

2.Redis分片机制

2.1 需求数据

如果需要在redis中进行海量的数据存储,如果只有一台redis显然不能实现该功能.如果通过扩大内存的方式也不能达到要求.因为时间都浪费在寻址中. 如何有效的存储海量的数据呢???

2.2 Redis分片说明

说明:一般采用多台redis,分别保存用户的数据,从而实现内存数据的扩容. 对于用户而言:将redis分片当做一个整体,用户不在乎数据到底存储到哪里,只在乎能不能存. 分片主要的作用: 实现内存扩容. 在这里插入图片描述

2.3 Redis分片准备

2.3.1 创建目录

说明:在redis根目录中创建一个shards目录 在这里插入图片描述

2.3.2 分片搭建策略

说明:由于Redis启动是根据配置文件运行的,所以如果需要准备3台redis,则需要复制3份配置文件redis.conf. 端口号依次为6379/6380/6381

复制配置文件: 在这里插入图片描述 修改端口号: 根据配置文件名称,动态修改对应的端口即可. 在这里插入图片描述 在这里插入图片描述 启动redis:

 redis-server6379.conf redis-server6380.conf redis-server6381.conf

在这里插入图片描述

2.3.3 Redis分片入门案例

 /** * 测试Redis分片机制 * 业务思路: *用户需要通过API来操作3台redis.用户无需关心数据如何存储, *只需要了解数据能否存储即可. * 思考: 2005的数据存储到哪台redis中 *redis分片是如何实现数据存储的! */@Testpublic void testShards(){List<JedisShardInfo> list = new ArrayList<>();list.add(new JedisShardInfo("192.168.126.129", 6379));list.add(new JedisShardInfo("192.168.126.129", 6380));list.add(new JedisShardInfo("192.168.126.129", 6381));ShardedJedis shardedJedis = new ShardedJedis(list);shardedJedis.set("2005", "redis分片学习");System.out.println(shardedJedis.get("2005"));}

2.4 一致性hash算法

2.4.1 算法介绍

一致性哈希算法在1997年由麻省理工学院提出,是一种特殊的哈希算法,目的是解决分布式缓存的问题。 [1] 在移除或者添加一个服务器时,能够尽可能小地改变已存在的服务请求与处理请求服务器之间的映射关系。一致性哈希解决了简单哈希算法在分布式哈希表( Distributed Hash Table,DHT) 中存在的动态伸缩等问题 [2] 。

2.4.2 常识介绍

1.常见hash多少位16进制数? 8位16进制数 2.16进制数取值有哪些 0-9 A-F 共16个数 3. hash的取值范围从 00000000 ~ FFFFFFFF (24)8 4. 上述取值的个数共有多少个??? 要求以2为底 2^32 幂 5. 对相同的数据进行hash值一致

2.4.3 一致性hash说明

步骤:1.首先计算node节点 2.将用户的key进行hash计算,之后按照顺时针的方向找到最近的node节点之后链接,执行set操作. 在这里插入图片描述

2.4.3 特性一 平衡性

①平衡性是指hash的结果应该平均分配到各个节点,这样从算法上解决了负载均衡问题 [4] 。 说明: 如果发现节点中存储的数据负载不均,则采用虚拟节点的方式实现数据的平衡(相对平衡) 在这里插入图片描述

2.4.3 特性一 单调性

②单调性是指在新增或者删减节点时,不影响系统正常运行 [4] 因为可以实现自动的数据迁移.。 原则: 在进行数据迁移时 应该尽可能少的改变原有的数据.

2.4.4 特性一 分散性

③分散性是指数据应该分散地存放在分布式集群中的各个节点(节点自己可以有备份),不必每个节点都存储所有的数据 [4] 。 鸡蛋不要放在一个篮子里

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。