博客 中间件技术的思考和记录


Java 9 来了,还带来一大波...

  • Jeff Zhang
  • 22 September 2017

发布

2017年9月21日,在几次推迟之后,Java9终于发布了。

带来了推迟了数年之久的关键特性—​模块化功能。

https://mreinhold.org/blog/jigsaw-complete 里面详细的进行了说明。

下月初JavaOne大会将会在美国召开,届时所有Java开发者都会沉浸在一种节日的快乐中,不仅仅是因为刚发布了新的Java大版本9,而是迎来了一系列的Java生态中重量级产品和项目。我仔细回想,集中在一个月内发布这么多有重大影响力的技术产品,这的确是头一次,一定要写些文字来记录。

Java9

首先,最重要的是Java9的发布。这个大的版本中,除了模块化特性以外,在语法上特别瞩目的改进其实不是很多;然而Jdk的打包结构发生了很大的变化,原有的rt.jar被移除,而加入各个模块jmod。这个变化也可以引出我个人认为第二重要的变化:即Jaotc的支持,可以使用jlink编译成本地二进制包,这个特性对于cloud native非常重要。其他重要的特性有jShell,多版本的jar,HTTP/2的支持,安全加密算法的众多改进等等。

Java9也许是最后一个以单个自然数为版本号的Java版本,在已经公开的JSR383草案中,就已经提出今后Java的版本号将采用年+月的命名方式,即下一个Java版本号为18.3。类似于Ubuntu Linux,采用3年一个LTS长期支持版的发布方式。我非常看好这种方式,这样既能满足了企业用户需要稳定和商业支持的版本需求,又可以按照市场的需要,每半年快速的发布具有新特性的Java版本。

在开源方面,前两天IBM把其JDK实现J9,捐献给Eclipse组织,并命名为OpenJ9开源项目。另外之前JFR(Java Flight Recorder)也宣布将会开源,开放时间最早可能会在Java10(18.3)时。

JavaEE 8

其次,JavaEE 8 也正式发布。Oracle在官网进行提供了JavaEE SDK(含Glassfish5)下载。 链接为 http://www.oracle.com/technetwork/java/javaee/downloads/index.html

之前在JCP网站上,就已经有了所有的规范最终文档和API定义。本次JavaEE 8 重大的更新有CDI2, Servlet4,BV2,新的Security规范等。 其中大多数子规范的参考实现,如Weld3,Hibernate Validation6等早已经发布(除了Tomcat9还处在M26版本)。

上周,Oracle公司把JavaEE转让给了Eclipse组织,包括文档,TCK,接口定义,Glassfish参考实现等等。也就是说未来不会再有由大型软件公司起主导作用的JavaEE9。JavaEE未来的发展,将通过开源社区来完成。请参考博文《JavaEE开放之路》http://www.useopen.com/blog/2017/javaee_open_road.html

Spring 5

第三,Pivotal将在9月底发布SpringFramework5(以下简称Spring5)。通过Reactor项目定义的响应式接口,Spring5可以异步获取所需要的数据,提升软件系统整体的运行效率。与此同时,几乎所有的Spring系列框架和项目,都在准备发布新的大版本,包括SpringBoot,SpringCloud,SpringSecurity,SpringData,SpringBatch,SpringIntegration等等。可以说是Spring系的一次全面更新!

这两年随着微服务技术的火爆,SpringBoot成为Java语言构建微服务的首选开源框架。SpringBoot2主要加入的功能也是利用响应式接口来异步获取数据。预计SpringBoot2会到年底前发布。

JUnit5

第四,经典测试框架JUnit发布了新一代版本5,对原有的JUnit结构做出非常大的改进。

JUnit5采用Platform+Jupiter+Vintage这样的体系,Platform是基础层,Jupiter利用Java8提供的函数化编程能力进行单元测试,Vintage则提供Junit4之前的兼容接口。

Junit5对于软件测试的更新意义将是巨大的。我们知道,当年的TDD和敏捷编程运动,使软件开发时进行测试需要面向接口编程和大量使用依赖注入,直接导致了AOP,Spring框架等出现,以及促使EJB3和后来JavaEE6的全面演进。

而今天的JUnit5的出世,将会使开发者更多的面向函数和不变集合,对异步响应式接口进行编程。Spring5是在适应这个变化了,在web和数据访问层已经加入了对应的接口和能力。JavaEE8目前处于落后状态,只在JPA2.2维护版加入了对Stream的支持;JSR371定义的MVC在今年4月从JCP转出到社区后,并没有很活跃,也许今后也可以加入相应的支持。

总结

综上所述,我们可以看的出,这些Java产品大的更新,对于实际的项目开发来说,最核心在于Java8之中的函数式编程和异步响应式接口的运用。

是的,我没有写错,是Java8而不是Java9。除了Java9本身,其他的几大更新都是围绕着适应Java8的技术展开的。

目前国内很多企业还都在以Java6作为开发基础,这次则是一个很好的契机,全面进行技术升级换代。我个人的建议是企业基础平台使用稳定的JDK8版本,而如果构建微服务架构,则可以激进些,使用最新的JDK9并使用模块化特性进行组件间的隔离。

接下来我将利用空闲时间写一系列的文章,对这些重大发布的关键特性进行技术描述:包括Java8/9,JavaEE8,Spring5,Junit5,以及JBoss的一些项目的重要更新。也为Java新技术推广普及尽微薄之力。

欢迎关注!

列表

JDK

  • Java 函数化支持之新的基石Lambda

  • Java 数据流通道Stream

  • Java 多线程异步操作之CompletableFuture/Flow

  • Java9 核心Module System

  • Java 获取本地计算能力JLink/Jatoc

  • Java 时间的更新和同JodeTime的差异

JavaEE

  • Servlet4 内部用HTTP/2焕然一新

  • CDI2 面向对象之王者归来

  • BeanValidation2 贯穿技术栈验证能力

Spring

  • Spring5/Reactor3 Java领域今年最耀眼的技术更新

  • SpringBoot2 这两年最火爆的微服务技术

  • SpringCloud DataFlow 处理数据和微服务框架配合之未来的方向

Other

  • JUnit5 第三方库首席之重大更新

  • Vertx3.5 一支阻击其他语言的Java小分队

  • wildfly-swarm 很受冷遇但金子总是会发光的

JavaEE开放之路

  • Jeff Zhang
  • 14 September 2017

开放之路

美国时间9月12日,Oracle公司在TheAquarium博客发出了"Opening up Java EE - An Update"的博文,正式宣布JavaEE技术及相关,包括RI实现Glassfish, TCK, 相关的规范文档,全部移交给Eclispe开源组织。

目前,JavaEE 8的所有规范,都已经通过了最终投票;所有的子规范都已经发布了最终规范文本,API定义和Java文档参考。接下来就是9月底JavaEE会完成所有的工作,并在10月初的JavaOne大会上正式宣布发布。也就是说,JavaEE 8是大公司控制下的最后一个版本,接下来JavaEE技术体系将会走向开放之路。

在之前的开发者投票征集移交到哪个开源组织时,大多数开发者都投给Apache组织,而我倾向Eclipse组织,而且我就相信最后会选择Eclipse。原因很简单,这个开源组织大公司的话语权大的多。JavaEE虽然不是主流热点技术了(否则Oracle也不会主动相与),但它依然是服务端—​特别是企业级的开发的主要技术选择。IBM/Oracle/Redhat这三个Java核心软件公司还会对JavaEE的走向起到决定性作用。

开放时间轴

让我们再梳理一下JavaEE"被"开放的时间线:

  1. 2009年4月Sun被Oracle收购,导致Java技术新版本的发布,停滞了一段时间。尽管我们看到JavaEE 6是在2009年12月发布的,但那个是Sun的技术专家在收购前早就做好的准备;而JavaEE 7一直到2013年6月才发布,比起一般3年一个大版本的周期要长一年时间,而JavaEE 8也在本来应该发布的2016年处于停滞状态。

  2. JavaEE应用服务器市场萎缩,利润下滑。原来的现金牛,比如WebLogic,受到开源方案的冲击,以及云服务的替换性方案的不断涌现,销售远不及从前。Glassfish也被放弃商业支持。2013年到2016年间,很多的JavaEE专家从Oracle出走,有的留在了其他公司继续发挥技术优势,而很多专家则切换了技术领域,投身于云计算,容器技术等。

  3. 2016年初,Oracle对于JavaEE的技术热度下降的非常厉害,Reza Rahman提出来JavaEE Guardians计划,来向Oracle"建言"投入更多的力量做JavaEE。这个行动是成功的,很快Oracle高层做出表态,并且推动了JavaEE 8的进展。

  4. 2016年7月,IBM,Redhat,Tomitribe(Tomee), Payara(Payara glassfish)宣布成立Microprofile的组织,提供一个小范围的,面向微服务的规范子集。初期只有JaxRS/CDI/JsonP少数规范;2017年2月,加入到Eclispe组织。目前已经发展到1.1版本。这个组织的潜台词就是:“既然你占着JavaEE的位置还不干活,那我们就自己搞一套新的。“如今JavaEE也即将进入到Eclipse,也许今后Microprofile也会融入到JavaEE之中。

  5. 2017年初Oracle战略全面转向云计算,JavaEE走向开放之路。

喜迎开放

那么,如何看待这个开放之举呢? 我的观点是:短期看好处巨大,长期看不明朗,但对国内软件发展,长期必受益。 短期内,随着JavaEE技术的开放,会有技术公司和开发者更多的参与,必然会提供更多更好的开源项目和解决方案出现。 长期看呢,这样庞大的技术体系,没有一个有实力的大公司给与有力的支持,是对发展很不利的。 对于国内呢?开放了肯定是天大的好事。目前国内JavaEE使用者群体很大,不过多数是采用Spring框架的方案。相信JavaEE开放以后,会有更多的国内公司仔细审视JavaEE技术方案,并且用在合适的架构中。特别的,对于我们这样的以中间件为技术核心的软件公司,更是可以击掌相庆的大好事了。

一些朋友,甚至是从事过服务器开发相关的朋友,都有点奇怪为什么我会坚持走JavaEE的技术路线。主要三个理由:

  1. JavaEE(包括Spring系列)的技术,在服务器软件开发,特别是企业应用系统的开发方面,JavaEE是当仁不让的最有优势的技术。其他的语言或者是技术方案,都没有如此完备的体系。

  2. 微服务,容器技术方案,也需要设计开发维护软件的业务实现。也就是说,集装箱运输系统再先进,箱里面的货物也是最关键要素。同样的,业务系统即使是上了云,应用容器技术进行微服务化改造,您不是还的选择具体的软件技术方案么?现在看来JavaEE还是重要的技术实现方式,比如微服务化的SpringBoot, Wildfly Swarm等。

  3. JavaEE在企业级应用,尤其是开发事务要求性高的相关应用时,还是最好的技术方案选择。对于流式计算,互联网级高并发等超出JavaEE范围的业务需求,我们可以选择其他的技术方案,也就是说JavaEE是基础软件拼图的重要一块,而不是被替换的。国外大软件公司市场宣传都在讲云计算化,技术转型,但实际大量的关键业务,依然是沉淀数十年的专家在提供技术服务。

至于公有云厂商现在全力推演的云端中间件方案,以及Severless等,我只能说也是一种选择,架构师需要深入理解,并充分调研和掌握是否被绑定在一家云服务商之上,以及成本风险等是否可控。未来必然还是会走回标准化,规划化的老路。

借JavaEE开放这个契机,我们国内的软件公司,也可以更好的多方位的参与相关技术的研发和标准制定工作。还是那句话,踏踏实实做事,认认真真钻研,只要能充分发挥自己技术专长,我相信就会有立足之地并有良好的发展。

Java语言发展盘点与展望

  • Jeff Zhang
  • 01 July 2017

本文是应InfoQ总编郭蕾的约稿,对当前的Java技术进行总结和展望。 InfoQ文章的连接

Java语言的发展回顾。

Java语言源于1991年Sun公司James Gosling领导的的Ork项目,1995年Sun公司正式起名为Java,并提出“Write once, Run anywhere"的口号。

1996年1月Java 1.0发布,提供了一个解释执行的Java虚拟机,其时恰逢互联网开始兴起,Java的Applet能在Mozilla浏览器中运行,被看作是未来的互联网语言。

1997年2月Java 1.1发布,Java语言的基本形态基本确定了,比如反射(reflection), JavaBean, 接口和类的关系等等,一直到今天都保持一致。然而,Java最初的一些目标,如在浏览器中执行Applet,以及跨平台的图形界面Awt很快遭遇到负面的评价。

1998年12月,Java第一个里程碑式的版本,即Java 1.2发布了。这个版本使用了JIT(Just in time)编译器技术,使得语言的可迁移性和执行效率达到最优的平衡,同时Collections集合类设计优良,在企业应用开发中迅速得到了广泛使用。Sun公司把Java技术体系分成三个方向,分别是J2SE(面向桌面和通用应用开发),J2EE(面向企业级应用开发),J2ME(面向移动终端开发)。这个分类影响非常久远,体现出主流语言设计者的思想:针对于不同的应用领域,在形态,API集合等进行划分。

2000年5月,Java 1.3发布,这个版本中Corba作为语言级别的分布式对象技术,成为J2EE的一个技术前提。J2EE受到Corba的设计的影响较大,早期EJB的Home,接口和实现就是Corba在C语言的实现,被移植到Java语言之中。J2EE中的Servlet规范获得了极大的成功,伴随着互联网的兴起,和浏览器直接通过HTTP协议交互的Servlet,和众多的MVC框架,成为Web1.0的网红。

2002年2月,Java 1.4发布,Java语言真正走向成熟,提供了非常完备的语言特性,如NIO,正则表达式,XML处理器等。同年微软的.NET框架发布,两者开始了为期十几年的暗自竞争。从语言特性上来说,.NET后发先至,一直处于优势。但Java依赖良好的开发者生态,绝大多数大型软件公司的使用者众多和不断贡献,以及对Linux操作系统良好的支持,渐渐的在服务器端获得优势地位。

2004年9月,Java 5发布,Sun不再采用J2SE, J2EE这种命名方式,而使用Java SE 5, Java EE 5这样的名称。我认为Java 5是第二个里程碑式的版本。Java语言语法发生很大的变化,如注解(Annotation),装箱(Autoboxing),泛型(Generic),枚举(Enum),foreach等被加入,提供了java.util.concurrent并发包。Java 5对于Java语言的推动是巨大的,特别是注解的加入,使得语言定义灵活了很多,程序员可以写出更加符合领域定义的描述性程序。

2006年5月, JavaEE 5发布,其中最主要是EJB3.0的版本升级。在此之前,EJB2.X版本被广泛质疑,SpringFramework创建者Rod Johnson在经典书籍“J2EE Development without EJB“中,对EJB2代表的分布式对象的设计方法予以批驳。EJB3则重新经过改造,使用注解方式,经过应用服务器对POJO对象进行增强来实现分布式服务能力。在某种程度,可以说EJB3挽救了JavaEE的过早消亡。

2006年12月,Java 6发布,这个语言语法改进不多,但在虚拟机内部做了大量的改进,成为一个相当成熟稳定的版本,时至今日国内的很多公司依然以Java6作为主要Java开发版本来使用。同年Sun公司做出一个伟大的决定,将Java开源。OpenJDK从Sun JDK 1.7版本分支出去,成为今天OpenJDK的基础。OpenJDK6则由OpenJDK7裁剪而来,目前由红帽负责维护,来满足Redhat Enterprise Linux 6.X 用户的需要。

2009年12月,JavaEE 6发布,这个版本应该说是JavaEE到目前为止改进最大影响最深远的一个版本。因为JavaEE5只有EJB3适应了Java注解语法的加入,而EE6全面接纳了注解。CDI和BeanValidation规范的加入,在POJO之上可以定义完备的语义,由容器来决定如何去做。Servlet也升级到3.0版本,并在接口上加入异步支持,使得系统整体效率可以大幅提高。EE划分为Full Profile和Web Profile,用户可以根据自己的需要选择不同的功能集。

在此之前,Oracle已经以74亿美金的价格收购了Sun公司,获得了Java商标和Java主导权。也收购了BEA公司,获得市场份额最大的应用服务器Webogic。JavaEE 6虽然是收购之后发布的版本,但主要的设计工作仍然由原Sun公司的Java专家完成。

2011年7月,Oracle发布Java 7, 其中主要的特性是NIO2和Fork/Join并发包,尽管语言上没有大的增强,但我个人认为,自从Oracle JDK(包括OpenJDK7),Java虚拟机的稳定性真正做到的工业级,成为一个计算平台而服务于全世界。

2013年6月,Oracle发布JavaEE 7,这个版本加入了Websocket,Batch的支持,并且引入Concurrency来对服务器多线程进行管控。然而所有的子规范,算上可选项(Optional)总共有40多项,开发者光是阅读规范文本就很吃力了,更不要说能够全局精通掌握。JavaEE规范的本质是企业级应用设计的经验凝结,每一个API都经过众多丰富经验的专家反复商议并确定。各个版本之间可以做到向后兼容,也就是说,即使是10年前写的Servlet程序,当前的开发者也可以流畅的阅读源码,经过部分代码调整和配置修改,可以部署在当今的应用服务器上。反过来,今后用Servlet4写的程序,浏览器和服务器通信使用全新的HTTP/2协议,但程序员在理解上不会有障碍,就是因为Servlet规范的API非常稳定,基本没有大的变化修改。

2014年3月,Oracle发布Java 8,这个版本是我认为的第三个有里程碑意义的Java版本。其中最引人注目的便是Lambda表达式了,从此Java语言原生提供了函数式编程能力。语言方面大的特性增加还有:Streams,Date/Time API, 新的Javascript引擎Nashorn,集合的并行计算支持等,Java8更加适应海量云计算的需要。

按照原来的计划,Java9应该在今年7月发布,但因为模块化(JPMS)投票未通过的原因,推迟到今年9月份发布。 JavaEE 8也会在今年发布,预计的时间在8-10月。其中最主要更新是Servlet 4.0和CDI 2.0,后者已经完成最终规范的发布和投票。

Java社区情况介绍。

我们按照两个方面介绍Java社区情况:

  1. Java User Group(JUG,Java用户组) 目前全世界范围有100多个JUG组织,分布在各个大洲各个国家,一般来说以地域命名。目前最有影响力的两个JUG分别是伦敦的LJC(London Java Community)和巴西的SouJava,目前都是JCP的EC(执行委员会)成员。 国内目前有GreenTea JUG(北京和杭州),Shanghai JUG,GuangDong JUG, Shenzhen JUG, Nanjing JUG等。 GreanTeaJUG以阿里巴巴研发部门成员为核心,包括北京和杭州两地各个公司从事Java开发的研发人员,过去几年成功举办了很多有业界影响力的活动,特别是邀请到众多国外的Java技术专家来分享知识,目前是国内最大的JUG开发者组织。

  2. Java开源社区 Java是一门开放的语言,其开源社区也是参与者众多。

最有名的应当数Apache社区,目前已经拥有近200个顶级项目,其中绝大多数是Java语言项目。在Java生态圈中,具有重要地位的如Ant,Commons, Tomcat,Xerces,Maven, Struts, Lucene, ActiveMQ, CXF, Camel, Hadoop等等。很多技术时代,一大批Java项目加入,如Web时代的Velocity, Wicket;JavaEE相关的Tomee, OpenJPA, OpenWebBeans,Myfaces;WebService时代的jUDDI, Axis,ServiceMix;Osgi时期的Flex, Karaf;大数据时代的HBase, Hive, Zookeeper, Cassandra;云时代的Mesos,CloudStack等等。涉及到软件开发的方方面面,可以说当今几乎所有的中型以上Java应用中,都会有Apache开源项目的身影。 国内最早参与Apache社区的以国外软件公司国内研发团队成员为主,如红帽,IONA,Intel,IBM研发中心等。如今国内互联网公司和软件公司也不断的参与,特别是开始主导一些Apache项目,如Kylin等。

JBoss开源社区,包含了50多个Java开源项目,其中有Hibernate,Drools,jBPM等业界知名开源项目,也有Undertow,Byteman, Narayana等名气不算大,但绝对是相应领域业界的顶级优秀项目。当前JBoss开源社区主要以企业应用中间件软件为主,Redhat是主要的技术贡献力量。

Eclipse开源社区,之前主要是包含Eclipse IDE的项目,后来也逐步进行多方面的扩展,比如OSGi,服务器等,目前一些知名Java项目,如Jetty,Vertx等都是Eclipse开源组织成员。此外IOT目前是Eclispe的一个重点方向,在这里可以找到完整的IOT Java开发方案。

Spring开源社区,以SpringFramework为核心,包括SpringBoot, SpringCloud, SpringSecurity, SpringXD等开源项目,在国内有广泛的应用场景。

目前大的玩家。

Java语言和品牌都是Oracle公司所有,所以Oracle公司是Java最主要的厂商。绝大多数JSR(Java规范提案)的领导者都是Oracle的雇员。 Java是一个庞大的生态圈,全世界的软件和互联网公司绝大多数都是Java用户,同时也可以参与推动Java语言的发展。任何组织或者个人都可以加入JCP(Java Community Process),并提交JSR来给JavaSE,JavaEE,JavaME等提交新的API或者服务定义。Java拥有当今最完备的语言生态,几乎所有能想到的应用范围,都有软件厂商提出过标准化的构想,其中很多已经被接纳为JSR提案。如今JSR总数已经都400多个。

JCP是发展Java的国际组织,其中的执行委员会(EC)以投票的形式对JSR提案进行表决。 目前EC包括16个合约(Ratified)席位,6个选举(Elected)席位和2个合伙(Associate)席位,以及Oracle作为所有者的永久席位。非永久席位每两年重新选举一次,每次选举为24个席位的一半,即为12个。 当前EC委员会中,对于Java起到最重要作用的,无疑是Oracle,IBM和Redhat三家公司。Oracle自然不用说;Redhat领导着JavaEE8中两项JSR,并且在操作系统,Linux,虚拟化,云计算等基础软件方面是产品领导者;IBM是软硬件最大的厂商,拥有自己的Unix操作系统和JDK版本。这三家软件厂商也是中间件厂商的强者,它们对于Java的影响是至关重要的。前不久投票被否决的JSR 376(JPMS)模块化提案,就是Redhat和IBM先后表示要投反对票,最后才没有通过的。

另外的几个重要的Java参与方分别包括:巨型互联网公司,以Twitter为代表;大型金融公司,以高盛,瑞信为代表;强大的硬件产商,Intel,NXP,Gemalto等;大型系统方案厂商,HP, Fijitsu;当然还有掌握先进Java技术的公司,如Azul,Hazelcast,Tomitribe,Jetrains等等。这些公司共同对Java的发展起到关键作用。

GC方面的进展。

JDK中主要的GC分类有:

  • Serial,单线程进行GC,在它进行垃圾收集时,必须暂停其他所有的工作线程,直到它收集结束。

  • Parallel,相比Serial收集器,Parallel最主要的优势在于使用多线程去完成垃圾清理工作,这样可以充分利用多核的特性,大幅降低GC时间。

  • CMS(Concurrent Mark-Sweep),是以牺牲吞吐量为代价来获得最短回收停顿时间的垃圾回收器。实现GC线程和应用线程并发工作,不需要暂停所有应用线程。

  • G1(Garbage First Garbage Collector),G设计初衷是为了尽量缩短处理超大堆(大于4GB)时产生的停顿。相对于CMS的优势而言是内存碎片的产生率大大降低。

目前在JDK8中以上4种GC都可以使用,而在JDK9中G1 GC会成为默认的垃圾收集器。

在OpenJDK方面,Redhat开源并贡献了Shenandoah GC。这是一种新的Java虚拟机GC算法,目标是利用现代多核CPU的优势,减少大堆内存在GC处理时产生的停顿时间。在使用大内存的应用上使用,如>20G堆空间。Fedora24以后,官方源中的OpenJDK即带有Shenandoah算法,不过JDK9中还不会被加入。

无停顿的高性能GC就是Azul公司的C4(Continuously Concurrent Compacting Collector) GC了,但只提供商业版本使用。 另外IBM J9中Balanced GC,表现也很出色,能够保证相对一致的暂停时间而避免破坏性的长时间停顿。Balanced GC应用在各类IBM中间件产品之中。

Java 9目前已经可以确认的特性介绍。

Java9中,最受人关注的新特性就是Jigsaw项目带来的模块化技术特性。

Java语言一直缺乏语言级别的模块化能力,目前模块化技术通过OSGi, JBoss Modules等项目,已经在服务端程序得到了广泛的应用。Java在语言级别引入模块化能力,将极大的促进Java应用程序组件化,模块化的改变。应用程序通过模块化拆分,可以做到更灵活的引入,加载,移除组件,占用更少的内存,更适合云计算时代的要求。在JDK9 EA(预览版)中,原有的rt.jar已经被划分为若干了jmod,通过模块内的module-info.java文件来声明模块间的引用关系。 然而,模块化改造是个渐进而适度的过程,Java9为了可兼容Java8以前应用程序的运行,做出很多的让步,模块定义严格性没有那么苛刻。各个厂商也有对自己现有系统可无缝运行在Java9上的商业诉求。Java模块化提案还得花更多的时间去讨论和修改。

Java9中的jshell工具实现了REPL,即读取,求值,打印,循环。这个工具可以使得开发者交互式的使用Java,方便于系统管理,调试,使用。可以想像到有了jshell后,Java语言更加适合初学者入门学习。

Jlink工具和AOT(预先编译技术)。一直以来,Java运行方式是把程序编译成class文件,然后通过jvm运行的。这种工作方式可以做到跨平台移植,在互联网时代初期,各种Unix繁荣和Windows在桌面的一统局面下,对于占据市场起到决定性作用。 然而到了今天,无论是大型互联网公司还是企业内部,x86平台64位服务器已经成为主要的选择。从运行效率考虑,可以把java程序编译成可执行的二进制文件,更加适应云计算和容器技术发展的需要。 利用jlink/jaotc工具,可以把一个Java程序编译成可执行文件,在Java9推出时,可能只有java.base模块支持AOT。

安全方面的加强。引入新的摘要算法SHA-3,内置ALPN使得更好的支持HTTP/2协议,提供DTLS(数据包传输层安全性协议),可以保证UDP数据传输的安全,PKCS12格式替代原有的JKS成为keystore的默认格式。

此外,统一JVM日志(Unified JVM Logging),多版本共存jar(Multi-release jar files),接口内部的私有方法(Interface provate method)等也是非常重要的新特性。

与其他语言的对比,Java的优势。

Java是最好的语言么?不是,因为在每个领域都有更合适的编程语言。

  • C语言无疑是现代计算机软件编程语言的王者,几乎所有的操作系统都是C语言写成的。C++是面向对象的C语言,一直在不断的改进。

  • Javascript是能运行在浏览器中的语言,丰富的前端界面离不开Javascript的功劳。近年来的Node.js又在后端占有一席之地。

  • Python用于系统管理,并通过高性能预编译的库,提供API来进行科学计算,文本处理等,是Linux必选的解释性语言。

  • Ruby强于DSL(领域特定语言),程序员可以定义丰富的语义来充分表达自己的思想。

  • Erlang就是为分布式计算设计的,能保证在大规模并发访问的情况下,保持强壮和稳定性。

  • Go语言内置了并发能力,可以编译成本地代码。当前新的网络相关项目,很大比例是由Go语言编写的,如Docker.Kubernetes等。

  • 编写网页用PHP,函数式编程有Lisp,编写ios程序有Swift/ObjectiveC

一句话概括,能留在排行榜之上的语言,都是好的语言,在其所在的领域能做到最好。

那么,Java语言到底有什么优势可以占据排行榜第一的位置呢? 其一,语法比较简单,学过计算机编程的开发者都能快速上手。 其二,在若干了领域都有很强的竞争力,比如服务端编程,高性能网络程序,企业软件事务处理,分布式计算,Android移动终端应用开发等等。 最重要的一点是符合工程学的需求,我们知道现代软件都是协同开发,那么代码可维护性,编译时检查,较为高效的运行效率,跨平台能力,丰富的IDE,测试,项目管理工具配合。都使得Java成为企业软件公司的首选,也得到很多互联网公司的青睐。 没有短板,容易从市场上找到Java软件工程师,软件公司选择Java作为主要开发语言,再在特定的领域使用其他语言协作编程,这样的组合选择,肯定是不会有大的问题。 所以综合而言,Java语言全能方面是最好的。

一些个人的心得和经验分享

软件业有个Hype Cycle模型,有很多技术受到市场的追捧而成为明星,也有些身不逢时而备受冷漠。

  1. EJB是一个广泛被误解的技术,在企业应用分布式计算方面,EJB给出了非常完备的技术体系。只是目前所有的应用服务器都实现的不够好。对于目前打算转型微服务设计的架构师,EJB也是一个非常值得学习借鉴的技术。

  2. Java的慢是相对的,有些是当前实现的不够好。比如原来有人对Java的网络IO性能提出质疑,然而稳定的Netty框架出现后,就没有人再怀疑Java处理网络IO的能力了,甚至在JDK8中自身的NIO也相当出色。要知道Java为了实现跨平台能力,采用的是各个操作系统的一个公共能力子集,而且其设计哲学就是给出API框架,实现是可以自行实现和加载服务的。

  3. Java在处理界面方面,Swing和Swt表现可圈可点(Idea和Eclipse分别采用的图形基础库),JavaFX已经运用到很多的行业软件上。在浏览器界面表现上,SpringMVC在模板渲染页面方面使用者最多;GWT似乎使用者不多,但基于GWT的Vaddin在国外企业中用户众多,而且很多服务器管理软件也用GWT写成;JSF也在企业软件中得到广泛使用,状态信息直接在后端进行管理,配合js前端框架,可以充分发挥各种技术的优势。

  4. CDI规范和SpringFramework在服务器程序中作用类似,Spring是一套设计优良,完备的框架,CDI具有更强的可扩展性。通过对注解的语义定义,一家公司可以维护一套自己的组件描述语言,来做到产品和项目之间的软件快速复用。CDI是定义软件组件内部模型的最佳方式,只可惜了解的软件工程师实在太少。

  5. 微服务架构在互联网应用,快速开发运维管理方面,配合容器技术使用,有很强的优势。但并不是所有的应用场景都适合微服务:强事务应用系统,采用单体结构的软件体系设计,更容易从整体方面维护,也能获得更优的性能。Java语言无论在微服务还是单体结构,都有成熟稳定的软件架构供选择使用。

Java语言当前的问题和未来方向的展望

如今的Java,已经在功能上相当丰富了,Java 8加入Lambda特性,Java 9加入模块化特性之后,重要的语言特性似乎已经都纳入进来。如果要说值得考虑的一些功能,我觉得有以下几点:

  1. 模块化改造完毕之后,可能会出现更多专业的JDK发行软件商,提供在功能方面,比如针对于分布式计算,机器学习,图形计算等,纳入相关的功能库作为文件。这样专业行业客户可以选择经过充分优化后的JDK版本。

  2. Java语义上对“模式匹配”有更强的支持,如今的switch语句能力还是比较欠缺,可以向Erlang, Scala等语言借鉴。

  3. 多线程并发处理,Java做的已经很好了。不过我个人觉得可以在多进程多线程配合,以及语言级别数据管道表示上,可以进行改造和优化。

  4. JDK9会有HTTP/2 client端的能力,但毫无疑问会有更多更好的三方库出现,JDK可以和这些三方库通力合作,提供一个更好API界面和SPI参考实现。

  5. 目前Java在云计算方面遇到的最大问题还是占用内存过大。我个人认为从两个方面来看:

    1. 如果该应用的确是长时间运行的服务,可以考虑结构清晰的单体结构,算下来总的内存消耗并不会比多个微服务进程占用的更多。

    2. 微服务应用,未来可以采用编译成本地代码的方式,并使用优化过的三方库,甚至本地so文件,减少单个进程的过多内存占用。

  6. 安全框架更加清晰,SPI可以允许三方库提供更强大更高效的安全功能。

  7. JavaEE方向则有更多的改进的地方:

    1. EJB重构目前的Corba分布通信基础,参考gRPC进行远程系统调用。

    2. 分解EJB规范,把JVM进程相关的特性,如注入/加强/事务/安全都统一到CDI规范中;对EJB进行裁剪,保留远程访问特性和作为独立执行主体分布式对象能力。

    3. 加强JMS和MDB,媲美Akka目前的能力。

    4. JaxRS适度优化,不必要依赖Servlet,或者适度调整,来提供更大的能力。

    5. JPA借鉴JDO,以及融入一部分特性,做到对NoSQL更良好的支持。

QCon 2017 北京站企业软件专题总结

  • Jeff Zhang
  • 19 April 2017

历时5个月,终于完成了QCon软件技术大会的出品任务。2017年4月18日,在国家会议中心311A大会议室,7位业界专家,同心协力,共同完成了一次有意义的企业软件专题系列演讲。

在我的印象中,之前的QCon大会还没有过独立的企业软件专题,这次的确是新的尝试。那么,企业软件是什么呢?简单来说就是企业中工作用到的软件,比如财务管理,公文流转,数据处理等等,而不是个人娱乐休闲用到的软件,比如游戏,视频,聊天等。而且在今日有另外一层潜在的含义,“企业软件和互联网应用有些对立的意味”,也就是所谓的2B和2C(面向个人)。

当然这种分界是不正确的,比如说打车软件是企业软件还是个人软件?答案可能是多样的,我个人认为只要一款软件收集业务信息,为某个企业或者组织机构服务,广义来说,就是企业软件,这样企业软件的范围就非常大了。不过在这个专题中,我还是严格的定义了企业软件的含义:“必须能够交付代码或者执行程序的软件产品,为企业业务而设计构建”这样一个狭义的概念。

寻找专家的过程是漫长的;议题的内容,公司的行业是两个关键的属性。最初的想法是分别在软件厂商,软件服务集成商,最终软件用户各自找2-3家公司;行业应该覆盖到金融,电力,教育,医疗等重点信息化建设行业;软件功能最好能覆盖到企业应用的方方面面。以上这些想法一直得以贯彻,最后基本得以完成。请到了来自于7个不同的公司(大学)的7位专家,按照不同的维度来介绍:

  1. 行业分布:金融,电力,制造,分销,教育,软件等分散在不同行业。

  2. 公司在软件生态的属性:软件厂商2家,服务集成商2家,最终软件用户3家,覆盖到软件生态全部环节。

  3. 演讲内容:工作流程管理,供应链管理,教育平台,中间件应用,容器技术运维应用,管理软件互联网化,前端工具技术。几乎覆盖了企业软件的各个方面。

  4. 讲师职责:有教授,技术部门管理者,架构师,资深开发工程师等等。

  5. 公司规模:4家具有全球范围的影响力,3家是国内所在行业的翘楚。

  6. 重叠属性:当全部选题完毕后,我才惊喜的发现,各位讲师之间都可以三三两两找到共同的兴趣点和互相借鉴参考之处,在会后的交流中也得到的确认。

  7. 重视程度:所在公司几乎都是第一次首次被邀请到QCon进行演讲,无论是讲师还是公司都非常重视。

  8. 丰富的行业经验:整个专题讲师平均年龄接近40,应该是本次大会所有专题中最大的。

一整天专题中,每位老师都非常成功的完成了演讲,令人惊喜的是所有人时间都控制的非常到位,几乎都是40分的最佳演讲时长,并留出长短适中的答疑时间。也就是说,每位老师都优秀的完成一次完备的顶级技术大会的演讲,实在是非常称赞。会后的PPT已经发布,视频预计在两周后发布,可以进入 QCon主页下载观看。

如果说有遗憾,就是没有去蹭热点,导致会场参与度不足。QCon的大会目前主要的购票者还是互联网企业,那么他们对企业软件专题可能不是特别感兴趣。我先前预料到可能会有这样的情况,但为了保持企业软件专题的朴实性,并没有给与老师们特定的指点和帮助,这方面本来是可以做的更完备周到一些的。

再次感谢所有的老师:

  • 主题一 企业级供应链系统服务化之路 吴众欣 新聚思架构部经理

  • 主题二 特大型央企流程管理平台应用实践 董爱强 中电普华研发事业部主任

  • 主题三 中国银联的开源应用之路 周亚国 中国银联技术开发中心资深工程师

  • 主题四 互联网思维下的 MOOC 课程实践 马昱春 清华大学计算机系副教授

  • 主题五 企业应用互联网化的架构演进之路 曾祥进 金蝶天燕中间件企业事业部负责人

  • 主题六 基于 kubernetes 的企业级容器云 周彩钦 联想 PaaS 团队资深工程师

  • 主题七 无需部署的前端中间件技术——企业移动化新思路 马铎 云适配技术研究院院长

也非常感谢QCon组委会的秀涛,刘芸,kitty,韩霖!

大概率的,企业软件这个专题会昙花一现,本次大会成为绝唱。但我坚信中国的企业软件市场终究会迎来繁荣的那一天,也许那时再找到所有的老师再次相聚!

QCon2017北京站合影留念
QCon2017聚餐留念
张.吉柯德

GreenTea JUG 第26次活动

  • Jeff Zhang
  • 13 April 2017

以下是GreenTea JUG官方网站的活动说明 链接

活动信息

  • 时间:2017-04-23 14:30-17:00

  • 地点:北京市海淀区中关村南路2号融科资讯大厦C座9层 红帽软件研发中心

  • 组织:张建锋@永源,张诚@红帽

2017年Java语言将迎来很多重大的更新发布,如Java9,JavaEE8等等。本次活动有幸邀请到Oracle甲骨文,Redhat红帽等Java大厂商的技术专家,来分享一线的开发实践经验,希望对Java语言的新特性在国内的普及起到一些作用。同时更重要的是提供一个北京Java用户组面对面交流机会,借此连接Java用户组的技术成员,今后可以经常举办技术交流活动。

主题一: Java 9新特性

时间: 2:30 - 3:20 讲师: 杨晓峰 (Oracle, Java核心类库组Lead) 主题简介:

  1. Java Platform Module System

    • 基本概念

    • 分析设计和实现的部分细节

    • 典型用例和诊断分析

  2. 概要介绍其他虚拟机、类库等方面的新特性

主题二: MicroProfile规范子集和实现技术

时间: 3:30 - 4:00 讲师: 宋志麒 (@KylinSoong, Redhat Teiid核心开发工程师) 主题简介:

  1. MicroProfile规范子集介绍及产生背景

  2. 目前状态,Feature backlog, release schedule等。

  3. Wildfly-Swarm中的实现技术分析

主题三:HTTP/2和Servlet4技术分析

时间: 4:10 - 4:50 讲师: 张建锋 (@shihang-EE守护者 永源中间件共同创始人) 主题简介:

  • HTTP/2

    • 特性

    • 协议分析

    • 二进制帧格式

    • 头部压缩/索引表

  • Servlet 4

    • 支持HTTP/2的特性

    • API增加和改变

  • Web服务器的支持

    • Tomcat9

    • Jetty 9.4

    • Undertow 2

  • 可选

    • Netty实现HTTP/2技术分析

交流讨论 10-30分钟

QCon 2017 北京站企业软件专题出品

  • Jeff Zhang
  • 08 April 2017

以下是我写好提交给QCon的原文,经过QCon编辑的认真校对和修改后,发表在InfoQ中文站。 链接

出品专题

非常有幸被邀请在QCon2017北京站成为出品人,经过深思熟虑以后,我建议设立一个企业软件互联网应用实践的专题。

对于技术人员,QCon是一个非常好的学习和交流的大会,首页的Logo下写着“全球软件大会”,但据我观察,近几年来绝大多数都是互联网公司的技术分享专题。诚然,互联网服务也是软件的一种,但我认为,“传统”的可以交付的软件应该是必不可少的,尤其在我们的国情下。云计算是好的方向没错,然而套装软件依然会拥有不可小觑的市场。放眼全球范围内,IBM微软甲骨文依然牢牢占据IT巨头第一梯队的位置。

软件技术大会,应该有纯软件厂商,IT服务商,行业应用软件公司以及应用IT走在前沿的企事业单位的声音。我经过3个月的努力,请到了来自不同组织(企事业单位)六位主讲老师。 这些组织来源于不同的行业领域,都有很高知名度:包括中国银联,联想,金蝶天燕中间件,中电普华,清华大学和新聚思。老师主题内容都是围绕自身企业应用的实践,分享技术和实际经验的闪光点。

中国银联是金融行业国字头企业,我们几乎每笔刷卡数据信息都会流入银联信息中心。联想是我国IT企业的老大哥,也是国际化企业。金蝶天燕中间件是国内中间件行业领导者。中电普华是电力及其他行业企业信息化建设产品和服务提供商。金蝶天燕中间件和中电普华都入选了2016年中国自主可靠企业核心软件品牌。清华大学是国内顶尖大学。新聚思Synnex是全球领先的供应链解决方案提供商。

在我看来,企业软件和互联网软件之间有个重要的差异,就是企业软件需要更高的成熟度和稳定性。企业软件可能没有那么酷,可能还是用着几年前不是那么新潮的技术,机器数目和用户访问量也没有互联网那么大,但业务复杂度却是非常高,无论从数据库表数目,代码行数,参与开发人员人数,都超过大多数互联网应用。同样的,面对客户多变的需求,巨大的业务数据量,更加苛刻的运营要求(商业环境下一分钱也不能出错,对事务特性要求很高),企业软件也需要不断的优化改进,来满足快速增长的业务需求。

我相信,中国最大的软件开发者群体,还是分布在广大的软件公司/集成服务商/IT应用企业中。其中程序员,测试,文档,项目管理人员,都努力工作通过编写软件系统来支撑起我们这个国家的信息化建设。我们这个专题的目标就是在QCon技术大会上,每位技术人员都能学到所在领域优秀企业的技术经验分享,都能够和专家在自己熟悉的技术方面进行交流。

主题一 企业级供应链系统服务化之路

吴众欣 新聚思架构部经理

SYNNEX SUPPLY CHAIN SERVICE SYSTEM,有超过 16 年的系统服务历史,它一直支持着 SYNNEX 公司业务量的攀升,公司在 2016 年位于《财富》美国 500 强的名次为 212。供应链系统纷繁复杂,包括仓库管理系统(WMS),运输管理系统(TMS),应收(AR)、应付(AP)、信用管理(CR)等系统应用。 SYNNEX 也由使用快速开发工具,转向两层 Java,继而走向 BS 系统,目前正在服务化道路上快速推进。业务模型铸就技术系统,随着一次次的并购过程,SYNNEX 公司的业务也在全球扩展,Hyve Solution 为巨型企业的 Data Center 生产服务器,不单单像舞蹈演员的华丽转身,公司的业务触角也由分销系统向服务整合转变,开发人员同样面对压力,艰辛跋涉。 这次演讲将分享 SYNNEX 公司的过去、现在及未来,与大家一起探讨技术浪潮推动且洗刷下的企业级应用系统的发展心路,我们是如何讨论、选择、思辨、跟进及革新的过程。

出品人有话说:

新聚思是全球领先的供应链解决方案提供商,我们更熟悉可能是其兄弟公司联强国际。作为IT供应链行业大型的公司,业务系统的复杂性可想而知。数据库的表结构,业务系统的架构复杂性,不断演变的系统和逐步加入的需求特性。这套驱动大型供应链业务系统的技术经验,值得每一位大型行业软件架构师和开发者关注。
吴老师具有丰富的经验,有著作和译作若干本,并且精于书法绘画国学等,是难得的技术全才。

主题二 互联网思维下的 MOOC 课程实践

马昱春 清华大学计算机系副教授

随着 MOOC 的汹涌来袭,在线教育逐渐开始走向各个领域。在互联网思维的影响下,专业领域知识的传播不再禁锢在高校的围墙之内,逐渐开放而面向不同的学习者。作为大规模的网络开放课程,MOOC 不仅仅是课堂搬到网上,如何在互联网的思维下开发和运营一门在线课程不仅仅需要授课者对知识的把握,更需要面向多样化的受众群体进行灵活的开发和设计。本演讲将分享基于 MOOC 平台的课程建设和运营实践,讲述信息类在线课程的特点和发展之路。 演讲大纲

MOOC 概况 互联网思维下的教学理念 MOOC 课程设计运营的关键要素 互联网环境下的教与学 信息类课程的特点与发展

出品人有话说:

清华大学是国内顶尖高校,也是每位理工科学生梦想的最高学府。如今MOOC可以满足每位开发者学习的上进心,通过互联网可以学到全球高校和专家的课程。
马老师是MOOC的实践者,具有丰富的经验。她教授的《组合数学》课程是精品课,组合数学是对编程最有帮助的一门数学课程,软件工程师必学,虽然冠以数学的字样,确是和软件开发密不可分。

主题三 特大型央企流程管理平台应用实践

董爱强 中电普华研发事业部主任

在国内特大型央企的 IT 建设中,各领域的业务系统在不同的历史时期使用了多种流程管理软件,它们所遵循的流程规范以及使用的技术标准均存在巨大差异,导致端到端的流程难以打通,且项目级的流程应用使流程资源难以集中管理、实施运维成本高、资源利用不合理。 如何在复杂的 IT 环境中实现统一流程标准、统一流程服务、统一流程运维,是一件极具挑战性的事。过去 10 年,企业级 BPM 作为 SOA 体系下的关键组件,经历了一个加速建设的过程,我们将邀请某特大央企资深的流程专家为我们分享其企业级 BPM 平台在建设过程中的经验与故事。让大家从过去 10 年 BPM 平台的建设实践中,了解流程领域的技术发展与架构变迁,了解大型企业如何基于统一流程平台实现多应用的统一支撑、降低管理与运维成本、提升对业务创新与管理优化的支撑能力,以及对未来架构演进方向的一些思考。

出品人有话说:

中电普华是知名的行业企业信息化建设软件提供商,产品和服务齐全,地域覆盖面广,面对的客户需求众多,流程管理平台在行业应用中起到关键的作用。
企业应用中,ESB,BPM,CEP和规则引擎是主要的技术产品,而BPM流程管理平台是重中之重。
我国特大型央企的信息化建设,毫不夸张的说,涉及到国计民生,重要而关键,有成千上万的技术人员进行研发保障。董老师会分享技术内容和运营经验,值得每个垂直行业业务系统的技术人员参考借鉴。董老师是研发事业部负责人,非常重视在QCon技术大会的分享和交流。

主题四 企业应用互联网化的架构演进之路

曾祥进 金蝶天燕中间件企业事业部负责人

在云计算、大数据、社交化、移动化的共同驱动下,企业应用从传统的单体架构三层结构沿着互联网公司走过的路,向现代化的新型应用架构演进,由于企业业务本身的复杂性要大于互联网公司的业务,包袱也更重,因此企业应用架构的转型所面临的困难、挑战也更多。传统企业应用面对更高的并发及更高的用户体验要求如何应对?具有内部复杂逻辑关系的应用如何向微服务架构转型?碎片化后的应用之间如何通信并进行业务协同?原有的 SOA 基础设施该如何去升级?具有强一致性要求的业务模块在新的架构体系里如何设计?本次演讲将尝试去分析一下这些问题。

出品人有话说:

金蝶中间件是国内中间件领域的领导者,我本人进入中间件这个领域,也受到了金蝶中间件原技术负责人袁红岗先生的影响。
中间件是基础软件,但因为和应用架构设计紧密结合,更多的融入到软件设计之中,作为独立软件反而不容易有巨大的市场红利。但毫无疑问,中间件是真正具有技术含量的基础软件,前面列举的IBM甲骨文微软都是中间件大型厂商(微软中间件融入在.NET框架中),阿里中间件团队也是首屈一指的国内技术团队。
当前中间件已经从JavaEE范畴不断外延到各个技术领域,包括云计算PAAS等。成老师有深度的技术积累和丰富经验,国内众多的企业应用的架构演进内容,相信值得每位企业应用架构师和开发者关注。

主题五 基于 kubernetes 的企业级容器云

周彩钦 联想 PaaS 团队资深工程师

互联网时代,市场发展变化越来越快,传统企业应用的开发模式也变得多样化以适应业务的变化。持续集成,持续交付成为一个常态,自动化工具和 IT 自助化服务已经形成一股潮流。 联想是一个国际化企业,内部的业务和需求都呈井喷式发展,开发团队对于 IT 基础架构的快速交付和自动化需求变得更加强烈,另外在应用的多样性和扩展性方面有更高的期望。基于此场景,PaaS 团队结合现在比较流行的 Docker 和 Kubernetes 技术打造了自有的企业级容器云,实现了服务的快速部署和交付,加速促进业务的发展。 本次演讲分享联想 PaaS 平台的基本架构,系统演变过程和平台开发运维过程中的一些实战经验和教训。

出品人有话说:

联想是国内IT企业老大哥,也是国际化IT企业。内部的信息系统繁多,用户来自各个部门,数据量庞大,运维面对巨大的复杂性。
基于容器的企业PaaS平台,可以管理和高效运维来自各个部门或者合作伙伴开发的各类企业业务系统。容器云和Kubernetes在当前都是比较新的技术,周老师所在团队,经过1年多的技术深入研究和研发打磨,构建了一套符合企业使用的PaaS平台。相信很多企业现在也在寻找或者调研开发一套类似的系统,那么周老师的一线技术经验分享不容错过。

主题六 中国银联的开源应用之路

周亚国 中国银联技术开发中心资深工程师

随着开源软件在金融行业的应用越来越多,中国银联作为一家银行卡组织,积极探索开源软件的应用,正在经历使用开源软件替换商业软件的过程,例如银联基于 JBoss 开源应用服务器定制开发,形成符合公司自身需要的发行版,本演讲着重以 JEE 应用服务器定制开发及分布式服务框架为例,讲述银联的开源应用之路。

演讲大纲 - 金融行业某银行卡组织的开源应用的背景及实践; - 如何定制化应用服务器及参与开源社区; - 应用服务器定制开发点; - 定制化应用服务器在使用过程中遇到的问题及使用经验; - 应用迁移的历程。

出品人有话说:

隆重的给大家介绍中国银联的周老师,他是我认识的少数比我还勤奋的国企技术人员之一,在应用服务器中间件,分布式架构设计,openstack/SDN等方面都具有丰富的一线技术经验。
可以说,周老师对于JBoss应用服务器的理解,在国内除了红帽JBoss团队成员,应该是排在前几位最熟悉的。他们团队维护着一个丰富的经验库,支持中国银联开源应用中遇到的种种技术问题。
中国银联作为国字头金融企业,原有系统也几乎都是商业公司产品,然而技术团队通过自身的学习和实践,掌握了开源产品的关键技术细节,并走查了每个用到的开源组件的代码,并从实践中不断归纳总结,进行修正改进,研发出符合自己需求的应用服务器产品。我个人认为是国内企业中,运用国际优秀开源软件典型成功案例。相信每个接纳以及打算学习开源技术,并受益于成本节约的企业技术人员,都能从周老师的分享中得到启发。

主题七 无需部署的前端中间件技术——企业移动化新思路

马铎 云适配技术研究院院长

受限于过去网络速度和终端设备的落后,碎片化时间始终无法被高效利用。随着科技发展和社会节奏的加快,企业对于时间利用率的追求也变得越来越高,这也促进了移动技术的蓬勃发展。对于企业尤其是大中型企业而言,IT 技术中僵化、庞大的系统无法快速演变,老化的核心系统,如 ERP 系统,需要升级成为围绕服务进行规划的系统。

马铎老师在多技术领域有深入研究和丰富实践,曾负责研发了国内最早基于业务模式实现可视化设计的企业级应用快速开发平台,主导了诸多大型企业的移动信息化项目,他将分享自己 10 多年的实践经验。

总结:

4月16日到4月18日,欢迎各位来到企业应用实践主题交流。估计我们这个主题各位讲师平均年龄应该是QCon各个主题中最大的,相信您会从各位老师丰富的经验阅历中获取满满收获。也希望今后的QCon大会中,企业应用实践能成为常设主题。

QCon2017北京站企业软件专题

永源中间件微服务系列课程

  • Jeff Zhang
  • 01 April 2017

微服务是目前的热度技术话题,对于企业和互联网软件应用的设计开发,都有良好的指导作用。

我们立足于Java语言,借鉴世界范围内优秀技术,结合自身的实践经验,总结开发出一系列的微服务课程。 目前有3组课程:

  1. 微服务全局内容:从微服务总体的角度,参考单体结构的系统,如何进行技术演进,对采用的技术进行详细说明和较深入的剖析。对于架构人员和高级开发人员在技术原型,架构设计和重构有帮助。

  2. 微服务Spring系列技术内容:目前SpringBoot和SpringCloud是Java领域最受瞩目的微服务技术框架,结合容器和编排技术,如何设计应用。对于开发人员进行具体的设计和开发会有帮助。

  3. MicroProfile微服务相关内容:MicroProfile是JavaEE面向微服务开发定义的技术子集,利用JavaEE API良好的设计和应用服务器稳定实现,来开发微服务应用。对于原有系统的无缝迁移和沿用JavaEE技术知识和保护原有投资,有很强的借鉴意义。同时MicroProfile也在不断的发展完善中,未来可能会成为Java语言微服务方面的标准。

以上3组课程各有侧重点,也有一些内容重合的地方,基本上来说覆盖范围和重合如下图:

Microservice三个系列课程范围

课程A-微服务技术全局内容

主题: 企业应用微服务化

时长: 大概需要2-3天

内容纲要:

一,经典企业应用架构

  1. JavaEE是蕴涵了企业应用特性需求的规范集合

  2. SpringFramework是优秀的实践落地框架

  3. 互联网,移动开发带来的设计挑战

二,微服务化的内在动力和外部助力

  1. 高并发量,分布式运算,无尽的需求和快速功能实现

  2. 架构微服务化

    • 微服务概述

    • 和单块应用的区别

    • 海量用户互联网

    • 应用设计的12要素

  3. 容器技术和服务编排技术不断成熟

    • Docker容器运行微服务

    • 使用Kubernetes来管理应用容器

    • Nginx或者Undertow提供Web层反向代理

  4. 对于运维管理的更高要求,架构设计和开发方式也变化

    • Keycloak安全权限管理

    • Api Gateway提供服务注册和消费,版本升级管理,服务限流,安全防护等

    • APM应用管理,检测服务调用路径

    • ELK集中管理日志

    • 服务治理的需求和实现思路

三,Java应用层技术

  1. 微服务的本质,不是体积微小,接口很小,而是领域对象聚合根的服务视图。

  2. SpringBoot+SpringCloud技术

    • SpringBoot应用设计

    • 关键点是配置项定义

    • 通过Rest或者Websocket提供服务

    • 各种组件通过maven组合构成

    • JavaEE规范技术栈的选用

    • 配合SpringCloud,保存配置,注册服务,路由管理,断路控制等

    • 系统自治,日志输出,安全设置等

  3. Wildfly-swarm的追赶,microprofile定义的规范集

    • Wildfly-Swarm基于JBoss MSC,设计思路

    • 架构分析

    • 应用示例

  4. Vertx异步响应服务框架

    • Vertx异步框架

    • 基于Netty,内部Json格式

    • 和Nodejs类似的循环执行线程,但有独立执行线程的扩展

    • Socket和HTTP服务

    • Vertx-Web处理Web应用请求

    • 异步调用方式处理,RxJava数据处理

    • 支持集群,多节点数据共享

  5. 模块化对微服务的设计的影响

    • 现有的OSGi模块化

    • 未来采用Jigsaw模块化

四,技术架构的思考

  1. 对事务需求的初步分析,尽可能的降低对一致性的需求

  2. 应用特性和面对的客户群

  3. 分布式运维能力

课程B-微服务Spring系列技术内容

主题:
SpringBoot和SpringCloud构建微服务

时长:
大概2-2.5天

一. SpringBoot

* 微服务设计方式适应互联网云端应用
* SpringBoot介绍
* SpringBoot设计原则,单一jar包组合方式,Initializer分析
* 构建工具一览和Maven构建
* Starter POMs
* 创建可以执行的Jar
* 多个层次可以选择适用的技术实现,如Tomcat/Jetty/Undertow,SpringMVC/Jersery,JPA/SpringDataRedis等等
* 创建REST API,具体实现和swagger使用
* 数据层访问,SpringData,加载数据
* 事务处理和多事务源的分布式事务考虑
* JMS和消息的配置和使用
* 自动配置的奥妙,代码分析
* Reactor,异步数据获取
* 安全部分Spring Sercurity结合使用
* Session全局管理
* 生产级功能,监控/管理/统计能力的实现
* Cli命令行管理方法

二. SpringCloud

* 配置信息的灵活管理,中心配置能力
* Netflix重点开源项目讲解
* 通过Eureka注册和发现实例
* CircuitBreaker的作用和重要性,Hystrix使用
* RestClient的能力和Ribbon负载均衡调度
* 通过Zuul进行路由和拦截操作
* 集中日志处理分析说明

三. MicroService

* 传统企业应用迁移到云端需要注意的问题,12条设计原则
* 微服务和JavaEE设计方案的对照分析,简化还是复杂
* 微服务对于运营能力的高要求,部署方式的改变等分析
* Docker和K8s容器和编排工具考虑
* 企业应用服务化迁移的案例和思考

课程C-Microprofile微服务技术和Wildfly-swarm实现

课程题目:
MicroProfile技术精解--JavaEE面向微服务的规范子集

时长:
大概2天

课程介绍:
MicroProfile是Java技术社区新定义的JavaEE规范子集,目前1.0包括JaxRS, CDI, JsonP三个规范。
在当前云计算,微服务的技术演进大背景下,企业应用设计开发也需要进行架构变革和技术适应。
JavaEE技术作为企业应用优秀的技术全集,对于需要快速迭代的互联网软件开发,有些过于庞大了。
把30多个规范其中一部分提取出来,构成一个干练的子集,用来构建微服务应用,正是Micro Profile的设计原则。

课程目标:
讲述MicroProfile中的各个规范技术特点。JaxRS规范和实现如何处理REST访问请求,CDI规范的技术内容,具体设计原则等。
以及利用wildfly-swarm进行微服务实战演练,wildfly-swarm基于Wildfly(JBossAS)应用服务器,
紧凑的内核设计和可扩展的子系统,可以方便的进行微服务系统的剪裁。
通过对这个课程的学习,学员可以了解如何利用JavaEE标准技术构建微服务,
以及进行微服务实践和掌握wildfly-swarm架构原理。并且对单体系统向微服务系统迁移的也有参考意义。

授课对象:
中高级Java程序员,架构师。对JavaEE有关规范有一定了解的开发者。


内容大纲:

一,MicroProfile规范集合
1. 形成背景,符合微服务设计
2. 主要的支持社区和开源实现

二,JaxRS规范
1. REST接口,基于HTTP的语义级别无状态协议,面向资源定义,考虑幂等性
2. 资源地址和Annotation注解
2. 传递格式,格式文本json/xml,通用解析工具,DOM/SAX/Stax解析方式对比
3. 响应处理,返回值和异常
4. 过滤器和实现
5. REST客户端API
6. 异步接口说明
7. 异步通信和推送

三,CDI
1. IOC注入解析和DI规范
2. CDI是DI针对企业应用开发的扩展,揭示对象间关系本质的规范
3. Scope/LifeCycle
4. Stereotypes
5. Decorator
6. Event
7. Portable extensions
8. CDI和EJB,CDI和SpringFramework的区别和相关分析

四,相关规范
1. JsonP处理Json格式数据
2. XML格式处理
3. JPA对象持久化到关系数据库中

五,Wildfly-swarm实现微服务
1. wildlfy-core为基础组件
2. 子系统扩展机制
3. Fraction组成机制
4. 配置文件读取方式
5. JaxRS和CDI规范实现Resteasy和Weld
6. 代码实践

新的一年中间件技术展望

  • Jeff Zhang
  • 25 December 2016

新的一年中间件技术展望

Java语言

2017年是Java语言技术大年。

  1. Java 9会在7月份发布,其中包含了推迟了若干年的模块化特性,这个会对未来的架构设计和开发方法产生深远的影响。HTTP/2,jShell,Flow API,Unified Log, Multi-Release JAR,jlink以及很多安全方面的改进和增强令人期待。

  2. SpringFramework5会发布,Reactor3成为异步框架的关键。这个新的框架将进一步提升通用Java应用的移动设备和网络应用的吞吐能力。

  3. MicroProfile已经被Eclipse组织接纳成为孵化项目,JavaEE在社区领域,出现了一个独立的开发规范集合,一大批开源框架和服务器正在不断成熟中,今后将会是Java微服务开发的主力。

  4. 如果顺利的话,JavaEE8会在四季度发布,尽管除了Servlet4之外,没有其他大的改进。但各个规范会进一步适应目前的异步化,服务化的开发需求,EE8还是非常值得期待的。

应用服务器

与Java语言傲居开发语言之首形成鲜明对比的是,JavaEE应用服务器市场规模依然在下滑,前不久Gartner Group还专门发了市场分析报告来唱衰这个市场,并预言微服务框架和PAAS平台会占据更大的份额。我基本同意应用服务器市场会从原先中间件开发平台垄断位置减少很大的市场份额,而且中间件基础软件会延续Linux的市场发展轨迹,走产品免费而订阅服务的商业模式。微服务框架产品目前已经成快速增长趋势,PAAS平台也开始被更多的企业所接纳。

然而我相信,应用服务器(或者说是整体交付的独立运行应用程序的服务器)还是有大片的市场需求的,尤其是在国内,目前各行业中企业软件还几乎全部是部署在应用服务器上。虽然各个企业都在寻求可能的服务化改进,并盯着一线互联网公司学习经验,但毫无疑问想要改变企业应用基础架构的技术路线,这个过程会非常漫长。

而且,应用服务器的市场还是会一直存在的。一个例子就是SAP的Hana服务器,近来会推出HANA2。这是一个内存杀手,把整个商业系统容纳在一个庞大的业务服务器中。给企业内部使用的,采用交付软件的方式,系统整体效率非常高,软件经过广泛的测试,成熟度和稳定性很好。

应用服务器的市场就是面向广大的企业应用,不需要很大的并发访问量(如果需要暴露数据到互联网上可以采用同步数据方式),功能特性非常丰富,需要有很强的事务处理能力,最终用户的开发力量不是很强,主要以业务用户和运营为主。在这个场景下,带有集群能力的应用服务器还是首选,使用目前较轻量级的应用服务器,可以做到快速开发部署,解开压缩包即用,几秒内迅速启动,配套的监控运维平台。在当前主流服务器硬件能力下,个位节点数组成的服务器集群,支撑上百万的并发访问不会有问题,足以满足绝大多数企业应用和中小网站的需求。

那么,为什么唱衰应用服务器呢?原因是过去它承担了太多的期望,各种应用,不论架构设计的合适还是不合适,都在应用服务器上开发和部署。各个厂商的产品都做成了大而全的大杂烩,动则500M以上,厚重而运行缓慢。Spring框架首先质疑并通过敏捷而优秀改进占领了Java服务器Web开发的大部分份额。后来OSGi技术也曾经发起过挑战,但由于自身也很复杂,学习曲线陡峭,除了集成,工控等领域,并没有被广泛运用于企业软件中。

从2014年开始,容器和微服务成为技术的热点词汇,可以说它们是相辅相成的,微服务需要一个能被管控的载体,恰好容器技术开始成熟并广泛应用。而容器技术也是一个筐,需要有具体的应用来完成技术的演进。

那么,容器和微服务真的是“新”技术么?首先容器一词,早在J2EE出现时就有了Web容器和EJB容器的说法,顾名思义,就是容纳应用的载体,开发者编写的程序通过API/插件/Addon等扩展机制,部署/运行在一个环境之中,而这个环境提供通用的技术设施和数据等服务。而微服务,Corba时代的进程,和后来的SOA,都是如假包换的服务程序。只不过如今的容器和微服务都有了更多的特点和更清晰的定义。

服务化

从技术的角度来看,JavaEE应用服务器的架构,从开始就是可以服务化的,比如Servlet通过远程调用EJB接口,只不过在规范中被定义成需要RMI/IIOP协议。这些看似“过时”的定义,其实在企业应用中可以工作的很好,如EJB3.1定义的异步接口能力,就可以大大的提高系统整体吞吐能力。而且如果能有效的进行改进,比如说未来的EE9,可以支持如gRPC等远程调用协议,将会唤回新的技术活力。

JavaEE的最大问题就是整体过于庞大,有33个子规范,而在面对某个类型应用时,绝大多数规范运用不上,能用上的呢,又定义的不是那么的细致全面,还比不上Spring框架或者第三方库等实务者。所以我们在具体技术选型时,可以忘掉JavaEE大而全,而要选择合适的,小而美的具体子规范,搭配使用来满足应用需要。

MicroProfile就是面向微服务而由社区形成的一个JavaEE子规范集,已经推出的1.0只包含三个JaxRS/CDI/JSONP,通过这三个现有的EE7子规范组合,就可以满足微服务开发的很多需求。目前Wildfly-swarm, Payara micro等已经完整支持。使用这个技术集的一个红利是:开发的产品,即可以部署在应用服务器中,也可以作为微服务程序开箱即用。

从具体的软件架构来说,传统的三层结构已经不能满足当前的互联网应用需求,分布式已经是必然要考虑的属性。而矛盾点就是,以事务为核心的企业应用,设计的一个原则就是避免分布!所以对于有扩展需求的应用,适当的软件架构非常重要。我的观点是,采纳DDD设计思路中的CQRS原则,在设计时就考虑,这样无论是在一个JVM,还是分布式架构,API是统一的,体系变得非常清晰。应用实体的修改,用事件存储机制和消息队列,数据的查询则采用类似RxJava这样的异步数据访问接口,数据直接通过中间件进行高效同步复制,并使用分布式缓存来优化存储和数据访问速度。

这样的体系架构,可以横跨应用服务器/微服务框架/PAAS运行平台,在一定程度上做到架构设计的可扩展性。从执行效率来讲,无论是命令模式API,还是消息队列,Rx式数据访问,都可以本地执行实现极速访问,也可以远程调用便于动态扩展。

新的一年,应用服务器,微服务平台,应用基础架构,中间件领域,新的机遇新的挑战。

Netflix OSS, Spring Cloud 以及 Kubernetes?关于它们的种种!

  • Jeff Zhang
  • 12 June 2016

说明

本文是一篇 翻译文章,来自于前同事,红帽中间件架构师 Christian Posta @christianposta 。

当我第一次读到时,就知道是一篇好文,详尽的解释了Spring Cloud 中 Netflix OSS组件在Kubernetes容器管理场景下,最优实践是怎样的。 之前的 微服务知识体系,有一些相似的想法和技术方案,也借鉴一些观点和技术方案,如采用Turbine来统一输出断路器信息。

经过Christian的授权,我翻译了这篇文章为中文供国内Java微服务开发者作为参考,有不通顺的地方请见谅。

以下译文(采用第一人称)

本文以下的内容,在我的新书"面向Java开发者的微服务“中也涉及到一些,该书由OReilly出版社在2016年6月即将出版发行。我想在这里给出一些更明确的说明,因为很多人问到了关于Netflix OSS和如何在Kubernetes上运行的的问题(这些项目都是非常棒的!),以及这些组件完成的功能是重叠的,我会试着解释一些原因。

Netflix OSS是一组开源的框架和组件库,Netflix公司开发出来解决分布式系统的一些有趣的可扩展问题。如今对于Java开发者来说,它们是在云端环境中开发微服务的非常棒的工具代名词。在服务发现,负载均衡,容错等模式方面,都给出了非常重要的概念,并带来了漂亮的解决方案。

Netflix决定把这些项目贡献给开源社区,促进了其他互联网公司也这样做,我们要说声“谢谢”。而有些大型的互联网公司专利化它们的技术,保持闭源,比起来实在是太糟糕了。

Netflix OSS

总的来说,在多数Netflix的开源项目开发的时期,只有AWS公有云可以选择而没有其他的替代。这个因素导致这些库并不是直接为今天采用的运行环境(如Linux上的容器)开发的。采用了Linux容器,Docker,容器管理系统等基础环境后,我们看到了大量的运行在Linux容器上的微服务,它们可能运行在公有云,私有云或者都有。另外,因为容器是服务不透明的包装,我们往往不关心容器里究竟运行什么技术方案(Java/Node.js/Go)。Netflix OSS基本上是Java开发,它们是一组组件库/框架/配置项,可以包含在你的Java应用/服务器代码中运行。

所以我们有了观点#1:

微服务可以由多种框架/语言来实现,但服务发现,负载均衡,容错等这类服务是非常重要的。

如果我们运行在容器中这些服务,我们可以利用强大的与语言无关基础设施的优势,做这些事情:构建,打包,部署,健康检查,滚动升级,蓝绿部署,安全性,和其他。例如,OpenShift(基于Kubernetes构建的企业开发部署方案),可以做所有这些事情:而不需要开发者必须知道或者关心基础设施的这些事情。而集中精力来保持你的应用程序和服务简单。

为什么基础设施可以帮助做服务发现,负载平衡和容错这些服务,难道不应该是应用层的事情么? 如果使用Kubernetes或者其衍生项目,那么答案是可以在基础设施实现这些服务。

Kubernetes中服务发现的方式

使用Netflix OSS,通常需要设置一个服务发现服务器,作为客户端可以发现的服务端点注册表。比如,你可能使用Netflix Ribbon来与其他服务通信,并需要发现服务在哪里运行。服务可以自行停止,也可以在集群中加入更多的服务来实现扩展。这个中心服务发现注册表跟踪什么服务在集群中是可用的。

一个问题是:你作为一个开发者需要做这些事情:

  • 决定是使用一个AP系统(consul, eureka等)还是CP系统(zookeeper, etcd等)

  • 弄清楚如何运行,管理和监视这些大规模系统(而不是小型的练手项目)

此外,你需要了解客户端使用什么编程语言和服务发现通信。前面提到过,微服务可以由许多不同类型的语言实现,Java客户端是没有问题的,但如果没有Go或者NodeJS客户端,就需要自己开发了。每种语言和开发者都有可能用自己的想法来实现客户端,你会面临维护多个客户端,它们试图做相同的事情,却在语义上有不同的方式。或者每种语言都有自己的服务发现服务器,以及自己的客户端程序呢?你要管理和维护这么多的服务发现实现么,想想就头疼。

如果我们仅用DNS呢?

好吧,这个算是解决了客户端库的问题。DNS是每个操作系统都有的基础服务,利用TCP/UDP协议,在私有云,公有云,容器,Windows,Solaris等都有。客户端只需要指向域名就可以了,基础服务可以路由到服务上,可以采用多个轮转DNS配置来实现均衡负载。好处是客户端都不需要知道服务发现服务器,而使用TCP客户端就可以了。而且也不用管理DNS集群,网络路由器支持负载均衡特性,而且这些都很简单容易被理解。

但对于弹性发现,DNS方案就做的很差了。DNS不适合做弹性的,动态的服务集群。当服务加入到集群或者移除时,系统做了什么?服务的IP地址可能还在DNS服务器或者路由器(甚至有些不是你能掌控的),或者你自己的IP堆栈上进行了缓存。另外,如果你的应用侦听的是非80端口,而要DNS保存非标准的端口信息,需要使用DNS SRV记录,而这样你又需要使用特定的应用层客户端来发现这些记录了。

Kubernetes服务

让我们只使用Kubernetes,在docker/linux容器上运行程序,而kubernetes是最合适的运行docker容器的场所,或者Rocket容器,Hyper.sh容器。

(我偏爱简单的技术,或者看起来是简单的,因为你不可能用复杂的零件构建出复杂的系统,人人都渴望简单,最好的是内在复杂而外在简单,google和红帽都对于kubernetes做了大量工作,使得它对于分布式系统的部署和管理部分看起来都很简单。)

使用kubernetes,我们建立一个kubernetes的服务,大功告成了!我们不用浪费时间建立一个发现服务器,编写定制的客户端,使用DNS等,已经可以工作的很好了。我们转而看下一部分,微服务提供的商业价值。

是如何工作的?

以下是kubernetes的一些抽象概念:

  • Pods

  • Labels / Label Selectors

  • Services

Pod很简单,就是Linux容器。Label也很简单,它们是键-值字符串,用于标记 Pod。比如 Pod A可以标记为app=cassandra, tier-backend, version=1.0, language=java,这些标记可以表示任何你的意图。

最后一个概念是服务,也很简单。服务是一个固定的群集IP地址。该IP地址是一个虚拟IP地址,可用于发现/调用在Pod/容器中的实际端点地址。实际的IP地址是如何被发现的?服务使用了label selector来选取你定义过的标签Pod。举例,使用选择器“app=cassandra AND tier=backend”,就得到一个虚拟的IP地址,访问所有具备上述标记的Pod,这个选择器是即时生效的,所以任何离开集群的pod或者加入到集群中的都可以自动被启动并参与到服务发现中。

Kubernetes Simple Services

另一个使用kubernetes服务的好处是,智能的选取Pod来加入到服务中,根据它们的存活和健康信息。Kubernetes使用内建的存活和健康检查方法,来确定一个Pod是否包含在一个特定服务之中,如果不满足条件,Pod会被驱逐出去。

注意Kubernetes服务不是一个“东西”,一个设施或者docker容器等,它就是一个虚拟表示,所以没有单独故障点,是一个IP地址,由kubernetes来路由消息。

这个概念难以置信的强大,对于开发者来说很简单,现在一个应用想用cassadra作为后端数据库,只需要用一个固定IP地址对应的一组cassadra数据库。然而硬编码固定IP地址不是好的主意,因为可以迁移应用到不同的环境下(QA/PROD),需要更改IP(或者注入一些配置信息),这时我们使用DNS。

使用Kubernetes的DNS集群方案是正确答案。因为对于给定的环境,IP是固定的,我们不用考虑其缓存,它们不会变化。我们使用DNS服务。比如应用配置使用http://awesomefooservice,当我们从Dev换到QA以及Prod环境时,配置相应的kubernetes服务,我们的应用不需要改变。

Kubernetes Services

我们不需要额外的配置,我们并不需要担心的DNS缓存/SRV记录,自定义库的客户端和管理额外的服务发现的基础设施。Pod可以被加入到集群中,标签选择器积极的选取符合标记的Pod,应用可以是Java, Python, Node.js, Perl, Go, .NET, Ruby, C++, Scala, Groovy等任何语言开发的。服务发现机制不关心特定的客户端而只是使用它。

那么客户端均衡负载的情况呢?

很有趣的是,Netflix编写了Eureka和Ribbon,组合使用它们,可以用来客户端的负载均衡。一般来说,服务注册器管理和跟踪集群中存在哪些服务,并且把这些数据发送给感兴趣的客户端。这样,客户端知道了集群中节点的信息,它可以选择一个(随机,粘滞或者自定义的算法),然后调用它。下一次调用时,又可以选择集群中另外的一个服务。

另一个重要的方面是:由于客户端知道服务在哪里,客户端可以直接联系服务端,而不用经过中途的跳转。

在我看来,客户端的负载均衡大概占据5%的用例。原因解释一下: 我们要的是一种方法,可以理想的做可扩展的负载均衡,而不需要任何额外的设施和客户端库。在大多数情况下,我们并不关心是否有中间的负载均衡器额外的跳转(大概你99%的应用情景是这样的)。我们遇到的情景是,服务A调用服务B,需要调用服务C,D,E,这样才能获得图片信息。这种情况下,很多的跳转带来更多的延时。所以可能的方案是“移除多余的跳转”,而不是均衡负载的跳转,调用下游服务的次数是必须的。我的博客中有关于事件驱动系统的文章,以及自治管理相关的讨论,可以关注。

使用Kubernetes的服务,我们完成了适度的负载均衡(没有服务注册,定制的客户端,DNS缺陷等的开销)。当我们通过DNS和一个Kubernetes服务进行交互时,将使用集群中的Pod进行负载均衡操作(使用标签选择器)。如果你不希望在负载均衡处有额外的跳转,请不要担心,虚拟IP直接路由到Pod,并不涉及到物理的网络。

好极了,95%的用例都变得很简单!因为应用情景总是在95%的场景中,所以不用过度设计,让事情越简单越好。

那么对于剩下的5%的用例呢?有时你会遇到这样的情况,需要根据业务决策来决定使用具体集群中哪一个后端服务。一般情况下,使用一些特定的算法,而比像“轮询”,“随机”,“会话粘滞”要复杂的自定义算法,根据具体的应用程序。这时使用客户端的均衡负载。在这种模式下,依然可以使用kubernetes的服务发现来找到是在哪个Pod集群,然后用客户端代码直接调用其中的Pod。fabric8.io社区的kubeflix项目,就使用Robbon作为发现插件,来使用REST API获得服务对应的所有Pod列表,然后客户端的代码决定调用哪一个pod。其他语言使用kubernetes的REST API也可以做类似的工作。可以投入做一些客户端发现库来简化这个操作。更确切的说,是把这样的业务逻辑,从应用程序中分离出来作为独立的中间件。通过使用kubernetes,你可以部署这样的模块,作为应用的独立部分,并把自定义的均衡负载逻辑定义在那儿。

Client load balance

重申一次,以上只是用在5%的用例中,有更多的复杂性。对于95%用例,就用内建的和特定语言的客户端无关的方式就好。

关于容错

依赖相关的系统,构建时应当总是要记住承诺性。这意味着,应用总是要时刻注意它的依赖系统是否处在不可用或者崩溃的状态下。问题是kubernetes是否有容错方面的考虑?

kubernetes的确有自愈的能力,如果一个pod或者pod中的一个容器停止了,可以将它重新启动,并保持ReplicaSet保持不变(比如,如果需要有10个“foo” pods,那么kubernetes总是保持有10个,如果有停掉的,会再次启动pod)

自愈设施是非常棒,而且是自带的服务。但我们需要讨论的是,当应用对应的依赖(如数据库或者其他服务)停止时,会发生什么?这取决于应用程序如何与之交互。例如,在Netflix,如果你尝试观看特定电影时,要调用“授权”服务,来知道你什么特权,是否可以看电影。如果该服务停止,我们应该阻止观看该影片的用户?还是显示异常堆栈信息? Netflix的做法是让用户观看电影。这是更好的方案,订阅者应当观看,一个服务依存关系在一段时间出现错误时,不应当影响到用户享受一次电影。

我们需要的是一种正常的降级方案,或者寻找一种替换的方法来保持服务承诺。Netflix的Hystrix项目就是给Java开发者一个非常棒的方案。它实现了方法来做到"bulkheading","circuit breaking", "fallbacks"。每种对应一个应用相关的实现,也有不同语言的客户端库。

Hystrix

这里kubernetes也能帮上忙么?是的!

我们再看看很棒的kubeflix项目,你可以使用Netflix Turbine项目来聚集和可视化集群中所有的运行中的断路器。Hystrix可以用SSE暴露信息送到Turbine中。然而Turbine如何发现哪些Pod中包含了Hystrix?可以使用kubernetes的标签。如果我们标记所有使用hystrix的pod,"hystrix.enable=true",那么Kubeflix Turbine引擎自动发现每个断路器,获得SSE流并且显示到Turbine页面上。这点感谢Kubernetes。

Turbine Hystrix

关于配置

Netflix Archaius用来处理云端的分布式配置管理服务。可以设置一个配置服务器,使用Java库来查找配置项。还支持动态配置改变。

这里又有95%用例情景。我们希望让环境特定的配置(这是一个重要的区别,不是每一个环境特定的配置需要根据运行环境而改变)存储在应用程序之外,并且基于运行的环境(DEV,QA,PROD)来注入这些配置项。但我们真的想要一个与语言无关的方式来查找配置,而不是使用Java库,或者使用classpath等使得配置复杂化。

在Kubernetes我们使用三个结构来注入基于环境的配置:

  1. Environment Variables 环境变量

  2. GitRepo Volume git仓库作为文件卷

  3. ConfigMap

通常我们可以设置环境变量,注入配置数据到Linux容器中,大多数语言都可以轻松读取到这些信息。 我们可以存储这些配置到git中,然后绑定配置仓库到我们的pod上(作为文件系统的文件),这样可以用任何框架来获取配置文件信息了。 最后,我们可以使用Kubernetes的ConfigMap来存储配置版本信息,作为文件系统mount到Pod上,同样的,可以用任何语言和框架来处理配置文件。

5%的用例情况呢?

在5%的使用情况,你可能希望在运行时动态更改配置。Kubernetes帮助做到了这一点。您可以更改配置文件,通过ConfigMap这些变化动态地传播到了mount的pod。在这种情况下,你需要有一个客户端库,能够检测这些配置的变化并通知你的应用程序。Netflix的Archais有一个客户端可以做到这一点。Spring Cloud Kubernetes的Java项目使这个更容易(使用ConfigMaps)。

关于Spring Cloud

使用Spring开发Java微服务,往往使用Spring Cloud中的Netflix项目,基本就是Netflix OSS项目。fabric8.io社区也有很多好用的项目,比如spring-cloud-kubernetes,大多数模式(包括配置,跟踪等)可以无须额外的,复杂的基础设施(如服务发现引擎,配置引擎等)而直接运行在kubernetes之上。

总结

如果你开始构建微服务的方法,你肯定已经被Netflix OSS/Java/Spring/SpringCloud所吸引。但是要知道你不是Netflix,也不需要直接使用AWS EC2,使得应用程序变得很复杂。如今使用docker和采用kubernetes是明智之举,它们已经具备大量的分布式系统特性。在应用层进行分层,是因为netflix5年前面临的问题,而不得不这样做(打赌说如果那时有了kubernetes,netflix OSS栈会大不相同)。避免应用程序复杂是一个明智的选择。

微服务技术体系

  • Jeff Zhang
  • 31 May 2016

微服务技术体系材料发布

近一年的技术考察和积累,我们总结出一套比较完善的微服务技术和开源产品框架。

经过一个月的材料收集和撰写,永源中间件的微服务技术体系演讲材料发布了。

包含一下五个大部分:

  1. 微服务技术

  2. SpringBoot开发框架

  3. Vertx异步框架

  4. 容器技术和配套服务

  5. 和原有JavaEE技术的对比和结合使用

从当前活跃开发的开源项目中,选取可靠稳定的产品进行组合,构建出一套完善的,开箱即用的微服务技术框架。

涉及到的项目有:

  • 容器相关技术:docker, kubernetes

  • JavaEE开发框架: SpringBoot, Wildfly-swarm

  • 异步开发工具:Vertx

  • SpringCloud以及配套项目

  • Nginx

  • 微服务管理:API Gateway, 分布式跟踪和性能监控, SSO Server, 统一日志管理

  • JavaEE应用服务器的应用思考

微服务知识体系大纲

微服务概述

  • 和单块应用的区别

  • 海量用户互联网

  • 应用设计的12要素

SpringBoot应用设计

  • 配置项定义

  • 通过Rest或者Websocket提供服务

  • 各种组件通过maven组合构成

  • JavaEE技术栈的选用

  • 配合SpringCloud,保存配置,注册服务,路由管理,断路控制等

  • 系统自治,日志输出,安全设置等

  • Wildfly-Swarm类似的设计思路

Vertx异步框架

  • 基于Netty,内部Json格式

  • 和Nodejs类似的循环执行线程,但有独立执行线程的扩展

  • Socket和HTTP服务

  • Vertx-Web处理Web应用请求

  • 异步调用方式处理,RxJava数据处理

  • 支持集群,多节点数据共享

容器技术和服务管理工具

  • Docker容器运行微服务

  • 使用Kubernetes来管理应用容器

  • Nginx或者Undertow提供Web层反向代理

  • Keycloak安全权限管理

  • Api Gateway提供服务注册和消费,版本升级管理,服务限流,安全防护等

  • APM应用管理,检测服务调用路径

  • ELK集中管理日志

  • 服务治理的需求和实现思路

JavaEE应用服务器回顾

  • Corba时代的微服务

  • 企业应用对事务的需求

  • EJB的灵活设计,

  • 远程EJB能力,其他RPC选择,如Dubbo,gRPC

  • Servlet和EJB支持非阻塞调用

  • 消息机制运用到设计中

  • Spring框架和CDI规范

  • JPA和SpringData

  • 数据源和缓存,分布式结构

  • "微"服务同样需要有完整的技术层次,稍复杂的应用打包后也是庞大的

  • 界面技术的选用,浏览器渲染能力,移动设备的考虑

  • 针对不同的应用和系统规模的大小,选用合适的架构

  • 同样是部署应用到容器,微服务是应用服务器整体的分布化。应用从进程内的调用,扩展到跨进程远程调用。

演示文件地址

Spring Boot 和 Wildfly Swarm 的性能基本对比测试

  • Jeff Zhang
  • 27 May 2016

Wildfly Swarm 1.0.0.CR1 发布

Wildfly-swarm 1.0.0.CR1今天发布了。 http://wildfly-swarm.io/posts/announcement-1-0-0-cr1

Wildfly-swarm是一个基于Wildfly-core的微服务项目,和Wildfly应用服务器共同使用相同的内核组件MSC。

我们可以认为它是和SpringBoot类似的项目,拥有相似的架构和开发/构建方法。基础组件对比如下:

  • 注入服务:SpringFramework和 Weld CDI容器

  • Web容器:嵌入式的Tomcat和嵌入式的Undertow

  • Rest数据:SpringMVC和JaxRS实现RestEasy

  • 持久层:均采用JPA和Hibernate作为实现

  • 嵌入式的数据库:HsqlDB和H2数据库

  • 构建:都采用Maven进行构建,可以选用Gradle

JavaEE原来开发应用的步骤是:1.启动应用服务器,2.进行部署。 微服务时代,JavaEE编程方式需要调整来适应。从部署到服务器中改造为直接启动应用进程,内嵌一个web容器。 把所需要的jar和应用代码全部打包到一个jar或者war中,通过

java -jar example.war

的方式来启动服务。

这个项目从启动到现在过去了一年多,如今进入到候选发布版本时期,也意味者整体架构和API不会再有大的变化,功能和性能都已经比较稳定了。

与此同时, SpringBoot毫无疑问是过去的一年中的明星项目,下载量节节升高,越来越多的项目采用SpringBoot来开发。Docker和微服务的各种技术大会上也都能听到开发者热烈讨论和学习。

Wildfly-swarm一直作为SpringBoot的一个潜在对手项目在努力开发中,如今发布了CR版本,我们希望通过简单的性能对比测试来得到一手的数据。

测试方法介绍

我们选用两个项目中现成的有代表性的例子作为测试用例。两个例子的架构基本相同:

  • 内嵌Web容器

  • 使用MVC或者JaxRS来表现Rest文本数据

  • 利用Spring框架或者CDI框架,注入beans

  • 持久层使用JPA,Hibernate 5作为实现

  • 使用嵌入式数据库,启动时加载少量测试数据

  • mvn构建打包好的war,可以直接用java执行

测试机器为 Linux Ubuntu 14.04.3, 8 Core, 8G Mem

Linux useopen-w5 3.16.0-33-generic #44~14.04.1-Ubuntu SMP Fri Mar 13 10:33:29 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux

Java虚拟机为Oracle JDK:

java version "1.8.0_74"
Java(TM) SE Runtime Environment (build 1.8.0_74-b02)
Java HotSpot(TM) 64-Bit Server VM (build 25.74-b02, mixed mode)

使用Apache-jmeter来进行简单的性能测试,版本为2.13。

创建一个线程组:十个并发线程,每个运行5000次,每一轮测试运行50000次访问(thread 10, Rarm-up: 1sec, loop count: 5000)。

创建一个HTTP Request来访问本地8080 web端口,并建立一个Generate Summary Result来输出测试的结果。

另外启动一个jconsole,挂到服务进程上查看资源的占用情况。

每个项目用例都运行两轮,方法是启动后先跑一次warm-up测试,记录相关数据后,连续跑三轮正常的应用测试。关闭并重启应用服务进程后,再做一遍第二轮的测试。

SpringBoot 测试

获取SpringBoot 1.4.0.M2版本,编译例子/spring-boot/spring-boot-samples/spring-boot-sample-jpa/,在target目录下有 spring-boot-sample-jpa-1.4.0.M2.jar文件,大小26.2M,解压后在三方包目录下有48个jar。

关键的组件版本如下:

  • tomcat-embed 8.0.33

  • spring 4.3.0.RC1

  • Jackson 2.7.3

  • hsqldb 2.3.3

  • hibernate 5.1.0

使用java启动进程,启动时间为 6.0秒 左右。

用浏览器访问http://localhost:8080,得到数据

Title	Body	Tags
Spring Boot	Takes an opinionated view of building production-ready Spring applications.
Spring Framework	Core support for dependency injection, transaction management, web applications, data access, messaging, testing and more.
Spring Integration	Extends the Spring programming model to support the well-known Enterprise Integration Patterns.
Tomcat	Apache Tomcat is an open source software implementation of the Java Servlet and JavaServer Pages technologies.

启动后的堆,活跃线程,加载的类数目分别为:

  • heap: 121M

  • live threads: 19

  • current classes loaded: 8649

使用jmeter压测一边,50000次访问后的两轮的结果为:

R1: Generate Summary Results =  50000 in    18s = 2841.4/s
R2: Generate Summary Results =  50000 in    19s = 2681.3/s

经过几秒等稳定后,观察jconsole中的系统状态,堆的大小两轮不太一致:

  • heap: 105-212M

  • live threads: 27

  • current classes loaded: 9411

分别记录两轮压测性能数据:

Generate Summary Results =  50000 in   7.3s = 6832.5/s
Generate Summary Results =  50000 in   7.4s = 6721.3/s
Generate Summary Results =  50000 in   7.5s = 6709.6/s

Generate Summary Results =  50000 in     8s = 6323.5/s
Generate Summary Results =  50000 in     8s = 6596.3/s
Generate Summary Results =  50000 in     8s = 6544.5/s

在测试过程中,Heap的变化曲线:

Heap - SpringBoot

手工GC后

  • heap: 37M

  • live threads: 27

  • current classes loaded: 9407

Wildfly-swarm 测试

获取Wildfly-swarm 1.0.0.CR1版本,编译例子/wildfly-swarm/wildfly-swarm-examples/jpa-jaxrs-cdi/jpa-jaxrs-cdi-war,在target目录下有 example-jpa-jaxrs-cdi-war-swarm.jar文件,大小88.2M,解压后在三方包目录下有325个jar。

不得不说这个包实在是太大了,里面基本包含wildlfy应用服务器的全部组件。具体的分析我会再写一篇分析文章。

关键的组件版本如下:

  • wildfly-core 2.0.12

  • undertow 1.3.15

  • resteasy 3.0.14

  • jackson 2.5.4

  • hibernate 5.0.7

  • weld 2.3.2

  • h2 1.4

使用java启动进程,启动时间为 3.4秒 左右。

用浏览器访问http://localhost:8080,得到数据

[{"id":1,"name":"Penny"},{"id":2,"name":"Sheldon"},{"id":3,"name":"Amy"},{"id":4,"name":"Leonard"},{"id":5,"name":"Bernadette"},{"id":6,"name":"Raj"},{"id":7,"name":"Howard"},{"id":8,"name":"Priya"}]

使用jmeter压测一边,50000次访问后的两轮的结果为:

R1: Generate Summary Results =  50000 in    10s = 5008.0/s
R2: Generate Summary Results =  50000 in    11s = 4754.7/s

经过几秒等稳定后,观察jconsole中的系统状态:

  • heap: 115M

  • live threads: 184

  • current classes loaded: 14114

分别记录两轮压测性能数据:

Generate Summary Results =  50000 in     4s = 13661.2/s
Generate Summary Results =  50000 in   3.5s = 14476.0/s
Generate Summary Results =  50000 in   3.3s = 14970.1

Generate Summary Results =  50000 in     4s = 13931.5/s
Generate Summary Results =  50000 in     4s = 13954.8/s
Generate Summary Results =  50000 in     4s = 14064.7/s

每次测试heap都会明显增加,在测试过程中,Heap的变化曲线:

Heap - WildflySwarm

手工GC后

  • heap: 29M

  • live threads: 185

  • current classes loaded: 14110

总结

SpringBoot和Widfly-swarm都是极为优秀的项目,在微服务时代来临时,它们让Java程序员利用已有的JavaEE编程知识,快捷高效的开发出健壮稳定的应用。

两个项目的启动时间都在几秒种,而且在普通的笔记本上,能用未经过调优的普通应用环境完成每秒上万个服务请求,性能已经很不错了。而且是较为完整的技术栈,包含页面数据,服务和数据库持久等层。

wildfly-swarm作为后来者,表现令人侧目!

  • 启动时间,

  • 热身测试

  • 正式的应用测试

都比SpringBoot差不多快了一倍。直观的比较图形:

Spring VS WildflySwarm

性能优异的原因我只能从架构上先简单猜测下,等进一步研究后再给出具体分析:

  1. wildfly-core内部MSC内核是异步注入容器,性能非常强劲。

  2. undertow的网络层使用XNIO框架,采用和Netty类似的原理,可能比Tomcat的网络层要高效一些?

  3. 不太确认两者分别在web/服务/JPA等层次是否有缓存,以及缓存的策略。因为我们的测试是不变数据,所以不能反应真实应用场景。

需要说明的是Wildfly-swarm应用的打包文件实在是太大,有些范例要超过150M,微服务不“微”。当然,打包中的jar存放在树形目录module中,也许可以利用docker的文件层次堆叠特性来做一个微服务jar公有仓库,这样每个包就可以很小了。

Java应用占用的内存也较大,不过都在可接受范围之内。需要针对具体的应用进行调优。

非常感谢Wildfly-swarm团队带给我们如此优秀的开源项目! Awesome wildfly-swarm!

JBoss开源应用服务器的最新培训资料

  • Jeff Zhang
  • 12 May 2016

Wildfly 10 and EAP 7

今天 JBoss EAP 7 正式发布了,这是在今年一月份JBoss Wildfly 10发布之后,红帽软件基于Wildfly10正式发布的商业支持的应用服务器产品。

Wildfly 10/EAP 7是同源的实现了JavaEE完整规范的应用服务器,和5年前的JBossAS7/EAP6相比,在性能,可靠性,安全性都有进一步的巨大提升。

以下为一些特色亮点:

  1. Web服务器基于Undertow,是借鉴了Nginx的设计思路,用Java实现的事件驱动的Web引擎。采用NIO为网络底层实现机制,同时支持非阻塞和阻塞IO模型,目前已经对Websocket和HTTP/2都有优秀支持。

  2. 基于Wildfly-core核心服务器,JavaEE规范实现代码和应用服务器核心代码很好的分离,对于其他项目,wildfly-core提供了一个坚实的基础服务器架构。

  3. 提供servlet容器的发布包,方便开发人员开发和部署基于Servlet的应用,而不需要部署在完整的JavaEE应用服务器之上。

  4. 重新构建安全基础架构,使用Wildfly-elytron作为核心。

  5. 服务器挂起和优雅停机方案,极大的改进了可用性。

  6. 基本安装对外端口减少为两个:应用端口和管理端口,适应云端的需求。

  7. 管理界面,cli控制台的加强和改进。

  8. 集群能力的提升

培训课程

庆祝JBoss应用服务器新版本的诞生,我们的应用服务器培训课程也进行了范围扩展和内容更新,主要分为以下几大部分:

1. JavaEE规范(I)

  • 1.1 整体综述

  • 1.2 Servlet/JSP/MVC

  • 1.3 JaxRS

  • 1.4 JaxWS

  • 1.5 Websocket

  • 1.6 JPA/JDBC

  • 1.7 事务

  • 1.8 JMS

  • 1.9 BV

2. JavaEE规范(II)

  • 2.1 EJB

  • 2.2 CDI

  • 2.3 JNDI

  • 2.4 安全

  • 2.5 JSF

  • 2.6 Concurrency和规范中的异步改进

  • 2.7 JCA和集成

  • 2.8 JCache

  • 2.9 JBatch

3. Wildfly-core核心部分

  • 3.1 JBossModule

  • 3.2 MSC

  • 3.3 控制器和管理接口

  • 3.4 Server以及服务器启动过程分析

  • 3.5 部署框架以及war/ear部署过程

  • 3.6 子系统,挂接到服务器上和开发自己的子系统

  • 3.7 域模式

  • 3.8 WebConsole开发原理和扩展方式

  • 3.9 JBossThread,线程池调优

  • 3.10 XNIO和JBossRemoting

  • 3.11 安全基础模块

  • 3.12 JBossLogging框架和系统对中文的支持

  • 3.13 服务器调优和GC/Heap分析

4. Wildfly应用服务器实现部分(上游项目和集成)

  • 4.1 服务器整体分析

  • 4.2 数据连接池实现分析和调优,JCA上游项目Ironacamar

  • 4.3 Undertow,Web容器实现,对Websocket和HTTP/2支持

  • 4.4 集群和容错能力分析,上游项目Infinispan和mod_cluster

  • 4.5 NamingServer的实现分析

  • 4.6 Resteasy,Rest实现

  • 4.7 Hibernate,JPA规范实现

  • 4.8 Weld,CDI规范和Spring框架比较性分析

  • 4.9 ActiveMQ,JMS实现

  • 4.10 CXF,Webservice实现

  • 4.11 EJB3规范的实现分析

  • 4.12 Narayana事务能力的支持

  • 4.13 PicketBox和BouncyCastle安全方面的实现

这次更新后的培训内容更加全面的覆盖了基于JavaEE应用服务器的整体架构和各个技术规范的知识点,对于项目的技术选型,设计,开发,部署,都会有极大的参考价值。

JBossAS7时,我们是一个团队,如今虽然有一些成员离开,但有更多开发人员加入。社区依然活跃,开源精神指引着技术前方的道路!

培训材料演示文件地址

如何给Wildfly提交PR

  • Jeff Zhang
  • 18 July 2015

我经常听到一些朋友说很难给JBoss开源社区提交代码,事实上的确如此,带有redhat或者jboss的邮件地址的贡献者会有优势,但代码质量和补丁描述才是最关键的。开源社区也有不同的文化,JBoss属于相对紧凑型的,简单来说开源贡献者需要适应JBoss的一些约定和规则。

这篇文章是前几天David M.Lloyd发到wildfly邮件列表的。原文在此 http://lists.jboss.org/pipermail/wildfly-dev/2015-July/004243.html

David目前是wildfly的总架构师,可以说从AS7以后的JBoss应用服务器产品的基本架构是他奠定的。David在多个项目上都体现出超凡的能力,如JBossRemoting, JBossLogging, XNIO, MSC, JBossModule等等。

这篇文章是难得的好文,指点如何给JBoss社区提交PR,包含一些规则和窍门。我把它翻译过来供大家参考。同时也是给其他开源社区贡献的参考资料。

如何给Wildfly提交PR(PullRequest)

自从代码管理迁移到Git以来,以及采用了审查为导向的贡献体系(contribution structure),对于wildfly和相关的开源项目,我们都已经看到了巨大的提高,包括质量和数量方面。然而,尽管我们已经写了很多文档,包括如何获取源码,进行修改,使用git创建分支,提交PR等等。但还没有讨论过如何比较标准的进行实际构建(actually build)和结构化PR请求(structure pull requests),这就是写这篇文章的目的。

有几个做这件事的原因:

首先,审查者人数现在很少。这样有几个不好的效果:

  • PR在审查队列中周期很长

  • 巨型PR获得的审查机会比小的PR还少

  • PR得到的审查质量及其不稳定

其次,我们看到各种有问题的RP请求,比如单一大文件无法审查的PR,成千小文件PR,混合了表单和函数各种功能改进的PR,还有一些隐蔽的情况,你如提交之间让编译失败的PR。

第三,项目已经发展到了一定的规模和范围,我们需要有更多的人手盯紧每一个变化-实际只能做到尽可能多的。

为此,借用Linux内核项目文档[1]中的一些概念,来制定以下的PR标准。 (关于如何开始给wildfly贡献代码,黑客指导(the hacking guide)[2]依然是最好的文档)

Wildfly贡献和提交PR标准

我们为wildfly和相关子项目,制定一些重要git提交的规则和准则。但不是完整的git教程,因为那样会超出本文的范围。

1) 充分的描述PR请求内容 描述应当包括JIRA编号,从而可以找到相关的相关的问题描述。描述语句恰当的,用人类易读的语言总结修改的内容。正确的拼写和语法是加分项。

2) 首先要保证编译和测试通过

当审查者花了大量时间去审查代码,发现其甚至不能编译时,他们会很恼火。经常会看到提交patch来通过checkstyle代码格式检验。 有时我们会依赖自动化的CI/GitHub功能来进行编译和测试。但这样通常会带来麻烦,所以不要这样做!

3) 分解变更内容—​但也不要分的太多

直接引用[1],我百分之百同意:

“将每个变化逻辑(logical change)划分为一个单独的补丁

“例如,如果你的改动是为一个驱动程序所写,包括bug修复和性能增强,那么划分为两个或者以上的补丁。如果改动包括API更新,及使用新API的驱动,划分为两个补丁。

“另一方面,如果你一次修改动了大量的文件,那么把这些改动划分在一起,这样一个补丁中包含逻辑变化所有修改。

“关键要记住,每个补丁应当让审查者很容易理解和验证。每个补丁的作用正当有理。

“一个补丁依赖于另一个补丁来保证完整性是可以的,需要在提交时注明‘这个补丁依赖于补丁X’。

“当你划分修改为一系列补丁,要特别注意确保wildfly可以在每个补丁后可以正确的编译和运行。有时开发者使用’git bisect’来追查问题,到你的一系列提交时没法继续时,他们可能会骂娘。

我想强调区分“功能”和“非功能”的改变非常重要,后一类包括格式化工作(建议没有必要的原因就不要做)

4) 避免大规模的分支和/或意识流"stream of consciousness"分支

我们知道开发是一个反复迭代的过程。尽管如此,我们并不需要记录完整的历史(比如在一次PR中先有"add foobar"紧跟着"remove foobar")。特别是对于大的变化或者大的项目(如wildfly)。一个好的实践是提交者重新审视提交,重新排列和结构化提交改变,只包含对于主干增量变化。

如果PR包含上百个普通提交,那么强烈建议分割成多个PR,每个PR的大小方便进行高效审查。如果太大了,审查者要么是没有进行足够的审查就匆忙合并,要么就忽略掉甚至直接关掉。你可以设想哪种情况更糟糕。

5) 重视和响应审查意见

虽然是我的经验,但wildfly贡献者都赞成这点。我直接引用[1]的内容

“你的补丁几乎肯定能得到来自审查者的意见,告知如何改善,你比如回应这些意见,忽略意见的结果一般就是PR被忽略。

“一定要告诉审查者你做的修改,并感谢他们投入的时间。代码审查是一项累人费时的过程,审查者有时会脾气暴躁。即便如此,也要礼貌和解决他们指出的问题”

此外,当需要进行修改时,正确的方式是修改原始提交,而不是在其之上进行添加。参考(4)内容。

6) 不要气馁

在PR接受前,多次迭代提交是很正常的,它总有机会通过审查。不要气馁—​反而这是好的现象,说明审查者高度关注代码库质量。同时,也要考虑审查者已经一遍遍反复说了同样提交意见,所以也请关怀他们,尽可能高质量提交,参考(5)。

7) 你也可以审查代码!

你不必成为正式的审查者,也可以审查PR。如果看到熟悉的领域,尽管去检验和进行注解来帮助评审。另外,所有的PR都需要进行基本审查保证非机器检验的正确性,如注意到糟糕的代码,NPE风险和运用反模式,还有无聊的拼写,语法和文档。

8) 针对重大重构

当遇到重大和长期重构时,上述限制变得不切实际,尤其是划分变化。这时,你可以使用一个工作分支来应用上述的规则。同时可以也提交给审查者。周期性的一段时间后,合并提交到上游分支上。

运用这种方式,当长期分支准备合并到主干“回家”时,审查者已经对大多数改变进行过评审,从而更容易通过。

北京JBoss User Group活动,JBoss社区迎接微服务

  • Jeff Zhang
  • 10 June 2015

6月10日晚上,在融科红帽研发中心办公室,举办了JBug 2015年第一次活动。主管JBoss应用服务器部门的Bruno做了主题演讲。Jim Ma 和我分别做了JBoss相关产品和项目在微服务设计的分享。 活动连接

wildfly swarm是一个最新的项目,借鉴了SpringBoot的优秀思路,利用wildfly-core和wildfly,可以快速编写符合微服务思路的应用程序。目前wildfly-swarm还在积极开发中。

这里是演示文档。

永源中间件完整拼图

  • Jeff Zhang
  • 31 May 2015

永源中间件课程设计的目标是完整的中间件开发体系,以Java为主力语言,配合JavaScript, Go, Ruby等语言发挥各自领域的优势。 目前已经推出四批共25门课程,还有7门正在设计中,欢迎软件领域朋友们参与和帮助完善。

Useopen Training

永源中间件第四批课程

  • Jeff Zhang
  • 30 May 2015

我们推出了第四批课程。包括:Glassfish应用服务器分析;Vertx3开发框架快速开发异步高并发应用;测试相关开源软件的使用;业务流程管理的定义和开源项目使用;移动后端服务的使用。欢迎大家关注并多提出宝贵意见。

第三批课程共5门:

Glassfish

Glassfish是JavaEE的参考实现,尽管Oracle不再提供商业服务支持,但良好的架构设计值得学习,payara是一个延伸出来有商业支持的产品。深入讲解Glassfish应用服务器核心技术,源码级分析,有助于开发/部署/和从Weblogic进行迁移。 授课时长 1-2天

  • 基础
  • 核心技术
  • 管理控制
  • 功能特性

Vertx3

Vertx 3经过重新设计和开发,利用Java8的函数式能力焕然一新。Vertx借鉴NodeJS的设计思路,充分发挥了Netty网络框架的威力,目前异步高并发,移动应用越来越多,Vertx的能力会得到充分发挥。 授课时长 1-2天

  • 基础
  • 核心模块
  • web模块
  • 功能特性

Testing

测试是开发过程中及其重要一环,软件的测试有单元测试,集成测试,回归测试等等。持续测试通过是保证软件质量的重要方法 授课时长 1-2天

  • JUnit
  • Mockito
  • Arquillian
  • JMeter
  • Cucumber

BPM

业务流程管理(工作流)系统是企业软件开发过程中经常用到功能。商业过程需要多个业务人员,多种角色协同工作。如果对商业过程进行建模,已经用软件有效管理,成为企业管理软件的重要目标。 授课时长 2-3天

  • BPMN
  • jBPM
  • Activiti

MBaas

移动时代到来,开发手机APP需要和后台服务进行交互,面向移动应用的后端服务可以帮助开发者,快速开发和部署移动应用。 授课时长 1-2天

  • MBaas
  • Usergrid
  • AeroGear Push

永源中间件第三批课程

  • Jeff Zhang
  • 31 March 2015

我们推出了第三批课程。包括一门基础课程:DDD领域驱动设计。以及JavaEE范围内的命名服务和配置服务,安全(主要是认证和授权),以及JSF和GWT的课程。另外有针对日志和搜索的课程,构建和持续交付课程。还有一门是企业应用中经常用到的ESB。欢迎大家关注并多提出宝贵意见。

到现在已经公布了共20门课程,这些课程已经可以较完整覆盖了中间件开发领域技术,特别是和JavaEE相关。接下来我们会深化细化这些课程内容,和广大开源爱好者共同学习和提高。

第三批课程共7门:

Domain Driven Design

讲解领域驱动设计的概念,实现方法。DDD领域驱动设计是目前企业应用设计的最佳方法,经过10多年体系知识的不断完善和编程语言的改进适配,如今已经可以很有效的指导复杂的企业应用的设计开发过程。本课程同时对CQRS(命令查询职责分离模式),DCI(数据Data 场景Context 交互Interactions)等相关知识进行讲述。 授课时长 2-3天

  • DDD Overview
  • DDD concept
  • Domain Events
  • DCI
  • DDD Projects

Naming & Configuration

设计简单的应用程序,也需要分析处理配置文件,运行时状态可以注册到命名服务中,供其他程序使用。在当前云计算化趋势下,配置和命名服务的集中管理变得非常重要。本课程就围绕相关概念和开源项目,分析和讲述 授课时长 1-2天

  • JNDI
  • Configuration
  • ZooKeeper

JavaEE Security

安全是企业软件的重要组成部分,尤其在云计算时代,软件系统安全是需要重点关注的问题。认证和授权部分是企业软件开发中最主要的两个部分 授课时长 1-2天

  • JavaEE Security
  • JBoss Security Projects
  • Apache Shiro
  • Spring Security

JSF & AngularJS

JSF是目前JavaEE的表示层技术,在企业软件中大量使用,但不被广大开发者熟悉。本课程讲解JSF的内容,并分析如何同其他JavaEE技术如CDI结合使用。 AngularJS是Google出品的基于JavaScript的前端框架。 GWT是Google出品的Java语言转成JavaScript在浏览器展现的优秀项目 授课时长 1.5-2天

  • JSF
  • JSF Projects
  • AngularJS
  • GWT

Logging & Searching

记录系统日志是企业软件必不可少的功能,是查找问题,分析排错的主要方式,也是大数据信息的主要来源。如何高效的记录和分析日志已经成为企业互联网应用的重点之一。海量信息通过搜索的方式查询,企业数据也有搜索引擎。 授课时长 1-2天

  • Logging
  • 集中式的日志
  • Searching

Building & Continuous Delivery

软件应用的设计开发周期越来越紧迫,系统交付需要一种可控的方式管理。软件代码编写后,如何进行构建,测试,发布,业界有一套实践可行的方案。 授课时长 1-2天

  • Building
  • Continuous Delivery

ESB

企业在运营中产生各种信息,如何通过软件平台传输,共享这些数据。ESB(Enterprise Service Bus)企业服务总线是一类产品的统称。可以方便的抽取企业信息,进行转换,处理,过滤后发布成webservice,供其他应用使用。 授课时长 1.5-2天

  • EIP
  • JBoss Fuse Service Work
  • JBoss Fuse ESB
  • Spring Integration

RPC框架性能基本比较测试

  • Jeff Zhang
  • 21 March 2015

gRPC是Google最近公布的开源软件,基于最新的HTTP2.0协议,并支持常见的众多编程语言。 我们知道HTTP2.0是基于二进制的HTTP协议升级版本,目前各大浏览器都在快马加鞭的加以支持。 我们可以设想一下,未来浏览器支持HTTP2.0,并通过现有开源序列化库比如protobuf等,可以直接和各种语言的服务进行高效交互,这将是多么“美好”的场景!

gPRC的Java实现底层网络库是Netty,而且是用到最新的Netty5.0.0.Alpha3的开发版本,因为最新版本针对HTTP/2做了很多改进。 为了跨语言,gPRC也和其他方案一样,采用了类似古老IDL的接口描述语言,利用自家的Protobuf项目带的protoc编译器来生成框架代码。这和目前最流行的Facebook开源的,现为Apache顶级项目的Thrift原理一致。

我比较好奇,这个新出世的框架的性能怎么样,和现有的RPC开源方案比较如何。就花了一些时间进行简单比较。 我选择了以下五种开源项目进行测试:gRPC, Thrift, Wildfly, Dubbo, JBoss EAP。 为了简化,测试范例都使用项目自带的demo或者sample等进行简单修改,使得跨进程网络调用次数一致。

gRPC https://github.com/grpc/grpc

  1. 从Github master主干上获得最新版本,按照说明文件进行编译。如上所述,网络框架是Netty5,基于最新的HTTP/2.

  2. 测试例子为 RouteGuideClient

  3. IDL为 route_guide.proto

  4. 选择其中getFeature方法,去除不用的语句和屏幕输出,进行10,000次同步调用。

TestClientSync client = new TestClientSync("localhost", 8980);
try {
  final long startTime = System.nanoTime();

  for (int i = 0; i < 10000; i++)
    client.getFeature(409146138, -746188906);

  final long endTime = System.nanoTime();
  info("method 1 : " + (endTime - startTime));
}
public void getFeature(int lat, int lon) {
  try {
    Point request = Point.newBuilder().setLatitude(lat).setLongitude(lon).build();
    Feature feature = blockingStub.getFeature(request);
  } catch (RuntimeException e) {
    logger.log(Level.WARNING, "RPC failed", e);
    throw e;
  }
}

多次执行,记录需要的时间。

gRPC还有一种非阻塞的调用方法,不过因为时间有限,为了简化测试,我只用标准的server启动的方式,asyncStub在大并发访问时出错,用时也较长,故这次测试没有这种方法的结果数据。

Thrift http://thrift.apache.org

  1. 从Apache网站获得最新的0.9.2版本,本机编译获得C的编译器和Java运行环境。

  2. 测试例子为 JavaClient.java

  3. IDL tutorial.thrift

int diff;
final long startTime = System.nanoTime();
try {
  for (int i = 0; i < 10000; i++)
     diff = client.calculate(1, work);
} catch (InvalidOperation io) {
  System.out.println("Invalid operation: " + io.why);
}
final long endTime = System.nanoTime();
System.out.println("method 1 : " + (endTime - startTime));

Thrift采用经典的基于网络端口的RPC,效率最高,在最后的总结数据可以看到。

Wildfly 8.2.0 http://www.wildfly.org

Wildfly是JBossAS改名后的JBoss应用服务器,实现了完整的JavaEE规范。我们知道JavaEE中远程RPC调用是在EJB规范中定义的。我们这里就是要测试Wildlfy中的远程EJB调用能力,

  1. 选用的Wildfly8.2是目前发布的最新稳定版本。这个版本也支持端口多路服用,也就是EJB远程调用是通过HTTP端口复用来进行的,利用HTTP的Upgrade机制做到二进制运行时刻协商升级。尽管不是纯粹的HTTP/2,但也运行机理也相差无几。

  2. 测试例子选用jboss-eap-quickstarts项目中的远程ejb调用例子 RemoteEJBClient.java

  3. 纯Java的RPC方案好处是不需要再有IDL文件定义和编译生成代码的过程,只要商议好接口就可以了

public interface RemoteCalculator {
    int add(int a, int b);
}
int sum=0;
final long startTime = System.nanoTime();

for (int i = 0; i < 10000; i++) {
         sum = statelessRemoteCalculator.add(a, b);
}

final long endTime = System.nanoTime();
System.out.println("method 1 : " + (endTime - startTime));

调用无状态的SessionBean方法10,000次,对应的远程EJB服务是部署在Wildfly应用服务器中的EJB。

Dubbo 2.5.4-SNAPSHOT https://github.com/alibaba/dubbo

Dubbo是阿里集团开源的一个极为成员的RPC框架,在很多互联网公司和企业应用中广泛使用。协议和序列化框架都可以插拔是及其鲜明的特色。同样的远程接口是基于Java Interface,并且依托于spring框架方便开发。可以方便的打包成单一文件,独立进程运行,和现在的微服务概念一致。

  1. 采用github中master主干,目前版本是 2.5.4-SNAPSHOT

  2. 测试例子选用其中的demo进行修改 DemoAction.java

public interface DemoService {
	String sayHello(String name);
}
final long startTime = System.nanoTime();

for (int i = 0; i < 10000; i ++) {
    try {
    	String hello = demoService.sayHello("world" + i);
    } catch (Exception e) {
        e.printStackTrace();
    }
}
final long endTime = System.nanoTime();
System.out.println("method 1 : " + (endTime - startTime));

调用完毕后查看输入log文件获得运行时间。

EAP是JBossAS的商业版本,实现了完整的JavaEE规范。

  1. EAP6基于AS7.2以后的版本构建,红帽提供商业支持。

  2. AS7在7.2以后,社区版没有再发布,具备能力的企业可以从源码进行编译使用,EAP6.3基于AS7.4分支构建,很快发布的EAP6.4基于AS7.5分支构建,不出意外这个会是最后一个EAP6的minor版本。

  3. AS7还没有像Wildfly完全采用端口复用的方式,短程EJB调用通过独立端口完成,基于JBossRemoting3的网络连接管理能力。

  4. 测试例子依然选用jboss-eap-quickstarts项目中的远程ejb调用例子

public interface RemoteCalculator {
    int add(int a, int b);
}

记录一万次调用后的时长。

数据结果。

最终经过4轮测试,不间断运行10,000次远程RPC调用后的结果如下:

RPC benchmark

我们可以看到Thrift的效率最高,大概领先一个数量级。而其他三个项目的性能数据在同数量级中,由高到低分别为JBossEAP, dubbo, wildfly和gRPC。

需要说明的有以下几点:

  1. 为了简化测试,我并没有选择同样的调用接口,而是顺手用了项目自带的,方便修改的示例程序。其中gRPC和Thrift的接口有对象传递,稍微复杂一些。

  2. 不是严格的性能测试流程,比如没有做预热过程,以及测试都运行在我的桌面用机上,没有完全恢复成“干净”的状态。

  3. 都是简单的服务器单一进程实例,标准示范例子,没有做特别优化和设置多个线程池之类的。而客户端调用也是最简单的阻塞式多次调用压力测试。应该是用多个机器多连接,多个线程,以及异步非阻塞的调用多种环境进行测试更为客观,有机会再继续完善。

  4. 之前没有看到过基于HTTP/2的RPC调用性能比较,理论上是应该低于经典的基于端口的RPC方案的。这个测试结果可以简单印证这个猜想。Thrift的数据遥遥领先.gRPC还在开发之中,基于的Netty还是alpha版本,而且非阻塞的方式还没有最后的数据。我想耐心一些,给gRPC一些时间,它会让我们惊艳的。

  5. Wildfly表现良好,要知道它的服务端可是完整的JavaEE服务器啊。不过有时间的化,我试试看经典RMI连接的效率如何,要是能和thrift一个数量级就更好了。

  6. dubbo性能也很出色,而且协议层可以更换的话,应该还能有更大提升。

  7. 我的测试在一台过时的笔记本上,受条件限制,没有先进的G级网络和多台服务器进行标准化性能测试。如果哪位在互联网或者企业工作的朋友有条件,也愿意充分完成这个测试,请和我联系,我会完整介绍我的测试搭建环境,共享代码,并帮助完成。我想那个结果会更有意义。

补记

  1. 最初四个测试时间为2015-03-11,03-21加入EAP6.3.2的测试,为基于JBossRemoting的EJB远程调用测试,性能良好。和thrift进入一个数量级,EJB功能可是很丰富的,带有事务,安全等高级企业级组件特性。

  2. Wildfly8经过配置后使用和EAP类似的远程调用选项,效率和EAP应该是一致的。

永源中间件第二批课程

  • Jeff Zhang
  • 18 March 2015

我们推出了第二批课程。包括互联网应用常用的服务:消息中间件和缓存中间件的课程。三门基础课程:线程/集合,NIO,RPC。以及经典的WebService,讲述SOA思想和JaxWS。欢迎大家关注并多提出宝贵意见。

第二批课程共6门:

Message & JMS

讲解消息机制和设计原则,消息提供的排队机制是处理高并发的基本方式。学习JMS规范API接口,并深入分析常见JMS服务器实现HornetQ, ActiveMQ,以及AMQP协议介绍和QPid实现分析。 授课时长 1.5-3天

  • 消息系统设计
  • JMS API
  • HornetQ
  • ActiveMQ
  • 消息文本接口

Cache

讲解缓存机制和设计原则,缓存是解决大容量并发访问的利器。企业开发逐步面向互联网和移动用户,缓存技术成为企业应用开发中重要角色,JCache将成为JavaEE规范成员。 授课时长 1-2天

  • 缓存设计
  • Infinispan
  • Hazelcast

Thread & Collection

讲解各种集合类型的特点,多线程编程,并发和并行等常见基础问题,为整个中间件体系的学习打下坚实基础。 授课时长 1-2天

  • Thread
  • Collection
  • Stream

Socket & NIO

讲解Java中网络编程的高级知识,各种异步通信框架,为整个中间件体系的学习打下坚实基础。 授课时长 1-2天

  • Socket & NIO
  • Netty
  • RxJava

RPC

讲解RPC远程调用的编程知识和各种RPC框架,针对不同的应用场景选择适当的技术实现。 授课时长 1-2天

  • RPC
  • Thrift
  • Dubbo
  • gRPC

WebService & JaxWS

讲解Webservice的重要知识点和JavaEE中JaxWS规范,并对开源项目CXF进行深入分析。 授课时长 1-2天

  • WebSerice
  • JaxWS
  • Apache CXF

你好,永源中间件

  • Jeff Zhang
  • 08 March 2015

经过多年的软件开发和对软件知识的消化,整理出一套中间件体系课程,和企业软件和互联网应用开发有密切关系。

其中包括:重点基础,JavaEE,Microservice,ApplicationServer,Enterprise,BigData,Cloud,Mobile等多个知识领域,每个领域包含若干门课程。

课程的知识点通过解答技术解决问题的本质提炼得出,辅助以当前最优秀开源软件进行技术讲解。

面向企业技术团队中高级技术人员授课,可以选择某一个领域一门课程,也可以根据企业需求进行定制。希望这套课程经过不断完善演进,成为世界级优秀的中间件技术课程。

目前推出第一批课程共7门:

Servlet & Web Container

讲解Web开发中最经典的Servlet技术,MVC设计模式,并深入分析常用Web容器 授课时长 2-3天

  • Servlet3 结构优美的框架
  • JSP & EL
  • MVC Framework
  • Tomcat
  • Jetty
  • Undertow
  • WebSocket

DI/CDI & EJB

开发者需要掌握面向对象开发模式,Ioc框架可以减化编程,便于测试。DI/CDI和EJB都是规范化的技术 授课时长 2-4天

  • Ioc框架
  • EJB
  • CDI
  • AOP

JPA Persistent

讲解持久层常用技术,如何进行对象和关系数据库映射,介绍当前对Nosql的主要技术 授课时长 2-3天

  • JDBC
  • JPA
  • Hibenate
  • 事务
  • JCA
  • Spring Data

Rest & JaxRS

讲解Restful网络服务接口设计方式,Java JaxRS规范内容,以及实现项目代码分析 授课时长 1.5-3天

  • Restful
  • JaxRS
  • JaxRS常用实现

SpringFramework

讲解经典Spring框架的设计原理和特性分析,SpringMVC是目前最有代表性的MVC框架 授课时长 2-3天

  • Ioc/DI
  • 核心特性
  • SpringMVC

SpringBoot & SpringCloud

适应微服务时代,优秀项目SpringBoot和SpringCloud的组合使用,更适应云计算平台和互联网应用 授课时长 1-2天

  • SpringBoot
  • SpringCloud
  • MicroService

JBossAS & Wildfly

深入讲解JBoss应用服务器核心技术,源码级分析,无论针对AS7,Wildfly和JBossEAP6都适用。帮助企业更好的理解JBoss开源应用服务器的特性,有助于开发/部署/迁移过程。 授课时长 2-3天

  • 核心技术
  • 功能特性
  • 高级特性