首页 文章 精选 留言 我的

精选列表

搜索[告别],共817篇文章
优秀的个人博客,低调大师

【建议使用】告别if,Java超好用参数校验工具类

一、前言 今天和小伙伴们分享一个常用的工具类,共计四个方法,使用场景比较广泛,有用于校验某个对象或对象中指定属性为空值时,直接返回异常,常用语校验前端请求参数;也有当值不为空时,执行指定动作,可减少大量的if条件,如:mybatis请求参数设置;还有用于判断当值不为空时,替代为新值,完成后续动作。 这样描述可能不够清晰,这里我列举了几个使用场景,更多的场景需要小伙伴们根据自己业务需求合理使用。 //场景一,点击登录时,后端校验用户名 if(StringUtils.isEmpty(name)){ throw new Exception("登录用户名不能为空"); } ​ //场景二:属性内容转换为新值 String address = "浙江省杭州市"; if(StringUtils.isNotEmpty(address)){ address ="地址:"+address; } ​ //场景三:替代过多的if条件 SysUserDto userDto = new SysUserDto();//前端参数 ​ SysUser user = new SysUser();//mybatis参数 if(StringUtils.isEmpty(userDto.getName())){ user.setUserName(userDto.getName()) } if(StringUtils.isEmpty(userDto.getPwd())){ user.setPassword(userDto.getPwd()) } 复制代码 \ 二、正文 首先创建一个测试实体类: import lombok.Data; ​ @Data public class SysUser{ private String name; private String password; } 复制代码 2.1 检查多个对象不能为空 测试范例 SysUser user = new SysUser(); SysUser user2 = null; Args.notEmptys(user,user2); 复制代码 方法内容 public static void notEmptys(Object... objects) { for (Object obj : objects) { if (obj == null) { throw new BusinessException("属性不能为空"); } if (obj.toString().trim().isEmpty()) { throw new BusinessException("属性不能为空"); } } } 复制代码 测试结果 Exception in thread "main" 属性不能为空 at com.basic.business.utils.Args.notEmptys(Args.java:27) at com.basic.business.demo.DemoController.main(DemoController.java:43) 复制代码 2.2 校验对象属性不能为空 若将参数【Boolean isAll】设置为true,则会校验全部属性;若设置为false,就需要将检测字段放入【propertys】中。 测试范例 SysUser user = new SysUser(); //用法一:校验全部参数 Args.checkField(user,true,""); //用法二:只校验password参数 Args.checkField(user,false,"password"); 复制代码 方法内容 /** * 对象多字段判空检查 * @param obj 被检查的对象 * @param isAll 是否检查全部参数 * @param propertys 被检查对象中的字段 可多个 */ public static void checkField(Object obj, Boolean isAll, String... propertys) { if (obj != null) { Class<? extends Object> clazz = obj.getClass(); if (isAll) { PropertyDescriptor[] propertyDescriptors = BeanUtils.getPropertyDescriptors(clazz); for (int p = 0; p < propertyDescriptors.length; p++) { checkEachField(obj, propertyDescriptors[p]); } } else { if (propertys != null && propertys.length > 0) { //遍历所有属性 for (int i = 0; i < propertys.length; i++) { String property = propertys[i]; //获取属性信息 BeanUtils.getPropertyDescriptors(clazz); PropertyDescriptor pd = BeanUtils.getPropertyDescriptor(clazz, property); checkEachField(obj, pd); } } } } } ​ private static void checkEachField(Object obj, PropertyDescriptor pd) { Class<? extends Object> clazz = obj.getClass(); String property = pd.getName(); if (pd != null) { //获取当前字段的javabean读方法 Method readMethod = pd.getReadMethod(); if (readMethod != null) { ​ Object invoke = null; try { invoke = readMethod.invoke(obj); } catch (Exception e) { throw new BusinessException("方法 " + readMethod.getName() + "无法执行"); } ​ if (invoke != null) { //String类型单独处理 Class<?> propertyType = pd.getPropertyType(); if ("java.lang.String".equals(propertyType.getName())) { if (StringUtils.isBlank((String) invoke)) { throw new BusinessException("错误 : [ " + property + " ] 不能为空!"); } } else if ("java.util.List".equals(propertyType.getName())) { List list = (List) invoke; if (list.size() == 0) { throw new BusinessException("错误 : [ " + property + " ] 不能为空!"); } } } else { throw new BusinessException("错误 : [ " + property + " ] 不能为空!"); } } else { throw new BusinessException("在 " + clazz + "中 找不到" + "[ " + property + " ] 的 读方法"); } } else { throw new BusinessException("在 " + clazz + "中 找不到" + "[ " + property + " ] 属性"); } } 复制代码 测试结果 用法一结果: Exception in thread "main" 错误 : [ name ] 不能为空! at com.basic.business.utils.Args.checkEachField(Args.java:116) at com.basic.business.utils.Args.checkField(Args.java:77) 用法二结果: Exception in thread "main" 错误 : [ password ] 不能为空! at com.basic.business.utils.Args.checkEachField(Args.java:116) at com.basic.business.utils.Args.checkField(Args.java:77) 复制代码 2.3 参数不为空时执行指定动作 我们经常会遇到这种场景,根据前端参数来组装数据库查询条件,如果不为空我们就将前端值设置到是实体类中,或者如下面这个例子中,当name不为空时,加入到list当中。 测试范例 List list = Lists.newArrayList(); ​ SysUser user = new SysUser(); user.setName("huage"); Args.doIfNotEmpty(user.getName(),list::add); System.out.println(list); 复制代码 方法内容 public static <R, T> R doIfNotNull(T t, Callback<T, R> callback) { try { return t == null ? null : callback.call(t); } catch (Exception e) { throw new BusinessException("[doIfNotNull error]", e); } } 复制代码 测试结果 [huage] 复制代码 2.4 参数为空时使用新值,并完成指定动作 本方法和2.较为类似,只是当目标值不为空时,使用新值进行后续的操作,如下面这个例子中,name初始值为【test】,执行完doIfNotNullNewValue后会将新值【huage】添加到list中,。 测试范例 List list = Lists.newArrayList(); ​ SysUser user = new SysUser(); user.setName("test"); Args.doIfNotNullNewValue(user.getName(),"huage",list::add); System.out.println(list); 复制代码 方法内容 public static <R, T> R doIfNotNullNewValue(T t,T newt, Callback<T, R> callback) { try { return t == null ? null : callback.call(newt); } catch (Exception e) { throw new BusinessException("[doIfNotNull error]", e); } } 复制代码 测试结果 [huage] 最后 如果你觉得此文对你有一丁点帮助,点个赞。或者可以加入我的开发交流群:1025263163相互学习,我们会有专业的技术答疑解惑 如果你觉得这篇文章对你有点用的话,麻烦请给我们的开源项目点点star:https://gitee.com/ZhongBangKeJi/crmeb_java不胜感激!

优秀的个人博客,低调大师

告别弱网,一直追剧一直爽

假设这样一个应用场景:下班途中,你刚上地铁,戴好耳机,准备看一集追到兴起的电视剧或者综艺节目,消磨乘坐交通工具的时间。这时,你却发现网络信号随着地铁的启动停站,变得时有时无,视频加载也开始不稳定。 如何解决这一问题?华为HMS Core无线传输服务(Wireless Kit)为开发者提供了完善的无线通信传输能力,打造定制化的蜂窝+WiFi通信解决方案。其中,弱信号预测可以在多种场景下提升用户视频观看体验。 1. 弱信号预测如何工作? 弱信号预测通过机器学习方式,采集并分析用户在固定路线上移动时的网络信号质量变化,并基于学习结果提前预测出用户即将进入信号质量不佳区域的时间,以及恢复为正常信号水平的时间。据此,应用可以预测信息,提前做出应对措施,以提升应用在弱网下的业务体验。 图1 弱信号预测工作示意图 2. 弱信号预测应用哪些场景? 对于视频App来说,常见的一个应用场景是用户上下班路途中观看视频。对此,各大运营商还联合腾讯、优酷、抖音等视频软件以及短视频平台,推出了流量包套餐。而人们观看视频过程中,经常会遇到的问题就是经过一片弱信号区域或者信号覆盖盲区造成的卡顿。如果手机能够最大限度的保障视频流畅度,并及时选择更优网络,就能够让用户有更好的观赏体验。 基于用户每天的上下班路线相对固定,网络的变化趋势可预测的情况,华为无线传输服务(Wireless kit)提供了基于学习的弱信号预测能力,根据用户的位置变化,主动预知网络变化趋势,以便视频应用提前做出应对,比如提升视频缓存时长。 也就是说,弱信号预测相当于连接起底层通信与用户体验之间的一座桥梁,把用户或应用平时不关注或者感知不到的底层信号变化特征及时反馈给上层应用,为用户体验保驾护航。 当前,华为HMS Core无线传输服务提供的弱信号预测已经与华为视频、优酷视频、爱奇艺视频、抖音短视频合作商用,后续期待支持更多的应用,服务如地铁、高铁、大型会议等更多场景。 10月23日,华为开发者大会HMS Core 6.0:连接与通信论坛,将系统介绍华为在连接与通信领域的多个解决方案,并邀请来自抖音、西山居、北斗应用研究院、爱联科技等合作伙伴,为开发者分享移动应用开发实践经验和解决方案,期待与开发者共同探索连接的价值。 扫描下方二维码,添加HDC·HMS Core分论坛小助手,加入“HDC连接与通信论坛交流群” 获取最新资讯,与行业专家交流,参与10月23日当天的在线直播。 如何集成弱信号预测服务,HMS Core为大家提供了详细的开发指导,欲了解更多详情,请参阅—— Wireless Kit开发指导 获取开发指导文档: Android、iOS、Web、快应用 访问华为开发者联盟官网 获取开发指导文档 华为移动服务开源仓库地址:GitHub、Gitee 关注我们,第一时间了解 HMS Core 最新技术资讯~

优秀的个人博客,低调大师

有了这个神器,快速告别垃圾短信邮件

前言 在日常生活中,我们时常会接收到一些垃圾短信和邮件,造成这种原因就是因为我们使用自己的手机号码在App上 注册了账号,导致手机号泄露,成为了别人发财的工具。 一、如何避免接收垃圾短信 众所周知,针对短信和邮箱都有相应的屏蔽号码或者是邮箱号的设置,但是并不是很智能。因为我们永远不知道下一秒钟究竟会是哪个大佬来光顾我们。一个一个去设置显得太麻烦,这里给大家介绍两个平台,超级好用。既不用担心泄露手机号码,也不会再接收到垃圾短信和邮件了。 Top 1.云短信 神器地址: https://www.materialtools.com/?page=1 它可以代替你的手机号进行注册,并且也会和接收到验证码,你只需要把上面能用的手机号输入到你想注册的app里面,然后发送验证就可以了。 不过,它有一个缺陷就是我们用的手机号接收的验证码它会显示在这上面,基本所有用这个神器的人都能看到,就给人一种毫无隐私可言的感觉。不过为了能不接收垃圾短信,也无妨,毕竟问题不大。 可以看到这是最近一段时间申请注册的平台名和时间。 这里可以看到已经有这么多人使用了,可见这个神器还是挺受欢迎的。有了这款神奇妈妈再也不用担心我会被人骚扰了。 Top 2.10分钟邮箱 神器地址: http://24mail.chacuo.net/ 看到这里大家想必应该能望文生义吧,其实它也是相当于云短信一样的功能,只是它的强大之处在于它是替换的邮箱号,而云短信则是专注手机短信领域方面,二者虽领域不同,但功能差不多,都是使用虚拟的号码来代替真实的号码在注册,这样以后再也不用担心别人发骚扰信息了,感觉世界会清净许多,下面我们来看下它的界面: 可以看到它目前支持两种邮箱后缀,一个是027168还有一个是chacuo。这里邮箱的获取方式有三种: 1.手动刷新 2.自动刷新 3.自定义邮箱 其中第三种方法最灵活,你想用什么奇葩的邮箱名都可以,比如小编想了一个好名字: ”哎呦不错哦@chacuo.net“,设置好后可以看到: 这样就完成了我们的个性化邮箱了。要注意的是,你的邮箱申请注册后它会提示你的邮箱是否可用,如果提示不可用就重新再设置一个,虽然很好用,但是遗憾的是,这个邮箱号只能保存十分钟,十分钟过后会自动销毁,所以要是用这个邮箱号接收到什么重要的邮件那就赶紧保存吧,免得造成损失了责怪小编没提醒你。 总结 通过对上面两个神器的了解,相信任何人用上了它们,都会给你的日常生活带来更好的感觉,不知道你是怎么认为的了?又或者你还有什么有趣的神器了?欢迎下方评论区留言。 看完本文有收获?请转发分享给更多的人 IT共享之家 入群请在微信后台回复【入群】 ------------------- End ------------------- 往期精彩文章推荐: 一篇文章教会你用Python抓取抖音app热点数据 一篇文章教会你使用Python定时抓取微博评论 手把手教你使用Python抓取QQ音乐数据(第四弹) 想要学习更多,请前往Python爬虫与数据挖掘专用网站:http://pdcfighting.com/

优秀的个人博客,低调大师

告别狗屎代码,请记住这 11 条编码秘诀!

这是一篇值得收藏起来,隔三差五就拿来重读的文章!因为作者向你保证,他“遇到的所有糟糕的代码,都是因为没采纳这些实践经验。而任何一段优秀的代码,都采纳了至少部分实践经验。” 还等什么?赶快看看这些经验就是什么吧? 我已经写了20年代码了,在此期间曾与17个团队共事过,使用不同的语言做过数百个项目。 这些项目从最简单的博客网站,到支持每秒3000多次请求的API,还有曾经热卖过的应用。 根据这些经验,再结合我读过的书,我认为编程中最重要的是:可读性。 1.可读性 表面上看来,可读性似乎很主观。不同语言、代码、和团队对于可读性的定义不尽相同。但如果深入本质的话,就会发现代码可读性有一些非常关键的因素。 许多程序员太倾向于计算机了,只要程序能运行就一了百了。尽管是老生常谈,但这种方式完全断绝了人参与的可能性。 最近几个月, 我在努力将这些人为因素提炼成11条写程序的实践经验,专门讨论如何增强可读性并降低复杂度。 我在BaseCode中写过这些详细内容,并将其应用到真实世界的代码片段中。 许多人会认为这些太基础、无关紧要,可以忽视。但我可以向你保证,我遇到的所有糟糕的代码都是因为没采纳这些实践经验。而任何一段优秀的代码都采纳了至少部分实践经验。 2.格式 我们在格式上消耗了太多精力。制表符还是空格,Allman还是K&R。总会有一天,你会意识到格式在编程中并不是最重要的。 选择一种格式,应用到代码中,然后将这个过程自动化。然后就可以重新专注于写代码本身了。 3.代码 所有注释掉的代码块、未使用的变量和无法到达的的代码都是垃圾。他们就像在对读者说,“我不关心这段代码”。 于是恶性循环开始了。日复一日,死代码最终会埋葬你的代码。这正是经典的破窗效应。 必须要找出并干掉死代码。虽然不需要把精力主要放在这里,但一定要时时留意。更多代码规范请看这篇文章《优秀 Java 程序员写代码的风格》。 4.嵌套代码 逻辑几乎是一切代码的基础。我们写代码是为了做决策、迭代和计算。一般情况下都会导致分支或嵌套,从而造成嵌套得很深的代码块。 虽然计算机很容易阅读这种代码,但对于人类则是非常大的精神负担。因此,代码会变得复杂、难以阅读。应该通过防御语句、提前返回或使用函数式编程等方式消灭嵌套代码。 5.使用对象 尽管现在是面向对象编程的时代,我们依然使用了过多的原始指令。 长长的参数列表,杂乱的数据,自定义的数组或字典结构等。这些都可以重构成对象。 这样不仅能让数据结构变得正规,还能容纳所有重复的、使用原始数据的重复的逻辑。 6.大型代码块 虽然没有具体的数字,但代码块的长度应该是有限制的。如果你认为你的代码块过大,就应该对其进行识别、重组并重构。 这个简单的过程可以让你确定代码块的上下文和抽象级别,以便正确地找出代码的任务,并将代码重构到更加易于阅读、更简单的代码块中。 7.命名规则 当然,好的命名很困难,但只是因为我们人为增加了难度。有个小技巧在编程的许多方面都能用得上,包括命名,那就是——延后。不要纠结某个东西的命名,继续写代码就好。 就算是用一整句话命名一个变量都没问题,继续写代码就好。我可以保证,当你完成整个功能之后,更好的名字就会浮出水面。 8.删除注释 在我看来这一条至关重要,删了注释我才能把精力放到可读性上。不管我如何解释删除注释的必要性,总会有人跟我抬杠,然后举出一个绝对需要注释的例子。 当然,如果哈勃望远镜要和古老的适配器连接,而后者返回一个意思不明的687,这种情况肯定需要注释来说明。但大多数其他情况下,你应该尽量重写代码使得它不需要注释也能看懂。 9.合理的返回 我们总是选择返回最奇怪的值,特别是对于边界条件的情况。像-1、687或null。然后就得写很多代码来处理这些值。实际上,null的创造者称它为“10亿美元的错误”。 应该努力返回更有意义的值。理想情况下,最好是即使在反面情况下也能让调用者继续执行的值。如果真的是异常情况,那么最好用其他方式来通信,而不是使用null。 10.三的原则 考虑一下数学上的序列。给出数字2并问你,“下一个数字是什么?”可能是3可能是4,但也可能是1或2.1。实际上你没办法知道。然后我提供了序列中的下一个数字2, 4然后问,“下一个是什么?”可能是6,8,也可能是16。 同样,尽管猜对的可能性增加了,但还是不能确定。然后我提供了数列中的第三个数字,2, 4, 16,然后问“下一个是什么?”有了三个数字之后,程序员的大脑很容易看出这是个平方序列,于是确定下一个数字是256。这就是三的原则。 这个例子虽然跟编程没关系,但它告诉我们,我们不应该太早做抽象。三的原则能阻止我们过早消除重复的努力,直到有了足够多的信息后再做出决定。用Sandi Mets的话说,“重复的代价远远低于错误的抽象。” 11.对称性 最后一条实践经验能给所有代码的可读性带来诗一般的润色,那就是对称性。这条来自Kent Beck的《实现模式》一书,书中说到: 代码中的对称性是说,同样的思想在任何地方都使用同样的实现。 不过说起来容易做起来难。对称性体现了编程的创造性。它是许多其他实践的基础:命名、结构、对象、模式等。不同语言之间、不同代码之间和不同团队之间对于对称性的定义都可能不一样。 因此,你需要花上许多年去追求对称性。但是,一旦开始在代码中使用对称性,就会迅速呈现纯粹的形式,代码的形状也会迅速变好。更多代码规范请看这篇文章《优秀 Java 程序员写代码的风格》。 原文发布时间为:2018-10-10 本文作者:Jason McCreary 本文来自云栖社区合作伙伴“Java技术栈”,了解相关信息可以关注“Java技术栈”。

优秀的个人博客,低调大师

告别高墙铁窗,AI或将终结传统监狱模式

科技几乎改变了社会的各个角落。而这种趋势之外的自由之地是顽固的刑事司法制度,特别是处理罪犯的方式。 几个世纪以来,惩罚罪犯最常见的方法就是将他们锁在“铁窗”之中。 丹·亨特教授是监狱罪犯心中的噩梦,但他并不是一个“狠心”的人。作为斯温伯恩大学法学院院长,他正在努力让基于人工智能技术的产品逐步“取代”看守所。他认为,应该通过对犯罪者的实时监测以及可以远程阻止罪犯的技术来取代监狱。这样做除了可以为政府节省大量经费之外,还能更好地保护社会免受侵犯。 “虽然技术已经在很多层面改变了我们的社会,但让人失望的是,21世纪的监狱却还是像100年前那样在运作。现在的监狱系统是臃肿和不可持续的,在过去的几十年以来,我们一直在尝试各种“封闭”的惩罚和监禁模式,但从后期的再次犯罪率的数据上可以得出,这显然是无效的;另外,如果利用监狱去看管罪犯,成本将会非常高

优秀的个人博客,低调大师

果粉请注意:准备告别 OS X,迎接 macOS 吧

苹果在改名字这件事上向来坚决。比如,2010年,随着工业设计令人惊艳的 iPhone 4 到来的,还有从 iPhone OS 更名为 iOS 的新操作系统。但有时候又会让人摸不着头脑,比如 2011 年的 iPhone 4S 叫了三年之后,随着 iPhone 5s 的到来,突然要变成小写的 iPhone 4s。又比如 iPhone SE 又大写了…… 最近,又有一个新的产品要改名字了:苹果 Mac 电脑的操作系统要从 OS X 改为 macOS(注意大小写)。这个改法其实不难猜,因为: 苹果手机的操作系统:iOS 苹果手表的操作系统:watchOS 苹果电视的操作系统:tvOS 苹果电脑的操作系统:macOS 据称,苹果将在今年 6 月的 WWDC 大会上公布这个消息。专注报道苹果消息的媒体 Apple Insider 在最新 Mac 电脑系统 10.11.4 的源代码中找到了 macOS 字样,而且知名果粉 John Gruber 在于苹果高级营销副总裁 Phil Schiller 讨论 tvOS 这个名字时,也得到了对方的暗示。 苹 果电脑的操作系统,在2000年之前一直叫 Mac OS,出到 Mac OS 9 之后更名 Mac OS X(不是 X,是罗马字母 X,代表 10,读 ten),命名变成 10.x。到了 2013 年,苹果连 Mac 也省了,变成 OS X 再加一个加州地名的方式来命名。 这次更名之后,那个伪果粉们从来没读对过的 OS X(ten),就成为了历史。 ====================================分割线================================文章转载自 开源中国社区[http://www.oschina.net]

优秀的个人博客,低调大师

LiteFlow v2.15.0 发布:拥抱虚拟线程,告别JVM参数!

概述 各位 LiteFlow 的使用者,大家好! 历经四个月的持续迭代,LiteFlow v2.15.0 正式发布!这是一个里程碑式的版本,共包含了 4 个新特性、7 项重要增强以及 7 个问题修复,累计解决了 18 个 issue。 至于为何版本号从 2.13.2 直接跳到了 2.15.0。其实也没啥特别的原因,可能是因为风水问题吧。 言归正传,对于正在使用 2.13.X 版本的用户,新版本在绝大多数场景下都能做到无缝兼容。我们对从 JDK 8 到 JDK 25 的所有主流版本进行了严苛测试,超过 2000 个测试用例确保了 LiteFlow 框架在各种 JDK 环境下的稳定运行。 平滑支持JDK8~JDK25的所有版本 在旧版本中,LiteFlow 虽然支持 JDK 8 至 17,但在 JDK 9 以上环境中运行时,需要用户额外添加 JVM 参数。其根本原因在于 LiteFlow 底层对 sun.* 包的部分反射调用,而这些内部 API 在高版本 JDK 中受到了严格的封装限制。 在新版本中,我们通过替换底层实现,彻底解决了这一问题。现在,无论您使用哪个 JDK 版本,运行 LiteFlow 都再也无需添加任何额外的 JVM 参数,体验更加平滑顺畅。 全面拥抱 JDK 21 虚拟线程 作为 JDK 21 中最核心的特性之一,虚拟线程能以极低的调度开销,显著提升高 I/O 密集型应用的性能。针对社区中大家高度关注的 JDK 21 及虚拟线程支持问题,我们在此版本中给出了完整的回应。 当您的应用运行在 JDK 21 及以上环境时,LiteFlow 内部的所有异步线程都将自动切换为虚拟线程,充分释放新版 JDK 的性能红利。而在 JDK 21 以下版本,框架则会平稳地回退至使用传统的平台线程。 更棒的是,无论您使用哪个 JDK 版本,都只需引入同一套依赖,无需任何版本区分。 支持 EL 表达式的即时执行 我们收到了许多社区反馈:对于一些简单的动态规则,通过 XML 定义 chain 显得过于繁琐,而每次都用代码动态构建又存在性能开销和手动清理的麻烦。 为此,2.15.0 版本引入了直接执行 EL 规则的新能力。 LiteflowResponse response = flowExecutor.execute2RespWithEL("THEN(a, b, c)", requestData, CustomContext.class); 现在,您可以直接执行一个 EL 表达式来完成流程编排,无需预先创建 chain。并且您完全不必担心性能问题——对于相同的 EL 表达式,框架只会在首次执行时编译一次,后续调用将直接复用缓存,高效可靠。 引入活跃规则的缓存策略 对于拥有海量规则(例如上万条)的复杂系统,此特性将带来显著的内存优化。 我们引入了一套全新的缓存策略。当系统中的规则过多时,该策略会自动维持 N 条最活跃规则的缓存,并将不活跃的规则从内存中卸载,从而有效避免堆内存的持续增长。当被卸载的规则再次被调用时,框架会自动重新编译并将其纳入活跃队列。 整个过程对用户完全透明。该策略默认关闭,您可以通过以下配置开启并调整: # 是否开启保活策略 liteflow.chain-cache.enabled=true # 保持活跃chain的数目,默认为10000 liteflow.chain-cache.capacity=10000 # 模式一定得为PARSE_ONE_ON_FIRST_EXEC liteflow.parse-mode=PARSE_ONE_ON_FIRST_EXEC 隐式子流程的改版 我们必须承认,旧版的隐式子流程在设计上存在诸多局限。为了兼容该特性,框架的许多核心功能不得不做出妥协,导致部分实现变得复杂且不够优雅,这一直是我们维护者心中的一个痛点。 因此,我们曾考虑彻底移除该功能。但考虑到这会给现有用户带来较大的迁移成本,我们最终选择了一条更优的路径:在保留原有调用方式的基础上,对其底层实现进行了彻底重构。 这次重构不仅理顺了内部逻辑,也为未来的功能扩展扫清了障碍。对于正在使用隐式子流程的用户,迁移过程非常简单,仅需将获取子流程请求数据的方法名从 getSubRequestData 统一更改为 getDataRequest 即可。 关于社区答疑 我们始终珍视社区的力量,并长期致力于为开发者提供免费的技术支持。随着 LiteFlow 社区的不断壮大(目前已拥有16个微信交流群),我们发现难以确保每一位开发者的问题都能得到及时和深入的解答。 为了提供更高效、更专注的答疑服务, 您可以选择加入LF CLUB知识星球。在星球里: 每一个问题都会得到详尽的解答。 沉淀了大量高质量的知识库文章、案例实践和深度解析。 具体加入方式请查看 LiteFlow 官方网站。 完整更新列表 特性#ICUMKV 全面支持jdk21,以及支持jdk21中的虚拟线程 https://gitee.com/dromara/liteFlow/issues/ICUMKV 特性#IBQCWB Liteflow的执行器FlowExecutor支持执行EL表达式,而不需要传入chainId https://gitee.com/dromara/liteFlow/issues/IBQCWB 特性#IAY66T 建立一种机制保证在过多的规则下只维持前N条最活跃的规则缓存 https://gitee.com/dromara/liteFlow/issues/IAY66T 特性#ICM6TX WHEN 并行编排增加关键字实现完成任务达到百分比阈值时方可放行 https://gitee.com/dromara/liteFlow/issues/ICM6TX 增强#ICO3IK 在switch节点中,希望能拿到target的列表信息 https://gitee.com/dromara/liteFlow/issues/ICO3IK 增强#ICUEG9 JDK支持度更加平滑 https://gitee.com/dromara/liteFlow/issues/ICUEG9 增强#ICANTH 隐式子流程改版 https://gitee.com/dromara/liteFlow/issues/ICANTH 增强#IC9GTV 脚本ScriptValidator新增返回ValidationResp的API https://gitee.com/dromara/liteFlow/issues/IC9GTV 增强#ICGGAW redis数据源支持集群模式 https://gitee.com/dromara/liteFlow/issues/ICGGAW 增强#ICR1PL AND关键字的逻辑和语意明确点 https://gitee.com/dromara/liteFlow/issues/ICR1PL 增强#ICU7Z4 升级liteflow的一些依赖 https://gitee.com/dromara/liteFlow/issues/ICU7Z4 修复#ICPDU7 Slot的conditionStack在多线程并发时无法保证Condition的弹栈压栈顺序 https://gitee.com/dromara/liteFlow/issues/ICPDU7 修复#ICO23A Spring设置BeanFactory的cacheBeanMetadata属性为false时,Liteflow项目无法注册声明式组件,后续解析EL失败,项目无法启动 https://gitee.com/dromara/liteFlow/issues/ICO23A 修复#ICJGIK PARSE_ONE_ON_FIRST_EXEC 模式下 Node 对象执行 Java 脚本 最终 instance.isEnd() 判断空指针问题 https://gitee.com/dromara/liteFlow/issues/ICJGIK 修复#IC9ZZ8 reids poll模式代码问题 https://gitee.com/dromara/liteFlow/issues/IC9ZZ8 修复#IC8UPJ 规则EL校验在liteflow.parse-mode=PARSE_ONE_ON_FIRST_EXEC时失效 https://gitee.com/dromara/liteFlow/issues/IC8UPJ 修复#IC71HA 在线程1的执行过程中线程2去remove chain导致的线程1无法平滑继续执行的bug https://gitee.com/dromara/liteFlow/issues/IC71HA 修复#IC2F4F 模糊文件路径的监听,添加新的规则文件没有自动加载 https://gitee.com/dromara/liteFlow/issues/IC2F4F

优秀的个人博客,低调大师

Eurynome Cloud 2.7.0.20 发布,告别 Java 8,正式开启 17 之旅

Eurynome Cloud 是一款企业级微服务架构和服务能力开发平台。首个全面拥抱 Spring Authorization Server 的版本,基于Spring Boot 2.7.0、Spring Cloud 2021.0.3、Spring Cloud Alibaba 2021.0.1.0、 Spring Authorization Server 0.3.0、Nacos 2.1.0 等最新版本开发,遵循SpringBoot编程思想,高度模块化和可配置化。具备服务发现、配置、熔断、限流、降级、监控、多级缓存、分布式事务、工作流等功能 平台定位 构建成熟的、完善的、全面的,基于 OAuth2 的、前后端分离的微服务架构解决方案。 面向企业级应用和互联网应用设计开发,既兼顾传统项目的微服务化,又满足互联网应用开发建设、快速迭代的使用需求。 平台架构使用微服务领域及周边相关的各类新兴技术或主流技术进行建设,是帮助快速跨越架构技术选型、研究探索阶段的利器。 代码简洁规范、结构合理清晰,是新技术开发应用的典型的、综合性案例,助力开发人员对新兴技术的学习和掌握。 [1]、发布背景 2021年11月8日 Spring 官方已经强烈建议使用 Spring Authorization Server 替换已经过时的 Spring Security OAuth2.0。 在 Spring Security OAuth2 彻底停止维护、Spring Boot 2.7.0 正式发布之时,又恰逢 Eurynome Cloud 开源一周年之际,推出基于 Spring Authorization Server 0.2.3、Spring Boot 2.7.0、Spring Cloud 2021.0.2、Spring Cloud Alibaba 2021.0.1.0 和 Nacos 2.1.0 的全新正式版本。该版本基于 Spring Authorization Server 0.2.3 和 Spring Boot 2.7.0 全新定制开发,细节满满,欢迎品鉴。 [2]、重要说明 Eurynome Cloud 自 v2.7.0.20 版本,开始全面使用 JDK 17。自该版本以后,系统代码将不再兼容 JDK 8,敬请悉知! 升级使用 JDK 17 的主要原因: Spring Authorization Server 0.3.0 版本,已经开始使用 JDK 11 进行代码编译。该版本在 JDK 8 下已无法编译成功,想要使用必须要升级 JDK 版本。 2022 年 11 月,Spring Boot 3 将会发布,最低版本要求 JDK 17。因此,直接将 JDK 版本升级至 17,为升级至 Spring Boot 3 提前做铺垫准备。 [3]、本次更新内容 重要更新 Eurynome Cloud 版本使用 JDK 从 8 升级至 17 (注意:现有版本不再兼容 JDK 8) 主要更新 Spring Cloud 版本升级至 2021.0.3 Spring Authorization Server 版本升级至 0.3.0 其它更新 根据 Spring Authorization Server 0.3.0 代码的变化,修改和调整现有系统代码 为支持 JDK 17,同时解决老旧依赖包安全漏洞问题,临时删除现有 baidu 短信模块 升级 Kryo 版本至 5.3.0,增加自定义拓展代码,解决 Kryo 现有版本与 JDK 17 不兼容问题而导致的 Jetcache 无法使用问题。 升级 Xnio 版本,解决 Undertow 在 JDK 17 环境下运行,抛出 `Could not initialize class org.xnio.channels.Channels` 错误,导致服务无法运行问题。 修复 docker-compose脚本配置错误。 修复现有工程中残留的 FastJson 使用代码。 依赖更新 JetCache 版本升级至 2.6.5 Tencentcloud-sdk-java 版本升级至 3.1.516 [4]、Eurynome Cloud 2.7.X 主要变化 基于 Spring Authorization Server 深度定制: 基于 Spring Data JPA,重新构建 Spring Authorization Server 基础数据存储代码,替代原有 JDBC 数据访问方式,破除 Spring Authorization Server 原有数据存储局限,扩展为更符合实际应用的方式和设计。 基于 Spring Authorization Server,在 OAuth 2.1 规范基础之上,增加自定义“密码”认证模式,以兼容现有基于 OAuth 2 规范的、前后端分离的应用。 基于 Spring Authorization Server,在 OAuth 2.1 规范基础之上,增加自定义Social Credentials 认证模式,支持手机短信验证码、微信小程序、第三方应用登录。 遵照 Spring Security 5 以及 Spring Authorization Server 的代码规范,进行 OAuth2 认证服务器核心代码的开发,遵照其使用 Jackson 反序列化的方式, 增加大量自定义 Jackson Module。 支持 Spring Authorization Server 的标准的Token加密校验方式外,还了增加支持自定义证书的 Token 加密方式,可通过配置动态修改 支持 OAuth2 OIDC 认证模式,补充前端 OIDC 认证相关配置操作,以及对应的 /userinfo 接口调用支持 和 客户端注册支持 支持 OAuth2 Authorization Code PKCE 认证模式 扩展 Spring Authorization Server 默认的 Client Credentials 模式,实现 Refresh Token 的创建。 扩展 Spring Authorization Server 默认的 Client Credentials 模式,实现真正的使用 Scope 权限对接口进行验证。 增加客户端 Scope 的权限配置功能,并与已有的用户权限体系解耦 自定义 Spring Authorization Server 授权码模式登录认证页面和授权确认页面,授权码模式登录采用数据加密传输。支持多种验证码类型,暂不支持行为验证码。 代码结构的大规模调整和优化: 对原有代码进行了深度的“庖丁解牛”,严格遵照“单一职责”原则,根据各个组件的职责以及用途,将整个工程拆解细化为多个各自独立组件模块,在最大程度上降低代码间的耦合,也更容易聚焦和定位问题。 将通用化组件提取为独立工程,独立编译、按需选用,极大的降低系统主工程代码量。相关组件也已上传至 Maven 中央仓库,降低系统主工程工程代码编译耗时,改进和提升 CICD 效率, 原有主工程代码结构也进行了深化调整,代码分包更加合理,代码逻辑也更加清晰。 [5]、额外说明 本项目以后将主要维护 Spring Authorization Server 版本,原有基于 Spring Security OAuth2 的版本已经移至 spring-security-oauth2 分支,可以从该分支或发行版页面获取历史版本继续使用。后期会根据 ISSUE 以及使用用户反馈情况,再行决定是否继续维护 Spring Security OAuth2 版本。 原有基于Java 8的SpringAuthorizationServer版本,已经移至spring-authorization-server-jdk8分支。可以从该分支或发行版页面获取历史版本继续使 最新版本代码,暂时继续沿用原有基于 Vue2、Vuetify2、Typescript开发的前端系统。基于 Vue3、Vite2、Vuetify3、Pinia 等新版前端正在加进开发中,由于 Vuetify3 版本发布跳票以及部分已有组件的缺失,导致新版前端开发延后。 原有基于 Vue2、Vuetify2、Typescript 开发的前端,由于使用了过渡性 Typescript IOC 组件,以及依赖组件版本限制等问题,初次接触该项目在编译过程中会出现一些问题,请移步至本项目在线文档,详见“常见问题”章节。

优秀的个人博客,低调大师

研究称芯片业已告别低迷期 迎来小幅复苏

7月28日消息,据国外媒体Venturebeat报道,致力于芯片市场分析的知名公司VLSI Research指出,种种迹象表明,芯片业持续了一年的低迷期已结束,目前正迎来复苏期。 芯片产业一直处在起起伏伏的经济周期中。芯片几乎被用于所有电子产品中,因此芯片业的销售预测是所有电子产品销量的风向标,如,传感器、引入先进技术的汽车以及智能手机。 这张分析图表显示形势已开始好转。图中可以看出,VLSI公司着重分析了芯片销量(蓝线)和订单活动之间的关系。VLSI指出,第二季度的供给和需求已从第一季度的饱和状态转变为更加平衡的状态。如今根据截止7月13日收集的数据,形势已出现回升迹象。VLSI指出,对于芯片涉及的不同领域,如内存、合同制造(代工)、集成设备制造、系统级芯片制造和物联网市场,价格环境已经改善。中国智能手机市场对芯片的需求尤其火爆。VLSI预计今年第三季度芯片销量将同比增长4%。尽管增长幅度不算很大,但很有希望会实现。 ====================================分割线================================ 本文转自d1net(转载)

优秀的个人博客,低调大师

告别1人年,教你21天搭建推荐系统!

免费开通大数据服务:https://www.aliyun.com/product/odps href="https://www.aliyun.com/product/odps" target="_blank"> 活动预告:为了让大家更好的了解如何在21天快速搭建推荐系统,特邀请本文作者、阿里云技术专家郑重(卢梭)开展一场线上课程,报名地址:https://yq.aliyun.com/webinar/join/14,时间6月16日晚20点直播。 本文作者为阿里云技术专家郑重(卢梭),主要分享内容是如何在21天内快速搭建推荐系统。推荐系统的搭建是个复杂工程,涉及到实时计算、离线计算,以及各种数据采集、流转等,对自建推荐系统来说,1人年是跑不掉的。 本文介绍的内容还包括如何搭建一个个性化推荐系统所需的环境准备、基本配置和离线技术等基本功

优秀的个人博客,低调大师

告别卡顿与等待,Rancher Vai 让集群操作“秒响应”

如果你正用 Rancher 在大规模环境中管理 Kubernetes,那么你一定知道,UI 性能不只是"锦上添花"------它对效率至关重要。Rancher 团队一直在不断努力提升平台在更复杂环境下的处理能力。 在这篇文章里,我们将深入探讨一个令人兴奋、正不断演进的改进项目:代号为 "Vai"(也称 UI 服务器端分页或基于 SQLite 的缓存)。目标是让你在使用 Rancher 时拥有更流畅、更快速、更具可扩展性的体验,尤其在你要管理大量 Kubernetes 资源的场景下。正因如此,Rancher 团队构建了 Vai 项目,该项目现已成为 SUSE Rancher Prime 中的一项生产就绪功能。 Rancher Prime 的 Vai 引擎通过重新设计数据流向 UI 的方式,实现更快、更可靠的 Kubernetes 管理。这保证了企业能够更顺畅地管理大型复杂环境,同时降低成本、提高效率。 更快更顺畅的 Rancher UI --- 提升效率 减轻 Kubernetes API 服务器的压力 --- 保持集群健康、提升性能 默认启用加密的安全缓存 --- 保护敏感数据 可扩展的基础设施 --- 随环境增长而扩展,并为未来洞察提供可能 问题所在:规模如何影响 UI 性能 随着 Rancher 部署规模的扩大,管理海量集群、节点及其内部资源成为常态。我们明确听到了用户的反馈:UI 性能,尤其是 Rancher Dashboard 的响应,在某些极限场景下已成为瓶颈。 为应对这一挑战,我们为 Rancher 的性能设定了一些目标。比如,为了保证 UI 在极端规模场景下也能正常应对,我们将一个基准目标设为:对某一种资源(以载荷 1MiB 的 ConfigMap 为例),能够分页显示数万个条目;在最坏情况下,分页结果从 API 返回时间不超过 0.5 秒,以便最终渲染在 1 秒之内完成。 这些数字并不仅仅是理论目标;它们映射了真实场景中的痛点:一个迟缓的 UI 会妨碍你有效地管理和监控 Kubernetes 环境。正如我们在内部所说:"当 Dashboard 无法达到用户期望时,用户对 Rancher 的印象就会变差,使用效率也会降低。" 这正是我们决心解决的关键痛点。 问题的核心通常归结于 UI 如何获取与处理大量 Kubernetes 对象列表。将数千个项(如 Pod、Deployment 或其他资源)拉入浏览器端进行缓存、排序与过滤,会对网络、浏览器内存造成压力,并导致明显延迟。此外,这样的操作会对 Kubernetes API Server 造成过度负载,从而对被管理集群产生负面影响。 因此,我们知道,必须设计一种更智能、更高效的数据交付方式给 UI。 解决方案:Vai 如何带来更快、可扩展的 UI 这正是 "Vai" 问世的原因。这个项目不仅仅是一次小优化,而是对 Rancher 内部 API(名为 Steve)如何向 UI 提供资源、以及其如何在大规模场景下与 Kubernetes 数据交互的根本性重构。 Vai 的主要目标是在服务器端实现高效的分页、过滤和排序。与其将庞大的数据集拉到浏览器端再处理,不如让服务器端先行处理这些操作,只将必要、已经处理过的那一页数据发送给 UI。 核心思路是构建一个位于 Kubernetes API Server 和 Rancher UI 之间的强大缓存层。这个缓存层以 SQLite 为后端存储,使 Steve(Rancher 的 Kubernetes API 代理组件)能够更快地响应 UI 对对象列表的请求,因为排序、过滤和分页操作都在服务器端完成,从而最小化数据传输量。 期望成果是什么?响应速度大幅提升的 UI、Kubernetes API Server 和 Rancher 本身负载显著降低、在资源分页浏览时获得更好的体验------即便在有数万个资源的环境中也能流畅应对。 技术深潜:Vai 的 SQLite 支撑架构 那么,Vai 到底是如何运作的?其"魔法"在于它的架构:将 Kubernetes 原生的 Informer 机制与 SQLite 的高速、低内存开销结合起来。 Vai 是对 Steve 的一种扩展,Steve 是 Rancher 用来将 UI 的 API 请求代理到 Kubernetes 的组件。Vai 利用专门的 Informer 来缓存 Kubernetes API 的信息。 如果你对 Kubernetes 控制器开发稍有了解,就知道 Informer 是一种标准机制,用于监听资源变动并维护本地同步缓存。当 UI 第一次请求某一种资源(例如 Pods)的列表时,会为该资源类型创建一个 Vai Informer。这个 Informer 首先向 Kubernetes API 发起 LIST 请求,然后再开启 WATCH,以保持缓存与 Kubernetes 实时同步。 关键区别在于:传统 Informer 缓存通常驻留在内存中,而 Vai Informer 使用 SQLite 作为其后端持久化存储。这意味着被缓存的 Kubernetes 对象被持久化写入磁盘(默认情况下,会写入 Rancher pod 或下游集群的 cattle-cluster-agent pod 内)。 与纯内存解决方案相比,磁盘存储提供了更大的缓存容量。这在处理我们测试的最坏情况时至关重要,例如前面提到的 80,000 个大型 ConfigMap 基准测试案例中约 80 GiB 的数据。 下面是一个简化流程: UI 请求:浏览器端(Rancher Dashboard 的 JavaScript 代码)向 Steve 的某个 API 端点请求一页 Pods,带有排序(如按创建时间)和过滤(如按名称)条件 Steve 与 Vai:Steve 接收到请求。如果对应资源类型的 Vai 缓存已被预热(即缓存已就绪),则 Steve 会将该请求转换成一个 SQL 查询 SQLite 查询:该 SQL 查询在 SQLite 数据库中执行,SQLite 引擎高效地完成过滤、排序、分页,只挑选出请求页所需的数据 响应 UI:Steve 将这页整理好的数据返回给 UI 美妙之处在于:后续对不同页、或对同一种资源做略有不同的过滤/排序请求,都可以直接在本地 SQLite 缓存中处理,而无需再次对 Kubernetes API Server 发起完整的 LIST 请求。这样便极大地减轻了对 kube-apiserver 和 etcd 的访问压力。 数据库本身为每种资源类型设计了一组表。通常包括一个"对象表"(object table),存储完整的资源对象 blob;以及一个"字段表"(fields table),包含可供排序或过滤使用的索引列,如 name、namespace、creation timestamp 以及其他模式定义属性。这个 "感兴趣字段"(fields of interest) 的概念至关重要。我们不会为每个对象的每个字段都建立索引,那样效率太低;相反,我们只索引 UI 交互中最常用的字段。这是在常见用例和索引开销之间的一个权衡。 Vai 的演进历程与替代方案回顾 Vai 的开发是一次迭代的旅程,从 HackWeek 项目起步,经过多轮设计讨论、RFC 制定、实现和优化。Rancher 2.8 提供了起步的基础能力,随着版本演进(2.9、2.10、2.11,直至 2.12),我们不断在其之上构建、修正与完善。沿途我们通过多个 EPIC GitHub issue 跟踪进展、修复 bug、调整实现,并解决诸如缓存预热性能、功能一致性等挑战。这个迭代方式使我们能够渐进交付,并依据反馈做及时调整。 在 Vai 之前,我们并非第一次尝试通过缓存优化 Steve 的 UI 性能。之前我们试过多种策略,并对它们做了系统化的评估和基准测试,最终选择了当前设计。 下面是几种我们在 Vai 之前探索过的替代方案,以及它们的利弊: | 替代方案 | 初步收益 | 主要痛点 | 它如何引导我们走向 Vai 的设计 | | --------------------------- | ------------------------ | --------------------------------------------------------------------------------- | ----------------------------------------------- | | Steve 原本的内存 LRU 缓存 | 作为 UI 性能基线 | 由于对每种查询参数变化或 RBAC 权限变化都可能产生新的缓存条目,导致内存效率低、数据重复 | 突显出需要一种更高效的缓存机制,以避免冗余数据存储,并能应对多样的 UI 请求而不消耗过多内存 | | 在从 Kubernetes API 返回后再做内存缓存 | 通过缓存原始 API 响应可略有提高效率 | 缓存频繁失效,因为即便元素未发生变化,资源版本(resourceVersion)也可能改变,从而导致每次"最新"请求都写入新的缓存条目 | 暴露出需要一种对资源版本频繁变化更具鲁棒性的缓存策略 | | 为内存缓存追踪 resourceVersion | 在不常变化的列表上,内存使用减少且响应一致性提升 | 对于频繁更新的资源(如 leader election leases),缓存几乎总被认为"过期",导致不断重新获取和加入新条目,对于包含数万个资源的动态场景不可行 | 促使我们考虑引入 Informer 机制以实现实时高效更新 | 这段历程展示了我们严谨的工程流程:我们并不是随意选定一个方案,而是识别已有方案的局限性,逐步推进到更健壮的架构。频繁更新的资源导致缓存抖动,是一个非常关键的推动因素。 Vai 正是为直接应对这些问题而选中的方案:通过 Informer 获取高效实时更新,通过 SQLite 获得更大、磁盘级持久缓存,并且能运用 SQL 提供服务器端排序、过滤、分页。这样便有效地将部分工作负载从 Kubernetes API Server 和客户端浏览器中卸载。 对你(工程师)而言,Vai 的意义 那这一系列变革,对你这个使用 Rancher 的技术工程师来说,有什么实打实的好处? 异常灵敏的 UI 体验:最直接的收益是,当你在 Cluster Explorer 中浏览成千上万条资源(如 Pods、Secrets、ConfigMaps 等)时,排序、过滤、翻页操作会感觉非常迅捷流畅,因为计算已在服务器端完成。 Kubernetes API 服务器负担减轻:由于大量 UI 数据请求可以直接从缓存返回,Vai 显著减少 Rancher 向下游 API 服务器发起的 LIST 和 GET 请求次数。这不仅对 Rancher 有利,也能改善被管理集群的健康和性能,为你的实际工作负载释放更多 API Server 资源。 图 1:Rancher 2.11.1 上的 kubapiserver 负载,这是 QA 测试的一部分。Steve 的 "list" 负载由 k6 生成,然后 Steve 又加载 Kubernetes API Server,此处由 Rancher Monitoring 进行监控。 图 2:Rancher 2.12.1(启用 Vai)上的 kubapiserver 负载,这是 QA 测试的一部分。更重的 Steve "list" 负载由 k6 生成(比上图高出 10 倍),而 Kubernetes API Server 的负载几乎未受影响。 为更丰富的数据洞察建立基础:使用 SQLite 为后端存储为未来 Rancher 版本提供了 SQL 引擎的灵活性。未来可以做更复杂的查询,比如在服务器端直接 JOIN 多种 Kubernetes 资源进行汇总视图。以前在无 Vai 的情况下,这类操作通常需要多个大型 LIST,然后在浏览器端进行映射、JOIN,资源消耗极大。 Rancher 更具可扩展性:这些效率提升意味着 Rancher 自身可以更有效地管理更多、更大的集群。其控制平面组件(如 Steve)也变得更加节省资源。 效率提升,减少等待:更快、更可靠的 UI 意味着你等待的时间更少,能做的事情更多。这正是我们设计 Vai 的出发点之一:避免一个缓慢的 Dashboard 给用户留下不好的印象并削弱生产效率。 总之,Vai 是一个基础性组件,能帮助 Rancher 随着你的需求扩展。它确保即便你的 Kubernetes 规模增长得很大,Rancher 仍然是一款强劲、高性能的工具。同时,这种改进也为未来更高级的功能铺路------响应式的数据访问层常常是许多高级特性的前提。 安全考虑:保护你的数据 谈到数据管理,特别是来自你 Kubernetes 集群的数据,安全问题至关重要。因为 Vai 会将 Kubernetes 对象的副本缓存到 Rancher server pod(对于本地集群)或 cattle-cluster-agent pod(对于下游集群)的磁盘上,我们在设计时就把"静态加密"(encryption-at-rest)纳入了架构之中。 具体来说,我们内建了两道防线: 可选的全缓存加密 :若你对 SQLite 缓存中的数据在磁盘上的安全性有顾虑,可以通过在相应的 Rancher 或 agent pod 中设置环境变量 CATTLE_ENCRYPT_CACHE_ALL=true 来启用对所有缓存对象的加密。 Secrets 和 Tokens 始终加密:无论你是否开启全缓存加密,Kubernetes Secrets 和 Rancher Tokens 在缓存中始终被加密。这为最敏感的信息提供了最低保护门槛。 加密机制本身采用 AES-GCM,使用一个驻内存的 Key-Encryption Key(KEK)来加密 / 解密 Data Encryption Keys(DEKs)。这些 DEK 用于加密实际资源数据,并且定期轮换以增强安全性。 此外,还有一个重要的安全考量是访问控制(RBAC、权限控制等):由于我们改变了缓存逻辑,必须确保政策和权限机制在启用 Vai 后仍然得到尊重。为此,我们与安全团队密切合作,执行深入的审查和自动化测试(启用与未启用 Vai 的场景同时测试),以确保一致性。 Rancher 性能的未来之路 Vai 代表了 Rancher 在大规模数据处理方面的一次重大进步,但这并不是终点。这个特性正走在成为 Rancher 体验核心的一条路径上。 在 Rancher 2.11 及之前的版本中,Vai 被视为实验性功能 ,默认关闭。但令人振奋的是,从 Rancher 2.12 开始,Vai 被认为是可用于生产环境的特性,并在默认情况下被启用且受 SUSE 支持。对我们来说,这可是一个重要里程碑,我们将继续根据真实使用反馈来增强它。 更进一步地,我们才刚刚开始挖掘底层 SQL 引擎所提供的额外灵活性。我们预期会利用这一基础,在未来丰富 Rancher 的数据摘要和洞察功能。我们的终极目标是,在未来的某个版本中,让这个强大的性能引擎默认开启,使得高度可扩展的 UI 成为每个人的标准体验。 帮我们测试与完善 Vai! 你的反馈非常重要!如果你愿意深度体验并帮忙验证,建议你先阅读 Rancher 文档中关于 UI Server-Side Pagination 的特性页面,然后将你的体验反馈给我们:在 GitHub 上开一个 Issue,分享你的发现和建议。 感谢你的阅读!我们期待听到你的使用体验,一起打造更加快速、可扩展的 Rancher 平台。

优秀的个人博客,低调大师

sqltoy-orm 5.2.63 发版,是时候跟 mybatis 告别了!

为什么选择mybatis?自由的sql?假设其他一切对等,sqltoy的sql写法是否可以否定掉mybatis的写法? 开源地址: github:https://github.com/sagframe/sagacity-sqltoy gitee:https://gitee.com/sagacity/sagacity-sqltoy idea 插件 (可直接在 idea 中检索安装):https://github.com/threefish/sqltoy-idea-plugins sqltoy 脚手架项目:https://gitee.com/momoljw/sss-rbac-admin sqltoy lambda 项目:https://gitee.com/gzghde/sqltoy-plus 更新内容 1、支持itemList[0].fieldName或itemList[0].item.name 形式传参 2、在@include(sqlId)基础上扩展支持@include(:scriptParam)动态sql,便于动态传递sql片段 String sql="select * from sqltoy_fruit_order where status=:status @include(:sqlScript)"; result = lightDao.find(sql,MapKit.keys("status", "saleCount", "sqlScript").values(1, 12, "and sale_count>:saleCount")); sqltoy 的关键优势: //------------------了解 sqltoy的关键优势: -------------------------------------------------------------------------------------------*/ //1、最简最直观的sql编写方式(不仅仅是查询语句),采用条件参数前置处理规整法,让sql语句部分跟客户端保持高度一致 //2、sql中支持注释(规避了对hint特性的影响,知道hint吗?搜oracle hint),和动态更新加载,便于开发和后期维护整个过程的管理 //3、支持缓存翻译和反向缓存条件检索(通过缓存将名称匹配成精确的key),实现sql简化和性能大幅提升 //4、支持快速分页和分页优化功能,实现分页最高级别的优化,同时还考虑到了cte多个with as情况下的优化支持 //5、支持并行查询 //6、根本杜绝sql注入问题 //7、支持行列转换、分组汇总求平均、同比环比计算,在于用算法解决复杂sql,同时也解决了sql跨数据库问题 //8、支持保留字自动适配 //9、支持跨数据库函数自适配,从而非常有利于一套代码适应多种数据库便于产品化,比如oracle的nvl,当sql在mysql环境执行时自动替换为ifnull //10、支持分库分表 //11、提供了取top、取random记录、树形表结构构造和递归查询支持、updateFetch单次交互完成修改和查询等实用的功能 //12、sqltoy的update、save、saveAll、load 等crud操作规避了jpa的缺陷,参见update(entity,String...forceUpdateProps)和updateFetch //13、提供了极为人性化的条件处理:排它性条件、日期条件加减和提取月末月初处理等 //14、提供了查询结果日期、数字格式化、安全脱敏处理,让复杂的事情变得简单,大幅简化sql或结果的二次处理工作 //-----------------------------------------------------------------------------------*/ sqltoy 特点介绍: sqltoy 的核心构建思想 sqltoy 的对比 mybatis (plus) 的核心点:查询语句编写、可阅读性、可维护性 对象化 crud 是基础,但 sqltoy 有针对性的改进:update、updateSaveFetch、updateFetch 等 sqltoy 的缓存翻译,大幅减少表关联简化 sql,让你的查询性能成几何级提升 极致的分页,同样帮助你实现查询的性能大幅提升 快速分页:@fast () 实现先取单页数据然后再关联查询,极大提升速度 分页优化器:page-optimize 让分页查询由两次变成 1.3~1.5 次 (用缓存实现相同查询条件的总记录数量在一定周期内无需重复查询 sqltoy 的分页取总记录的过程不是简单的 select count (1) from (原始 sql);而是智能判断是否变成:select count (1) from 'from 后语句 ', 并自动剔除最外层的 order by sqltoy 支持并行查询:parallel="true",同时查询总记录数和单页数据,大幅提升性能 便利的跨数据库统计计算:数据旋转 便利的跨数据库统计计算:无限极分组统计 (含汇总求平均) 便利的跨数据库统计计算:同比环比 5、树形表排序汇总 6、扩展集成

优秀的个人博客,低调大师

易水组件 5.2.0 发布,告别单表 CURD 重复性代码

易水公共组件是基于springboot的高度封装的通用型组件,在对spring security和spring security oauth2高度可定制化的功能封装外,还支持第三方登录和sso单点登录功能,使用户能够快速开启QQ登录和微信登录能力,搭建属于自己的认证/授权中心。 此外,工具还提供各种常见的图形验证码、短信验证码和邮件验证码功能,并支持跨域设置和全局异常捕获功能,实现自定义异常信息提示。 另外,组件还包含swagger接口文档功能,支持一键导出离线接口使用文档。 最后,组件提供了大量丰富的配置属性,支持通过属性配置完成各项功能设置,真正实现零侵入、防止暴力破解的无缝接入功能。 在保证功能灵活可用的基础上,易水公共组件还针对国人的使用习惯进行了一些本地化配置,提供了详细完整的中文使用说明文档。总的来说,易水公共组件在保证单机应用的高效性能同时,还能支持分布式署环境,能自动识别单体应用还是集群应用,是目前主流的微服务开发过程中不可或缺的重要伙伴。 快速启动 在项目中加入以下依赖 <dependency> <groupId>com.yishuifengxiao.common</groupId> <artifactId>common-spring-boot-starter</artifactId> <version>5.2.0</version> </dependency> 易水组件已经发布到maven中央仓库,最新版本的依赖可参见https://mvnrepository.com/artifact/com.yishuifengxiao.common/common-spring-boot-starter。 在项目中引入上述依赖之后,就可以直接使用易水组件的相关功能了。 本次更新主要更新点如下: 数据库操作 例如操作数据库时再也不需要编写简单的CURD的操作代码,只需要在项目中加入以下代码即可操作数据库了: @Autowired private JdbcHelper jdbcHelper; 也可以使用静态工具类JdbcUtil对数据进行操作。 下面是数据库操作工具JdbcHelper的一些典型接口 /** * 根据主键从指定表查询一条数据 * * @param <T> POJO类 * @param clazz POJO类 * @param primaryKey 主键 * @return 查询到的数据 */ <T> T findByPrimaryKey(Class<T> clazz, Object primaryKey); /** * 查询所有符合条件的数据 * * @param <T> POJO类 * @param t 查询条件 * @return 符合条件的数据 */ <T> T findOne(T t); /** * 查询所有符合条件的数据 * * @param <T> POJO类 * @param t 查询条件 * @param order 排序条件 * @return 符合条件的数据 */ <T> List<T> findAll(T t, Order order); /** * 根据主键全属性更新方式更新一条数据 * * @param <T> POJO类 * @param t 待更新的数据 * @return 受影响的记录的数量 */ <T> int updateByPrimaryKey(T t); /** * 根据主键可选属性更新方式更新一条数据 * * @param <T> POJO类 * @param t 待更新的数据 * @return 受影响的记录的数量 */ <T> int updateByPrimaryKeySelective(T t); /** * 根据主键删除一条数据 * * @param <T> POJO类 * @param clazz 操作的对象 * @param primaryKey 主键值 * @return 受影响的记录的数量 */ <T> int deleteByPrimaryKey(Class<T> clazz, Object primaryKey); /** * 以全属性方式新增一条数据 * * @param <T> POJO类 * @param t 待新增的数据 * @return 受影响的记录的数量 */ <T> int insert(T t); /** * 以可选属性方式新增一条数据 * * @param <T> POJO类 * @param t 待新增的数据 * @return 受影响的记录的数量 */ <T> int insertSelective(T t);

优秀的个人博客,低调大师

告别日志查询 | 阿里云发布链路追踪服务Tracing Analysis

近日,在杭州云栖大会上,阿里云发布了链路追踪服务Tracing Analysis,成本是自建链路追踪系统的1/5或更少,可为分布式应用的开发者提供完整的调用链路还原、调用请求量统计、链路拓扑、应用依赖分析等工具,帮助开发者快速分析和诊断分布式应用架构下的性能瓶颈,提高微服务时代下的开发诊断效率。 Tracing Analysis 传送门:https://www.aliyun.com/product/xtrace 微服务时代,分布式应用架构虽然满足了应用横向扩展的需求,但是运维和诊断的过程变得越来越复杂,例如会遇到接口诊断困难、应用性能诊断复杂、架构分析复杂、多语言程序接入难统一、调用链路数据离线分析困难等难题。传统的监控工具并无法满足提供跨越不同服务的能见度需求。 阿里云链路追踪服务Tracing Analysis可以跟踪所有分布式架构

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

用户登录
用户注册