聊聊JetCacheProxyConfiguration

本文主要研究一下JetCacheProxyConfiguration

JetCacheProxyConfiguration

com/alicp/jetcache/anno/config/JetCacheProxyConfiguration.java

@Configuration
public class JetCacheProxyConfiguration implements ImportAware, ApplicationContextAware {protected AnnotationAttributes enableMethodCache;private ApplicationContext applicationContext;@Overridepublic void setImportMetadata(AnnotationMetadata importMetadata) {this.enableMethodCache = AnnotationAttributes.fromMap(importMetadata.getAnnotationAttributes(EnableMethodCache.class.getName(), false));if (this.enableMethodCache == null) {throw new IllegalArgumentException("@EnableMethodCache is not present on importing class " + importMetadata.getClassName());}}@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext = applicationContext;}@Bean(name = CacheAdvisor.CACHE_ADVISOR_BEAN_NAME)@Role(BeanDefinition.ROLE_INFRASTRUCTURE)public CacheAdvisor jetcacheAdvisor(JetCacheInterceptor jetCacheInterceptor) {CacheAdvisor advisor = new CacheAdvisor();advisor.setAdviceBeanName(CacheAdvisor.CACHE_ADVISOR_BEAN_NAME);advisor.setAdvice(jetCacheInterceptor);advisor.setBasePackages(this.enableMethodCache.getStringArray("basePackages"));advisor.setOrder(this.enableMethodCache.<Integer>getNumber("order"));return advisor;}@Bean@Role(BeanDefinition.ROLE_INFRASTRUCTURE)public JetCacheInterceptor jetCacheInterceptor() {return new JetCacheInterceptor();}}

JetCacheProxyConfiguration定义了JetCacheInterceptor、CacheAdvisor

JetCacheInterceptor

com/alicp/jetcache/anno/aop/JetCacheInterceptor.java

public class JetCacheInterceptor implements MethodInterceptor, ApplicationContextAware {private static final Logger logger = LoggerFactory.getLogger(JetCacheInterceptor.class);@Autowiredprivate ConfigMap cacheConfigMap;private ApplicationContext applicationContext;private GlobalCacheConfig globalCacheConfig;ConfigProvider configProvider;CacheManager cacheManager;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext = applicationContext;}@Overridepublic Object invoke(final MethodInvocation invocation) throws Throwable {if (configProvider == null) {configProvider = applicationContext.getBean(ConfigProvider.class);}if (configProvider != null && globalCacheConfig == null) {globalCacheConfig = configProvider.getGlobalCacheConfig();}if (globalCacheConfig == null || !globalCacheConfig.isEnableMethodCache()) {return invocation.proceed();}if (cacheManager == null) {cacheManager = applicationContext.getBean(CacheManager.class);if (cacheManager == null) {logger.error("There is no cache manager instance in spring context");return invocation.proceed();}}Method method = invocation.getMethod();Object obj = invocation.getThis();CacheInvokeConfig cac = null;if (obj != null) {String key = CachePointcut.getKey(method, obj.getClass());cac  = cacheConfigMap.getByMethodInfo(key);}/*if(logger.isTraceEnabled()){logger.trace("JetCacheInterceptor invoke. foundJetCacheConfig={}, method={}.{}(), targetClass={}",cac != null,method.getDeclaringClass().getName(),method.getName(),invocation.getThis() == null ? null : invocation.getThis().getClass().getName());}*/if (cac == null || cac == CacheInvokeConfig.getNoCacheInvokeConfigInstance()) {return invocation.proceed();}CacheInvokeContext context = configProvider.newContext(cacheManager).createCacheInvokeContext(cacheConfigMap);context.setTargetObject(invocation.getThis());context.setInvoker(invocation::proceed);context.setMethod(method);context.setArgs(invocation.getArguments());context.setCacheInvokeConfig(cac);context.setHiddenPackages(globalCacheConfig.getHiddenPackages());return CacheHandler.invoke(context);}public void setCacheConfigMap(ConfigMap cacheConfigMap) {this.cacheConfigMap = cacheConfigMap;}}

JetCacheInterceptor实现了aop的MethodInterceptor方法,其invoke方法先从spring中获取configProvider、globalCacheConfig,若globalCacheConfig为null或者是没有开启methodCache,则直接执行invocation.proceed(),否则获取cacheManager,然后从invocation获取key,从cacheConfigMap找到对应的CacheInvokeConfig,若为null则执行invocation.proceed(),否则通过configProvider.newContext(cacheManager).createCacheInvokeContext(cacheConfigMap)创建CacheInvokeContext,执行CacheHandler.invoke(context)

CacheHandler.invoke

com/alicp/jetcache/anno/method/CacheHandler.java

    public static Object invoke(CacheInvokeContext context) throws Throwable {if (context.getCacheInvokeConfig().isEnableCacheContext()) {try {CacheContextSupport._enable();return doInvoke(context);} finally {CacheContextSupport._disable();}} else {return doInvoke(context);}}private static Object doInvoke(CacheInvokeContext context) throws Throwable {CacheInvokeConfig cic = context.getCacheInvokeConfig();CachedAnnoConfig cachedConfig = cic.getCachedAnnoConfig();if (cachedConfig != null && (cachedConfig.isEnabled() || CacheContextSupport._isEnabled())) {return invokeWithCached(context);} else if (cic.getInvalidateAnnoConfigs() != null || cic.getUpdateAnnoConfig() != null) {return invokeWithInvalidateOrUpdate(context);} else {return invokeOrigin(context);}}   private static Object invokeOrigin(CacheInvokeContext context) throws Throwable {return context.getInvoker().invoke();}     

CacheHandler的invoke方法主要是执行doInvoke,它根据配置判断是走invokeWithCached、invokeWithInvalidateOrUpdate还是invokeOrigin

invokeWithCached

    private static Object invokeWithCached(CacheInvokeContext context)throws Throwable {CacheInvokeConfig cic = context.getCacheInvokeConfig();CachedAnnoConfig cac = cic.getCachedAnnoConfig();Cache cache = context.getCacheFunction().apply(context, cac);if (cache == null) {logger.error("no cache with name: " + context.getMethod());return invokeOrigin(context);}Object key = ExpressionUtil.evalKey(context, cic.getCachedAnnoConfig());if (key == null) {return loadAndCount(context, cache, key);}if (!ExpressionUtil.evalCondition(context, cic.getCachedAnnoConfig())) {return loadAndCount(context, cache, key);}try {CacheLoader loader = new CacheLoader() {@Overridepublic Object load(Object k) throws Throwable {Object result = invokeOrigin(context);context.setResult(result);return result;}@Overridepublic boolean vetoCacheUpdate() {return !ExpressionUtil.evalPostCondition(context, cic.getCachedAnnoConfig());}};Object result = cache.computeIfAbsent(key, loader);return result;} catch (CacheInvokeException e) {throw e.getCause();}}

invokeWithCached先获取key,若key为null或者不满足表达式则执行loadAndCount,否则执行cache.computeIfAbsent(key, loader)

loadAndCount

    private static Object loadAndCount(CacheInvokeContext context, Cache cache, Object key) throws Throwable {long t = System.currentTimeMillis();Object v = null;boolean success = false;try {v = invokeOrigin(context);success = true;} finally {t = System.currentTimeMillis() - t;CacheLoadEvent event = new CacheLoadEvent(cache, t, key, v, success);while (cache instanceof ProxyCache) {cache = ((ProxyCache) cache).getTargetCache();}if (cache instanceof AbstractCache) {((AbstractCache) cache).notify(event);}}return v;}

loadAndCount主要是执行invokeOrigin,然后发布CacheLoadEvent事件

invokeWithInvalidateOrUpdate

    private static Object invokeWithInvalidateOrUpdate(CacheInvokeContext context) throws Throwable {Object originResult = invokeOrigin(context);context.setResult(originResult);CacheInvokeConfig cic = context.getCacheInvokeConfig();if (cic.getInvalidateAnnoConfigs() != null) {doInvalidate(context, cic.getInvalidateAnnoConfigs());}CacheUpdateAnnoConfig updateAnnoConfig = cic.getUpdateAnnoConfig();if (updateAnnoConfig != null) {doUpdate(context, updateAnnoConfig);}return originResult;}

invokeWithInvalidateOrUpdate先执行invokeOrigin,然后根据判断执行doInvalidate或者doUpdate

CacheFunction

CacheInvokeContext

com/alicp/jetcache/anno/method/CacheInvokeContext.java

	private BiFunction<CacheInvokeContext, CacheAnnoConfig, Cache> cacheFunction;public void setCacheFunction(BiFunction<CacheInvokeContext, CacheAnnoConfig, Cache> cacheFunction) {this.cacheFunction = cacheFunction;}public BiFunction<CacheInvokeContext, CacheAnnoConfig, Cache> getCacheFunction() {return cacheFunction;}

CacheInvokeContext定义了cacheFunction,是一个BiFunction,第一个参数为CacheInvokeContext,第二个参数为CacheAnnoConfig,返回类型为Cache

createCacheInvokeContext

com/alicp/jetcache/anno/support/CacheContext.java

    public CacheInvokeContext createCacheInvokeContext(ConfigMap configMap) {CacheInvokeContext c = newCacheInvokeContext();c.setCacheFunction((cic, cac) -> createOrGetCache(cic, cac, configMap));return c;}protected CacheInvokeContext newCacheInvokeContext() {return new CacheInvokeContext();}    private Cache createOrGetCache(CacheInvokeContext invokeContext, CacheAnnoConfig cacheAnnoConfig, ConfigMap configMap) {Cache cache = cacheAnnoConfig.getCache();if (cache != null) {return cache;}if (cacheAnnoConfig instanceof CachedAnnoConfig) {cache = createCacheByCachedConfig((CachedAnnoConfig) cacheAnnoConfig, invokeContext);} else if ((cacheAnnoConfig instanceof CacheInvalidateAnnoConfig) || (cacheAnnoConfig instanceof CacheUpdateAnnoConfig)) {cache = cacheManager.getCache(cacheAnnoConfig.getArea(), cacheAnnoConfig.getName());if (cache == null) {CachedAnnoConfig cac = configMap.getByCacheName(cacheAnnoConfig.getArea(), cacheAnnoConfig.getName());if (cac == null) {String message = "can't find cache definition with area=" + cacheAnnoConfig.getArea()+ " name=" + cacheAnnoConfig.getName() +", specified in " + cacheAnnoConfig.getDefineMethod();CacheConfigException e = new CacheConfigException(message);logger.error("Cache operation aborted because can't find cached definition", e);return null;}cache = createCacheByCachedConfig(cac, invokeContext);}}cacheAnnoConfig.setCache(cache);return cache;} private Cache createCacheByCachedConfig(CachedAnnoConfig ac, CacheInvokeContext invokeContext) {String area = ac.getArea();String cacheName = ac.getName();if (CacheConsts.isUndefined(cacheName)) {cacheName = configProvider.createCacheNameGenerator(invokeContext.getHiddenPackages()).generateCacheName(invokeContext.getMethod(), invokeContext.getTargetObject());}Cache cache = __createOrGetCache(ac, area, cacheName);return cache;}public Cache __createOrGetCache(CachedAnnoConfig cac, String area, String cacheName) {QuickConfig.Builder b = QuickConfig.newBuilder(area, cacheName);TimeUnit timeUnit = cac.getTimeUnit();if (cac.getExpire() > 0) {b.expire(Duration.ofMillis(timeUnit.toMillis(cac.getExpire())));}if (cac.getLocalExpire() > 0) {b.localExpire(Duration.ofMillis(timeUnit.toMillis(cac.getLocalExpire())));}if (cac.getLocalLimit() > 0) {b.localLimit(cac.getLocalLimit());}b.cacheType(cac.getCacheType());b.syncLocal(cac.isSyncLocal());if (!CacheConsts.isUndefined(cac.getKeyConvertor())) {b.keyConvertor(configProvider.parseKeyConvertor(cac.getKeyConvertor()));}if (!CacheConsts.isUndefined(cac.getSerialPolicy())) {b.valueEncoder(configProvider.parseValueEncoder(cac.getSerialPolicy()));b.valueDecoder(configProvider.parseValueDecoder(cac.getSerialPolicy()));}b.cacheNullValue(cac.isCacheNullValue());b.useAreaInPrefix(globalCacheConfig.isAreaInCacheName());PenetrationProtectConfig ppc = cac.getPenetrationProtectConfig();if (ppc != null) {b.penetrationProtect(ppc.isPenetrationProtect());b.penetrationProtectTimeout(ppc.getPenetrationProtectTimeout());}b.refreshPolicy(cac.getRefreshPolicy());return cacheManager.getOrCreateCache(b.build());}           

createCacheInvokeContext方法会设置cacheFunction为(cic, cac) -> createOrGetCache(cic, cac, configMap),通过createOrGetCache来创建或者获取Cache;createOrGetCache从cacheAnnoConfig.getCache()获取Cache,不为null则返回,为null则通过createCacheByCachedConfig来创建,其最后是创建QuickConfig,然后通过cacheManager.getOrCreateCache(b.build())来创建Cache

CacheAdvisor

com/alicp/jetcache/anno/aop/CacheAdvisor.java

public class CacheAdvisor extends AbstractBeanFactoryPointcutAdvisor {public static final String CACHE_ADVISOR_BEAN_NAME = "jetcache2.internalCacheAdvisor";@Autowiredprivate ConfigMap cacheConfigMap;private String[] basePackages;@Overridepublic Pointcut getPointcut() {CachePointcut pointcut = new CachePointcut(basePackages);pointcut.setCacheConfigMap(cacheConfigMap);return pointcut;}public void setCacheConfigMap(ConfigMap cacheConfigMap) {this.cacheConfigMap = cacheConfigMap;}public void setBasePackages(String[] basePackages) {this.basePackages = basePackages;}
}

CacheAdvisor继承了spring的AbstractBeanFactoryPointcutAdvisor,其getPointcut返回的是CachePointcut

CachePointcut

com/alicp/jetcache/anno/aop/CachePointcut.java

public class CachePointcut extends StaticMethodMatcherPointcut implements ClassFilter {private static final Logger logger = LoggerFactory.getLogger(CachePointcut.class);private ConfigMap cacheConfigMap;private String[] basePackages;public CachePointcut(String[] basePackages) {setClassFilter(this);this.basePackages = basePackages;}@Overridepublic boolean matches(Class clazz) {boolean b = matchesImpl(clazz);logger.trace("check class match {}: {}", b, clazz);return b;}private boolean matchesImpl(Class clazz) {if (matchesThis(clazz)) {return true;}Class[] cs = clazz.getInterfaces();if (cs != null) {for (Class c : cs) {if (matchesImpl(c)) {return true;}}}if (!clazz.isInterface()) {Class sp = clazz.getSuperclass();if (sp != null && matchesImpl(sp)) {return true;}}return false;}public boolean matchesThis(Class clazz) {String name = clazz.getName();if (exclude(name)) {return false;}return include(name);}private boolean include(String name) {if (basePackages != null) {for (String p : basePackages) {if (name.startsWith(p)) {return true;}}}return false;}private boolean exclude(String name) {if (name.startsWith("java")) {return true;}if (name.startsWith("org.springframework")) {return true;}if (name.indexOf("$$EnhancerBySpringCGLIB$$") >= 0) {return true;}if (name.indexOf("$$FastClassBySpringCGLIB$$") >= 0) {return true;}return false;}@Overridepublic boolean matches(Method method, Class targetClass) {boolean b = matchesImpl(method, targetClass);if (b) {if (logger.isDebugEnabled()) {logger.debug("check method match true: method={}, declaringClass={}, targetClass={}",method.getName(),ClassUtil.getShortClassName(method.getDeclaringClass().getName()),targetClass == null ? null : ClassUtil.getShortClassName(targetClass.getName()));}} else {if (logger.isTraceEnabled()) {logger.trace("check method match false: method={}, declaringClass={}, targetClass={}",method.getName(),ClassUtil.getShortClassName(method.getDeclaringClass().getName()),targetClass == null ? null : ClassUtil.getShortClassName(targetClass.getName()));}}return b;}private boolean matchesImpl(Method method, Class targetClass) {if (!matchesThis(method.getDeclaringClass())) {return false;}if (exclude(targetClass.getName())) {return false;}String key = getKey(method, targetClass);CacheInvokeConfig cac = cacheConfigMap.getByMethodInfo(key);if (cac == CacheInvokeConfig.getNoCacheInvokeConfigInstance()) {return false;} else if (cac != null) {return true;} else {cac = new CacheInvokeConfig();CacheConfigUtil.parse(cac, method);String name = method.getName();Class<?>[] paramTypes = method.getParameterTypes();parseByTargetClass(cac, targetClass, name, paramTypes);if (!cac.isEnableCacheContext() && cac.getCachedAnnoConfig() == null &&cac.getInvalidateAnnoConfigs() == null && cac.getUpdateAnnoConfig() == null) {cacheConfigMap.putByMethodInfo(key, CacheInvokeConfig.getNoCacheInvokeConfigInstance());return false;} else {cacheConfigMap.putByMethodInfo(key, cac);return true;}}}public static String getKey(Method method, Class targetClass) {StringBuilder sb = new StringBuilder();sb.append(method.getDeclaringClass().getName());sb.append('.');sb.append(method.getName());sb.append(Type.getMethodDescriptor(method));if (targetClass != null) {sb.append('_');sb.append(targetClass.getName());}return sb.toString();}private void parseByTargetClass(CacheInvokeConfig cac, Class<?> clazz, String name, Class<?>[] paramTypes) {if (!clazz.isInterface() && clazz.getSuperclass() != null) {parseByTargetClass(cac, clazz.getSuperclass(), name, paramTypes);}Class<?>[] intfs = clazz.getInterfaces();for (Class<?> it : intfs) {parseByTargetClass(cac, it, name, paramTypes);}boolean matchThis = matchesThis(clazz);if (matchThis) {Method[] methods = clazz.getDeclaredMethods();for (Method method : methods) {if (methodMatch(name, method, paramTypes)) {CacheConfigUtil.parse(cac, method);break;}}}}private boolean methodMatch(String name, Method method, Class<?>[] paramTypes) {if (!Modifier.isPublic(method.getModifiers())) {return false;}if (!name.equals(method.getName())) {return false;}Class<?>[] ps = method.getParameterTypes();if (ps.length != paramTypes.length) {return false;}for (int i = 0; i < ps.length; i++) {if (!ps[i].equals(paramTypes[i])) {return false;}}return true;}public void setCacheConfigMap(ConfigMap cacheConfigMap) {this.cacheConfigMap = cacheConfigMap;}
}

CachePointcut继承了spring的StaticMethodMatcherPointcut,其matches方法委托给了matchesImpl,它主要是通过cacheConfigMap.getByMethodInfo(key)来获取CacheInvokeConfig,如果是noCacheInvokeConfigInstance则返回false,若不为null则返回true,若为null则创建CacheInvokeConfig维护到cacheConfigMap中

CommonConfiguration

com/alicp/jetcache/anno/config/CommonConfiguration.java

@Configuration
public class CommonConfiguration {@Bean@Role(BeanDefinition.ROLE_INFRASTRUCTURE)public ConfigMap jetcacheConfigMap() {return new ConfigMap();}
}

CommonConfiguration创建ConfigMap实例

小结

JetCacheProxyConfiguration主要是定义了JetCacheInterceptor、CacheAdvisor,其中JetCacheInterceptor实现了aop的MethodInterceptor方法,其invoke方法主要是通过configProvider.newContext(cacheManager).createCacheInvokeContext(cacheConfigMap)创建CacheInvokeContext,执行CacheHandler.invoke(context)通过context.getCacheFunction().apply(context, cac)获取com.alicp.jetcache.Cache,然后进行相关操作;CachePointcut继承了spring的StaticMethodMatcherPointcut,其matches方法委托给了matchesImpl,它主要是通过cacheConfigMap.getByMethodInfo(key)来获取CacheInvokeConfig,如果是noCacheInvokeConfigInstance则返回false,若不为null则返回true,若为null则创建CacheInvokeConfig维护到cacheConfigMap中。

doc

  • jetcache

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/26359.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大数据在商业中的应用——Kompas.ai如何助力企业决策

引言 在现代商业中&#xff0c;大数据逐渐成为企业决策的重要工具。通过对海量数据的分析和处理&#xff0c;企业可以获得重要的市场信息和决策支持。本文将探讨大数据在商业中的应用&#xff0c;并介绍Kompas.ai如何通过AI技术助力企业决策。 大数据的发展及其重要性 大数据…

为什么要学习Flink系统管理及优化课程?

Flink系统是一种流式处理框架&#xff0c;能够高效地处理大规模数据流。然而&#xff0c;要确保Flink系统的正常运行&#xff0c;就需要进行系统管理和优化。系统管理是指对Flink集群的监控、调度和维护&#xff0c;而系统优化则是指通过调整参数和优化算法&#xff0c;提高Fli…

Anime Girls Pack

动漫女孩包 35个动画&#xff08;就地&#xff09;支持人形。 8情绪。 角色列表&#xff1a;原艾艾琪惠美子惠理文子星薰和子佳子奈子理子凛老师小樱老师津雨僵尸女孩01 下载&#xff1a;​​Unity资源商店链接资源下载链接 效果图&#xff1a;

[vue2]深入理解路由

本节目标 单页应用程序路由概念VueRouter基本使用组件分类存放路由模块封装声明式导航其他路由配置路由模式编程式导航案例-面经基础版 单页应用程序 单页应用程序(SPA): 所有的功能都在一个HTML页面上实现 网易云音乐: 网易云音乐 多页应用程序(MPA): 不同功能通过切换不同…

Kotlin 协程真的轻量吗?

前言 在官方文档的介绍中,提到了: 协程是轻量的 并给出了一个例子: fun main() = runBlocking {repeat(50_000) {// 启动大量的协程launch {delay

计算机网络之网络层知识总结

网络层功能概述 主要任务 主要任务是把分组从源端传到目的端&#xff0c;为分组交换网上的不同主机提供通信服务。网络层传输单位是数据报。 分组和数据报的关系&#xff1a;把数据报进行切割之后&#xff0c;就是分组。 主要功能&#xff1a; 路由选择与分组转发 路由器…

JS中的export与Node中的exports

一、JS 中的 export 在 JavaScript ES6 中&#xff0c;export 与 export default 均可用于导出常量、函数、文件、模块等。 export、export default 负责 导出&#xff0c;import 则负责导入。 export 在一个js文件中可以有多个&#xff0c;export default 最多只能有一个。 ex…

网络安全相关的密码学

网络安全相关的密码学是一个复杂且重要的领域&#xff0c;它涵盖了信息的加密、解密、认证以及密钥管理等多个方面。以下是对网络安全相关密码学的详细概述&#xff1a; 一、密码学概述 密码学是研究编制密码和破译密码的技术科学。它研究密码变化的客观规律&#xff0c;应用…

5-1RT-Thread互斥量

5-1RT-Thread互斥量 互斥量斥量的管理方式 互斥量 互斥量又称为互斥型信号量&#xff0c;是一种特殊的二值信号量。以超市的储物柜为例&#xff0c;当用户A存入物品并关闭柜门&#xff0c;则用户A就获得了此格柜子的使用权。此时其他用户无法使用此个柜子&#xff0c;只有当用户…

vue3中用setup写的数据,不能动态渲染(非响应式)解决办法

相比于2.0&#xff0c;vue3.0在新增了一个setup函数&#xff0c;我们在setup中可以写数据也可以写方法&#xff0c;就像我们以前最开始学习js一样&#xff0c;在js文件中写代码。 For instance <template><div class"person"><h2>姓名&#xff1…

Elasticsearch-通过分析器进行分词

在Elasticsearch中&#xff0c;分析器&#xff08;Analyzer&#xff09;是用于将文本转换为可搜索的术语&#xff08;tokens&#xff09;的组件。这个过程通常被称为分词&#xff08;Tokenization&#xff09;。Elasticsearch使用分析器来处理文本字段&#xff0c;以便进行索引…

C语言题目:排序问题2

题目描述 将十个数进行从大到小的顺序进行排列 输入格式 十个整数 输出格式 以从大到小的顺序输出这个十个数 样例输入 1 2 3 4 5 6 7 8 9 10样例输出 10 9 8 7 6 5 4 3 2 1 代码解析 1. 引入头文件 代码首先引入了stdio.h头文件&#xff0c;这是C语言标准输入输出库…

Python对象序列化库之dill使用详解

概要 在 Python 编程中,序列化(Serialization)和反序列化(Deserialization)是处理对象持久化和数据传输的常见任务。Python 提供了内置的 pickle 模块用于对象序列化,但它在处理复杂对象(如带有 lambda 函数、生成器和闭包的对象)时存在一定局限性。dill 库是 pickle …

处理docker的镜像下载问题

文章目录 概要问题背景操作步骤小结 概要 命令解析 启动 systemctl start docker重启守护进程 sudo systemctl daemon-reload重启docker服务 sudo systemctl restart docker重启docker服务 sudo service docker restart关闭docker service docker stop关闭do…

Go微服务: 分布式之发送带有事务消息的示例

分布式之发送带有事务消息 现在做一个RocketMQ的事务消息的 demo 1 &#xff09;生产者 package mainimport ("context""fmt""time""github.com/apache/rocketmq-client-go/v2""github.com/apache/rocketmq-client-go/v2/prim…

Oracle 19C 数据库表被误删除的模拟恢复

Oracle 19C 数据库表被误删除的模拟恢复操作 1、模拟创建表用于恢复测试 sqlplus zzh/zzh SQL> create table obj_tb tablespace users as select * from dba_objects; Table created. SQL> select count(*) from obj_tb; COUNT(*) ---------- 72373 2、记录当前…

博客摘录「 AXI三种接口及DMA DDR XDMA介绍(应用于vivado中的ip调用)」2024年6月10日

关键要点&#xff1a; 1.AXI Stream经过协议转换可使用AXI_FULL&#xff08;PS与PL间的接口&#xff0c;如GP、HP和ACP&#xff09;。 2.传输数据类里就涉及一个握手协议&#xff0c;即在主从双方数据通信前&#xff0c;有一个握手的过程。基本内容&#xff1a;数据的传输源会…

浅谈配置元件之HTTP请求默认值

浅谈配置元件之HTTP请求默认值 在进行HTTP请求的测试计划设计时&#xff0c;"HTTP请求默认值"配置元件扮演着极其重要的角色&#xff0c;它能够简化测试计划的设置&#xff0c;提高测试效率。本问将详细介绍如何使用JMeter中的“HTTP请求默认值”配置元件。 HTTP请求…

rocketmq-5.1.2的dleger高可用集群部署

1、背景 原先为5.0.0版本&#xff0c;因检查出有漏洞&#xff0c;升级到5.1.2版本。 【Rocketmq是阿里巴巴在2012年开发的分布式消息中间件&#xff0c;专为万亿级超大规模的消息处理而设计&#xff0c;具有高吞吐量、低延迟、海量堆积、顺序收发等特点。在一定条件下&#xf…

天锐绿盾 | 无感知加密软件、透明加密系统、数据防泄漏软件

摘要&#xff1a;文件加密软件,包含禁止非授权的文件泄密和抄袭复制解决方案即使被复制泄密都是自动加密无法阅读,透明加密,反复制软件,内网监控,文件加密,网络安全方案,透明文件加密,加密文件,图纸加密,知识产权保护,加密数据; 通过绿盾信息安全管理软件&#xff0c;系统在不改…