filtered = Lists.newArrayList();
for (int i = 0; i < flags.size(); i++) {
final String receiverId = receiverIds.get(i);
if (EXISTS != flags.get(i)) {
filtered.add(receiverId);
log.warn("rateLimiterFilter_pass. [rateLimiterKey={}]", buildRecieverRateLimiterKey(msgType, receiverId, topic));
} else {
log.warn("rateLimiterFilter_not_pass. [rateLimiterKey={}]", buildRecieverRateLimiterKey(msgType, receiverId, topic));
}
}
return filtered;
}
}
} catch (Exception e) {
log.error("pipeline_rateLimiter_fr_redis_error. [msgType={} topic={} receiverIds={}]", msgType, topic, JSON.toJSONString(receiverIds), e);
} finally {
if (pipeline != null) {
pipeline.close();
}
}
问题现象
以上代码一旦执行到 pipeline.syncAndReturnAll() 时,返回Lua执行的结果中,全是异常,异常类型为 redis.clients.jedis.exceptions.JedisMovedDataException ,描述为"MOVED 10493 10.101.39.148:11115";
原因分析
Redis集群模式下,通过hash槽算法维护key与slot的映射,从而来确定一次命令需要路由到哪个节点执行;关于Redis solt的知识点,可参考我之前的文章《Redis——Cluster数据分布算法&哈希槽》;
顾名思义,JedisMovedDataException 这类问题一般发生于执行redis命令时,发现准备路由的节点与该key实际所在的节点不一致;常见的场景如Redis节点扩缩容导致的slot迁移,最简单的解决办法就是使用JedisCluster对象替换Jedis对象 ;
但是有时候,"JedisCluster对象替换Jedis对象"并不能由我们决定,如此次使用的JedisClusterPipeLine对象,执行eval方法时,封装好的源码就是通过Jedis来执行的,也就是说我们改不了;
既然不能直接解决问题,就得分析原因了,为什么根据key找不到正确的slot?在搞清楚这个问题之前,先要弄清楚一个问题——Lua脚本是允多key和多参数的,对应Lua中的KEY[N] 和ARGV[N] ,既然hash槽算法是通过 CRC16("key")%16384 计算slot的,那么当可能存在单key OR 多key 情况时——
Redis Cluster模式下能否使用Lua脚本呢?
先说结论——可以,但是对Multi-keys有要求;分以下2种情况:
集群模式下,是支持执行单Key的Lua脚本的;比较容易理解,因为只有1个key,所以直接根据这个key来找slot即可,不存在冲突问题;
但是对于多key,当这多个key执行 CRC16("key")%16384 落到相同的slot时,Lua脚本可以正常执行;当结果分散在不同的slot时,会发现Redis报错 :
(error) CROSSSLOT Keys in request don’t hash to the same slot
如何能保证Lua中的多个key落在相同的hash槽呢?
默认下,redis在计算key的槽时,会对整个key做CRC16哈希取值,但是其API也开放了功能——redis hashtag ,即通过tag,对key中指定的一段做CRC16哈希取值,这样可以让不同的key落到相同的哈希槽上;
通过redis hashtag源码解析可知,仅对key中{...}里的部分参与hash,如果有多个花括号,从左向右,取第一个花括号中的内容进行hash;若第一个花括号中内容为空如:a{}c{d},则整个key参与hash;达到的效果就是,相同的hashtag被分配到相同的槽,即相同的redis节点;不过滥用hash tag可能导致节点上的key数量分布不均匀 ;
明确上面的问题后,再来看下我们的问题——
既然我们的Lua只有单个Key,为什么根据key找不到正确的slot ?
查看 pipeline.eval(...) 的源码,如下:
可以看到,源码是用script来作为计算slot的参数的,而非key;那这算不算Bug呢?
——算!查阅jedis的GitHub issues,发现确实有:fix eval & evalsha in pipeline by minisancy · Pull Request #2257 · redis/jedis · GitHub
后面咨询了公司中间件工程师,了解到该问题于2020年9月修复,已经是Jedis 3.x版本了,我们当前的Jedis版本不支持;
所以,问题的原因是Jedis旧版本的一个BUG;
看了下后序Jedis的一个commit修复记录,如下:
src/main/java/redis/clients/jedis/MultiNodePipelineBase.java
使用了CommandObjects对象来包装命令,根据命令key来计算slot,解决了pipeline执行Lua脚本的问题;
此外还发现了旧版本Jedis执行Lua脚本的一个"限制 OR Bug",Jedis封装Lua脚本的执行结果时,强制返回类型为String,如果Lua返回的值为数值型,执行后会报错Long转byte[]的类型转换错误,代码如下:
小结
问题的结论就是,老版本的Jedis的pipeline开放了eval方法,但是实际上是不支持的,因为无法确保对script取slot跟对原key取到的slot一致;此外,执行eval的结果强制为String类型,而我们一般的Lua返回结果为数值型,在执行时会出现运行时异常java.lang.ClassCastException;
可见,第三方的中间件包也不一定靠谱,在发现问题时要能根据源码和原理分析原因,敢于去官方Git下去咨询或提Issue;
补充:使用Lua脚本常遇到的问题
1. Lua中get命令获得的东西判断nil的坑
现象:
此时的key不存在,那么按理说Lua结果应该返回nil,也就是说上面的执行结果应该是0才对,但是Lua给出了1这个匪夷所思的结果 ;
参考了stackoverflow上的这个问题redis lua can't work properly due to wrong type comparison - Stack Overflow以及它里面提到的官方的这篇文章EVAL | Redis,发现了下面这个“潜规则”:
Redis Nil bulk reply and Nil multi bulk reply -> Lua false boolean type
也就是说,Lua中的get会将nil转换成false,根据这个结果,我们重新调整了上面的Lua script如下:
结论 :对get的返回结果预期为数值型时,使用tonumber转换结果再判断;若非数值型,通过false判断是否存在而不要使用nil判断 ;
2. Redis到Lua数据的类型转换
示例:
127.0.0.1:6379> set test 2
OK
127.0.0.1:6379> object encoding test
"int"
可以看到,我们将key test设置成了整型2,查看它的encoding发现也是int类型,那么我们在lua script中将test get成一个变量,感觉应该也是number类型吧,但是现实是残酷的:
127.0.0.1:6379> eval "local a = redis.call('get', 'test'); return type(a);" 0
"string"
我们得到的是string类型。这是为啥嘞?
这个问题我们google了很久,最后查看了很长时间的源码,后来发现官方的文档其实已经说明了这个问题,但是不是那么明显。在官方的这篇文档中,提到了Redis将会怎样把类型映射到lua中:
Redis to Lua conversion table.
Redis integer reply -> Lua number
Redis bulk reply -> Lua string
Redis multi bulk reply -> Lua table (may have other Redis data types nested)
Redis status reply -> Lua table with a single ok field containing the status
Redis error reply -> Lua table with a single err field containing the error
Redis Nil bulk reply and Nil multi bulk reply -> Lua false boolean type
官方文档中提到的这个table,有一个很重要的信息,就是redis对于类型的转换,是针对每一个命令的,和key本身是个啥没有关系,这就是上面每一条对应的都是一个XXX reply;
结论 :lua内获得的redis的数据,不根据key的类型决定,而是根据key的reply决定;另外多提一句,eval中传入的ARGV数组,redis官方全部都是作为string来处理的 !
3. Lua script在cluster中执行的目标机器
在redis cluster环境中,key是按照slot槽来存储的,而不同的slot槽又是存储在不同的机器上的,那当我们运行的一个lua script涉及到多个key时,到底由哪个机器来执行呢?
这个坑里涉及2个问题:
(1)能不能把key直接写到lua script里?
(2)如果我们有多个key,redis到底会把lua script放到哪个机器上去执行?
eval命令后面会跟一个key的列表,但是同样,命令没有禁止我们把key直接写到lua script里,即也提供了不含key的eval重载方法;
如果我们把key写到了lua script中,那么即使lua script能够顺利进入某个机器开始执行,大概率也会出现当前机器中没有我们写死的这个key,此时会得到下面的错误:
Lua script attempted to access a non local key in a cluster node
下面这段是来自Redis官方的eval命令的文档:
All Redis commands must be analyzed before execution to determine which keys the command will operate on. In order for this to be true for EVAL, keys must be passed explicitly. This is useful in many ways, but especially to make sure Redis Cluster can forward your request to the appropriate cluster node.
加粗的那句话表明,为了能让redis正确的搞明白key到底该怎么执行,需要显式的传进去,也就是说,我们需要用eval的key的参数列表来传入我们要操作的key,而不能把它直接写到lua script里 !
接下来的一个问题就是,如果我们有多个key,redis到底会把lua script放到哪个机器上去执行? 我们其实可以自己去尝试一下,执行一个需要多个key的lua script,极大概率你会得到下面的错误:
(error) CROSSSLOT Keys in request don't hash to the same slot
Redis要求,在使用eval的时候,涉及到的key必须在同一个slot槽中,否则,就会出现上面的错误 !
解决上面问题的方法就是使用hash tag (hash tag可以参照官方文档);我们需要把key中的一部分使用{}包起来,redis将通过{}中间的内容作为计算slot的key,类似key1{mykey}、key2{mykey}这样的都会存放到同一个slot中;当然,hash tag带来的一个问题就是会让cluster中某个节点压力增加,这个只能取舍了;
4. eval和evalsha的使用区别
eval会把script全部都发过去执行,而evalsha是执行缓存在redis服务器的scipt(通过参数中的script的hash值去找),如果redis服务器上没有缓存这个script,会抛出错误NoScriptError;
建议使用evalsha方法 ,因为会节省网络传输的数据提升性能,但是首次需要先把写好的lua script使用script load方式加载到redis服务器,事实上通过eval命令就可以触发;下面是spring-data-redis的代码实现:
Object result;
try {
result = connection.evalSha(script.getSha1(), returnType, numKeys, keysAndArgs);
} catch (Exception e) {
if (!ScriptUtils.exceptionContainsNoScriptError(e)) {
throw e instanceof RuntimeException ? (RuntimeException) e : new
RedisSystemException(e.getMessage(), e);
}
// 通过eval命令达到load script的作用
result = connection.eval(scriptBytes(script), returnType, numKeys, keysAndArgs);
}
5. Redis LuaScript并非真的强原子性
redis script 不具备 all or nothing 特性的,可能是 crud 程序猿会遇到,这可能是思维惯性导致的;举个例子:
redis.call('SET', 'key1', 'value1');
local a = b;
redis.call('SET', 'key2', 'value2');
redis 在执行 local a = b; 这一行时,就会报错如下的错误:
(error) ERR Error running script (call to f_71007e955106f406b23cfaba7647eec1081fda7d): @enable_strict_lua:15: user_script:1: Script attempted to access nonexistent global variable 'b'
然后后续的代码便不再执行,对于长期习惯于丢异常就会回滚修改的 crud 程序员来说,key1 和 key2 的值肯定没有设置成功;然而事实是,上诉代码是一半成功(成功设置 key1),一半根本没有执行(没有执行到 key2 的位置) ;
简而言之,redis script 的原子性特性只是指 redis 只使用一个 lua 解释器执行 script,且是单线程执行 script;但是 script 执行中途报错,是不会将修改回滚的,回滚特性应该属于事务,而 redis 其实是没有严格的事务特性的,redis script 是没有 all or nothing 的特性;关于Lua脚本事务性的验证可参考我之前的文章Redis——“事务“/Lua脚本_lua脚本;
其他:B站之前一次大的线上问题也是由网关层的Lua脚本对执行结果的预期值与实际结果类型不一致导致的:2021.07.13 B站是这样崩的_哔哩哔哩_bilibili
参考:
Redis——Cluster数据分布算法&哈希槽
Redis Cluster中使用Lua脚本
Redis集群扩容导致的Jedis客户端报JedisMovedDataException异常
fix eval & evalsha in pipeline by minisancy · Pull Request #2257 · redis/jedis · GitHub
Redis eval命令踩得那些坑 · Issue #7 · nethibernate/blog · GitHub
你可能感兴趣的:(编码踩坑,Redis,jedis,redis,pipeline,lua,java)
iOS安全和逆向系列教程 第16篇:Frida入门与高级应用
自学不成才
iOS安全和逆向系列教程 cocoa macos objective-c
iOS逆向工程专栏第16篇:Frida入门与高级应用前言欢迎来到iOS逆向工程专栏的第16篇文章!在上一篇中,我们探讨了Cycript这一强大的逆向分析工具。今天,我们将深入学习功能更为强大、更为灵活的动态插桩工具——Frida。Frida作为现代iOS逆向工程中最受欢迎的工具之一,其强大的跨平台能力和灵活的JavaScript引擎使得我们能够轻松地分析和修改iOS应用的运行时行为。无论是逆向分析
Github 2025-03-07 Java开源项目日报Top7
老孙正经胡说
github java 开源 Github趋势分析 开源项目 Python Golang
根据GithubTrendings的统计,今日(2025-03-07统计)共有7个项目上榜。根据开发语言中项目的数量,汇总情况如下:开发语言项目数量Java项目7TypeScript项目1Ruby项目1Java实现的算法集合:使用Gitpod.io进行编辑和贡献创建周期:2883天开发语言:Java协议类型:MITLicenseStar数量:57266个Fork数量:18692次关注人数:5726
Github 2025-03-02 php开源项目日报Top10
老孙正经胡说
github php 开源 Github趋势分析 开源项目 Python Golang
根据GithubTrendings的统计,今日(2025-03-02统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下:开发语言项目数量PHP项目10Blade项目1JavaScript项目1Nextcloud服务器:安全的数据之家创建周期:2796天开发语言:PHP,JavaScript协议类型:GNUAfferoGeneralPublicLicensev3.0Star数量:248
Github 2024-07-12 Java开源项目日报Top10
老孙正经胡说
github java 开源 Github趋势分析 开源项目 Python Golang
根据GithubTrendings的统计,今日(2024-07-12统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下:开发语言项目数量Java项目10Android开源轻量级流媒体前端创建周期:3158天开发语言:Java协议类型:GNUGeneralPublicLicensev3.0Star数量:28641个Fork数量:2896次关注人数:28641人贡献人数:312人Open
JDBC(超详细)
肉肉的小白
数据库 java mysql
1简介JDBC(JavaDataBaseConnectivity,java数据库连接)是一种用于执行SQL语句的JavaAPI,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序Java具有坚固、安全、易于使用、易于理解和可从网络上自动下载等特性,是编写数据库应用程序的杰出语言。
Lucene初探之总体架构
Derrick_gu
java Lucene 架构 文档 对象 搜索 Lucene
从总体上来说,Lucene的可以被概括为三点:高效、可扩展的全文检索库;基于Java实现;支持对纯文本文件进行索引可搜索;Lucene的工作流程和架构如下所示:通过该图片,我们可以看出,Lucene的工作流程可以被分为两个部分:索引、搜索。我们可以将这些过程进行抽象组件化:通过上下两个图片的对比,基本上可以直观地了解各个组件的工作:Document代表被索引的各个分散的文档;IndexWirter
分布式锁—Redisson的读写锁
液态不合群
分布式 junit
1.Redisson读写锁RedissonReadWriteLock概述(1)RedissonReadWriteLock的简介RedissonReadWriteLock提供了两个方法分别获取读锁和写锁。RedissonReadWriteLock的readLock()方法可以获取读锁RedissonReadLock。RedissonReadWriteLock的writeLock()方法可以获取写锁R
Java中getter和setter方法的作用
以恒1
java 开发语言
Java中getter和setter方法的作用在Java中,getter和setter方法是面向对象编程中实现封装的核心手段,它们的作用不仅限于访问或修改对象的属性,还为代码的灵活性、安全性和可维护性提供了重要保障。以下是其核心作用的详细说明:idea快捷键:alt加insert加enter,选择getter和setter方法即可一、核心作用1.实现封装(Encapsulation)隐藏内部实现:
【Flink】(二)详解 Flink 运行架构_flink的运行架构负荷分担是什么
2301_82242724
flink 架构 大数据
作业管理器(JobManager)、资源管理器(ResourceManager)、任务管理器(TaskManager),以及分发器(Dispatcher)。因为Flink是用Java和Scala实现的,所以所有组件都会运行在Java虚拟机上。每个组件的职责如下:作业管理器(JobManager)控制一个应用程序执行的主进程,也就是说,每个应用程序都会被一个不同的JobManager所控制执行。Jo
DevOps落地实践点滴和踩坑记录-(1)
xuhss_com
计算机 devops 运维 计算机
优质资源分享学习路线指引(点击解锁)知识定位人群定位Python实战微信订餐小程序进阶级本课程是pythonflask+微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一个全栈订餐系统。Python量化交易实战入门级手把手带你打造一个易扩展、更安全、效率更高的量化交易系统记录初衷本人一直在从事企业内DevOps落地实践的工作,走了不少弯路,也努力在想办法解决面临的问题,期间也经历过不少人和事
Java 大视界 -- Java 大数据在智能安防入侵检测与行为分析中的应用(108)
青云交
大数据新视界 Java 大视界 java 大数据 智能安防 入侵检测 实时流处理 LSTM 联邦学习
亲爱的朋友们,热烈欢迎来到青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而我的博客正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也期待你毫无保留地分享独特见解,愿我们于此携手成长,共赴新程!一、欢迎加入【福利社群】点击快速加入:青云交灵犀技韵交响盛汇福利社群点击快速加入2:2024CSDN博客之星创作交流营(NEW)二、本博客的精华专栏:大数据新视
Java泛型类型擦除问题
ikt4435
编程 程序员 Java java 开发语言
以前就了解过Java泛型的实现是不完整的,最近在做一些代码重构的时候遇到一些Java泛型类型擦除的问题,简单的来说,Java泛型中所指定的类型在编译时会将其去除,因此List和List在编译成字节码的时候实际上是一样的。因此java泛型只能做到编译期检查的功能,运行期间就不能保证类型安全。我最近遇到的一个问题如下:假设有两个bean类/**Test.*/@Data@NoArgsConstructo
Java 大视界 -- 基于 Java 的大数据分布式任务调度系统设计与实现(117)
青云交
大数据新视界 Java 大视界 java 大数据 分布式 分布式任务调度 系统设计 调度算法 容错机制
亲爱的朋友们,热烈欢迎来到青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而我的博客正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也期待你毫无保留地分享独特见解,愿我们于此携手成长,共赴新程!一、欢迎加入【福利社群】点击快速加入:青云交灵犀技韵交响盛汇福利社群点击快速加入2:2024CSDN博客之星创作交流营(NEW)二、本博客的精华专栏:大数据新视
图片转base64编码用途
太空漫步11
mysql
将这张图片转成base64编码格式,就能将图片以字符串类型存储在数据库中。该字符串很长,用varchar类型不够,要使用TEXT类型。createtableimages(idintPRIMARYKEYAUTOINCREMENT,codeTEXT)data:image/jpeg;base64,UklGRjpIAABXRUJQVlA4IC5IAABwYQGdASqAAoQBPpFCm0olo6ktqV
ListView展示图片
太空漫步11
windows
packagecom.example.myapplication5;importandroid.os.Bundle;importandroid.widget.ListView;importandroidx.appcompat.app.AppCompatActivity;importcom.example.adapter.ImageAdapter;importjava.util.ArrayList;
Java中的插件系统
城南|阿洋-计算机从小白到大神
java python 开发语言
大家好,我是城南。在现代软件开发中,插件系统作为一种灵活、可扩展的架构设计,逐渐成为构建大型应用程序的利器。今天我们将深入探讨Java中的插件系统,带你了解其实现细节和设计哲学。什么是插件系统?插件系统是一种允许应用程序通过外部组件来扩展功能的机制。通过这种机制,开发者可以在不修改原有代码的情况下,动态地添加、删除或更改应用程序的功能。这种架构的优势在于其高扩展性和灵活性,使得软件能够快速响应变化
使用Lua和lua-resty-http-simple库的爬虫程序爬取图片
q56731523
lua http 爬虫
使用Lua和lua-resty-http-simple库编写爬虫程序来下载图片是一个很实用的任务。lua-resty-http-simple是一个用于HTTP请求的简单库,可以帮助我们轻松地发送GET请求并处理响应。下面是一个完整的示例程序,展示如何使用lua-resty-http-simple库来下载图片。1.安装lua-resty-http-simple库你可以通过luarocks安装lua-
java取列表a和b的交集_JAVA——两个List集合求交集、并集和差集(去重)模板
FreVision优选
java取列表a和b的交集
关注微信公众号:CodingTechWork,一起学习进步。引言经常遇到一些集合类之间的过滤数据、求合集之类的问题,在此以List为例,毕竟在数据库中取数据后,我们使用比较多的是List集合进行操作。模板代码publicstaticvoidmain(String[]args){ListstringList=newArrayList(Arrays.asList("a,b,c,d,e,f,g,h".s
Java List集合取交集的五种方式
偏爱星雾缠绕15
java list 开发语言
在Java中,List集合是用于存储一系列对象的数据结构。当我们要获取两个List集合的交集时,有多种方法可以实现。下面将介绍几种常见的方式。1.使用Java8的StreamAPIJava8引入了StreamAPI,它提供了一种声明式的方式来处理数据。importjava.util.Arrays;importjava.util.List;importjava.util.stream.Collect
利用Java的反射和动态代理实现插件化架构
Coder_Kevin_Vans
架构 jvm
插件化架构是一种将应用程序的功能模块化并以插件形式加载和运行的架构模式。利用Java的反射和动态代理可以实现插件化架构的核心功能,包括插件的加载、实例化、调用和卸载等。下面是一种基本的实现思路:1.定义插件接口:首先定义一个插件接口,用于规范插件的功能和调用方法。2.插件的实现:编写插件实现类,实现插件接口,并提供相应的功能实现。3.插件加载器:编写插件加载器,用于加载和管理插件。插件加载器可以扫
conda的作用
一只积极向上的小咸鱼
conda
一概览Conda是一个开源的包管理和环境管理工具,主要用于Python及其他编程语言的依赖管理和环境隔离。它的核心作用有以下几点:1.包管理可以安装、更新、卸载Python及其依赖包(类似于pip)。支持多语言(不仅限于Python,还支持C/C++,R,Ruby,Lua等)。依赖自动管理,能解决复杂的库依赖问题,例如:condainstallnumpypandas2.环境管理允许创建多个独立的虚
java 如何判断两个List<String>集合是否存在交集
单线程bug
AI对话优质回答 java list
在Java中判断两个List集合是否存在交集,可以使用以下几种方法:方法一:使用retainAll方法retainAll方法保留集合中与另一个集合相同的元素,如果集合发生变化,则表示存在交集。Listlist1=Arrays.asList("a","b","c");Listlist2=Arrays.asList("c","d","e");Listtemp=newArrayListlist1=Arr
java构造方法,构造代码块,静态代码块的执行顺序
后端java
构造方法,构造代码块,静态代码块的执行顺序静态代码块:用static声明,jvm加载类时执行,仅执行一次类中直接用{}定义,每次创建对象时执行同级别的变量(static和普通变量)的执行顺序由代码执行顺序决定(从上到下也就是代码书写顺序)代码解读复制代码packagecom.rumenz;publicclassRumenz{privateIntegerid=100;privatestaticStr
内网激活JRebel插件(无网络环境)
Cynicism_Smile
后端 java idea jrebel
1.官网下载安装包,JRebelandXRebelJRebelandXRebel-IntelliJIDEsPlugin|Marketplace2.以IInstallPluginfromDisk的方式读取3.运行JrebelServer.jar终端输入:java-jarJrebelServer.jar-p8080(默认8080端口)服务会自动打开浏览器至http://localhost:8080/点
【最佳实践】FIT框架:插件化架构如何彻底解决大型项目依赖管理难题?
华为数据存储开源
架构 java python
在传统Java开发模式中,大型项目的依赖管理问题一直是开发团队的痛点。无论是依赖版本冲突、服务更新时的依赖调整,还是模块间的耦合性问题,都像一张错综复杂的蜘蛛网,让开发者疲于应对。然而,FIT框架的出现,彻底改变了这一局面。它以插件化架构为核心,通过自定义的类加载隔离机制,将复杂依赖问题简化为插件与接口之间的清晰关系,为传统开发模式中棘手的依赖排查问题提供了一种全新的解决方案。传统Java开发中的
Java Web 中的 Server-Sent Events (SSE) 入门介绍
zru_9602
前端 java 前端 开发语言
JavaWeb中的Server-SentEvents(SSE)入门介绍Server-SentEvents(服务器发送事件,简称SSE)是一种用于实现服务器向客户端推送实时更新的技术。与WebSocket不同,SSE是一种单向通信技术,适用于只需要从服务器到客户端的数据流场景。1.基本概念SSE的特点:单向通信:数据只能从服务器发送到客户端。长连接:客户端与服务器保持一个长时间的HTTP连接。自动重
SpringBoot对接外部API三大绝技:RestTemplate vs WebClient vs Feign,你Pick哪个?
墨瑾轩
一起学学Java【一】 java
在SpringBoot应用中调用外部接口是常见的需求,通常用于集成第三方服务、微服务间通信等场景。以下是三种常用的调用外部接口的方式,包括代码示例和详细注释:1.使用RestTemplateRestTemplate是Spring提供的一个用于访问REST服务的客户端模板类,它简化了HTTP请求的处理过程。 Javaimportorg.springframework.beans.factory.an
机器学习——使用分类特征的一种独热编码,
小卷心菜.
机器学习 人工智能
在我们目前看到的例子中,每个特性只能具有两个可能的值中的一个,耳朵形状不是尖的就是软的,脸型不是圆就是不圆,胡须不是存在就是不存在,但是如果特性可以具有两个以上的离散值呢?如何使用一个热编码来解决这样的特性?下图是我们宠物收养中心申请的新培训集,所有的数据都是一样的,除了耳形特征有尖软之外还有椭圆形,所以这个特征仍然是一个分类值特征,但它可以有三个可能的值,而不仅仅是两个可能的值,这意味着当你在这
java手机小游戏源码_Java手机版数独小游戏(J2me)JAVA游戏源码下载
weixin_39748773
java手机小游戏源码
数独游戏,相信朋友们都知道的,以前也经常玩的,用VB、VC++和Delphi版编写的都在网上宣布过,今天放出一个鉴于Java的J2me手机版的,大致看一下截图,这是在Java模拟机运行的界面,带有Java源码,学习J2me编程的朋友有资料看了。Java手机版数独小游戏(J2me)(1folders,2files,1.38KB,754.03KBintotal.)源码(1folders,2f
java课程 数独 文库_JAVA版数独小游戏源码(课程设计)
weixin_39640543
java课程 数独 文库
【实例简介】JAVA版数独小游戏源码(课程设计)【实例截图】【核心代码】Sudoku├──bin│└──com│└──marssoft│└──sudoku│├──Sudoku.class│├──bean││├──Base.class││├──Member.class││└──Number.class│├──display││├──LineFrame$RePaint.class││└──LineFr
Hadoop(一)
朱辉辉33
hadoop linux
今天在诺基亚第一天开始培训大数据,因为之前没接触过Linux,所以这次一起学了,任务量还是蛮大的。
首先下载安装了Xshell软件,然后公司给了账号密码连接上了河南郑州那边的服务器,接下来开始按照给的资料学习,全英文的,头也不讲解,说锻炼我们的学习能力,然后就开始跌跌撞撞的自学。这里写部分已经运行成功的代码吧.
在hdfs下,运行hadoop fs -mkdir /u
maven An error occurred while filtering resources
blackproof
maven 报错
转:http://stackoverflow.com/questions/18145774/eclipse-an-error-occurred-while-filtering-resources
maven报错:
maven An error occurred while filtering resources
Maven -> Update Proje
jdk常用故障排查命令
daysinsun
jvm
linux下常见定位命令:
1、jps 输出Java进程
-q 只输出进程ID的名称,省略主类的名称;
-m 输出进程启动时传递给main函数的参数;
&nb
java 位移运算与乘法运算
周凡杨
java 位移 运算 乘法
对于 JAVA 编程中,适当的采用位移运算,会减少代码的运行时间,提高项目的运行效率。这个可以从一道面试题说起:
问题:
用最有效率的方法算出2 乘以8 等於几?”
答案:2 << 3
由此就引发了我的思考,为什么位移运算会比乘法运算更快呢?其实简单的想想,计算机的内存是用由 0 和 1 组成的二
java中的枚举(enmu)
g21121
java
从jdk1.5开始,java增加了enum(枚举)这个类型,但是大家在平时运用中还是比较少用到枚举的,而且很多人和我一样对枚举一知半解,下面就跟大家一起学习下enmu枚举。先看一个最简单的枚举类型,一个返回类型的枚举:
public enum ResultType {
/**
* 成功
*/
SUCCESS,
/**
* 失败
*/
FAIL,
MQ初级学习
510888780
activemq
1.下载ActiveMQ
去官方网站下载:http://activemq.apache.org/
2.运行ActiveMQ
解压缩apache-activemq-5.9.0-bin.zip到C盘,然后双击apache-activemq-5.9.0-\bin\activemq-admin.bat运行ActiveMQ程序。
启动ActiveMQ以后,登陆:http://localhos
Spring_Transactional_Propagation
布衣凌宇
spring transactional
//事务传播属性
@Transactional(propagation=Propagation.REQUIRED)//如果有事务,那么加入事务,没有的话新创建一个
@Transactional(propagation=Propagation.NOT_SUPPORTED)//这个方法不开启事务
@Transactional(propagation=Propagation.REQUIREDS_N
我的spring学习笔记12-idref与ref的区别
aijuans
spring
idref用来将容器内其他bean的id传给<constructor-arg>/<property>元素,同时提供错误验证功能。例如:
<bean id ="theTargetBean" class="..." />
<bean id ="theClientBean" class=&quo
Jqplot之折线图
antlove
js jquery Web timeseries jqplot
timeseriesChart.html
<script type="text/javascript" src="jslib/jquery.min.js"></script>
<script type="text/javascript" src="jslib/excanvas.min.js&
JDBC中事务处理应用
百合不是茶
java JDBC编程 事务控制语句
解释事务的概念; 事务控制是sql语句中的核心之一;事务控制的作用就是保证数据的正常执行与异常之后可以恢复
事务常用命令:
Commit提交
[转]ConcurrentHashMap Collections.synchronizedMap和Hashtable讨论
bijian1013
java 多线程 线程安全 HashMap
在Java类库中出现的第一个关联的集合类是Hashtable,它是JDK1.0的一部分。 Hashtable提供了一种易于使用的、线程安全的、关联的map功能,这当然也是方便的。然而,线程安全性是凭代价换来的――Hashtable的所有方法都是同步的。此时,无竞争的同步会导致可观的性能代价。Hashtable的后继者HashMap是作为JDK1.2中的集合框架的一部分出现的,它通过提供一个不同步的
ng-if与ng-show、ng-hide指令的区别和注意事项
bijian1013
JavaScript AngularJS
angularJS中的ng-show、ng-hide、ng-if指令都可以用来控制dom元素的显示或隐藏。ng-show和ng-hide根据所给表达式的值来显示或隐藏HTML元素。当赋值给ng-show指令的值为false时元素会被隐藏,值为true时元素会显示。ng-hide功能类似,使用方式相反。元素的显示或
【持久化框架MyBatis3七】MyBatis3定义typeHandler
bit1129
TypeHandler
什么是typeHandler?
typeHandler用于将某个类型的数据映射到表的某一列上,以完成MyBatis列跟某个属性的映射
内置typeHandler
MyBatis内置了很多typeHandler,这写typeHandler通过org.apache.ibatis.type.TypeHandlerRegistry进行注册,比如对于日期型数据的typeHandler,
上传下载文件rz,sz命令
bitcarter
linux命令rz
刚开始使用rz上传和sz下载命令:
因为我们是通过secureCRT终端工具进行使用的所以会有上传下载这样的需求:
我遇到的问题:
sz下载A文件10M左右,没有问题
但是将这个文件A再传到另一天服务器上时就出现传不上去,甚至出现乱码,死掉现象,具体问题
解决方法:
上传命令改为;rz -ybe
下载命令改为:sz -be filename
如果还是有问题:
那就是文
通过ngx-lua来统计nginx上的虚拟主机性能数据
ronin47
ngx-lua 统计 解禁ip
介绍
以前我们为nginx做统计,都是通过对日志的分析来完成.比较麻烦,现在基于ngx_lua插件,开发了实时统计站点状态的脚本,解放生产力.项目主页: https://github.com/skyeydemon/ngx-lua-stats 功能
支持分不同虚拟主机统计, 同一个虚拟主机下可以分不同的location统计.
可以统计与query-times request-time
java-68-把数组排成最小的数。一个正整数数组,将它们连接起来排成一个数,输出能排出的所有数字中最小的。例如输入数组{32, 321},则输出32132
bylijinnan
java
import java.util.Arrays;
import java.util.Comparator;
public class MinNumFromIntArray {
/**
* Q68输入一个正整数数组,将它们连接起来排成一个数,输出能排出的所有数字中最小的一个。
* 例如输入数组{32, 321},则输出这两个能排成的最小数字32132。请给出解决问题
Oracle基本操作
ccii
Oracle SQL总结 Oracle SQL语法 Oracle基本操作 Oracle SQL
一、表操作
1. 常用数据类型
NUMBER(p,s):可变长度的数字。p表示整数加小数的最大位数,s为最大小数位数。支持最大精度为38位
NVARCHAR2(size):变长字符串,最大长度为4000字节(以字符数为单位)
VARCHAR2(size):变长字符串,最大长度为4000字节(以字节数为单位)
CHAR(size):定长字符串,最大长度为2000字节,最小为1字节,默认
[强人工智能]实现强人工智能的路线图
comsci
人工智能
1:创建一个用于记录拓扑网络连接的矩阵数据表
2:自动构造或者人工复制一个包含10万个连接(1000*1000)的流程图
3:将这个流程图导入到矩阵数据表中
4:在矩阵的每个有意义的节点中嵌入一段简单的
给Tomcat,Apache配置gzip压缩(HTTP压缩)功能
cwqcwqmax9
apache
背景:
HTTP 压缩可以大大提高浏览网站的速度,它的原理是,在客户端请求网页后,从服务器端将网页文件压缩,再下载到客户端,由客户端的浏览器负责解压缩并浏览。相对于普通的浏览过程HTML ,CSS,Javascript , Text ,它可以节省40%左右的流量。更为重要的是,它可以对动态生成的,包括CGI、PHP , JSP , ASP , Servlet,SHTML等输出的网页也能进行压缩,
SpringMVC and Struts2
dashuaifu
struts2 springMVC
SpringMVC VS Struts2
1:
spring3开发效率高于struts
2:
spring3 mvc可以认为已经100%零配置
3:
struts2是类级别的拦截, 一个类对应一个request上下文,
springmvc是方法级别的拦截,一个方法对应一个request上下文,而方法同时又跟一个url对应
所以说从架构本身上 spring3 mvc就容易实现r
windows常用命令行命令
dcj3sjt126com
windows cmd command
在windows系统中,点击开始-运行,可以直接输入命令行,快速打开一些原本需要多次点击图标才能打开的界面,如常用的输入cmd打开dos命令行,输入taskmgr打开任务管理器。此处列出了网上搜集到的一些常用命令。winver 检查windows版本 wmimgmt.msc 打开windows管理体系结构(wmi) wupdmgr windows更新程序 wscrip
再看知名应用背后的第三方开源项目
dcj3sjt126com
ios
知名应用程序的设计和技术一直都是开发者需要学习的,同样这些应用所使用的开源框架也是不可忽视的一部分。此前《
iOS第三方开源库的吐槽和备忘》中作者ibireme列举了国内多款知名应用所使用的开源框架,并对其中一些框架进行了分析,同样国外开发者
@iOSCowboy也在博客中给我们列出了国外多款知名应用使用的开源框架。另外txx's blog中详细介绍了
Facebook Paper使用的第三
Objective-c单例模式的正确写法
jsntghf
单例 ios iPhone
一般情况下,可能我们写的单例模式是这样的:
#import <Foundation/Foundation.h>
@interface Downloader : NSObject
+ (instancetype)sharedDownloader;
@end
#import "Downloader.h"
@implementation
jquery easyui datagrid 加载成功,选中某一行
hae
jquery easyui datagrid 数据加载
1.首先你需要设置datagrid的onLoadSuccess
$(
'#dg'
).datagrid({onLoadSuccess :
function
(data){
$(
'#dg'
).datagrid(
'selectRow'
,3);
}});
2.onL
jQuery用户数字打分评价效果
ini
JavaScript html jquery Web css
效果体验:http://hovertree.com/texiao/jquery/5.htmHTML文件代码:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>jQuery用户数字打分评分代码 - HoverTree</
mybatis的paramType
kerryg
DAO sql
MyBatis传多个参数:
1、采用#{0},#{1}获得参数:
Dao层函数方法:
public User selectUser(String name,String area);
对应的Mapper.xml
<select id="selectUser" result
centos 7安装mysql5.5
MrLee23
centos
首先centos7 已经不支持mysql,因为收费了你懂得,所以内部集成了mariadb,而安装mysql的话会和mariadb的文件冲突,所以需要先卸载掉mariadb,以下为卸载mariadb,安装mysql的步骤。
#列出所有被安装的rpm package rpm -qa | grep mariadb
#卸载
rpm -e mariadb-libs-5.
利用thrift来实现消息群发
qifeifei
thrift
Thrift项目一般用来做内部项目接偶用的,还有能跨不同语言的功能,非常方便,一般前端系统和后台server线上都是3个节点,然后前端通过获取client来访问后台server,那么如果是多太server,就是有一个负载均衡的方法,然后最后访问其中一个节点。那么换个思路,能不能发送给所有节点的server呢,如果能就
实现一个sizeof获取Java对象大小
teasp
java HotSpot 内存 对象大小 sizeof
由于Java的设计者不想让程序员管理和了解内存的使用,我们想要知道一个对象在内存中的大小变得比较困难了。本文提供了可以获取对象的大小的方法,但是由于各个虚拟机在内存使用上可能存在不同,因此该方法不能在各虚拟机上都适用,而是仅在hotspot 32位虚拟机上,或者其它内存管理方式与hotspot 32位虚拟机相同的虚拟机上 适用。
SVN错误及处理
xiangqian0505
SVN提交文件时服务器强行关闭
在SVN服务控制台打开资源库“SVN无法读取current” ---摘自网络 写道 SVN无法读取current修复方法 Can't read file : End of file found
文件:repository/db/txn_current、repository/db/current
其中current记录当前最新版本号,txn_current记录版本库中版本