Java生态系统总结(QCon2019)

QCon是由InfoQ主办的综合性技术盛会, 19年5月6-8日为北京站,会议包含众多领域的前沿技术及实践,如云安全,机器学习,人工智能,大数据,前端,服务架构,数据存储,容器等。
其中着重介绍了前端前沿技术,包括重提了RTC(用于Browser的Audio, Video), AR, VR, 3D,WebGL, GPU, PipeLine, 机器学习及深度学习在前端的应用,流媒体解决方案,W3C标准趋势等,前端开发人员可着重了解下。
本文针对Java生态系统(会议内容分四部分: Jakarta EE和MicroProfile的明天会怎样、Java容器化部署-从应用服务器到云原生、Seata在微服务一致性中的探索、Shenandoah:Your Next Garbage Collector)前三部分进行总结,包含会议内容及个人理解。

Jakarta EE和MicroProfile的明天会怎样

本章主要介绍MicroProfile,如何使用MicroProfile构建MicroService, 简单提了下Jakarta EE,一笔带过ServiceMesh, Istio, Agile, DevOps, Cloud等。

云原生微服务(cloud-native microservice)特性(基本要求)

①无状态(如RestFul),可动态伸缩服务节点。
②可配置,动态更新配置可提供不同服务,即服务做成开关的形式。
③容错性,出现不可预料的问题后,也可提供服务。
④安全,只要部署到外网提供服务,安全问题是一定要考虑的,配置服务对哪些外部(哪些服务、ip或用户)提供服务。
⑤监控,服务运行状态可实时查看,服务间调用可追踪。
⑥服务与云基础设施通信,即服务主动或被动通知运行状况到所在机器,可类比为Zookeeper监控每个服务运行状态,也可类比为kubernetes probe。

MicroProfile版本简介

①MicroProfile 1.0
基础构件包含CDI 1.2、JAX-RS 2.0、JSON-P 1.0
②MicroProfile 2.2(19年2月)
相比1.0, 有21 Component Releases,除了CDI等组件升级,新增Metrics、JWT等组件。

MicroProfile组件

MicroService可实现如下MicroProfile规范的组件

  • JAX-RS:Java API for RESTful Web Services,是JAVA EE6引入的新技术
  • CDI(content and dependency injection): 思想类似Spring DI, 如CDI的@Inject同Spring的@Autowired
  • JSON-P(JSON with Padding):核心原理就是目标页面回调本地页面的方法, 并带入参数。利用script标签不受浏览器同源安全限制((不可跨域访问服务器及cookie, js脚本不受跨域限制)
  • JSON-B: 提供序列化和反序列化Java类到Json,类似Gson
  • JWT Propagation(json web token): token安全通信的规范
  • OpenAPI: 类似swagger
  • Fault Tolerance:容错处理, 如@Retry注解,异常出现再次请求
  • Config: 配置可放到程序之外,功能类似Ctrip Apollo或SpringClud Config
  • Health:定义服务健康状态
  • Metrics:运行监控
  • Open Tracing:服务调用链路追踪,功能类似istio中的jeager
  • Rest Client

Start MicroProfile

MicroProfile在线创建, 类似springboot在线创建方式。
官网搜索MicroProfile,可找到相关学习资源。

Java EE -> Jakarta EE

Oracle开源了Java EE, 并将项目移交给Eclipse基金会,重命名为Jakarta EE。

Java容器化部署-从应用服务器到云原生

应用服务器

微服务架构比对

仅比对如下三种:过时的Corba, 业界准标准的gRPC, 国内热门的Dubbo

Corba gRPC Dubbo
多种语言 Java
接口定义 IDL IDL Java Interface
协议 IIOP Protobuf/Http2 dubbo等多种
异步响应式 callBack stream callBack
服务治理 - -

前后端交互演变

浏览器和前端技术的发展, 推动架构演变,大致分为如下5个阶段。
1.传统Client-Server
qc_architecture1_cs
2.J2EE
qc_architecture2_j2ee
3.JavaEE with Spring
qc_architecture3_j2ee_spring
4.JS框架和REST
qc_architecture4_js_rest
5.Micoservice架构
qc_architecture5_microservice

上述5个阶段Java部署架构比对如下

部署包 是否可执行 应用服务器容器 说明
CS 独立服务器jar - 客户端维持状态
J2EE ear,war,jar - Servlet/EJB 分布对象的争议
SpringWeb war - Servlet MVC模式
JS/Rest war - Servlet 异步响应式
Java微服务 war or jar 可选 三个维度划分

Spring Framework与J2EE区别

SpringFramework基于Java EE, 依赖注入框架,集成各种技术库。

Java EE Spring Framework
依赖注入 CDI IOC Container
AOP Intercepter Spring AOP
Persistence JPA JPA, JDBC, SpringData
Transaction JTA, EJB JTA, JDBC, JPA
Rest JAxRs SpringMvc
Messaging JMS, EJB Spring Messaging, JMS
Security JavaEE Security, EJB, Servlet Spring Security

应用服务器状态信息处理

Java复制状态信息,适用于节点较少的集群服务,节点太多时,限制在了复制状态数据后的网络传输,状态数据包含Servlet的session、有状态的Session Bean、Hibernate 缓存、Wildfly利用Infinispan、JVM的状态缓存。
较多节点的集群服务,互联网产品采用引入Redis等来解决各节点状态共享问题。

微服务要考虑的因素

提到应用最广的SpringBoot框架,自然想到SpringCloud,SpringCloud与MicroProflie部分组件比对如下。

微服务要素 Spring Cloud MicroProfile
配置管理 Confg server Config
服务发现 Eureka (JavaEE naming)
负载均衡 Ribbon (By Application Server)
性能指标 SpringBoot Actuator Metrics, health
分布式追踪 Spring Cloud Sleuth Opentracing
故障容错 Hystrix Fault-tolerance
路由和拦截器 Zuul (JavaEE Sevlet, Interceptor)

Java微服务

以Spring微服务举例

  • JDK + SpringBoot + SpringCloud + 各种三方库
  • Jar包非常大
  • 启动时,需要相关服务就绪

SpringCloud虽然集成了许多框架,产品线齐全,但是相比JavaEE或单个SpringBoot应用,SpringCloud每个服务的java包很大,并且内存占用很大,启动时间也较长。

云原生

应用容器化部署

应用开发及部署需遵守如下规范

  • 受容器管控
  • 向容器设施申请资源
  • 提供全局管理功能
  • 平台提供接口,方便应用开发

应用服务器可看成单个域,实际最多管理两位数应用,而云原生(如Kubernetes容器编排)可管理大规模集群。

容器化组件

概念比对

容器 JavaEE应用服务器 Docker and Kubernetes
无状态组件 Managed Bean, Stateless EJB Pods
有状态组件 Servlet Session, Stateful EJB Stateful Set
任务 Scheduled Bean Job, CronJob
主控和任务节点 DomainController, Node Master, Worker Node
控制器 Controller Controller Manage
服务群组 Server groups Label selector
扩展性 Extension CustomResourceDefinitions

Java是否适合云原生

1.函数化:jdk8之后提供了Function,Spring也有Function框架
2.启动速度:jdk AppCDS(Application Class-Data Sharing), 使加载的类可被dump出,即写在硬盘之上,启动时无需动态加载
3.容器镜像大小: java9之后支持模块化,也可以通过Jlink工具,只提取必须的Pod,部署jdk占用空间及Modules文件大幅度减小。使用更小的镜像源,如OpenJDK Slim(FROM debian:sketch-slim)替换为Alpine(FROM alpine:3.9)
4.占用内存大小: 优化java应用类加载; java程序静态化,函数化

性能比较

Rest数据服务

方式 SpringBoot jar包 Quickus JVM Quarkus native
大小 16.7M 49.5k 20M
含libs总体积 16.7M 9.8M 20M
启动时长 1850ms 530ms 10ms
占用内存(RSS) 264M 117M 13.7M
说明 SpringBoot2.1.4 Tomcat9 Quarkus0.14 JDK8 Quarkus0.14

启动时长与占用内存比对

Wildfly Full Spring War SpringBoot Quarkus JVM Quarkus Native
启动时长(ms) 4500 1800 1850 530 10
占用内存(MB) 461 287 264 117 14

容器化部署技术选择

根据如下情况选择合适架构

  • 用户规模,访问频次
  • 组件状态和事务要求
  • 运维团队和技能
  • 云计算设施情况
  • Java和其他语言以及相关技术栈的熟悉程度

其他简介

①ServiceMesh提供服务治理功能,业务组件专注逻辑实现。
②Knative(简介参考)是谷歌开源的serverless架构方案,基于Kubernetes平台,旨在提供一套简单易用的serverless方案,把serverless标准化。
Knative将开发云原生应用在三个领域(如下组成)的最佳实践结合起来。

  • Build(构建容器函数)
  • Serving(为工作负载提供服务和动态扩展)
  • Event(事件)

③Quarkus的核心技术及组件,使用方式,构建过程。

拓展:发布方式比对

蛮力发布->金丝雀(灰度)发布->滚动更新->双服务器组(蓝绿发布),实际使用,基于k8s LB策略的滚动更新就ok的。
A/B测试(基于LB的灰度发布测试, 问题备注),控制唯一自变量,实际测试可考虑这种方式,常用于验证需求是否可行,排查用户群体。
影子测试适用于代码大的重构或者数据库迁移,分别重放生产环境请求到两组测试服务器群,成本太高。

JSeata在微服务一致性中的探索

分布式事务使用现状

抽样数据反映使用状态

  • Message Queue: 48%
  • TCC: 23%
  • XA: 18%
  • Sega: 4%
  • OtherL 7%

常见分布式事务比对

刚性事务

  • 标注分布式事务(2PC/3PC): 缺点为性能差、资源占用时间长、需要实现XA接口

柔性事务

  • 异步确保型:方式包含本地事件表,外部事件表,缺点为侵入性高、依赖可靠事件服务、实时性差、消费失败状态不可逆
  • 纯补偿性:缺点为侵入性高、开发成本高、一致性差
  • TCC:将事务提交分为 Try-Confirm-Cancel 3个操作,缺点为引入性高、开发成本高
  • 最大努力通知:即补单流程,超时未收到Ack或失败则再次通知,缺点为侵入性高、开发成本高、实时性差

Seata(Simple Extensible Autonomous Transaction Architecture)

以上常见分布式事务方式有各种问题,此时Seata应运而生。

简介

Seata是阿里巴巴开源的分布式事务中间件,以高效并且对业务0侵入的方式,解决微服务场景下面临的分布式事务问题。
参考链接1, 参考链接2

前期技术积累:TXC、GTS、XTS。
愿景:像使用本地事务一样使用分布式事务。
qc_architecture1_cs
单体应用转换为微服务应用,使用seata后,事务注解由 @Transactional 替换为 @GlobalTransactional

Seata支持的RPC及资源

RPC:Dubbo、Spring Cloud、Motan和自定义的RPC框架。
资源:Mysql、Oracle、PostgreSql、H2、RDS系列等数据库、MQ、NoSql、XA、用户自定义类型资源。

原理

一个分布式事务是由若干本地事务分支组成
qc_architecture1_cs

qc_architecture1_cs

qc_architecture1_cs

qc_architecture1_cs

qc_architecture1_cs

其他

近三年qcon演讲ppt下载
qconsh2017
qconsh2018
qconsh2019