一切福田,不離方寸,從心而覓,感無不通。

Category Archives: Java

CD基金会、Jenkins、Jenkins X、Spinnaker和Tekton的常问问题

FAQ 什么是持续交付(CD)? CD是一种软件工程方法,团队在短周期内生成软件,确保软件可以随时可靠地发布。微服务、云原生架构的兴起引发了持续交付实践的必然结果。这与CI/CD有关,其中包括持续集成(CI) – 将所有开发者工作副本一天多次合并到共享主线的做法。 宣布了什么? CDF(Continuous Delivery Foundation,持续交付基金会)是一个新的、中立的组织,将发展和维持一个开放的持续交付生态系统。它将提供统一的治理和与供应商中立的管理,以及对资金和运营的监督。CD基金会的第一批项目是Jenkins、Jenkins X、Spinnaker和Tekton。 为什么CD社区组成基金会。为什么需要? 整个行业都迫切需要围绕管道、工作流程和其他CI/CD领域合作定义行业规范,并为CI/CD工具提供基础支持。例如,Jenkins社区正在寻求一个“全方位服务”的基金会来托管Jenkins(最受欢迎的CI/CD项目之一),并构建一个增强协作的平台。还需要一个全行业的中立DevOps/CD会议。 这是否代表了云原生态系统的转变? 是的,市场已转向容器化和云原生技术,因此CI/CD系统、DevOps和相关工具的生态系统发生了根本性的变化。CNCF云原生互动景观展示了CI/CD领域的多样性,以及在该领域中活跃的众多项目和供应商。 通过建立供应商中立的持续交付基金会,业界顶级开发者、最终用户和供应商可以将CI/CD作为方法,定义/记录最佳实践以及创建培训材料,以使全球任何软件开发团队能够交付代码更改更快、更可靠、无论它们是否为云原生。 开发者为何要关心? CI/CD项目目前面临的挑战,包括工具复杂性和管道和其他CI/CD工具缺乏行业标准化,正在抑制增长和创新。由于缺乏中立的法律实体和强有力的治理,项目很难吸引新开发者和组织的宝贵支持。项目维护者和开发者花费大量时间和金钱处理安全程序和监督等方面的变通方法。这使人们不再关注新的发展和创新。拥有广泛行业支持的基金会将能够更快地定义行业规范,并为跨项目协作创造更多机会,以改善开发者的工具。 谁用CD? CD广泛应用于云计算、企业IT,并且正在迅速扩展到其他顶级行业垂直领域。例如,在网络运营商与供应商并肩工作,开发CI/CD工具,使开发者能够直接与上游项目的分支合作 – 大幅缩短实施新功能的时间,并解决数月到数天的错误。使用云原生技术(如Kubernetes)时,设置CI/CD管道将加快发布生命周期。这使开发者每天可以多次发布;让团队灵活到足以快速迭代。 CDF如何与渐进式交付相关? 渐进式交付(Progressive delivery)是现代持续交付技术的一种形式,例如灰度发布、功能标记、A/B测试、经过验证的部署组等。渐进式交付技术和技术与持续交付密切相关。有关渐进式交付的更多信息,请阅读James Governor关于此主题的Redmonk博客:https://redmonk.com/jgovernor… 这将如何影响开源软件的开发? 持续交付可提高软件开发团队的速度、生产力和可持续性。CDF促进行业顶级开发者、最终用户和供应商之间的合作,以确保CD方法的软件工程充分发挥其潜力,推进开源软件开发。 哪些项目将包含在CDF中? CDF正在推出四个项目:Jenkins、Jenkins X、Spinnaker和Tekton,还有更多感兴趣的项目正在筹备中。我们邀请人们关注CDF技术监督委员会(“TOC”),该委员会将在未来做出项目决策:https://github.com/cdfoundati…。 我是否必须是成员才可以贡献到CDF项目? 绝对不是,CDF中的开源项目或任何Linux基金会计划的技术贡献都不需要成员资格。组织作为成员加入CDF,因为它们希望在持续交付模型和最佳实践的增长和发展中扮演积极的角色,而不只是支持CDF中的开放源码项目。如果你有兴趣加入,请参阅https://cd.foundation/members…。 什么是Jenkins? Jenkins是领先的开源自动化服务器,由大量不断增长的开发者、测试者、设计者和其他对持续集成、持续交付和现代软件交付实践感兴趣的人提供支持。它基于Java虚拟机(JVM),提供超过1,500个插件,可将Jenkins扩展为几乎所有技术软件交付团队使用的自动化服务器。2019年,Jenkins有超过了200,000个已知安装,使其成为部署最广泛的自动化服务器。 什么是Jenkins X? Jenkins X是Kubernetes上现代云应用程序的开源CI/CD解决方案。Jenkins X提供管道自动化、内置GitOps和预览环境,以帮助团队协作并加速他们的软件交付。Jenkins X使用最好的OSS工具自动化Kubernetes的CI + CD,如Jenkins、Tekton、Prow、SkaffoldKaniko和Helm。 为什么Jenkins和Jenkins X成为CDF的一员? Jenkins和Jenkins X将成为与技术兴趣相关的中立社区的一部分,并在构建开发者社区和项目治理方面获得帮助。CD基金会还将协助Jenkins和Jenkins X的营销和文档工作。 这对现有Jenkins用户有何影响? 将Jenkins和Jenkins X捐赠给CD基金会将促进行业内开发者、最终用户和供应商之间的更多合作。有关详细信息,请参阅此电子邮件和与Jenkins社区的对话:https://groups.google.com/for… 什么是Tekton? Tekton是一组用于构建CI/CD系统的共享开源组件。它使持续交付控制平面现代化,并将软件部署的大脑转移到Kubernetes。Tekton的目标是通过供应商中立的开源基金会为CI/CD管道、工作流程和其他构建模块提供行业规范。Tekton的代码在https://github.com/tektoncd/p…。 为什么Tekton成为CDF的一员?为什么Google会捐赠代码? 作为CDF的创始成员,谷歌正在捐赠Tekton。正如Kubernetes通过提供一组标准的API在云中进行交互而彻底改变了应用程序开发,Google的目标是通过CD基金会为DevOps从业者提供相同的优势。CDF将提供行业规范、安全、实用和可扩展的持续交付构建块,可用于在任何地方部署代码。 Tekton对knative build的影响是什么? 从第1天开始,可插拔性一直是knative的核心功能。将Build与Serving分离的目标是强化这种可插拔性概念。已经对构建系统感到满意的用户可以将其与Knative Serving一起使用。Tekton将继续支持Knative生态系统作为一流的目标环境。Tekton管道将部署到Knative环境。 在可预见的未来,Knative Build将继续作为Knative的一部分,专注于无服务器环境的源到容器工作流程。这两个项目将在标准和界面上保持紧密联系。 什么是Spinnaker? Spinnaker是云端优先的持续交付平台,最初由Netflix创建,目前由Netflix和Google共同领导。它支持所有主要的云平台和Kubernetes,并得到各个供应商的贡献。Spinnaker通常用于大规模组织,DevOps团队通过提供“黄金路径”(golden path)应用程序部署管道来支持许多开发者。 为什么Google/Netflix将Spinnaker捐赠给CDF? 随着Spinnaker最近将其治理正式化,将其转移到基金会是社区自然的下一步。Spinnaker设计为持续交付平台,通常与Jenkins结合使用,因此CDF真的是项目的理想之家。 Spinnaker也是一个多组件系统,在概念上与Tekton分享了许多想法 – 看到两个项目在一个基金会上聚集在一起,是将持续交付向前推进的巨大机会。 这对Spinnaker用户有何影响? Spinnaker作为CDF的一员,社区将有更多机会创建更简单、更强大的端到端体验,并就CI/CD的一套通用标准进行协作。Spinnaker用户在持续交付领域拥有丰富的经验,加入CDF提供了一个与更广泛的社区分享专业知识的绝佳机会。 Spinnaker用户还将受益于CDF社区中广泛的CI/CD知识,他们使用的各种工具之间的一致性,当然还有不断改进的生态系统! 未来的CI/CD项目进入CDF的过程是怎样? 其他项目预计将通过其即将成立的技术监督委员会(TOC)加入CDF:https://github.com/cdfoundati…,重点是将CD生态系统整合在一起,围绕可移植性和互操作性构建规范和项目。 CDF的下一步是什么? 接下来的步骤是启动治理结构。将成立一个理事会、技术和外联/营销委员会。我们计划在未来几个月内实现这一目标,并邀请新成员加入我们的社区。如果你有兴趣加入社区推进CD,请到https://cd.foundation/members…。 CNCF的参与程度,为什么需要一个单独的基金会? 首先要注意的是,CD适用于整个软件行业,而不仅仅适用于现代云原生应用程序。CNCF(Cloud Native Computing Foundation,云计算本地计算基金会)是CDF的姐妹基金会,拥有自己的治理结构和使命。每个基金会都有不同的使命,由其创始成员和技术专家定义。CNCF认为大多数与CD相关的工具超出了他们专注的云原生定义的范围,后者主要关注容器化、微服务、服务网格和编排。CDF超越云和容器,包括传统基础设施、移动、物联网、裸机等。CNCF和CDF都属于较大的Linux基金会旗下,计划在许多领域进行合作,包括同场会议。例如,CDF将于5月20日在西班牙巴塞罗那的KubeCon + CloudNativeCon Europe 2019举办持续交付峰会(CDS)活动。 CDF如何支持或与DevOps领域的其他玩家合作? CDF的使命是为开发者、最终用户和供应商提供一个中立的家庭,以便在CI/CD方法上进行协作。在这方面,CDF将通过发布关注可移植性的最佳实践、培训材料和行业指南来支持DevOps从业者。 有兴趣成为这个新基金会成员并制定治理方案的组织应到CDF加入的页面。开发者可以在此处注册CD基金会邮件列表:info@lists.cd.foundation。任何有兴趣加入CDF的项目都可以联系技术监督委员会(TOC):https://github.com/cdfoundati…。 KubeCon […]

龙生   12 Nov 2019
View Details

Java Set集合的详解

一,Set Set:注重独一无二的性质,该体系集合可以知道某物是否已近存在于集合中,不会存储重复的元素 用于存储无序(存入和取出的顺序不一定相同)元素,值不能重复。 对象的相等性    引用到堆上同一个对象的两个引用是相等的。如果对两个引用调用hashCode方法,会得到相同的结果,如果对象所属的类没有覆盖Object的hashCode方法的话,hashCode会返回每个对象特有的序号(java是依据对象的内存地址计算出的此序号),所以两个不同的对象的hashCode值是不可能相等的。 如果想要让两个不同的Person对象视为相等的,就必须覆盖Object继下来的hashCode方法和equals方法,因为Object  hashCode方法返回的是该对象的内存地址,所以必须重写hashCode方法,才能保证两个不同的对象具有相同的hashCode,同时也需要两个不同对象比较equals方法会返回true 该集合中没有特有的方法,直接继承自Collection。  

  案例:set集合添加元素并使用迭代器迭代元素。

  二,HashSet  

  HashSet 哈希表边存放的是哈希值。HashSet存储元素的顺序并不是按照存入时的顺序(和List显然不同) 是按照哈希值来存的所以取数据也是按照哈希值取得。 HashSet不存入重复元素的规则.使用hashcode和equals 由于Set集合是不能存入重复元素的集合。那么HashSet也是具备这一特性的。HashSet如何检查重复?HashSet会通过元素的hashcode()和equals方法进行判断元素师否重复。 当你试图把对象加入HashSet时,HashSet会使用对象的hashCode来判断对象加入的位置。同时也会与其他已经加入的对象的hashCode进行比较,如果没有相等的hashCode,HashSet就会假设对象没有重复出现。 简单一句话,如果对象的hashCode值是不同的,那么HashSet会认为对象是不可能相等的。 因此我们自定义类的时候需要重写hashCode,来确保对象具有相同的hashCode值。 如果元素(对象)的hashCode值相同,是不是就无法存入HashSet中了? 当然不是,会继续使用equals 进行比较.如果 equals为true 那么HashSet认为新加入的对象重复了,所以加入失败。如果equals 为false那么HashSet 认为新加入的对象没有重复.新元素可以存入. 总结: 元素的哈希值是通过元素的hashcode方法 来获取的, HashSet首先判断两个元素的哈希值,如果哈希值一样,接着会比较equals方法 如果 equls结果为true ,HashSet就视为同一个元素。如果equals 为false就不是同一个元素。 哈希值相同equals为false的元素是怎么存储呢,就是在同样的哈希值下顺延(可以认为哈希值相同的元素放在一个哈希桶中)。也就是哈希一样的存一列。 hashtable 图1:hashCode值不相同的情况 图2:hashCode值相同,但equals不相同的情况。 HashSet:通过hashCode值来确定元素在内存中的位置。一个hashCode位置上可以存放多个元素。 当hashcode() 值相同equals() 返回为true 时,hashset 集合认为这两个元素是相同的元素.只存储一个(重复元素无法放入)。调用原理:先判断hashcode 方法的值,如果相同才会去判断equals 如果不相同,是不会调用equals方法的。   HashSet到底是如何判断两个元素重复。 通过hashCode方法和equals方法来保证元素的唯一性,add()返回的是boolean类型 判断两个元素是否相同,先要判断元素的hashCode值是否一致,只有在该值一致的情况下,才会判断equals方法,如果存储在HashSet中的两个对象hashCode方法的值相同equals方法返回的结果是true,那么HashSet认为这两个元素是相同元素,只存储一个(重复元素无法存入)。 注意:HashSet集合在判断元素是否相同先判断hashCode方法,如果相同才会判断equals。如果不相同,是不会调用equals方法的。   HashSet 和ArrayList集合都有判断元素是否相同的方法, boolean contains(Object o) HashSet使用hashCode和equals方法,ArrayList使用了equals方法   案例: 使用HashSet存储字符串,并尝试添加重复字符串 回顾String类的equals()、hashCode()两个方法。

  使用HashSet存储自定义对象,并尝试添加重复对象(对象的重复的判定)

  问题:现在有一批数据,要求不能重复存储元素,而且要排序。ArrayList 、 LinkedList不能去除重复数据。HashSet可以去除重复,但是是无序。 所以这时候就要使用TreeSet了 三,TreeSet   案例:使用TreeSet集合存储字符串元素,并遍历

 

  红–黑树 红黑树是一种特定类型的二叉树 红黑树算法的规则: […]

龙生   28 Oct 2019
View Details

LinkedList、ConcurrentLinkedQueue、LinkedBlockingQueue对比分析

写这篇文章源于我经历过的一次生产事故,在某家公司的时候,有个服务会收集业务系统的日志,此服务的开发人员在给业务系统的sdk中就因为使用了LinkedList,又没有做并发控制,就造成了此服务经常不能正常收集到业务系统的日志(丢日志以及日志上报的线程停止运行)。看一下add()方法的源码,我们就可以知道原因了:

  demo  Lesson2LinkedListThreads 展示了在多线程且没有做并发控制的环境下,size的值远远大于了队列的实际值,100个线程,每个添加1000个元素,最后实际只加进去2030个元素: List的变量size值为:88371 第2031个元素取出为null 解决方案,使用锁或者使用ConcurrentLinkedQueue、LinkedBlockingQueue等支持添加元素为原子操作的队列。 上一节我们已经分析过LinkedBlockingQueue的put等方法的源码,是使用ReentrantLock来实现的添加元素原子操作。我们再简单看一下高并发queue的add和offer()方法,方法中使用了CAS来实现的无锁的原子操作:    public boolean add(E e) { return offer(e); }

  接下来,我们再利用高并发queue对上面的demo进行改造,大家只要改变demo中的内容,讲下面两行的注释内容颠倒,即可发现没有丢失任何的元素: public static LinkedList list = new LinkedList(); //public static ConcurrentLinkedQueue list = new ConcurrentLinkedQueue(); 再看一下高性能queue的poll()方法,才觉得NB,取元素的方法也用CAS实现了原子操作,因此在实际使用的过程中,当我们在不那么在意元素处理顺序的情况下,队列元素的消费者,完全可以是多个,不会丢任何数据:

  关于ConcurrentLinkedQueue和LinkedBlockingQueue: 1.LinkedBlockingQueue是使用锁机制,ConcurrentLinkedQueue是使用CAS算法,虽然LinkedBlockingQueue的底层获取锁也是使用的CAS算法 2.关于取元素,ConcurrentLinkedQueue不支持阻塞去取元素,LinkedBlockingQueue支持阻塞的take()方法,如若大家需要ConcurrentLinkedQueue的消费者产生阻塞效果,需要自行实现 3.关于插入元素的性能,从字面上和代码简单的分析来看ConcurrentLinkedQueue肯定是最快的,但是这个也要看具体的测试场景,我做了两个简单的demo做测试,测试的结果如下,两个的性能差不多,但在实际的使用过程中,尤其在多cpu的服务器上,有锁和无锁的差距便体现出来了,ConcurrentLinkedQueue会比LinkedBlockingQueue快很多: demo Lesson2ConcurrentLinkedQueuePerform:在使用ConcurrentLinkedQueue的情况下100个线程循环增加的元素数为:33828193 demo Lesson2LinkedBlockingQueuePerform:在使用LinkedBlockingQueue的情况下100个线程循环增加的元素数为:33827382   from:https://www.cnblogs.com/mantu/p/5802393.html

龙生   27 Oct 2019
View Details

Java并发容器之非阻塞队列ConcurrentLinkedQueue

参考资料:http://blog.csdn.net/chenchaofuck1/article/details/51660521 实现一个线程安全的队列有两种实现方式:一种是使用阻塞算法,阻塞队列就是通过使用加锁的阻塞算法实现的;另一种非阻塞的实现方式则可以使用循环CAS(比较并交换)的方式来实现。 ConcurrentLinkedQueue是一个基于链表实现的无界线程安全队列,它采用先进先出的规则对节点进行排序,当我们添加一个元素的时候,它会添加到队列的尾部,当我们获取一个元素时,它会返回队列头部的元素。默认情况下head节点存储的元素为空,tair节点等于head节点。 一:入队     入队主要做两件事情,   第一是将入队节点设置成当前队列的最后一个节点。   第二是更新tail节点,如果原来的tail节点的next节点不为空,则将tail更新为刚入队的节点(即队尾结点),如果原来的tail节点(插入前的tail)的next节点为空,则将入队节点设置成tail的next节点(而tial不移动,成为倒数第二个节点),所以tail节点不总是尾节点!

    二:出队     不是每次出队时都更新head节点,当head节点里有元素时,直接弹出head节点里的元素,而不会更新head节点。只有当head节点里没有元素时,则弹出head的next结点并更新head结点为原来head的next结点的next结点。

    三:非阻塞却线程安全的原因     观察入队和出队的源码可以发现,无论入队还是出队,都是在死循环中进行的,也就是说,当一个线程调用了入队、出队操作时,会尝试获取链表的tail、head结点进行插入和删除操作,而插入和删除是通过CAS操作实现的,而CAS具有原子性。故此,如果有其他任何一个线程成功执行了插入、删除都会改变tail/head结点,那么当前线程的插入和删除操作就会失败,则通过循环再次定位tail、head结点位置进行插入、删除,直到成功为止。也就是说,ConcurrentLinkedQueue的线程安全是通过其插入、删除时采取CAS操作来保证的。不会出现同一个tail结点的next指针被多个同时插入的结点所抢夺的情况出现。 from:https://www.cnblogs.com/ygj0930/p/6544543.html

龙生   27 Oct 2019
View Details

java 中 阻塞队列 非阻塞队列 和普通队列的区别

阻 塞队列与普通队列的区别在于,当队列是空的时,从队列中获取元素的操作将会被阻塞,或者当队列是满时,往队列里添加元素的操作会被阻塞。试图从空的阻塞队列中获取元素的线程将会被阻塞,直到其他的线程往空的队列插入新的元素。同样,试图往已满的阻塞队列中添加新元素的线程同样也会被阻塞,直到其他的线程使队列重新变得空闲起来,如从队列中移除一个或者多个元素,或者完全清空队列. 1.ArrayDeque, (数组双端队列) 2.PriorityQueue, (优先级队列) 3.ConcurrentLinkedQueue, (基于链表的并发队列) 4.DelayQueue, (延期阻塞队列)(阻塞队列实现了BlockingQueue接口) 5.ArrayBlockingQueue, (基于数组的并发阻塞队列) 6.LinkedBlockingQueue, (基于链表的FIFO阻塞队列) 7.LinkedBlockingDeque, (基于链表的FIFO双端阻塞队列) 8.PriorityBlockingQueue, (带优先级的无界阻塞队列) 9.SynchronousQueue (并发同步阻塞队列) 阻塞队列和生产者-消费者模式 阻塞队列(Blocking queue)提供了可阻塞的put和take方法,它们与可定时的offer和poll是等价的。如果Queue已经满了,put方法会被阻塞直到有空间可用;如果Queue是空的,那么take方法会被阻塞,直到有元素可用。Queue的长度可以有限,也可以无限;无限的Queue永远不会充满,所以它的put方法永远不会阻塞。 阻塞队列支持生产者-消费者设计模式。一个生产者-消费者设计分离了“生产产品”和“消费产品”。该模式不会发现一个工作便立即处理,而是把工作置于一个任务(“to do”)清单中,以备后期处理。生产者-消费者模式简化了开发,因为它解除了生产者和消费者之间相互依赖的代码。生产者和消费者以不同的或者变化的速度生产和消费数据,生产者-消费者模式将这些活动解耦,因而简化了工作负荷的管理。 生产者-消费者设计是围绕阻塞队列展开的,生产者把数据放入队列,并使数据可用,当消费者为适当的行为做准备时会从队列中获取数据。生产者不需要知道消费者的省份或者数量,甚至根本没有消费者—它们只负责把数据放入队列。类似地,消费者也不需要知道生产者是谁,以及是谁给它们安排的工作。BlockingQueue可以使用任意数量的生产者和消费者,从而简化了生产者-消费者设计的实现。最常见的生产者-消费者设计是将线程池与工作队列相结合。 阻塞队列简化了消费者的编码,因为take会保持阻塞直到可用数据出现。如果生产者不能足够快地产生工作,让消费者忙碌起来,那么消费者只能一直等待,直到有工作可做。同时,put方法的阻塞特性也大大地简化了生产者的编码;如果使用一个有界队列,那么当队列充满的时候,生产者就会阻塞,暂不能生成更多的工作,从而给消费者时间来赶进进度。 有界队列是强大的资源管理工具,用来建立可靠的应用程序:它们遏制那些可以产生过多工作量、具有威胁的活动,从而让你的程序在面对超负荷工作时更加健壮。 虽然生产者-消费者模式可以把生产者和消费者的代码相互解耦合,但是它们的行为还是间接地通过共享队列耦合在一起了 类库中包含一些BlockingQueue的实现,其中LinkedBlockingQueue和ArrayBlockingQueue是FIFO队列,与 LinkedList和ArrayList相似,但是却拥有比同步List更好的并发性能。PriorityBlockingQueue是一个按优先级顺序排序的队列,当你不希望按照FIFO的属性处理元素时,这个PriorityBolckingQueue是非常有用的。正如其他排序的容器一样,PriorityBlockingQueue可以比较元素本身的自然顺序(如果它们实现了Comparable),也可以使用一个 Comparator进行排序。 最后一个BlockingQueue的实现是SynchronousQueue,它根本上不是一个真正的队列,因为它不会为队列元素维护任何存储空间。不过,它维护一个排队的线程清单,这些线程等待把元素加入(enqueue)队列或者移出(dequeue)队列。因为SynchronousQueue没有存储能力,所以除非另一个线程已经准备好参与移交工作,否则put和take会一直阻止。SynchronousQueue这类队列只有在消费者充足的时候比较合适,它们总能为下一个任务作好准备。 非阻塞算法 基于锁的算法会带来一些活跃度失败的风险。如果线程在持有锁的时候因为阻塞I/O,页面错误,或其他原因发生延迟,很可能所有的线程都不能前进了。 一个线程的失败或挂起不应该影响其他线程的失败或挂起,这样的算法成为非阻塞(nonblocking)算法;如果算法的每一个步骤中都有一些线程能够继续执行,那么这样的算法称为锁自由(lock-free)算法。在线程间使用CAS进行协调,这样的算法如果能构建正确的话,它既是非阻塞的,又是锁自由的。非竞争的CAS总是能够成功,如果多个线程以一个CAS竞争,总会有一个胜出并前进。非阻塞算法堆死锁和优先级倒置有“免疫性”(但它们可能会出现饥饿和活锁,因为它们允许重进入)。 非阻塞算法通过使用低层次的并发原语,比如比较交换,取代了锁。原子变量类向用户提供了这些底层级原语,也能够当做“更佳的volatile变量”使用,同时提供了整数类和对象引用的原子化更新操作。       from:https://blog.csdn.net/u012240455/article/details/81844055

龙生   27 Oct 2019
View Details

java队列——queue详细分析

Queue: 基本上,一个队列就是一个先入先出(FIFO)的数据结构 Queue接口与List、Set同一级别,都是继承了Collection接口。LinkedList实现了Deque接 口。   Queue的实现 1、没有实现的阻塞接口的LinkedList: 实现了java.util.Queue接口和java.util.AbstractQueue接口 内置的不阻塞队列: PriorityQueue 和 ConcurrentLinkedQueue PriorityQueue 和 ConcurrentLinkedQueue 类在 Collection Framework 中加入两个具体集合实现。 PriorityQueue 类实质上维护了一个有序列表。加入到 Queue 中的元素根据它们的天然排序(通过其 java.util.Comparable 实现)或者根据传递给构造函数的 java.util.Comparator 实现来定位。 ConcurrentLinkedQueue 是基于链接节点的、线程安全的队列。并发访问不需要同步。因为它在队列的尾部添加元素并从头部删除它们,所以只要不需要知道队列的大 小,          ConcurrentLinkedQueue 对公共集合的共享访问就可以工作得很好。收集关于队列大小的信息会很慢,需要遍历队列。 2)实现阻塞接口的: java.util.concurrent 中加入了 BlockingQueue 接口和五个阻塞队列类。它实质上就是一种带有一点扭曲的 FIFO 数据结构。不是立即从队列中添加或者删除元素,线程执行操作阻塞,直到有空间或者元素可用。 五个队列所提供的各有不同: * ArrayBlockingQueue :一个由数组支持的有界队列。 * LinkedBlockingQueue :一个由链接节点支持的可选有界队列。 * PriorityBlockingQueue :一个由优先级堆支持的无界优先级队列。 * DelayQueue :一个由优先级堆支持的、基于时间的调度队列。 * SynchronousQueue :一个利用 BlockingQueue 接口的简单聚集(rendezvous)机制。       下表显示了jdk1.5中的阻塞队列的操作:     add        增加一个元索                     如果队列已满,则抛出一个IIIegaISlabEepeplian异常   remove   移除并返回队列头部的元素    如果队列为空,则抛出一个NoSuchElementException异常   element  返回队列头部的元素             如果队列为空,则抛出一个NoSuchElementException异常   offer       添加一个元素并返回true       如果队列已满,则返回false   poll         移除并返问队列头部的元素    如果队列为空,则返回null   peek       返回队列头部的元素             如果队列为空,则返回null   put         添加一个元素                      如果队列满,则阻塞   take        移除并返回队列头部的元素     如果队列为空,则阻塞   remove、element、offer 、poll、peek 其实是属于Queue接口。    阻塞队列的操作可以根据它们的响应方式分为以下三类:aad、removee和element操作在你试图为一个已满的队列增加元素或从空队列取得元素时 抛出异常。当然,在多线程程序中,队列在任何时间都可能变成满的或空的,所以你可能想使用offer、poll、peek方法。这些方法在无法完成任务时 只是给出一个出错示而不会抛出异常。   注意:poll和peek方法出错进返回null。因此,向队列中插入null值是不合法的   最后,我们有阻塞操作put和take。put方法在队列满时阻塞,take方法在队列空时阻塞。     LinkedBlockingQueue的容量是没有上限的(说的不准确,在不指定时容量为Integer.MAX_VALUE,不要然的话在put时怎么会受阻呢),但是也可以选择指定其最大容量,它是基于链表的队列,此队列按 FIFO(先进先出)排序元素。 ArrayBlockingQueue在构造时需要指定容量, 并可以选择是否需要公平性,如果公平参数被设置true,等待时间最长的线程会优先得到处理(其实就是通过将ReentrantLock设置为true来 达到这种公平性的:即等待时间最长的线程会先操作)。通常,公平性会使你在性能上付出代价,只有在的确非常需要的时候再使用它。它是基于数组的阻塞循环队 列,此队列按 FIFO(先进先出)原则对元素进行排序。 PriorityBlockingQueue是一个带优先级的 队列,而不是先进先出队列。元素按优先级顺序被移除,该队列也没有上限(看了一下源码,PriorityBlockingQueue是对 PriorityQueue的再次包装,是基于堆数据结构的,而PriorityQueue是没有容量限制的,与ArrayList一样,所以在优先阻塞 队列上put时是不会受阻的。虽然此队列逻辑上是无界的,但是由于资源被耗尽,所以试图执行添加操作可能会导致 OutOfMemoryError),但是如果队列为空,那么取元素的操作take就会阻塞,所以它的检索操作take是受阻的。另外,往入该队列中的元 素要具有比较能力。 DelayQueue(基于PriorityQueue来实现的)是一个存放Delayed […]

龙生   27 Oct 2019
View Details

为什么用Dubbo而不是Spring Cloud?基于支付场景的微服务高可用架构实战

今天给大家带来的分享是基于支付场景的一个微服务实战,会更偏向于应用层的内容。 主要围绕以下四点进行分享: SOA 与微服务 老支付架构遇到的挑战 基于微服务怎么做的改造 未来计划要做的事 SOA 与微服务 在我看来,微服务虽是国外传进来的技术,却和咱们中国的一些理论是挂钩的。所以在正式进入主题之前,先给大家简单介绍一下麦田理论。 关于麦田理论 古代周朝时期,老百姓种地实际是没有任何规划的,也没有任何区域的限制。 一般来说在地里一会种水稻,一会种小麦,一会种蔬菜地交叉来种,可收成之后发现庄稼受阳光程度非常低,营养非常不均衡,后期维护成本非常高。 直到战国时期,有一位农业专家把地划分为多个区域,每一个区域种一种庄稼,地跟地隔开,形成最初的微服务理念。 过去我们看到的很多文章都只是讲到 SOA 和微服务之间的比较,我今天在这个基础上加了一个 DDD。下面就 DDD、SOA 以及微服务的演进过程先做个引子。 DDD、SOA 与微服务 SOA 架构 SOA 是上一个时代的产物,大概是在 2010 年之前出现的,最早提出时是提供给传统行业计算领域的解决方案,当时 Oracle、IBM 也提了很多方案,包括出现的很多流程引擎。 它的思想是将紧耦合的系统,划分为面向业务的粗粒度、松耦合、无状态的服务。 在这之后,微服务的提出者基于 SOA 做了一个改进,就把它变成单一职责、独立部署、细小的微服务,是一个相反的概念。 微服务与 DDD 今天我们一说到微服务就会想到 DDD,有不少朋友认为 DDD 就是为微服务而生的。其实不是这样的,我在接触 DDD 时,它最早是用来做 UML 设计、领域建模的。 DDD 讲究充血模型,而 J2EE 模型以传统的分层架构和 Spring 架构捆绑在一起形成了以贫血模型为主的架构模式。 贫血模型的优点是容易入门、分层清晰,而充血模型要求设计者前期对业务理解较深,不然后期项目会产生混乱。 另外就是 DDD 思想比较宽泛,导致形成百家争鸣的姿态,没有形成一套固定的方法论。 开发者不容易理解,所以后面关注 DDD 的人变少了,而微服务的提出巧妙地借鉴了 DDD 里面的限界上下文、子域、领域事件等关键词,在微服务得到越来越多业界认可的情况下,也给 DDD 带来了重新的焕发机会。 老支付架构遇到的挑战 判断项目好坏的两个角度 我们判断一个优秀项目的好坏,可以从优秀的代码和高可用架构两个方向来讲。 我们在设计高可用架构的同时,也不能忽视代码的重要性,优秀的代码指的是冗错能力、冥等操作、并发情况、死锁情况等,并不一定是指代码写得多漂亮。 这就好比盖楼一样,楼房的基础架子搭得很好,但盖房的工人不够专业,有很多需要注意的地方忽略了,那么在往里面填砖加瓦的时候出了问题。 后果就是房子经常漏雨,墙上有裂缝等各种问题出现,虽然不至于楼房塌陷,但楼房也已经变成了危楼。 从代码和设计的角度来看有: 由不合理的代码所引起的项目无扩展性 数据库经常发生死锁 数据库事务乱用,导致事务占用时间过长 代码容错能力很差,经常因为考虑不足引起事故 程序中打印的大量的无用日志,并且引起性能问题 常用配置信息依然从数据库中读取 滥用线程池,造成栈和堆溢出 从库中查询数据,每次全部查出 业务代码研发不考虑幂等操作 使用缓存不合理,存在惊群效应、缓存穿透等情况 代码上下流流程定义混乱 异常处理机制混乱 再从整体架构角度来看: 整体依然使用单体集群架构 采用单机房服务器布署方式 采用 Nginx+hessian 的方式实现服务化 业务架构划分不彻底,边界模糊 项目拆分不彻底,一个 […]

龙生   17 Oct 2019
View Details

Dubbo和Spring Cloud微服务架构比较

Dubbo 出生于阿里系,是阿里巴巴服务化治理的核心框架,并被广泛应用于中国各互联网公司;只需要通过 Spring 配置的方式即可完成服务化,对于应用无入侵,设计的目的还是服务于自身的业务为主。 微服务架构是互联网很热门的话题,是互联网技术发展的必然结果。它提倡将单一应用程序划分成一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。 虽然微服务架构没有公认的技术标准和规范或者草案,但业界已经有一些很有影响力的开源微服务架构框架提供了微服务的关键思路,例如 Dubbo 和 Spring Cloud。 各大互联网公司也有自研的微服务框架,但其模式都与这二者相差不大。 微服务主要的优势 降低复杂度 将原来耦合在一起的复杂业务拆分为单个服务,规避了原本复杂度无止境的积累。 每一个微服务专注于单一功能,并通过定义良好的接口清晰表述服务边界;每个服务开发者只专注服务本身,通过使用缓存、DAL 等各种技术手段来提升系统的性能,而对于消费方来说完全透明。 可独立部署 由于微服务具备独立的运行进程,所以每个微服务可以独立部署。当业务迭代时只需要发布相关服务的迭代即可,降低了测试的工作量同时也降低了服务发布的风险。 容错 在微服务架构下,当某一组件发生故障时,故障会被隔离在单个服务中。比如通过限流、熔断等方式降低错误导致的危害,保障核心业务正常运行。 扩展 单块架构应用也可以实现横向扩展,就是将整个应用完整的复制到不同的节点。 当应用的不同组件在扩展需求上存在差异时,微服务架构便体现出其灵活性,因为每个服务可以根据实际需求独立进行扩展。 本文主要围绕微服务的技术选型、通讯协议、服务依赖模式、开始模式、运行模式等几方面来综合比较 Dubbo 和 Spring Cloud 这 2 种开发框架。 架构师可以根据公司的技术实力并结合项目的特点来选择某个合适的微服务架构平台,以此稳妥地实施项目的微服务化改造或开发进程。 核心部件 微服务的核心要素在于服务的发现、注册、路由、熔断、降级、分布式配置,基于上述几种必要条件对 Dubbo 和 Spring Cloud 做出对比。 总体架构 Dubbo 核心部件(如下图): Provider:暴露服务的提供方,可以通过 jar 或者容器的方式启动服务。 Consumer:调用远程服务的服务消费方。 Registry:服务注册中心和发现中心。 Monitor:统计服务和调用次数,调用时间监控中心。(Dubbo 的控制台页面中可以显示,目前只有一个简单版本。) Container:服务运行的容器。 Dubbo 总体架构 Spring Cloud总体架构(如下图): Service Provider: 暴露服务的提供方。 Service Consumer:调用远程服务的服务消费方。 EureKa Server: 服务注册中心和服务发现中心。 Spring Cloud 总体架构 点评:从整体架构上来看,二者模式接近,都需要服务提供方,注册中心,服务消费方。 微服务架构核心要素 Dubbo 只是实现了服务治理,而 Spring Cloud 子项目分别覆盖了微服务架构下的众多部件,服务治理只是其中的一个方面。 Dubbo 提供了各种 Filter,对于上述中“无”的要素,可以通过扩展 Filter 来完善。例如: 分布式配置:可以使用淘宝的 diamond、百度的 disconf 来实现分布式配置管理。 服务跟踪:可以使用京东开源的 Hydra,或者扩展 Filter 用 Zippin 来做服务跟踪。 批量任务:可以使用当当开源的 Elastic-Job、tbschedule。 点评:从核心要素来看,Spring […]

龙生   16 Oct 2019
View Details

Dubbo与DubboX区别

 前世今生: Dubbo源于阿里的淘宝网开源的分布式的服务架构,致力于提供高性能和透明化的RPC远程服务调用方案,是SOA服务化治理方案的核心框架。淘宝网将其开源之后,得到了很多的拓展和支持(比较出名的有:当当网的扩展版本dubbox,京东的扩展版本jd-hydra等)        Dubbox(即Dubbo eXtensions)是当当网Fork基于dubbo2.x的升级版本,兼容原有的dubbox。其中升级了zookeeper和spring版本,并且支持restfull风格的远程调用。。 版本: Dubbo目前已停止更新;        Dubbox目前还在更新。 说明:dubbox和dubbo 2.x是兼容的, 没有改变dubbo的任何已有的功能和配置方式(除了升级了Spring之类的版本)。   据说淘宝网dubbo与一个非开源的框架HSF有争执,导致dubbo的团队已经解散了,但是其扩展的版本dubbox却得到不断的发展(升级更新); <!——--升级详情——--|——————-- dubbox-2.8.0:该版本已经在生产环境中使用,主要支持REST风格远程调用、支持Kryo和FST序列化、升级了Spring和Zookeeper客户端、调整了demo应用等等 dubbox-2.8.1:主要支持基于嵌入式tomcat的http-remoting,优化了REST客户端性能,在REST中支持限制服务端接纳的最大HTTP连接数等等 dubbox-2.8.2: 支持REST中的HTTP logging,包括HTTP header的字段和HTTP body中的消息体,方便调试、日志纪录等等 提供辅助类便于REST的中文处理 改变使用@Reference annotation配置时的异常处理方式,即当用annotation配置时,过去dubbo在启动期间不抛出依赖服务找不到的异常,而是在具体调用时抛出NPE,这与用XML配置时的行为不一致。 较大的充实了Dubbo REST的文档 dubbox-2.8.3: 在REST中支持dubbo统一的方式用bean validation annotation作参数校验(沈理) 在RpcContext上支持获取底层协议的Request/Response(沈理) 支持采用Spring的Java Config方式配置dubbo(马金凯) 在Dubbo协议中支持基于Jackson的json序列化(Dylan) 在Spring AOP代理过的对象上支持dubbo annotation配置(Dylan) 修正Dubbo管理界面中没有consumer时出现空指针异常(马金凯) 修正@Reference annotation中protocol设置不起作用的bug(沈理) 修正@Reference annotation放在setter方法上即会出错的bug(Dylan) 详见:https://github.com/dangdangdotcom/dubbox/releases ———/> 嵌入: dubbo:嵌入式Jetty dubbox:基于嵌入式tomcat实现dubbo的 HTTP remoting体系(即dubbo-remoting-http) 对Servlet API的支持: dubbo:2.5 dubbox:升级到3.1 序列化: dubbo: dubbox:基于Dubbo默认的RPC协议添加新的JSON序列化实现; 支持基于Kryo和FST的Java高效序列化实现; Zookeeper注册中心: dubbo:Dubbo提供了Zookeeper注册中心,在整个Dubbo的设计里面充分考虑到了各类用户的需求,一些底层的通讯或者是信息存储都提供有大量的不同的存储方案; dubbox:升级ZooKeeper客户端到最新版本; 使用场景: dubbo:使用Dubbo的RPC调用方式,服务间仍然会存在API强依赖; dubbox:相对于Dubbo支持了REST风格的原创调用(HTTP +JSON/XML); ——————————————————- ——简言之(dubbox基于dubbo的升级): ——————- 支持REST风格远程调用(HTTP + JSON/XML); 支持基于Kryo和FST的Java高效序列化实现; 支持基于Jackson的JSON序列化; 支持基于嵌入式Tomcat的HTTP remoting体系; 升级Spring至3.x; 升级ZooKeeper客户端; 支持完全基于Java代码的Dubbo配置; ————————————————- 附录: Dubbo: 官网首页:http://dubbo.io/ , 官方用户指南: http://dubbo.io/User+Guide-zh.htm可以当做SOA架构的学习资料 Dubbox: dubbox入门:http://www.cnblogs.com/yjmyzz/p/dubbox-demo.html dubbox架构: http://www.cnblogs.com/Javame/p/3632473.html  当当网dubbox学习参考文档:http://dangdangdotcom.github.io/dubbox/ 分布式服务框架 dubbo/dubbox 入门示例:http://www.cnblogs.com/wanghang/p/6298957.html  ———————- […]

龙生   11 Oct 2019
View Details

Spring Boot 容器选择 Undertow 而不是 Tomcat

Spring Boot 内嵌容器Undertow参数设置 配置项:

来看看源代码: https://github.com/undertow-io/undertow/blob/master/core/src/main/java/io/undertow/Undertow.java

很显然,Undertow认为它的运用场景是在IO密集型的系统应用中,并且认为多核机器是一个比较容易满足的点,Undertow初始化假想应用的阻塞系数在0.8~0.9之间,所以阻塞线程数直接乘了个8,当然,如果对应用较精确的估测阻塞系数,可以配置上去。   Spring Boot内嵌容器支持Tomcat、Jetty、Undertow。为什么选择Undertow? 这里有一篇文章,时间 2017年1月26日发布的: Tomcat vs. Jetty vs. Undertow: Comparison of Spring Boot Embedded Servlet Containers 1. Setup Spring Boot Application We will use Maven to setup a new project in Eclipse with the appropriate dependencies. We will use the starter parent for this example but the dependencies in a production application will likely be altered to streamline, optimize or customize. 1.1 Setup Spring Boot Dependencies The default embedded servlet container is Tomcat. This version of Spring Web […]

龙生   24 Sep 2019
View Details
1 40 41 42 63