Qicz’s Thoughts HUB

The creative and technical writing. Do more, challenge more, know more, be more.

  • 分布式ID生成器-GeDid

    源起 ​ 尝试设计实现一个分布式id工具,已是好几年前的事了,这里是历史的痕迹。 ​ 最初实现了基于redis(jedis客户端)的版本,而后在19年左右,考虑接入Zookeeper版本的。但是一直没有着手去做。 ​ 最近借助一次"翻新"的机会,把它又拿出来,考虑完成Zookeeper版本的实现。因spring-boot-x已经有了很多的基础,也便于Gedid在springboot环境下使用,与springboot的整合和利用已有的springboot资源,所以考虑把Gedid迁移至spring-boot-x,以至于进行了大量的改造。多次调整之后,变有了现在的结果。也有了这个文章的整理。 ​ 这个文章目的:把Gedid的使用场景和使用方式道明白。 ​ 开始 引入依赖 1<dependency> 2 <groupId>org.openingo.boot</groupId> 3 <artifactId>spring-boot-x</artifactId> 4 <version>${spring-boot-x.version}</version> 5</dependency> 在启动类上加入@EnableExtension 目前最新版本 ID引擎 目前支持引擎如下: EtcdIdEngine since v4.

    Read more…
  • Spring Boot Bean动态校验

    springboot中的bean校验使用的是hibernate-validator,相对来说,这种通过注解的校验,对业务代码的“污染”会很少很多很多了。但是,这种方式的局限也很明显: 使用注解的方式,可以说是一种明确的、静态的校验方式,因为“校验”都通过注解呈现了,也就是已经固化了。当需要根据接口的入参去校验关联的属性时,就无法完成了。 如果要实现这种“根据接口的入参去校验关联的属性”就不得不进行根据入参的动态校验,同时还不能影响原有的校验机制,就是静态校验和动态校验的并存,且不能对业务有过多的“污染”。这也是此文的由来了,接下来会讲解一种静态、动态校验可并存的机制。 举例:校验用户的信息,如果用户是微信用户,需要校验微信用户相关的信息,如果用户18岁以上,还需要校验身份证信息;如果是微博用户,需要校验微博相关的信息。 这个场景中,使用静态的方式就不能完成所有场景的校验了。那么传统的做法,可能需要根据org.openingo.account.User#userType的具体取值去判断,比如是org.openingo.account.UserTypeEnum#WECHAT时去校验org.openingo.account.User#weChatAccount等等,如果对应的数据不合法,则抛出对应的异常。这其实就是动态校验的核心逻辑了,下面看具体的源码: 1@Getter 2@AllArgsConstructor 3public enum UserTypeEnum { 4 5 WECHAT(1), 6 WEIBO(2), 7 ; 8 9 private Integer code; 10 11 @JsonCreator 12 public static UserTypeEnum newByCode(Integer code) { 13 return Stream.

    Read more…
  • 细说spring-boot-x

    特别说明:通常,我们会将SpringBoot写作SpringBoot,而此处写作spring-boot是因项目的确就叫做spring-boot-x。以下简称项目。 项目地址:https://github.com/OpeningO/spring-boot-x 源起 娱坛有云一人一首成名曲,虽互联网技术与娱之文艺不同,但个人仍以为技术与艺类同,皆为高雅之事。故成此项目,是以个人有利器,便于而后开疆扩土。 总览 更新说明 支持分布式锁、幂等处理 [2021.8.16更新] since v5.1.0 重构整个包,发布4.0.0.RELEASE版本 [ 2021.6.30更新 ] 优化分布式id生成器,隔离默认的redis配置及Zookeeper配置,让id生成与业务完全分离 [ 2021.6.30更新 ] since v3.2.0.RELEASE 特性清单 手动事务管理 [2021.6.29更新] 分布式id生成器gedid,DidLoader [ 2021.

    Read more…
  • SpringBoot环境的ik应用

    2021第一篇黑科技 背景 最近有个项目接入了es,对于检索关键字需要扩大范围检索结果的匹配范围,所以考虑将检索关键字进行分词处理,再交给es处理。(当然这里可以用es的highlevelclient的analyze接口,此处不考虑这种情况)。于是研究ik-analysis,然后有了ik-springboot-demo这个项目,接下来都将以此项目展开描述。 解决的问题 在SpringBoot项目中直接且简单便捷的使用ik。 收获 得到了SpringBoot项目中使用ik的两种方式; 得到了SpringBoot项目的资源管理的更优方案。 重头戏 从ik的项目情况开始 (以下摘录自ik的github README) IKAnalyzer.cfg.xml can be located at {conf}/analysis-ik/config/IKAnalyzer.cfg.xml or {plugins}/elasticsearch-analysis-ik-*/config/IKAnalyzer.cfg.xml ik_max_word: 会将文本做最细粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,中华人民,中华,华人,人民共和国,人民,人,民,共和国,共和,和,国国,国歌”,会穷尽各种可能的组合,适合 Term Query;

    Read more…
  • 《一往无前》读后感

    过去一周,读了一本书,书名《一往无前》,作者是范海涛女士。多年前,读过范女士的一部著作《世界因你不同》,讲述的是李开复的故事。收益颇深。范女士是哥伦比亚大学首位口述历史硕士学位获得者。而这部《一往无前》,是许久前就发现和关注的一部著作,2020年出版,讲述的是可谓是商业的又一个神话级的公司的发展史,那就是小米。 一直以来对各类商业发展史都有或多或少的研究和兴趣,对小米的了解之前也是很浅层次的。通过读此书对小米的发展有了更深刻的了解。对小米的成功也感触颇深: 从创立之初雷军的状态 创立小米之初,雷军正直40之龄,是一个已实现财富自由,在IT届已经赫赫有名的大佬。当就是这样一位大佬,还未实现青年时期的梦想,所以为了自己梦想,选择了重新开始。而这将是对中国制造的巨大革新,对Made In China的重新诠释的开始。这也是小米诞生的开始。 团队的组建 作为的一个互联网老兵,雷军甚至做一件事,人的重要性,这也是他直到现在在找人少不遗余力的原因。他的用人原则就是,看准的人,不惜任何代价的收入。因为看到了这样的合适的人,而直接收购对方公司的案例太多太多了。没有阿里那般18罗汉的浩大,但也是颇费周折,但比起那当初的18罗汉,可谓是大佬云集。来自google,微软,摩托罗拉等等的比比皆是。 而这些人,选择加入小米的原因就是梦想,相信“风口的猪会飞起来”。这些早已实现财富自由的人,凑在了一起,跳出了自己的舒适区,重新出发。 这个世界上做到的悲剧是比你优秀的人,比你富有的人,却比你努力,而且比你千倍百倍。 业务的爆发 小米国际化 小米的国际化开始于,雨果巴拉的加入。他来自google,从美国来到中国,从小米还是一个小不点的时候,毅然放弃了google的工作来到了小米。 机会面前,人人平等——选择比努力更重要。 Are you ok之开拓印度 经典的鬼畜《Are you OK》相信很多人都听过。但是小米的印度之旅却比这更有意思。 一个错误的判断,面向小米的手机为3G制式,结果手机挤压500万台,这可是10亿的活,这对于小米来说是天大大灾难。不过,最终并没有困住英勇的小米人。把这个10亿的货转战其他国家,最后不仅解决了此困局,而且还收入了其他的国家的尝试。

    Read more…
  • Kong系列之入门(上)

    说明:作者Qicz将有可能随时的修订本文的内容,为了保证内容的一致性和严谨性,作者Qicz保留本文的所有权利。未经作者Qicz本人同意,不得转载或者以其他方式使用这些内容。 本文作为kong系列的入门,主要内容如下: Api gateway概述 Kong安装 Kong.conf 一、Api gateway概述 1、从gateway说起 wikipedia上给gateway了很多定义,gateway是一个入口或者门口,可以说是一个网络间数据或协议交换的物理设备(Router),也可以是设备之前协议转化或数据共享的程序,而这样的程序就是我们这里讨论的重点。 在微服务甚至又出现的宏服务时代,gateway作为一个入口程序,关联着上游服务的数据交互、权限管控、链路跟踪、限流等等,那么kong也在这样的时代背景下应运而生。而且是站在巨人的肩上成长了起来。 这个巨人就是nginx,高性能的代理服务器。 Kong官网 介绍,Kong是一个运行在Nginx中的基于Lua - Nginx模块实现的Lua应用程序。Kong与OpenResty一起发布的,以此替代在Nginx中还需编译Lua - Nginx模块,OpenResty已经包含了lua- Nginx模块。OpenResty不是Nginx的一个分支,而是一组扩展其功能的模块。 Kong是一个基于云的、快速的、可伸缩的分布式微服务抽象层(也称为API网关或API中间件)。2015年作为开源项目发布,其核心价值是高性能和可扩展性。 2、为何选择Kong? 如果您正在为web、移动或物联网构建服务,那们您可能还需要通用功能来运行您的实际软件。Kong可以充当微服务请求的网关(或侧卡),同时通过插件提供负载平衡、日志记录、身份验证、速率限制、转换等功能。 Kong的构建遵循以下主要原则: 高性能:亚毫秒级处理延迟,可支持关键任务用例和高吞吐量。 可扩展性:带有可插拔的体系结构,可通过Kong的Plugin SDK扩展Lua或GoLang中的Kong。 可移植性:要在每个平台,每个云上运行,并通过我们的现代Ingress Controller本地支持Kubernetes。 3、功能特性 Cloud-Native:与平台无关,Kong可以在任何平台上运行-从裸机到容器-并且可以在本机上的每个云上运行。 Kubernetes-Native:使用官方的Ingress Controller通过本地Kubernetes CRD声明性地配置Kong,以路由和连接所有L4 + L7通信。 动态负载平衡:在多个上游服务之间平衡流量。 基于哈希的负载平衡:具有一致的哈希/粘性会话的负载平衡。 断路器:智能跟踪不健康的上游服务。 **运行状况检查:**主动和被动监视上游服务。 服务发现:在第三方DNS解析器(例如Consul)中解析SRV记录。 无服务器:直接从Kong调用和保护AWS Lambda或OpenWhisk功能。 WebSockets:通过WebSockets与您的上游服务进行通信。 gRPC:与gRPC服务进行通信,并通过日志记录和可观察性插件观察流量 OAuth2.

    Read more…
  • Kong 系列大纲

    说明:作者Qicz将有可能随时的修订本文的内容,为了保证内容的一致性和严谨性,作者Qicz保留本文的所有权利。未经作者Qicz本人同意,不得转载或者以其他方式使用这些内容。 入门 api gateway概述 kong安装 kong.conf 配置 kong.conf高级配置 nginx配置 proxy配置 ssl配置 AdminApi Services Routes Consumer Plugins Upstreams Targets Tags 常用插件 key-auth rate-limiting proxy-cache oauth2.

    Read more…
  • Kong Routes Headers Params Expected a Map

    Kong 提供了对Routes的扩展header方式,但是对于这个参数的设置,不小心就会出错了。作者在使用过程中也遇到了问题。 使用postman设置routes的headers参数时,出现如下错误: schema violation (headers: expected a map) 大写的!!! 找了很多资料,几乎都是使用raw的方式,而kong并不支持对routes的headers设置使用raw的方式。 找了很多资料,想起空对数组的处理方式,比如paths,可以像如下这样赋值: 1paths[] = '/foo' 2paths[] = '/example' 于是,用同样的方式尝试,居然成功了,😝

  • 记2020年第一长跑

    非常特别的一次长跑——2020年第一个10km。 有些时间,甚至说就没有进行过这样的运动,这真如突来的长跑,让我思考许多。现在回想,在整个过程中的感受,依据回味无穷。可惜,手机原因未能记录完整数据记录。以下是文字记录: 第0km 起跑时,先整了一个冰的红牛。刚起步,感觉是”轻“。在非常清非常缓的状态下,开始了。预计,在跑到300-500m的时候,感觉就上来了,把速度提了一点,据同行伙伴的数据,应该进入了6分左右。但之后的感受就不一样了,身体有点难以适应了,感觉这与头段时间自己的轻松5km感觉非常不同。 上次的5km,自己是一边跑,一边思考。这样的情况下,顺利的”一心多用“。对5km的完成,没有太多感受。 从装备来说,我选择了一双真的非常不太合适的鞋,鞋底有些硬,稍微懂一点距离,脚就已经有明细的不适。从心里感受来说,我尝试去思考问题,可是无法进入状态。可以也正因为这样,我才可以更加投入的思考,这次跑步的感受。 第1km 到了1km的时候,心里的痛苦的,因为身体并没有适应,坚持跑了”很久“,感受过了”3km“甚至更多那么久🤦‍♂️。但当告诉我,这仅仅是完成了第一个1km时,心里别提多么的崩溃了,这可是还有9km,不过再想想,或许在坚持一下,我的身体适应了,就好了。尝试着提速,并调整和感受身体的适应变化。慢慢的开始适应了。 心里此刻想的, 目标10km,我可以! 第2km 第2km时,内心没有太多变化。当身边无数的”专业“运动者一批一批的从身边经过时,我再加把油,冲冲。 第3km ”这啥时候是最后的最后“,在第3km的时候,身体还未适应,反倒脚的不适越来越明显了,心想坏菜了,这鞋要影响我了。这在身体也会适应的情况下,心里的波动是非常明显的。 继续前进了一会,看着路标指示,这是第3km的开始,还有7km,我离目标又近了一点,还没有到身体适应点,我是不是再坚持一下,身体适应了,就好了呢?继续吧。 第4km 继续进行着,终于来到了身体适应点,尽管这过程中,朋友的运动手表,已经好几次提示我心率过高(最高194),我将速度适当调整之后,继续进行。遇到有微微的上坡的地方,我也会适当的调整为快走的方式。然后继续进行着。 在第4km即将结束,第5km即将开始的时候,遇到了一段上坡更加明显的地方,此刻身体还是有点”拒绝“,一度提示我心率太高。”安全考虑,我再次放缓了“😁。 第5km 第5km开始的时候,心想:”哟,马上进入目标的一半了,虽然刚开始有各种不适,还是坚持下来,再坚持坚持就可以完成了。“一口气,跑到了第6km。 第6km 离目标越来越近了,但是心里的状态似乎又有了新的变化。好像就是为了这10km了。一直盯着还有多少结束,还有多久可以看到终点。就这样一边思量着,一边继续往前。 第7km 哟,还有3km,还记得第一圈的时候,跑到第3km时的状态:“啥时候才是结束”。此刻想的却是,这一路都是我跑过的,我遇到过的,我在找到熟悉的重点接近的感觉。想着3km很快的。原本以为直接离重点已经很近了,结果当我发现一个熟悉的陌生的地方的时候,才发现,原来还早着呢… 第8km 到了第8km,没有了之前的想法,想着最后了,不论如何一定要坚持跑下来。到了有坡的地方,知道现在我也觉得是最爽的地方,我可以颠着跑,可惜鞋是真不行,脚不舒服。继续着… 第9km 离目标越来越近了。 此刻,已经没有太多的想法,就想着我往前,一会就到了重点了,我可以休息一下了。 此刻,除了鞋已经全部湿透了。第一次这种出汗,心里想着还是很美的。想着才坚持就结束了。

    Read more…
  • Kong Quick Start & Core Concepts (cn)

    说明:作者Qicz将有可能随时的修订本文的内容,为了保证内容的一致性和严谨性,作者Qicz保留本文的所有权利。未经作者Qicz本人同意,不得转载或者以其他方式使用这些内容。 从技术的角度来说,Kong是什么(因为Kong也有金刚意思)? (https://docs.konghq.com/2.1.x/getting-started/introduction/) Kong是一个运行在Nginx中的基于Lua - Nginx模块实现的Lua应用程序。Kong与OpenResty一起发布的,以此替代在Nginx中还需编译Lua - Nginx模块,OpenResty已经包含了lua- Nginx模块。OpenResty不是Nginx的一个分支,而是一组扩展其功能的模块。 Kong是一个基于云的、快速的、可伸缩的分布式微服务抽象层(也称为API网关或API中间件)。2015年作为开源项目发布,其核心价值是高性能和可扩展性。 为何选择Kong? 如果您正在为web、移动或物联网构建服务,那们您可能还需要通用功能来运行您的实际软件。Kong可以充当微服务请求的网关(或侧卡),同时通过插件提供负载平衡、日志记录、身份验证、速率限制、转换等功能。 Kong的构建遵循以下主要原则: 高性能:亚毫秒级处理延迟,可支持关键任务用例和高吞吐量。 可扩展性:带有可插拔的体系结构,可通过Kong的Plugin SDK扩展Lua或GoLang中的Kong。 可移植性:要在每个平台,每个云上运行,并通过我们的现代Ingress Controller本地支持Kubernetes。 Features Cloud-Native:与平台无关,Kong可以在任何平台上运行-从裸机到容器-并且可以在本机上的每个云上运行。 Kubernetes-Native:使用官方的Ingress Controller通过本地Kubernetes CRD声明性地配置Kong,以路由和连接所有L4 + L7通信。 动态负载平衡:在多个上游服务之间平衡流量。 基于哈希的负载平衡:具有一致的哈希/粘性会话的负载平衡。 断路器:智能跟踪不健康的上游服务。 **运行状况检查:**主动和被动监视上游服务。 服务发现:在第三方DNS解析器(例如Consul)中解析SRV记录。 无服务器:直接从Kong调用和保护AWS Lambda或OpenWhisk功能。 WebSockets:通过WebSockets与您的上游服务进行通信。 gRPC:与gRPC服务进行通信,并通过日志记录和可观察性插件观察流量 OAuth2.

    Read more…
  • Kong Quick Start & Core Concepts (En)

    Note: Author Qicz may revise the content of this article from time to time. In order to guarantee the consistency and rigor of the content, author Qicz reserves all rights of this article.

    Read more…
  • 阅读致以轻松,阅读聊以蔚然

    阅读的意义是无限的,近来认识一新朋友,他游历全国各地,而每次的游历都会做足了功夫,会对目的地了解非常,多以历史为主。时间久了,就积累各种历史史事,每每聊到此类话题,都肃然起敬,感叹中华文明之悠远。 因今之疫情,心情难免波浮,此时唯有阅读聊以蔚然。 的确,很久没有静心阅读了,近来阅读了基本文学著作,也找到了对应的电影,深入的透析了一把。 阅读是一个很美的事,阅读可以让心平静下来。昨天还看到一则新闻,一位湖北的农民工大叔,在东莞打工17年,却在东莞图书馆阅读了12年之久,因今年的疫情情况,原来的工作单位不能在工作,计划离别东莞,在离别之际,还写了一感谢信。从字里行间,能够感受到,这12年的阅读,对他的帮助之大,他小学文化,但是选择了以这种方式来提升自己,而时间的积累也效果明显。**阅读不只是一种提升的方式,更是一种休闲的方式。**阅读聊以蔚然。

  • Spring动态数据源原理

    提到Spring的动态数据源重点在于对AbstractRoutingDataSource实现及工作原理的认知。 先从Spring的DataSource开始说起,而说到DataSource,用最原始的jdbc来说明可能会更容易理解了。 在使用jdbc时,要进行一个sql操作,我们需要这样的一个链路: Statement <- Connection <- DataSource 也就是根源上就是获取一个DataSource,这就是关联到一个具体源的对象。那么切换源,从原理上来讲就是切换这个DataSource对象了。 那么,下一步,来看看这个AbstractRoutingDataSource的工作原理是不是就是这样的呢?这里摘取它的部分实现源码: 1@Nullable 2private Map<Object, Object> targetDataSources; 3 4@Nullable 5private Object defaultTargetDataSource; 6... 7@Override 8public void afterPropertiesSet() { 9 if (this.

    Read more…
  • 效率工具清单List of Efficiency Tools

    此清单将进行不定期的修订 整理此清单,目的是为了参考市场的各类工具,并应用到生活、工作中,从而提供各种效率。 TODO List类 - 奇妙清单Wunderlist 很早前,就接触和使用了它。它可以非常好的管理好自己的待办。操作界面也比较简约,支持PC、Mac、移动端,方便随时的关注和管理自己的待办。 - Microsoft To Do 早先,有去尝试过,它也是奇妙被微软收购之后的产物,相比奇妙来说,你可以根据自己的情况,把众多的清单归类到一个分组,这算是与奇妙唯一的差异。其中的区别、差异,就我的应用场景来说,目前来说没有找到特别的。 Pomotodo 番茄土豆,按照番茄时钟的方式管理todo。 - 滴答清单 待尝试 笔记类 - 印象笔记 这个产品,我使用时间也笔记旧了,自己也注册了各种的账号,用途就是整理各种各样的笔记。创建不同的NoteBook,在不同的NoteBook中创建不同等Note,可以对Note加入不同的tag。 新版本的印象支持了Markdown,习惯用Markdown的朋友,也可以方便在里面应用。对OCR、Mindmap也有了很多的应用,不过因为我本人可能用不到这类高级功能(我可能会借助其他工具完成),所以没有购买印象的高级功能,并尝试这些高级特性。 - Typora 这个产品,是我目前为止使用过的Markdown类产品中,最爽的:简约,支持自定义很多内容,比如主题,切换交互方式:文本,源码等等。我现在写这篇文章就是用的它。日常工作中,我整理笔记也会用到它。 它的不足就是,它只是一个本地的文本Editor,不能将内容保存到云端。(PS:可以考虑看看有没有办法自己定制一个)

    Read more…
  • Thought and Felling About Technology in 2020

    从故事说起 前段时间,一朋友公司招聘CTO,因为朋友不太懂技术,我帮着参谋了一下。共参与面试了两个人。我想说说对此次面试的感受吧。 第一个,47岁,看到简历,过去的经历非常的丰富。工作经验都20多年了,相比一定的大牛,我还特别担心是不是可以聊得了。但结果却让我大跌眼镜。 到现在,我记得比较深刻的几个问题: linux的发现版有哪些?——因为他提到他对linux很熟悉 答:redhat,centos,其他的就不知道了 其实这个问题,是我在与他沟通过程中发现了很多的问题,他对linux并不熟悉,所以想从这个口去看看他对Linux的了解,结果这根本谈不上了解。甚至还没到Linux系统层面的东西。 未来技术发展趋势? 答:好好学习,学习使用… … 这个让我大大的大跌眼镜,这种说法表面既不成熟,也对技术发展没有任何了解。 按照高可用的标准改造一个他熟悉的系统的思路 基本上答非所问… 另一个,40岁,也是朋友公司比较看重的一个人,从简历上看经历也是相当的丰富的。想着面对这样的人,必定也经历和面试过很多人,换种方式来沟通,让他自己用一种他任何合适的方式来展示自己。

    Read more…
  • 记在2020年的随笔

    2020年对于世界和每个人都是及其特别的一年。 2019年12月开始,陆陆续续爆发的新型冠状病毒疫情,肆虐了国内外。 在国内,疫情最严重的地方就是湖北武汉,而来自全国各地的专家、医护人员的舍命付出,在春暖花开的时节,一切都回归了生机,迎来了难得的胜利之光。 每次看到出征武汉,平平安安回家的英雄们,在回到自己家乡时,都得到了最高级别的迎接礼,每每看到这画面心里有太多说不出来的激动,感慨在疫情面前,在生命面前,每一位医护人员是多么的伟大。 时隔3个月,国内疫情之战,到现在收获了阶段性的胜利,国内疫情已经明显得到了控制,而国外开始肆虐了。而我们国家早就已经”提醒“了国外,而他们却真的错过了非常重要的时间。致使现在国外爆发惊人。到现在全球确认人数已经超过100万之多,想想这一切多么吓人。 刚才又看到一个消息,在国外很多人因为疫情原因都失业了。这场影响严重的疫情,给每个人的生活也带来了巨大的改变。 我看到很多人,因为疫情失去了工作,很多公司因为疫情裁员,甚至就此解散。但面对这突入起来的变顾,我们应该积极的面对。在最初的时候,我觉得这一切在这个时候出现,真的让我雪上加霜了,但后来深入思考,这一切非人为,应该积极的去面对。而且,在这情况下,更应该让自己变得更强才对。 一直以来,给自己定位我是一个有想法有原则的人,时刻会问自己为什么的人。我觉得只有时刻保持这进步、好奇之心,我们才会变得更强。在任何困苦面前,都可以迎难而上。 2020年,我希望是一个艰难的开头,但是有一个完美的收官。 2020年,我要全力提高自身的能力,让自己软技能有大幅提升,硬实力跟强硬。我要让自己在2020年收获更多,成长更多,期待2020年的收官。

  • SpringBoot FatJar vs ThinJar&SpringBoot Thin Planing

    什么是FatJar和ThinJar? FatJar FatJar又叫做UberJar,就是一种超级Jar,其实就是把一个基础Jar及其依赖都打包到一个Jar里面,然后用了它就可以独立工作的Jar。总数很“重”。 ThinJar ThinJar就是对超级Jar相对应的Jar,“纤瘦”的Jar。只有自身的资源组合(.class,properties等等)。 从二者的“身段”来看,和字面来看,FatJar就是一种肥Jar,ThinJar就是一种瘦Jar。在SpringBoot中二者的对比就会更加的明显。因为一个通常的SpringBoot应用(Jar)万万都在几MB,而ThinJar的Jar可能就在几KB,大点也就是几十KB的样子。 如果有一种方式可以让SpringBoot瘦身,你要不要? 我们先看看为什么要瘦身? 因为ThinJar很小,易于部署到服务器(可能是因为我网速慢@.@)。想想如果在一台服务器上部署多个服务的话(也会你不会这样用,但是不一定就不会存在),相同的很多依赖包在网速贼慢的情况下,还得慢慢悠悠的传。 下面就该看看如何瘦身了。从一本书开始说起,书叫《SpringBoot 2 Recipes》。在书中看了一个thinjar的章节(11-3 Reduce Archive Size Through the Thin Launcher Problem)。 Spring Boot, by default, generates a so-called fat JAR, a JAR with all the dependencies inside it.

    Read more…
  • MyBatis Plugin工作机理

    故事开头: 在使用MyBatis的RowBounds时,发现结果没有和理论的一致,然后深入研究RowBounds的实现原理:MyBatis仅借助RowBounds在内存中完成了数据的分页处理——逻辑分页。还有一种是物理分页,就是常见的Limit offset, limit的方式(MySQL)。然后查资料,研究找到了很多的实现方式。我先尝试了一下其中的一种:使用Interceptor的方式。大体的逻辑是在当前执行的SQL后面把RowBounds的offset,limit按照limit offset,limit的方式拼接在SQL后面。 实现如下: 1@Intercepts({@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})}) 2public class PageInterceptor implements Interceptor { 3 4 @Override 5 public Object intercept(Invocation invocation) throws Throwable { 6 Object[] args = invocation.

    Read more…
  • 快速的生成你需要的.gitignore文件

    怎样在项目中快速的生成.gitignore文件呢? 使用git过程中,重视需要加入gitignore忽略文件把项目中不必要的文件忽略掉。但是每次都拷贝之前旧的文件很不方便。而且,针对不同的环境,不同的程序语言,使用的忽略文件可能还不一样,如何快速的生成对应的 ignore 文件呢? ps:因为我在 mac 平台,我就以 mac 平台举例了。 gitignore.io 帮助完成ignore文件的自动化生成 在Terminal中执行如下操作 1echo "function gi() { curl -sL https://www.gitignore.io/api/\$@ ;}" >> \ 2~/.bash_profile && source ~/.bash_profile 使用举例 需要macOS下使用Idea(intellij)、Maven开发 Java的ignore,在项目根目录下(.git 文件夹所在目录)执行如下操作 1gi java,macos,maven,intellij >> .

    Read more…
  • 软件设计原则及常用设计模式

    软件设计原则 开闭原则 Open-Closed Principle, OCP 软件实体如类、模块和函数应该对扩展开放,对修改关闭。 所谓的开闭,也正是对扩展和修改两个行为的一个原则。**用抽象构建框架,用实现扩展细节。**可提高软件系统的可复用性和可维护性。 单一职责原则 Simple Responsibility Principle,SRP 不要存在多于一个导致类变更的原因。如有一个 Class 负责两个职责,一旦发生需求变化,修改其中一个职责的逻辑代码,有可能会导致另一个职责的功能发生故障——这个 Class 就存在了两个导致类变更的因素。此时,我们就需要给两个职责分别用两个 Class 来实现,实现解耦职责的清晰拆分。后期的需要变更维护互不影响。如此设计,可降低类的复杂度,提高类的可读性,提高系统的可维护性,降低变更引起的风险。一个 Class/Interface/Method只负责一项职能. 依赖倒置原则 Dependence Inversion Principle,DIP 设计代码结构时,高层模块不应该依赖底层模块,二者都应该是依赖其抽象。**抽象不应依赖细节;细节应该依赖抽象。**通过依赖倒置,可减少类与类的耦合性,提高系统的稳定性,提高代码的可读性和可维护性,并可以降低修改程序所造成的风险。【依赖注入】

    Read more…
  • 分布式系统/高并发系统设计原则

    DID 原则 : Design - Implement - Deploy 设计(Design)20倍的容量。 实现(Implement)3倍的容量。 部署(Deploy)1.5倍的容量。 确保一定时间内,不会因为业务体量的变化出现对架构较大的升级调整。但尽快如此,也不能过度咯。 1、换个思路理解 DID 在软件建构领域,有一个原则叫DID, 通常用来保证资源和时间的最小化。 DID: 设计(Design)20倍的容量。 实现(Implement)3倍的容量。 部署(Deploy)1.5倍的容量。 这个DID一般是从资源成本的更小消耗来出发,希望将更低成本的设计发挥更大的作用,对更高成本的部署更谨慎的使用。 换个思路,在需求开发与系统设计层面出发,也应该遵循这种规律,即在前期设计层面下足功夫,用更周到的设计来实现 方案,以便在部署上线后的改动最小。 但是,往往在实际开发中这个过程都是本末倒置的,从 ‘拍脑袋就做’ 到 ‘开发中发现行不通’ 到 ‘返工’,或者更严重的上线 之后才发现问题,导致更大的返工成本。

    Read more…
  • 软件设计模式之单例模式

    单例模式是软件设计中非常常见的模式,但真正用好也用对的好像还有很多路要走。一起来研究一下。 单例,最最起码得有这些吧 私有的构造方案 一个 static 的实例 一个 static 的外部访问入口 具体代码应该是这样的(懒汉模式) 1public class Singleton { 2 3 private static Singleton instance = null; 4 5 private Singleton(){} 6 7 public static Singleton getInstance() { 8 if (null == instance) { 9 instance = new Singleton(); 10 } 11 return instance; 12 } 13} 当然了,看着好像是那么回事,完成了以上操作,我们来测试一下

    Read more…
  • 木桶与扬长避短

    木桶视盛水的多少来具体他应有的价值,所以出现了,短板决定其价值的说法。 扬长避短,说的是要去发挥长处,避开短处。似乎与“木桶”相反了。  但,人无完人金无足赤,完人不可能存在,也就是人之短,必然存在。当对于长短如何取舍呢 ?  商业行为中,攻破短板可能是制胜之宝。比如几个人一起合伙创业,各种能力不一,但在创业这件事上,绝对都是“长长”结合,最后也实现了“有效木桶”。  但对于个人来说,既然人无完人,而且人生短短数载,我们的选择又是什么呢? 在我来看,选择极致效果可能更大,也就是全力去发挥自己的长处。  有一种说法,一个人的某一方面有问题,那么别的方面肯定有强项,而且是非常强的强项。比如一个失聪之人,可能视力可能会非常出众;失明之人,可能听力又特长。失聪之人,如何努力也不可能把自己的“短”长些,失明之人亦是。所以发挥自己的强项,于个人而见,更优。  最近,看到一种“T”型理论,说的是T之竖向,为个人长向,T之横向,为个人之短向延伸。这样确保了,你可以成为一个“综合性人才”。  所以,完完全全的舍弃短向,自然不可取。  对于长短的合理分配,个人见解,优长次短。要想实现“扬长避短”,第一点,是要对自身各方面的优劣长短,有清晰客观的界定、描述和洞察。第二点,是在知道了“短”与“长”之后的具体操作,比如“避短”就包括多种方式,技巧性地藏拙、战略性地舍弃、主动式地攻克短处彻底提升等;比如“扬长”需要环境与时机,需要卖点与亮点,需要适量与适度。  不论木桶,长短理论,对自己的认知,才是基础,要找到自己的“长”才是最核心的前提,用有限的时间,更有效的投入到“长”上,收获可能会更多。让自己的“短”得以合适的发挥,让自己“更全面”。  世界上的事,往往知易行难,而且,越是那些对人生有重大警示与助益的道理,越是如此。而知易行难,表面上看是由于不够自律不够坚持等,其实却大多是由于没有理解透彻,没有透彻到化成自己的思维意识,对这些道理只是在人云亦云、隔靴搔痒。  比如“扬长避短”,本是一个高度凝练的、助人良多的成语,但在现实生活中,却几乎沦为一句“无实义”的套语。  要想实现“扬长避短”,第一点,是要对自身各方面的优劣长短,有清晰客观的界定、描述和洞察。  第二点,是在知道了“短”与“长”之后的具体操作,比如“避短”就包括多种方式,技巧性地藏拙、战略性地舍弃、主动式地攻克短处彻底提升等;比如“扬长”需要环境与时机,需要卖点与亮点,需要适量与适度。  关于第一点,我们在《自知之明:管理学的终极法宝》一文中有过专门论述,而第二点,则要借鉴著名的“木桶理论”来进一步细说。

    Read more…