时间轮算法(转)

JavaGuide Yesterday The following article is from yes的练级攻略 Author 是Yes呀 大家好,我是 Guide哥。今天这篇文章所聊的话题,非常重要!不论是你想在面试中脱颖而出,还是你想要搞懂 Netty、Kafka、Zookeeper 等等中间件的原理,你都务必要把这篇文章仔细阅读完!一遍看不懂就多看几遍,相信我,你一定会有收获!总之,搞懂时间轮算法真的非常有必要!!! 另外,我建议你在搞懂了时间轮算法的原理之后,可以参考一些开源项目对时间轮算法的实现,自己也手写一个。 下面是正文! 最近看 Kafka 看到了时间轮算法,记得以前看 Netty 也看到过这玩意,没太过关注。今天就来看看时间轮到底是什么东西。 为什么要用时间轮算法来实现延迟操作? 延时操作 Java 不是提供了 Timer 么? 还有 DelayQueue 配合线程池或者 ScheduledThreadPool 不香吗? 我们先来简单看看 Timer、DelayQueue 和 ScheduledThreadPool 的相关实现,看看它们是如何实现延时任务的,源码之下无秘密。再来剖析下为何 Netty 和 Kafka 特意实现了时间轮来处理延迟任务。 如果在手机上阅读其实纯看字也行,不用看代码,我都会先用文字描述清楚。不过电脑上看效果更佳。 Timer Timer 可以实现延时任务,也可以实现周期性任务。我们先来看看 Timer 核心属性和构造器。 核心就是一个优先队列和封装的执行任务的线程,从这我们也可以看到一个 Timer 只有一个线程执行任务。 再来看看如何实现延时和周期性任务的。我先简单的概括一下,首先维持一个小顶堆,即最快需要执行的任务排在优先队列的第一个,根据堆的特性我们知道插入和删除的时间复杂度都是 O(logn)。 然后 TimerThread 不断地拿排着的第一个任务的执行时间和当前时间做对比。如果时间到了先看看这个任务是不是周期性执行的任务,如果是则修改当前任务时间为下次执行的时间,如果不是周期性任务则将任务从优先队列中移除。最后执行任务。如果时间还未到则调用 […]

EPIGRAMS IN PROGRAMMING

http://www.cs.yale.edu/homes/perlis-alan/quotes.html 1. One man’s constant is another man’s variable. 2. Functions delay binding; data structures induce binding. Moral: Structure data late in the programming process. 3. Syntactic sugar causes cancer of the semicolon. 4. Every program is a part of some other program and rarely fits. 5. If a program manipulates a large amount of […]

命令行工具——curl(转)

作者 | 琼璞 责编 | 张红月 来源 | 晚晴幽草轩(ID:nice-links) curl 非常有用的命令行工具库,用于通过 URL 传输数据。它的名字就是客户端(client)的 URL 工具的意思(command line tool and library for transferring data with URLs)。它的功能非常强大,命令行参数多达几十种。如能熟练使用,可以在很多应用场景下,发挥巨大的价值。本篇文章,就跟大家一起探讨下 curl 以及关于它的那些妙用。 关于 curl **** curl 是免费的开源软件,截止 2021 年 2 月,最近稳定版本是 7.75.0;它支持包括 FTP、HTTP、HTTPS、FTP、SCP,SFTP 数十种协议;curl 在命令行或脚本中用于传输数据。另外,它还用于汽车,电视机,路由器,打印机,音频设备,移动电话,平板电脑,机顶盒,媒体播放器中,并且是数千种每天影响数十亿人口的软件应用程序的互联网传输基础。如果您想了解更多关于 curl,可参见 curl.se 或 github.com/curl/curl。 如何使用 **** 如上命令,不带有任何参数时,curl 就是发出 GET 请求(向 nicelinks.site,服务器返回的内容会在命令行输出。当然,你还可以为其添加各种参数(如 -A、-b、-c、-d、-e、-F、-H等等),使得可以完成更多复杂任务; -e -e参数用来设置 HTTP 的标头Referer,表示请求的来源。 […]

IntelliJ IDEA 调试技巧(转)

转自:十光年 链接:www.cnblogs.com/jun1019/p/9741224.html 一、条件断点 **** 循环中经常用到这个技巧,比如:遍历1个大List的过程中,想让断点停在某个特定值。 参考上图,在断点的位置,右击断点旁边的小红点,会出来一个界面,在Condition这里填入断点条件即可,这样调试时,就会自动停在i=10的位置 二、回到”上一步” **** 该技巧最适合特别复杂的方法套方法的场景,好不容易跑起来,一不小心手一抖,断点过去了,想回过头看看刚才的变量值,如果不知道该技巧,只能再跑一遍。 参考上图,method1方法调用method2,当前断点的位置j=100,点击上图红色箭头位置的Drop Frame图标后,时间穿越了 回到了method1刚开始调用的时候,变量i变成了99,没毛病吧,老铁们,是不是很6 🙂 注:好奇心是人类进步的阶梯,如果想知道为啥这个功能叫Drop Frame,而不是类似Back To Previous 之类的,可以去翻翻JVM的书,JVM内部以栈帧为单位保存线程的运行状态,drop frame即扔掉当前运行的栈帧,这样当前“指针”的位置,就自然到了上一帧的位置。 三、多线程调试 **** 多线程同时运行时,谁先执行,谁后执行,完全是看CPU心情的,无法控制先后,运行时可能没什么问题,但是调试时就比较麻烦了,最明显的就是断点乱跳,一会儿停这个线程,一会儿停在另一个线程,比如下图: 如果想希望下一个断点位置是第2句诗句,可能要失望了: 如果想让线程在调试时,想按自己的愿意来,让它停在哪个线程就停在哪个线程,可以在图中3个断点的小红点上右击, 即:Suspend挂起的条件是按每个线程来,而非All。把这3个断点都这么设置后,再来一发试试 注意上图中的红框位置,断点停下来时,这个下拉框可以看到各个线程(注:给线程起个容易识别的名字是个好习惯!),我们可以选择线程“天空中的飞鸟” 断点如愿停在了第2句诗。 四、远程调试 这也是一个装B的利器,本机不用启动项目,只要有源代码,可以在本机直接远程调试服务器上的代码,打开姿势如下: 4、1 项目启动时,先允许远程调试 起作用的就是 注意:远程调试从技术上讲,就是在本机与远程建立scoket通讯,所以端口不要冲突,而且本机要允许访问远程端口,另外这一段参数,放要在-jar 或 ${main_class}的前面 4、2 idea中设置远程调试 然后就可以调试了 前提是本机有项目的源代码 ,在需要的地方打个断点,然后访问一个远程的url试试,断点就会停下来。 五、临时执行表达式/修改变量的运行值 调试时,可以临时执行一些表达式,参考下图:点击这二个图标中的任何1个都可以 点击+号后,就可以在新出现的输入框里输入表达式,比如i+5 然后回车,马上就能看到结果 当然,如果调试时,想动态修改变量的值,也很容易,在变量上右击,然后选择Set Value,剩下的事,地球人都知道。 ) 六:方法上断点 注:Spring boot项目,在方法上加断点,会严重降低启动速度,甚至卡住,故断点的添加要在启动后,且用后移除 当不知道在业务中究竟调用的哪个实现的时候,可以在方法上加断点。

Kubernetes 部署 Kafka & Zookeeper(转)

bash 正文:以下内容适用于Kubernetes v1.20.0之前的版本,因为从该版本开始弃用selfLink。nfs-client-provisioner已无法使用:临时解决方案:https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner/issues/25 相似的还有:https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner/tree/master/charts/nfs-subdir-external-provisioner 以上均已无法使用。可考虑降级kubernetes todo:topic已创建成功,但无法生产及消费消息 关于StorageClass 在K8S环境,当pod需要存储空间时,StorageClass比PV更灵活和方便,官方文档地址:https://kubernetes.io/docs/concepts/storage/persistent-volumes/ 本次实战 本次实战的目标是快速创建NFS类型的StorageClass,并验证该StorageClass正常可用,全文由以下部分组成: 创建StorageClass; 通过helm下载tomcat的chart; 修改chart,让tomcat使用刚才创建的StorageClass; 在NFS服务端检查文件夹已正常写入; 环境信息和准备工作 以下是创建StorageClass必备的环境信息: Kubernetes:1.15 Kubernetes宿主机:CentOS Linux release 7.7.1908 NFS服务:IP地址192.168.50.135,文件夹/volume1/nfs-storageclass-test 如果您已经准备好了kubernetes和NFS,咱们就开始实战吧; 如何创建StorageClass 把创建StorageClass要做的的事情理清楚: 创建namespace,这里用hello-storageclass(您也可以选用自己喜欢的); 创建rbac:因为StorageClass有对应的pod要运行,每个pod都有自己的身份即serviceaccount,而这个serviceaccount是和某个角色绑定的,所以要创建:serviceaccount、rule、rolebinding; 创建provisioner,即关联NFS的工作类,负责给PVC提供存储资源,这里用的是nfs-client-provisioner; 创建StorageClass,所有需要PVC通过该StorageClass即可获得存储空间; 接下来请SSH登录kubernetes环境,按照上述步骤操作; 创建StorageClass 创建namespace:kubectl create namespace hello-storageclass 创建rbac的脚本直接从我的github下载吧,地址:https://raw.githubusercontent.com/zq2599/blog_demos/master/storageclass-demo/rbac.yaml 下载的rbac.yaml文件中,namespace是kafka-test,现在要替换成hello-storages,执行命令替换:sed -i ‘s/kafka-test/hello-storageclass/’ rbac.yaml 创建rbac:kubectl apply -f rbac.yaml 创建provisioner的脚本也从我的github下载,地址:https://raw.githubusercontent.com/zq2599/blog_demos/master/storageclass-demo/deployment.yaml 下载的deployment.yaml文件中,namespace是kafka-test,现在要替换成hello-storages,执行命令替换:sed -i ‘s/kafka-test/hello-storageclass/’ deployment.yaml 打开deployment.yaml,设置NFS参数,修改下图红框的四个参数,红框1和3都是NFS server地址,红框2和4都是NFS分配的文件夹目录,请您按照实际的NFS资源来设置: 创建provisioner:kubectl apply -f deployment.yaml […]

kubernetes之helm简介、安装、配置、使用指南。包含安装WordPress(转)

原文地址:https://feiutech.blog.csdn.net/article/details/81087911?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.control helm简介 很多人都使用过Ubuntu下的ap-get或者CentOS下的yum, 这两者都是Linux系统下的包管理工具。采用apt-get/yum,应用开发者可以管理应用包之间的依赖关系,发布应用;用户则可以以简单的方式查找、安装、升级、卸载应用程序。 我们可以将Helm看作Kubernetes下的apt-get/yum。Helm是Deis (https://deis.com/) 开发的一个用于kubernetes的包管理器。每个包称为一个Chart,一个Chart是一个目录(一般情况下会将目录进行打包压缩,形成name-version.tgz格式的单一文件,方便传输和存储)。 对于应用发布者而言,可以通过Helm打包应用,管理应用依赖关系,管理应用版本并发布应用到软件仓库。 对于使用者而言,使用Helm后不用需要了解Kubernetes的Yaml语法并编写应用部署文件,可以通过Helm下载并在kubernetes上安装需要的应用。 除此以外,Helm还提供了kubernetes上的软件部署,删除,升级,回滚应用的强大功能。 Helm 组件及相关术语 Helm Helm 是一个命令行下的客户端工具。主要用于 Kubernetes 应用程序 Chart 的创建、打包、发布以及创建和管理本地和远程的 Chart 仓库。 Tiller Tiller 是 Helm 的服务端,部署在 Kubernetes 集群中。Tiller 用于接收 Helm 的请求,并根据 Chart 生成 Kubernetes 的部署文件( Helm 称为 Release ),然后提交给 Kubernetes 创建应用。Tiller 还提供了 Release 的升级、删除、回滚等一系列功能。 Chart Helm 的软件包,采用 TAR 格式。类似于 APT 的 DEB 包或者 YUM 的 […]

Jpa no session(包含多数据源)

在springboot中,在application.properties的配置文件中新增spring.jpa.open-in-view=true方法失效,经过测试,有两种解决办法:1、在application.properties的配置文件中新增spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true;2、在测试的方法上添加@Transactional注解 多数据源相关转自 多数据源场景 解决办法:将方法细化。单个方法只使用一个session(有读有写的逻辑,读写都使用同一个session),在方法上使用事务注解标注事务的管理器 @Transactional(value = “transactionManagerLinux”, rollbackFor = Exception.class) 当前查询及更新问题已修复。接下来就是一大波代码重构 以下是一些介绍及说明 文章目录 [一、首先要配置druid数据源] [二、数据源生成类:] [三、EntityManager生成类] [四、问题汇总] 一、首先要配置druid数据源 1、druid的某个配置很重要,因为数据库的每个连接是默认有一个8小时的超时时间的,如果过了8小时,连接会自动断掉,而druid此时还不知道连接已经断掉,也没有回收,一直用那个连接就会报错。此种情况一般出现于定时任务,比如某个统计需要每天统计一次,某个连接可能24小时才会使用一次,这时就会出现这个问题。解决方案:①、更改数据库默认的wait_outtime,改长一点,不推荐②、可以从数据源入手,更改druid的配置,让druid每隔一段时间自动去检测连接池中每个连接是否可用,如果不可用则回收。后面需要连接时,会重新开启一个连接。这个时间间隔需要小于数据库的超时时间才对。 2、druid配置和jpa配置 ①、主库配置: ②、从库配置 ③、JPA配置 注意:①: 因为jpa或者说hibernate是orm框架,有一个自动更新数据库的配置,可以使数据库根据项目中的实体类自动生成相应的表结构,非常方便好用。但是这也引来了一些问题,如果从库也应用这个配置,就会更改从库的表结构,而从库只要自己发生变化而不是主库复制来的,就会发生mysql错误,使主从复制停止,造成重大错误。所以此时jpa的配置应该主从分离,此操作实现在EntityManager生成配置类中。②:为了避免上述情况在我们不经意间发生,最好给从库配置一个只能读不能写的权限的用户,我们所有操作都用这个用户来执行,避免人为错误。 二、数据源生成类: 三、EntityManager生成类 与jpa结合起来: 1、主库: 2、从库 四、问题汇总 1、在service层引入entityManager的时候,用spring的@Autowired或者@Resource引入会有一些问题,有时候数据源中的连接的获取会不正常,所以用官方的方法引入比较好,比如引入从库的entityManager: 2、如果两个实体之间具有管理关系,并且是懒加载的,在从库查询时会有no session问题,就算配置了spring.jpa.open-in-view=true,还是会有问题。springboot对于这个配置是这样处理的:JpaBaseConfiguration.java源码: jpa底层判断spring.jpa.open-in-view是否为true,如果是true,则注册OpenEntityManagerInViewInterceptor这个拦截器。OpenEntityManagerInViewInterceptor对于懒加载的处理: 在请求到服务端时,先经过这个拦截器,将getEntityManagerFactory()作为key,将EntityManager em = createEntityManager();EntityManagerHolder emHolder = new EntityManagerHolder(em);emHolder作为值,存入TransactionSynchronizationManager的当前线程的ThreadLocal变量中,在后面的懒加载的处理,就可以通过entitymanager去加载数据,但是这个拦截器getEntityManagerFactory()和createEntityManager()都是用的默认的entityManager(主库的),所以对于从库的查询就不行了,为了解决这个问题,需要在方法中显式的存入entityManager,如下:(也可以通过注解配置,见下面代码中注释的@Transactional部分) 全局懒加载 关于延迟加载 在 Spring 中,默认情况下所有定的 bean 及其依赖项目都是在应用启动时创建容器上下文是被初始化的。测试代码如下: 启动应用日志: 如上日志: 在 Tomcat started […]

Spring 代码的部分技巧(二)(转)

第二篇关于Spring代码技巧的博文。感谢大佬。 CSDN Today The following article is from 苏三说技术 Author 因为热爱所以坚持ing 作者 | 苏三 责编 | 张文 来源 | 苏三说技术(ID:gh_9f551dfec941) 本文继续总结我认为 Spring 中还不错的知识点,希望对您有所帮助。 @Conditional的强大之处 **** 不知道你们有没有遇到过这些问题: 某个功能需要根据项目中有没有某个jar判断是否开启该功能。 某个bean的实例化需要先判断另一个bean有没有实例化,再判断是否实例化自己。 某个功能是否开启,在配置文件中有个参数可以对它进行控制。 如果你有遇到过上述这些问题,那么恭喜你,本节内容非常适合你。 @ConditionalOnClass 问题1可以用@ConditionalOnClass注解解决,代码如下: 如果项目中存在B类,则会实例化A类。如果不存在B类,则不会实例化A类。 有人可能会问:不是判断有没有某个jar吗?怎么现在判断某个类了? 直接判断有没有该jar下的某个关键类更简单。 这个注解有个升级版的应用场景:比如common工程中写了一个发消息的工具类mqTemplate,业务工程引用了common工程,只需再引入消息中间件,比如rocketmq的jar包,就能开启mqTemplate的功能。而如果有另一个业务工程,通用引用了common工程,如果不需要发消息的功能,不引入rocketmq的jar包即可。 这个注解的功能还是挺实用的吧? @ConditionalOnBean 问题2可以通过@ConditionalOnBean注解解决,代码如下: 实例A只有在实例B存在时,才能实例化。 @ConditionalOnProperty 问题3可以通过@ConditionalOnProperty注解解决,代码如下: 在applicationContext.properties文件中配置参数: 各参数含义: prefix 表示参数名的前缀,这里是demo name 表示参数名 havingValue 表示指定的值,参数中配置的值需要跟指定的值比较是否相等,相等才满足条件 matchIfMissing 表示是否允许缺省配置。 这个功能可以作为开关,相比EnableXXX注解的开关更优雅,因为它可以通过参数配置是否开启,而EnableXXX注解的开关需要在代码中硬编码开启或关闭。 其他的Conditional注解 当然,spring用得比较多的Conditional注解还有:ConditionalOnMissingClass、ConditionalOnMissingBean、ConditionalOnWebApplication等。 […]

线上发布-阿里云微服务引擎MSE?(转)

CSDN 4 days ago The following article is from 阿里巴巴中间件 Author 方剑(洛夜) 作者 | 方剑(洛夜) 责编 | 张文 来源 | 转载自阿里巴巴中间件(ID:Aliware_2018) 主要是通过阿里的微服务引擎MSE来实现的。 在资金允许的情况下,这些成熟的方案的确能减少不少的工作。比如在阿里云上使用Spring Cloud Alibaba及相关的产品,就会很好用。 本文,我们继续聊聊《揭秘大流量场景下发布如丝般顺滑背后的原因》中的另外一环——灰度发布,也叫金丝雀发布。 很多互联网公司在半夜发布的另外一个重要原因是不具备可灰度能力,新版本存在 bug 或者其它原因会影响线上的客户,无奈之下只能选择在半夜进行发布来减少影响面。 我们知道默认情况下,无论是 Kubernetes 还是 ECS,新老版本都存在的情况下会根据特定的负载均衡算法随机地路由到不同的实例上,随机意味着出问题也会随机出现。我们需要一套动态路由来完成灰度发布的解决方案。 在 RPC 领域,我们称灰度发布为动态路由,动态路由的意思是指流量可以动态地路由到指定的实例上。 动态路由场景 **** 动态路由是微服务里非常核心的功能,流量动态路由意味着可以做非常多的事情。由此衍生出各个场景: 金丝雀发布:只有满足特定规则(比如 Query Parameter、HEADER、COOKIE 中某些 KEY 满足一些条件)或者是固定流量比例的流量才会进入新版本,其它流量都路由到老版本上。 同机房优先路由:当公司规模扩大之后,应用会跨机房部署来达到高可用的目的。由于异地跨机房调用出现的网络延迟问题,需要确保服务消费方能优先调用相同机房的服务消费方,这就需要同机房优先路由的能力。 标签路由:金丝雀发布的新场景。金丝雀发布一般只有新和老两个版本,标签路由可以在线上部署多个版本,每个版本都对于一个标签。 全链路灰度:在业务比较复杂,服务调用链路较长的场景下,每个应用都需要设置路由规则会显得非常繁琐,全链路灰度在金丝雀/标签路由的基础上加上了 “标签透传” 的能力,让灰度流量只在灰度版本之间路由。 接下来我会分几篇文章详细讲一下这几个场景,今天我们先来聊聊金丝雀发布。金丝雀发布可以让我们在白天流量高峰喝着茶吃着瓜子进行线上发布,不需要在半夜为发布的事情而苦恼。 大流量下的应用部署现状 应用 Demo Demo […]

Jdk编译

https://openjdk.java.net/groups/build/doc/building.html 下载源码: git clone https://github.com/openjdk/jdk.git Get the complete source code:git clone https://git.openjdk.java.net/jdk/ Run configure:bash configure If configure fails due to missing dependencies (to either the toolchain, build tools, external libraries or the boot JDK), most of the time it prints a suggestion on how to resolve the situation on your platform. Follow the instructions, and try running bash configure again. Run make:make images Verify […]

lWoHvYe 无悔,专一