云原生的进一步具象化

alicloudnative阅读(56)评论(0)

本文转载自公众号:HelloJava。

云原生这个概念已经越来越深入人心,但对“云原生到底是什么?”这个问题,仍然是各种各样的解读,最近对云原生具体是什么有了点感触,于是写下来分享和探讨下。

我现在认为云原生其实是让众多的公司,通过基于云的产品迅速获得在构建一个现在这个时代的应用(是不是有点像 AWS 一直讲的 Modern Applications)所必需的各种基础能力(如:极强的规模伸缩性、极高的可用性、极低的创新/运营成本、大数据的分析/运营能力等等),而不需要像以前的很多公司,为了具备这些能力,投入巨大,或者用另外一句话说:云原生就是专业的基础能力普惠化,随手可得

当今时代的应用和多年前的应用面临的状况差别太大,这个差异和当今业务面临的激烈竞争和玩法有很大的关系,我以前一直觉得像阿里在发展过程中积累的很多能力,外面很少有公司会需要,就像当年百亿、千亿美金的公司是多么难才出现,但现在看来则完全不一样,所以这也奠定了当今时代的应用在技术层面能力的要求也远不一样,简单说几个点:

  1. 对可用性的要求远高于以前的应用:现在的应用通常一上线对可用性要求就已经不低了,因为一旦出问题就很容易把用户送给竞对;
  2. 对伸缩性的能力要求也远比以前高,主要体现在两个方面:一是团队规模,现在的业务公司很容易迅速发展到百人以上,而百人以上的研发效率如何保持尽量不下降,这对系统的伸缩能力有着很高的要求;二是用户规模,现在众多业务的用户规模可以很快地突破百万、千万规模,这就要求系统必须能根据用户规模快速地伸缩;
  3. 创新和运营的成本必须低:业务竞争无比激烈,快是关键,所以怎么在不需要太大投入的情况下快速上线各种业务,是无比重要的;另一个方面就是运营的成本,这个是和现在应用的用户规模、激烈竞争密切相关的;
  4. 大数据的玩法:现在的很多业务对获客、推荐、搜索等的大数据化要求还是相当高的。

阿里是一家在自身发展过程中,逐步碰到上述的挑战(当年的竞争环境基本还不会要求一个业务上来就把各种能力具备好),但以前也没有云可用,所以在发展过程中不断积累各种能力,现在通过开源、云商业化对外输出这些能力,使得即使到了现在这样的竞争环境下,各种有业务创新想法的同学们,还是可以像当年一样快速上线业务,而不是要先投入巨多力量、花费巨多时间把需要的基础能力打磨出来。

我自己并没有完全经历阿里的发展过程,接下来主要还是简单说下我自己经历的一些。

  1. 在 2007 年,淘宝在基础能力上面临的最大问题是伸缩性,两个现象当时都出现了:用户数量大量增加,加机器已经基本要加到瓶颈了;研发人员大量增长,研发效率下滑非常明显。在这个阶段,淘宝做了一轮非常重要的架构改造,磨练出了例如服务框架、消息中间件、分库分表方案、分布式文件系统、分布式缓存等基础技术产品,结合业务架构的重新设计,很好地解决掉了伸缩性的问题。
  2. 在 2009 年,淘宝面临了可用性问题,经常出各种故障,于是开始积累各种监控、快速恢复、tracing、系统设计里如非关键路径异步化等技能。可用性这块的投入一直在持续,到后来为解决 双11 这种特殊情况的可用性、确定性诉求而创造的全链路压测;通过同城双活、异地多活的多机房体系构建的强容灾能力以及快速恢复能力等;以及在线下场景加入后来面临的不一样的可用性方案等。各种场景的高可用方案的积累,也使得业务的可用性越来越有保障。
  3. 2011 年左右,阿里开始觉得未来在资源投入上的运营成本可能会很夸张,于是在 2011 年开始通过容器化来提升机器使用效率、持续进行成本优化,后来又持续通过云资源弹性来解决 双11 这类型的短时高峰的成本投入问题,通过在线离线混部解决大数据机器投入越来越大、在线机器集群利用率不高产生浪费的问题,经过多年努力,使得业务在高速增长的情况下,机器资源投入上的运营成本还是相对可控的。

如上文所讲,阿里是依靠巨大的人力投入、场景打磨和多年的持续投入才逐渐形成了完备的能力。而现在的业务,则可以用云原生的方式构建,使自身一上来就具备这些能力,至少能够让自己在如今激烈且要求更高的业务竞争环境中,不会在这些基础能力上拖后腿,以此可以花更多的精力、时间、资源在真正的业务创新上。这样具象化的云原生对整个社会的创新还是相当有价值的。

阿里云入选 2021 Gartner APM 魔力象限,国内唯一入选云厂商

alicloudnative阅读(47)评论(0)

来源 | 阿里巴巴云原生公众号

近日,Gartner 发布了《2021 年 Gartner APM 魔力象限》,阿里云成为国内唯一入选的云厂商,产品能力和战略愿景获得 Gartner 分析师高度认可。

Gartner 是全球最具权威的 IT 研究与顾问咨询公司,其每年的 Gartner  APM 魔力象限报告对于企业选择 APM 工具提供了可靠的参考标准。本次评测应用实时监控服务(ARMS)作为阿里云 APM 的核心产品,联合云监控以及日志服务共同参与。Gartner 评价阿里云 APM:

  • 中国影响力最强:阿里云是中国最大的云服务提供商,阿里云用户可以使用云上监控工具来满足其可观测性需求。
  • 开源集成:阿里云非常重视将开源标准和产品(例如 Prometheus)集成到其平台中。
  • 成本优势:与在阿里云上使用第三方 APM 产品相比,阿里云 APM 产品具有更高的成本效益。

1.png
图片来源:2021 Gartner APM 魔力象限

当下,企业正逐步加快数字化转型的步伐,导致 IT 系统更新频繁,应用复杂度急剧升高。微服务、容器化等之前仅有技术型公司关注的前沿技术也逐渐在传统企业中兴起,而云服务早已经成为企业大规模运营数字业务所必备的技术服务。以用户体验为核心的应用性能管理(APM)受到广泛关注,APM 在帮助企业实现数字化转型及智能化运维的道路上表现出巨大的价值。

例如,用户打开某个应用后,可能涉及上千次调用。打开这样一个页面的响应时间,不仅是前端应用的指标,也是所有服务中心都应该去关心的重要指标。当出现问题,传统运维通过排查、电话通知的操作,不仅低效还容易丢失信息。如何实时监控整个链路的运行情况,出现问题快速定位根因,对应到责任人,这些是企业在服务化过程中亟需解决的问题。

2017 年,阿里将内部锤炼多年的监控工具对外,应用实时监控服务 ARMS 正式商业化。作为云原生一体化可观测性平台,ARMS 提供全栈式的性能监控和端到端的全链路追踪诊断能力,同时,结合阿里云日志服务(SLS)的日志数据分析能力以及云监控丰富的云服务与基础设施监控能力,用户可以轻松完成用户体验、应用、云服务、容器的一站式监控。

2.png

阿里云在 APM 领域不仅建立了丰富的产品布局,其产品能力也得到了众多客户的认可。道旅科技凭借 ARMS,在数分钟内搭建和启动了基于大数据平台的应用实时监控系统,极大地提升了 IT 人员的效率。华润万家不管在应用上出现任何问题,ARMS 都可以清楚地呈现问题出在哪一行代码,大大缩短了修复故障的时间。

随着企业数字化转型进程加速,企业各类应用程序的性能状况直接影响了数字化业务的顺利开展,APM 产品的市场需求仍在不断扩大。经过 10 多年的技术实践,阿里云已拥有国内规模最大的云原生产品家族和开源生态,提供云原生裸金属服务器、云原生数据库、容器服务、微服务、可观测、高可用等超过 100 款创新产品,让企业更加从容地迈向云原生架构。

5.15 相约上海!2021 年度首届云原生 Meetup | KubeSphere & Friends

KubeSphere阅读(64)评论(0)

时至今日,Kubernetes 虽然变成了云原生这套系统化方法论和开源技术的核心一环,但已经无法独立存在,而是与云原生生态中所有的技术形态息息相关。为了将云原生生态中的各个技术形态结合起来,帮助企业最大化资源利用效率,KubeSphere 打造了一个以 Kubernetes 为内核的云原生分布式操作系统,提供可插拔的开放式架构,无缝对接第三方应用,极大地降低了企业用户的使用门槛,解决了云原生产品体验的一致性这个痛点。

KubeSphere v3.1.0 的发布是 KubeSphere 的一个重大拐点,将混合多云从云端延伸到了边缘场景,实现应用与工作负载在云端和边缘节点进行统一分发和管理。同时进一步增强了多集群管理和多租户管理等企业级功能,优化了在更多场景下的使用体验。

KubeSphere 之所以能够如此快速发展,得益于开源社区带来的天然优势,以及社区里长期活跃的用户、贡献者积极参与社区,帮助推动产品和社区快速成长,我们坚持认为 KubeSphere 开源社区的每一位用户和贡献者朋友都是 KubeSphere 生态中的重要组成部分。

自从去年 12 月份的年度 meetup 之后,KubeSphere 社区组织的 Kubernetes meetup 与大家阔别了四个月。如今,Kubernetes meetup 重新启程,于五月和六月,在上海、杭州、深圳、成都这四个城市分别与大家见面,致力于汇聚各个城市的优秀云原生人才,连接 KubeSphere 社区与云原生开发者,促进对云原生的推广和实践。

活动议程

上海站是今年 Kubernetes meetup 的第一站,目前已基本确定讲师和议题。

时间地点

活动时间:5月15日 下午 13:00-18:00

签到时间:13:30-14:00

活动地点:上海市虹口区杨树浦路 188 号 2 号楼 102 赤兔创业咖啡

活动报名

上海站目前已经开启招募,若您希望获取经验,期待和各位极客交流,那就抓紧报名吧!位置有限,先到先得!

扫描下方二维码即可进入到报名页面进行报名,活动免费

活动礼品

我们特别定制了 KubeSphere 全套纪念周边礼品:T恤、马克杯、纪念徽章、帆布袋、口罩等。

报名参与或者提交议题即可获得定制周边纪念品!

除了提供周边礼品之外,我们还会赠送各种云原生相关的硬核书籍,有电子工业出版社提供的 《Kubernetes 生产化实践之路》:

还有人民邮电出版社图灵原创提供的张磊大神的巨著《深入剖析 Kubernetes》:

 

你以为只有这两套书吗?当然不是,本次 meetup 还会送出以下书籍(机械工业出版社华章公司):

 

现场参与互动即可获取以上书籍奖品哟~

提交主题分享

您充满了开发创意却无处施展吗?我们已经为您搭好舞台:Serverless、微服务、DevOps、开源、容器… 任何关于云原生和 KubeSphere 的观点、干货、技术实践、用户故事都是我们社区非常欢迎的。

目前上海站还有一个主题演讲空缺,其他城市站还有多个主题演讲空缺,我们面向大家公开招募。只要您有兴趣分享,就可以提交您的议题,采纳后即可获得讲师专属大礼包一份!

扫描下方二维码提交您的议题吧!

 

2020 活动现场精彩回顾

于 KubeSphere

KubeSphere (https://kubesphere.io)是在 Kubernetes 之上构建的开源容器混合云,提供全栈的 IT 自动化运维的能力,简化企业的 DevOps 工作流。

KubeSphere 已被 Aqara 智能家居、本来生活、新浪、华夏银行、四川航空、国药集团、微众银行、紫金保险、中通、中国人保寿险、中国太平保险、中移金科、Radore、ZaloPay 等海内外数千家企业采用。KubeSphere 提供了开发者友向导式操作界面和丰富的企业级功能,包括多云与多集群管理、Kubernetes 资源管理、DevOps (CI/CD)、应用生命周期管理、微服务治理 (Service Mesh)、多租户管理、监控日志、告警通知、审计事件、存储与网络管理、GPU support 等功能,帮助企业快速构建一个强大和功能丰富的容器云平台。

 ✨ GitHub:https://github.com/kubesphere
 💻 官网(中国站):https://kubesphere.com.cn
 👨‍💻‍ 微信群:请搜索添加群助手微信号 kubesphere

seata-golang 一周年回顾

alicloudnative阅读(322)评论(0)

作者 | 刘晓敏
来源 | 阿里巴巴云原生公众号

Seata 是一款简单易用,高性能、开源的一站式分布式事务解决方案。Seata 从2019 年 1 月开源后就受到了大家的追捧,目前已经有几百家企业在生产环境进行了技术的落地。

2020 年 4 月,我们开始基于 Seata 着手做多语言 golang 项目,经过一年时间的开发,很高兴 seata-golang 发布了 1.0.0 版本。

今年 4 月 17 号,有幸在成都 gopher meetup 上将 seata-golang 介绍给热衷于 golang 的 gopher。

1.png

2.png

会上我们向大家演示了如何利用 seata-golang 来接入到微服务中保证服务间的数据一致性,另外还向大家介绍了 Seata 的核心原理、MySQL driver 原理和接入、seata-golang 的未来规划,最后就大家关注的 Seata 相关的问题做了 QA。

3.png

Seata 原理

活动上,我们结合 seata-golang 的demo 和大家分享了 seata 的工作原理。如下图所示,是一个 seata at 模式的简单工作流程。

4.png

  • TC(即图中右半部分):Transaction coordinator,它是一个分布式事务协调器。
  • TM:Transaction manager,它是一个事务管理器,负责全局事务的开启、提交和回滚。
  • RM:Resource Manager,它是管理分支事务资源的,它加入全局事务组后,向 TC 报告分支事务的执行状态。
  • XID:TM 开启全局事务时,会在 TC 创建一个 GlobalSession,GlobalSession 的全局唯一标识即为 XID。
  • BranchID:RM 向 TC 注册分支事务后,在 TC 侧生成一个 BranchSession,BranchID 全局唯一标识这个 BranchSession。

当 RM 向 TC 报告分支执行失败时,TC 会标记这个 BranchSession 的状态为失败,然后 TM 发起回滚时,TC 根据 XID 找到所有成功执行的事务分支,通知他们进行回滚。

MySQL Driver

最近研发开源出来的mysql driver 项目,基于 go-sql-driver/mysql 1.5.0 版本开发,天然集成了 seata-golang 的分布式事务能力,完全支持 database/sql 库这层抽象,由于很多 orm 框架都基于 database/sql 做了封装,所以对 database/sql 的支持意味着 seata-golang 可以完美无缝地接入各种 orm 框架。

5.png

driver 的 mysqlTx 对象执行 Commit 或者 Rollback 时,会根据 mysqlConn 的 connCtx 是否有值来决定是否和 tc 交互,报告分支事务的执行状态。如果执行 Commit,connCtx 有值则把 sqlUndoItemsBuffer 中的 undoLog 和业务数据一起提交到数据库,然后报告 tc 事务分支提交的状态(成功还是失败),否则执行正常的提交。如果执行 Rollback,connCtx 有值则回滚然后向 tc 报告分支执行失败,tc 会根据这个状态回滚整个全局事务,connCtx 没有值则只需正常回滚。

6.png

上图是 undoLog json 序列化后的结构数据,我们可以看到这条数据修改之前,它的 name 是 “TXC”,修改之后它的 name 是 “GTS”,如果对它进行回滚,则生成一个反向的补偿语句:update product set name = ‘TXC’ since = 2014 where id = 1。如果是 insert 操作,则反向补偿操作为 delete,如果是一个 delete 操作则方向补偿操作为 insert。

未来规划

社区已经有小伙伴将 mysql driver集成到 gorm,并将 seata-golang 用到生产环境。目前 seata-golang 只支持 mysql,小伙伴们可根据 mysql driver 的思路,实现 pgsql 和 oracle 的 driver 。这也是未来 seata-golang  将要规划做的事情之一。

7.png

随着 go 语言微服务开发的兴起,分布式事务问题会越来越受到关注,希望社区的朋友可以更多参与进来完善这个框架,让它发挥生命力、服务社区、创造价值。

如果你有任何疑问,欢迎钉钉扫码加入交流群【钉钉群号 33069364】

作者简介

刘晓敏(GitHubID dk-lockdown),目前就职于 h3c 成都分公司,擅长使用 Java/Go 语言,在云原生和微服务相关技术方向均有涉猎,目前专攻分布式事务。

参考资料

KubeSphere 3.1.0 GA:混合多云走向边缘,让应用无处不在

KubeSphere阅读(236)评论(0)

2021 年 4 月 29 日,KubeSphere 开源社区激动地向大家宣布,KubeSphere 3.1.0 正式发布!为了帮助企业最大化资源利用效率,KubeSphere 打造了一个以 Kubernetes 为内核的云原生分布式操作系统,提供可插拔的开放式架构,无缝对接第三方应用,极大地降低了企业用户的使用门槛。

KubeSphere v3.1.0 主打 “延伸至边缘侧的容器混合云”,新增了对 “边缘计算” 场景的支持。同时在 v3.0.0 的基础上新增了 计量计费,让基础设施的运营成本更清晰,并进一步优化了在 “多云、多集群、多团队、多租户” 等应用场景下的使用体验,增强了 “多集群管理、多租户管理、可观测性、DevOps、应用商店、微服务治理” 等特性,更进一步完善交互设计提升了用户体验。

云原生产业联盟撰写的《云原生发展白皮书》提到,万物互联时代加速了云-边协同的需求演进,传统云计算中心集中存储、计算的模式已经无法满足终端设备对于时效、容量、算力的需求,向边缘下沉并通过中心进行统一交付、运维、管控,已经成为云计算的重要发展趋势。

面对这一发展趋势,KubeSphere 与 KubeEdge 社区紧密合作,将 Kubernetes 从云端扩展至边缘,以统一的标准实现了对边缘基础设施的纳管。通过与 KubeEdge 集成,解决了边缘节点纳管、边缘工作负载调度和边缘可观测性等难题,结合 KubeSphere 已有的多集群管理将混合多云管理延伸至边缘侧。

并且,v3.1.0 得到了来自青云 QingCloud 之外的更多企业与用户的贡献和参与,无论是功能开发、功能测试、缺陷报告、需求建议、企业最佳实践,还是提供 Bug 修复、国际化翻译、文档贡献,这些来自开源社区的贡献都为 v3.1.0 的发布和推广提供了极大的帮助,我们将在文末予以特别致谢!

解读 v3.1.0 重大更新

KubeSphere 3.1.0 增加了计量计费功能,支持集群、企业空间的多层级与多租户在应用资源消耗的计量与统计。通过集成 KubeEdge,实现应用快速分发至边缘节点。同时还提供了更强大的可观测性能力,如兼容 PromQL、内置主流告警规则、可视化对接钉钉、企业微信、Slack 和 Webhook 等通知渠道。DevOps 的易用性在 3.1.0 也上了一个台阶,例如内置多套常用流水线模板,支持多分支流水线和流水线复制等,关于重大更新详情请查看文末海报。

多维度计量计费,让 K8s 运营成本更透明

在企业运营和管理 Kubernetes 容器平台时,通常需要分析资源消耗,查看集群及其中租户的消费账单,洞察资源使用情况,分析基础设施运营成本。

在 KubeSphere 3.1.0 中,可从多个维度来分析平台资源消耗:

  • 从集群维度,可查看每个集群资源消耗,深入到节点中分析运行的工作负载,精准规划每个节点中工作负载的资源使用状况。
  • 从企业空间维度,可查看每个企业空间资源消耗,获取企业空间中项目、应用、工作负载的消费账单,分析多租户环境中各个租户的资源使用是否合理。

另外,除了可以通过界面查看和导出数据,KubeSphere 计量计费平台也提供了所有操作的 API。接下来在后续的版本里,会持续加强并构筑端到端完整的计量计费可运营系统。

边缘节点管理

KubeEdge 是一个开源的边缘计算平台,它在 Kubernetes 原生的容器编排和调度能力之上,实现了 云边协同计算下沉海量边缘设备管理边缘自治 等能力。但 KubeEdge 缺少云端控制层面的支持,如果将 KubeSphere 与 KubeEdge 相结合,可以很好解决这一问题,实现应用与工作负载在云端与边缘节点进行统一分发与管理。

这一设想在 v3.1.0 中得以实现,KubeSphere 现已支持 KubeEdge 边缘节点纳管、KubeEdge 云端组件的安装部署、以及边缘节点的日志和监控数据采集与展示。结合 KubeEdge 的边缘自治功能和 KubeSphere 的多云与多集群管理功能,可以实现云-边-端一体化管控,解决在海量边、端设备上统一完成应用交付、运维、管控的需求。

强化微服务治理能力

KubeSphere 基于 Istio 提供了金丝雀发布、蓝绿部署、熔断等流量治理功能,同时还支持可视化呈现微服务之间的拓扑关系,并提供细粒度的监控数据。在分布式链路追踪方面,KubeSphere 基于 Jaeger 让用户快速追踪微服务之间的通讯情况,从而更易于了解微服务的请求延迟、性能瓶颈、序列化和并行调用等。

KubeSphere 3.1.0 对微服务治理功能进行了强化,将 Istio 升级到了 1.6.10,支持图形化流量方向检测,图像化方式显示应用流量的流入/流出。同时还支持对 Nginx Ingress Gateway 进行监控,新增 Nginx Ingress Controller 的监控指标。

多云与多集群管理

虽然 KubeSphere 3.0.0 带来的多云与多集群管理提供了面向多个 Kubernetes 集群的中央控制面板,实现了应用跨云和跨集群的部署与运维,但 member 集群管理服务依赖 Redis、OpenLDAP、Prometheus 等组件,不适合轻量化部署。KubeSphere 3.1.0 移除了这些依赖组件,使 member 集群管理服务更加轻量化,并重构了集群控制器,支持以高可用方式运行 Tower 代理服务。

更强大的可观测性

可观测性是容器云平台非常关键的一环,狭义上主要包含监控、日志和追踪等,广义上还包括告警、事件、审计等。3.1.0 除了对已有的监控、日志、告警等功能进行优化升级,还新增了更多新特性。

  • 监控:支持图形化方式配置 ServiceMonitor,添加集群层级的自定义监控,同时还实现了类似于 Grafana 的 PromQL 语法高亮。
  • 告警:在 v3.1.0 进行了架构调整,不再使用 MySQL、Redis 和 etcd 等组件以及旧版告警规则格式,改为使用 Thanos Ruler 配合 Prometheus 内置告警规则进行告警管理,兼容 Prometheus 告警规则。
  • 通知管理:完成架构调整,与自研 Notification Manager v1.0.0 的全面集成,实现了以图形化界面的方式对接邮件、钉钉、企业微信、Slack、Webhook 等通知渠道。
  • 日志:新增了对 Loki 的支持,可以将日志输出到 Loki。还新增了对 kubelet/docker/containerd 的日志收集。

更易用的 DevOps

KubeSphere 3.1.0 新增了 GitLab 多分支流水线和流水线克隆等功能,并内置了常用的流水线模板,帮助 DevOps 工程师提升 CI/CD 流水线的创建与运维效率。大部分场景下可基于流水线模板进行修改,不再需要从头开始创建,实现了真正的开箱即用。

灵活可插拔的集群安装工具

KubeKey 不仅支持 Kubernetes 1.17 ~ 1.20 在 AMD 64 与 ARM 64 的安装,还支持了 K3s。并且,Kubekey 还新增支持 Cilium、Kube-OVN 等网络插件。鉴于 Dockershim 在 K8s 1.20 中被废弃,Kubekey 可用于部署 containerd、CRI-O、iSula 等容器运行时,让用户按需快速创建集群。

运维友好的网络管理

KubeSphere 将 IaaS 云平台强大的网络能力继承到容器云平台,让用户在 Kubernetes 之上获得与 IaaS 一样稳定、安全和易用的网络使用体验。v3.1.0 新增了网络可视化拓扑图,你可以通过拓扑图洞悉各个服务之间的网络调用关系。

鉴于 Calico 是目前最常用的 Kubernetes CNI 插件之一,v3.1.0 现已支持 Calico IP 池管理,也可以为 Deployment 指定静态 IP。此外,v3.1.0 还新增了对 Kube-OVN 插件的支持。

认证鉴权与多租户

统一的身份管理和完备的鉴权体系,是多租户系统中实现逻辑隔离不可或缺的能力。KubeSphere 基于 Kubernetes 的角色访问控制(RBAC),提供了细粒度的权限控制能力,在支持 Namespace 层级资源隔离的同时通过 Workspace 进一步对租户进行了定义,多层级的权限管控更加契合企业用户的使用场景。

v3.1.0 中新增了组织架构管理功能,可以通过用户组简化批量授权操作。除此之外还支持了企业空间的资源配额管理,实现对资源用量的管控,进一步满足企业用户的实际需求。

统一认证方面,v3.1.0 中简化了身份提供商(IdentityProvider, IdP)的配置方式,除 LDAP 之外新增了对 CAS(Central Authentication Service)、OIDC(OpenID Connect)、OAuth2 等通用认证协议的支持,并提供了插件化的拓展方式,以便不同账户系统之间的集成。

完全开源:社区化与国际化

借助于开源社区的力量,KubeSphere 迅速走向全球,目前 KubeSphere 在全球的 90 多个国家和地区有超过 10w 下载量。v3.1.0 Console 支持中、英、繁中和西班牙语,KubeSphere 未来将进一步拓展海外市场。

KubeSphere 3.1.0 将继续秉承 100% 开源的承诺,3.0.0 版本带来的诸多新功能也早已在 GitHub 开源,例如 PorterOpenPitrixFluentbit Operator、 KubeKeyKubeEyeNotification ManagerKube-Events,还开源了一套前端组件库 Kube Design,这些新特性的代码与设计文档在 GitHub 相关仓库都可以找到,欢迎大家在 GitHub 给我们 Star + Fork + PR 三连。

3.1.0 重要更新一览

安装升级

KubeSphere 已将 v3.1.0 所有镜像在国内镜像仓库进行了同步与备份,国内用户下载镜像的安装体验会更加友好。关于最新的 v3.1.0 安装与升级指南,可参考 KubeSphere 官方文档

致谢

以下为 KubeSphere 3.1.0 主要仓库贡献者的 GitHub ID,排名不分先后:


Kubernetes and Cloud Native Meetup 上海站(5 月 15 日)强势来袭,快来和 KubeShpere Community 在上海的初夏里来一场线下的技术狂欢吧!

随着 KubeSphere 社区的不断发展,社区用户的持续增多,KubeShpere 生态也逐渐走向成熟。本次 Meetup 我们联合 CNCF 基金会邀请来自 DevOps、数据库、存储等行业专家畅聊他们在云原生的应用与实践;现场更有来自社区用户与大家分享容器化之路;同时,KubeSphere 社区也将现场解读 KubeSphere 3.1.0 的最新特性与 Roadmap。感兴趣的同学不要犹豫,扫描下方二维码免费报名吧!

于 KubeSphere

KubeSphere (https://kubesphere.io)是在 Kubernetes 之上构建的开源容器混合云,提供全栈的 IT 自动化运维的能力,简化企业的 DevOps 工作流。

KubeSphere 已被 Aqara 智能家居、本来生活、新浪、华夏银行、四川航空、国药集团、微众银行、紫金保险、中通、中国人保寿险、中国太平保险、中移金科、Radore、ZaloPay 等海内外数千家企业采用。KubeSphere 提供了开发者友向导式操作界面和丰富的企业级功能,包括多云与多集群管理、Kubernetes 资源管理、DevOps (CI/CD)、应用生命周期管理、微服务治理 (Service Mesh)、多租户管理、监控日志、告警通知、审计事件、存储与网络管理、GPU support 等功能,帮助企业快速构建一个强大和功能丰富的容器云平台。

 ✨ GitHub:https://github.com/kubesphere
 💻 官网(中国站):https://kubesphere.com.cn
 👨‍💻‍ 微信群:请搜索添加群助手微信号 kubesphere

灵雀云第三期(2020-2021)传统行业云原生技术落地调研报告

灵雀云阅读(177)评论(0)

引言

如果说2019年是“云原生技术商业化元年”,那么2020年就是“云原生技术成为新常态”的一年。在这一年里,云原生技术正在快速开拓新的技术边界,支持新的应用范式,并更加关注全栈能力和生态建设。突如其来的疫情,更是给2020年的云原生应用落地速度与格局带来了深远的影响,云原生技术已经成为传统企业数字化转型的唯一解决方案。在这样的背景下,云原生技术实践联盟(CNBPA)联合灵雀云、云原生技术社区发起了“2020-2021年(第三期)传统行业云原生技术落地调研”。调研期间,总计收到了783份有效调研问卷,参与者分别来自金融、制造、能源、医药、电信、政企等不同领域、不同规模的传统企业。本次调研与前两期相比在多个维度上保持了统一和延续性,同时也对技术问题的颗粒度进行了更细致的拆解,不仅可以纵向对比前两年的调研数据,宏观了解云原生技术在传统行业的应用情况在三年内的变化,还可以深入了解企业在云原生基础设施、应用架构、开发流程、数据服务等各个板块的应用情况和落地成熟度,带您从全栈角度重新观察云原生。

核心观点

云原生技术(容器、DevOps、微服务)在生产环境中的应用相比去年已翻倍;

Kubernetes 已成为所有基础设施类软件的核心;

Service Mesh 使用率呈猛增势头,有望超过 Spring Cloud 成为市场最受欢迎的微服务框架;

服务网格、无服务及边缘计算成为企业最关注的三个云原生新兴方向;

01: 疫情之下,传统企业的IT规模逆势上扬

2020年,我国是全球唯一经济正增长的主要经济体,“新基建”与“增强产业链能力”等政策极大促进了传统企业数字化转型的发展。随着云计算在各行各业的落地不断深化,被技术赋能的传统企业早已将加速构建企业级云平台,作为创新发展的重要行动目标。

今年参与调研的企业中,100台服务器以下的企业占40.4%,100-500台服务器规模的占22.4%,500-1000台服务器的占13.1%,1000台以上服务器的企业则达到了24%,是2019年的2倍。

从团队规模来看,拥有100人以上研发团队的企业达到了52%,创三年调研的新高。

在问到企业IT预算投入的问题时, IT预算下降的企业占24.1%,增长保持在1%-5%的占38.4,增长5-10%的比例为22.1%,还有15.5%的企业IT预算有10%以上的增长。对比往年数据不难发现,2020年疫情像是为云时代的到来按下了加速键,传统企业的数字化转型步伐加快,IT投入上呈稳步增长态势。拥有较大IT规模企业,服务器用量与团队规模在2020年都有明显扩张,初创型及中型企业也基本维持了前两年的IT规模。

02: 云原生技术(包括容器、DevOps、微服务)在生产环境中的应用相比去年已翻倍

在云原生技术的支撑下,IT系统每周、每月更新升级的企业比例都有所升高,3-6个月更新以及半年更新的企业比例再次下降。相应地,系统维护压力和学习成本越来越高,给企业IT部门带来巨大挑战。

 

伴随着云原生技术的普及,企业面临着自研和外采的两难选择。自研不但人力成本和时间成本较高,也会遇到技术选型困难、陡峭的学习曲线、投入产出比预期复杂,效果难预测等情况。对比去年数据,在选用云原生技术时,依靠自研能力自建云原生平台的企业在逐年减少,同时企业呈现了与专业的云原生技术厂商合作的趋势,采购相对标准化的第三方云原生基础平台,自身聚焦于应用开发,已经成为用户实现云原生落地最稳健的选择。

对于云原生技术落地阶段,调研数据如预期——将包括容器、DevOps、微服务在内的云原生技术用于核心业务生产的企业已达到34.89%,相比往年数据有近1倍的提升。这也从侧面说明,云原生这一整套的技术体系和方法论,在几年的落地实践中已经为企业取得了显著的业务成果,在企业数字化转型中扮演了重要的角色。

03: 云原生基础设施:Kubernetes已成为所有基础设施类软件的核心

在过去几年,容器完全改变了云计算的基础设施架构。但云原生的基础设施到今天已经远远不限于容器管理,在大规模企业落地时,会看到一些更加现实的业务应对和趋势。

调查显示,受访企业中,72.7%的企业采用Kubernetes作为容器编排技术,保持了绝对的优势地位。这与最近CNCF发布的中国区云原生调查报告中的数据保持了相当高的一致性,同期全球调查报告的数字是78%。我们可以看到,在Kubernetes的使用率上,国内传统企业与全行业,甚至全球Kubernetes的使用率是持平的,Kubernetes已经完全进入主流市场,成为所有人都在使用的技术。多云部署的快速推进,与Kubernetes在企业生产环境中的运用不无关系。Kubernetes作为一个可移植层,它能够屏蔽基础设施的很多细节,可以很容易地做跨云迁移,对混合云和多云管理非常有好处。

调查显示,有15.3%的被访问企业的云计算服务部署在公有云,53%部署在私有云,31.7%已经使用了多云/混合云的部署方式。另外,还有48.9%的受访人表示,所在的企业将要考虑多云/混合云部署云服务,也就是说,近8成未采用多云/混合云部署云服务的企业,打算在将来采用。由此可见,传统企业中多云/混合云部署已成明确的趋势。

04: 云原生应用架构:Service Mesh使用率呈猛增势头,有望超过Spring Cloud成为市场最普遍的微服务框架

企业一定要意识到微服务并不是免费的,它的本质是用运维的复杂度去换取敏捷性。因此在微服务改造大行其道的今天,企业采用微服务仍能遇到一些阻力和问题。

对比2019-2020两年数据,受调研的企业在微服务采用阶段上基本保持了相对稳定的比例。采用微服务开发新系统(41% / 43.7%)和对遗留应用进行改造(23% / 24.8%)的企业比例都有些许提升。同时,彻底不打算实施微服务架构的企业比去年同期有所增加,说明部分企业对于到底需不需要这样的敏捷性,有没有必要用过多的复杂度作为代价,也经历了深入的思考和判断。

对于微服务框架的选择,今年的调研数据有比较大的突破。虽说市面上存在丰富的微服务框架,可是对稳定有极高要求的传统企业却常常陷入无型可选的尴尬境地,这也是为何Java系的Spring Cloud在前几年几乎一统天下的原因。以 Istio为代表的新一代微服务框架Service Mesh虽然还在演进过程中,但经过几年的实践深耕,以及在头部互联网企业宣传和能力平台化的推动下,已经被认定为微服务治理的最佳实践。在被调研的企业中,Service Mesh的使用率从2019年的11.8%提升到了今年的40.4%,涨幅达到三倍。Spring Could虽然仍占据选型第一的位置,但Service Mesh的势头不容小觑。

在用微服务架构开发新的应用系统的过程中,企业也不可避免地遇到了诸多难题。最大的挑战是“微服务拆分缺乏专业的人才,没有最佳实践指导”,占57.4%之多。微服务的演进成熟需要时间,企业熟悉掌握和应用新技术也需要时间。如果在没有明确业务需求、相应组织架构及技术关键细节的前提下,就强推微服务框架,反而有可能会达到反向作用。

05: 云原生开发流程:超6成DevOps基于容器建设

云原生技术的普及带来了诸多红利,其中之一就是DevOps产业的井喷式发展。在与容器化的新一代基础设施以及微服务架构搭配下,DevOps能够更加充分地利用云化资源、自动弹性伸缩等特性,在保证稳定的同时,更加快速交付高质量的软件及服务,灵活应对快速变化的业务需求和市场环境。

对比往年数据,DevOps已经实施或即将实施的比例越来越高,今年逼近9成。这其中,有62.3%的企业DevOps建立基于容器环境,25.7%的企业基于物理环境或VM。

DevOps的深入渗透,和云原生技术推动数字化转型的步伐基本保持了一致。我们认为,在云原生场景下,平台需要覆盖 DevOps完整的流程和场景,DevOps使用的整条工具链需要和Kubernetes平台对齐打通。不仅如此,Kubernetes可以编排一切,DevOps工具可以放在Kubernetes平台上去做管理。

这与Gartner于2020年9月发布的首份“Market Guide for DevOps Value Stream Delivery Platform(VSDP)”(DevOps价值流交付平台的市场指南报告)中的观点相一致。该报告指出,所有采用DevOps的企业都将从工具链方式向平台方式转型,到2023年,预计将有40%的企业和组织采用平台化方式的DevOps价值链交付平台。

06: 云原生数据服务:超5成受访企业考虑迁移至云原生数据库

在去年的调研中我们提到,企业在落地云原生的时候更关注完整、体系化的云原生解决方案。所以越来越多的数据库、存储、网络、中间件、安全等周边技术、组件正在跟云原生技术对齐。其中,容器化的数据服务目前成为为企业云原生的一个重要落脚点。

在问到企业是否愿意将本地数据迁移至云原生数据库时,调研数据显示,25.1%的受访企业已经做了迁移,而有29.5%的企业表示有意愿,还未迁移,另有36.1%的企业表示正在评估。

在对比云原生数据库与传统数据库时,“云原生数据库可扩展性”、“故障易处理”、“安全性增强”等优势成为传统行业企业最看中的优势。从调研结果可以看到,实施云原生过程中,越来越多的企业对于数据服务类的组件,已经不再满足于把数据服务留在虚拟机甚至物理机中“稳字当头“的应对思路了,提供兼容广泛的开源数据库、各类主流数据服务在Kubernetes Operator上实现自动化运维的一站式解决方案,将帮助企业降低开发测试人员的使用、管理成本,更专注于业务本身。

07: 展望未来:服务网格、无服务及边缘计算成企业最关注的三个云原生新兴方向

在已有工作重点的基础上,传统企业还将目光投向了云原生的新兴方向。最受企业关注的依然是服务网格(Service mesh),如前面调研数据显示,Service Mesh在企业中呈爆发性增长,有望成为市场上使用最普遍的微服务框架,但Service Mesh的成熟度还有待考察。

在新兴技术关注度上排名第二的是无服务器架构(FaaS/Serverless),Serverless是正在兴起的一种云原生工作负载,从 CNCF的调查报告来看,Serverless的普及率要高于service mesh。但是多数Serverless的使用都是在公有云上面,目前来说公有云上的 Serverless能力也会更加成熟,但长期来看,私有云环境也会慢慢有对Serverless编程范式和架构范式的需求。排名第三的是边缘计算,边缘计算是对云计算的一个补充和拓展。随着5G的发展,运营商、工业制造、智慧城市等传统行业都会涉及到海量、超低延时、多样性的数据处理,边缘计算就显得尤为重要了。数据表明,“新基建”时代80%的数据和计算将发生在边缘,并会有更多场景落地。此外,机器学习/联邦学习、低代码、Chaos mesh 也得到了企业相当多的关注。 综上,从整个报告的数据来看,传统行业企业开始全面拥抱云原生。基础设施、应用架构、开发流程、数据服务等方面的云原生化改造,让更多业务应用从诞生之初就生长在云端,从技术理念、核心架构等多个方面,帮助企业IT平滑、快速、渐进式落地上云之路。

云原生新边界——阿里云边缘计算云原生落地实践

alicloudnative阅读(187)评论(0)

作者 | 黄玉奇
来源 | 阿里巴巴云原生公众号

日前,在由全球分布式云联盟主办的“Distributed Cloud | 2021 全球分布式云大会·云原生论坛”上,阿里云高级技术专家黄玉奇发表了题为《云原生新边界:阿里云边缘计算云原生落地实践》的主题演讲。

1.png

大家好,我是阿里云云原生团队的黄玉奇,非常感谢能有这个机会来跟大家分享。今天分享的题目是《云原生新边界∶ 阿里云边缘计算云原生落地实践》,从题目也能看到,分享内容应该是包括几个部分:云原生、边缘计算、二者结合架构设计、阿里云在商业和开源的实践以及案例。

今天大家所熟知的云原生(Cloud Native)理念,本质是一套“以利用云计算技术为用户降本增效”的最佳实践与方法论。所以,云原生这个术语自诞生,到壮大,再到今天的极大普及,都处于一个不断的自我演进与革新的过程当中。云原生已经作为一系列的工具、架构、方法论而深入人心,并为广泛使用;那么云原生到底是如何定义的呢?早期,云原生含义包括∶ 容器、微服务、Devops、CI/CD;2018 年以后 CNCF 又加入了服务网格和声明式 Api。

而回过头,我们再粗线条的看看云原生的发展历史,早期因为 Docker 的出现,大量的业务开始容器化、Docker 化。容器化通过统一交付件、隔离性从而带来了 Devops 的快速发展;Kubernetes 的出现让资源编排调度与底层基础设施解耦,应用和资源的管控也开始得心应手,容器编排实现资源编排、高效调度;随后,lstio 为代表的服务网格技术解耦了服务实现与服务治理能力。今天云原生几乎”包罗万象”般的无处不在,越来越多的企业、行业开始拥抱云原生。

2.png

而阿里巴巴作为云原生技术的践行者之一,云原生早已成为阿里的核心技术战略之—,这源自于过去十多年阿里在云原生领域的积累、沉淀和实践。大致可以分为三个阶段:

  • 第一阶段通过应用架构的互联网化沉淀了核心中间件、容器、飞天云操作系统等基础云原生能力;
  • 第二阶段是核心系统的全面云原生以及云原生技术的全面商业化;
  • 第三是云原生技术的全面落地和升级阶段,尤其是以 Serverless 为核心代表的下一代云原生技术正在引领整个技术架构升级。

阿里云容器服务 ACK 作为阿里云原生能力相关的商业化平台,正在为广大客户提供丰富的云原生产品及能力,这些都是拥抱云原生最好的佐证,我们坚信云原生是未来。

云原生技术已经无处不在, 阿里云作为云原生服务的提供者,我们认为云原生技术会继续高速发展,并被应用于”新的应用负载”、”新的计算形态”和”新的物理边界”;从阿里云云原生产品家族大图中我们可以看到∶ 容器正被用于越来越多类型应用和云服务中;并且通过越来越多的计算形态承载,如 Serverless、函数计算等等;而丰富的形态也开始从传统的中心云走向边缘计算,走向终端。这就到了今天分享的主题:边缘计算中的云原生,下面我们看看什么是边缘计算。

首先,我们从直观感受上看看什么是边缘计算。随着 5G、loT、音视频、直播、CDN 等行业和业务的发展,我们看到一个行业趋势,就是越来越多的算力和业务开始下沉到距离数据源或者终端用户重近的地方,从而来获得很好的响应时间和降低成本;这明显区别传统的中心式的云计算模式。并越来越被广泛应用于汽车、农业、能源、交通等各行各业。

3.png

再从 IT 架构上看边缘计算,可以看到它具有明显的按照业务时延和计算形态来确定的分层结构,这里分别引用 Gartner 和 IDC 对边缘计算顶层架构的解释∶ Gartner 将边缘计算分为”Near Edge”、”Far Edge”、”Cloud”三部分,分别对应常见的设备终端,云下 IDC/CDN 节点,以及公共云/私有云;而 IDC 则将边缘计算定义为更直观的”Heavy Edge”、”Light Edge”来分别表示数据中心维度,和低功耗计算的端侧。从图中我们可以看到分层结构中,层层相依。互相协作。

这种定义也是现在业界对边缘计算和云计算关系所达成的一个共识。说完背景、架构,我们再看看边缘计算的趋势;我们尝试从业务、架构和规模三个维度去分析边缘计算的三大趋势:

第一,Al、loT 与边缘计算的融合,会有种类越来越多、规模越来越大、复杂度越来越高的业务运行在边缘计算场景中,从图上我们也能看到一些非常震撼人心的数字。

第二,边缘计算作为云计算的延伸,将被广泛应用于混合云场景,这里面需要未来的基础设施能够去中心化、边缘设施自治、边缘云端托管能力,同样图上也有部分引用数字。

第三,基础设施的发展将会引爆边缘计算的增长,随着 5G、loT、音视频行业的发展,边缘计算的爆发是理所当然,去年疫情期间在线直播、在线教育行业的爆发式增长也是一个例子。

随着架构的共识形成,在落地过程中我们发现,边缘计算的规模、复杂度正逐日攀升,而短缺的运维手段和运维能力也终于开始不堪重负,那么如何去解决这个问题呢?

云和边缘天然就是不可分割的有机整体,”云边端一体”的运维协同是目前比较能形成共识的一种方案。而作为云原生领域的从业人员,我们试着从云原生的角度来思考和解决这个问题;试想,如果”云边端一体”有云原生的加持,将会更好的加速云边融合进程。

4.png

在这个顶层架构设计下,我们抽象出了云边端协同的云原生架构:在中心(云),我们保留了原汁原味的云原生管控和产品化能力,通过云边管控通道将之下沉到边缘,使海量边缘节点和边缘业务摇身一变成为云原生体系的工作负载,通过服务流量和服务治理更好的和端进行交互;从而完成业务、运维、生态的一体化;而通过边缘云原生,我们可以获得和云上一致的运维体验,更好的隔离性,安全性以从及效率。产品落地就顺师理成章了许多。

接下来我们介绍阿里云在商业化和开源上的边缘计算云原生实践。

5.png

阿里云 ACK@Edge 主打“云端标准管控,边缘适度自治”的服务理念;“云边端”三层结构分层明显,能力协同。第一层是中心的云原生管控能力,提供标准的云原生北向接口供上层业务集成,诸如城市大脑、工业大脑、CDN PaaS,loT PaaS 等;第二层是云边运维管控通道,有多规格、软硬多链路方案来承载云边下沉管控流量和业务流量;再往下就是关键的边缘侧,我们在原生的 K8s 能力基础上叠加了类似:边缘自治、单元化管理,流量拓扑,边缘算力状态精细化检测等能力;边云协同,从而构成了一个完整的云边管控闭环;目前,这套架构已经广泛用于 CDN、loT 等领域。

那么边缘容器到底需要哪些核心能力和业务目标呢,图中所示包括∶ 四个能力,五个目标;四个能力是边缘算力管理、边缘业务容器化管理、边缘业务高可用支持和最终要实现的边缘云原生生态;从而实现边缘算力可接入、可运维,业务可管理、编排,服务高可用,业务有生态。下面对这些核心能力的设计做简单阐述。

阿里云边缘容器产品 ACK@Edge 通过内置 SD-WAN 能力实现云上云下网络互联,业务流量互通,大大提升云边协同效率和稳定性、安全性;而通过云端资源对接,实现了云上云下的资源弹性互通,提升了边缘场景下的业务弹性能力。

6.png

第二个核心能力是边缘自治能力,在云边一体架构中,运维协同是一项重要的能力,但是通常受限于云和边缘之前的网络条件,边缘需要适当的自治能力来保证业务的连续性和持续稳定运行,换句话讲就是边缘资源和边缘业务能够在脱离云端管控的条件下继续完成业务的全生命周期管理,包括创建、启停、迁移、扩缩容等。

7.png

第三个异构资源的支持比较好理解,边缘计算区别于传统中心云计算的一个标志性特征就是计算资源、存储资源种类多样、异构明显。ACK@Edge 目前支持 arm x86 cpu 架构,支持 linux、windows 操作系统,支持将 linux 应用和 windows 应用混合部署,来很好地解决边缘场景资源异构问题。

通过配合阿里云容器镜像服务,提供在边缘场景下的多地域交付能力,能够支持多种云原生制品的多地域交付,包括容器镜像,应用编排资源包等。

8.png

这里还要和大家同步一个信息,就是上述所有核心的边缘容器能力我们都开源在边缘容器平台项目 OpenYurt 中,OpenYurt 是 CNCF 的边缘容器官方项目,是一个延伸原生 Kubernetes 到边缘计算的智能开放平台项目。

作为 ACK@Edge 的核心框架,已经服务了超百万容器实例规模,并被广泛应用于主流的边缘计算场景中;在介绍完商业和开源实践后,还有几个案例和大家分享:

9.png

第一个,是盒马鲜生基于边缘云原生实现的“人货场”数字化融合转型,通过云原生体系将多种类型的边缘异构算力统一接入、统一调度,包括∶ENS(阿里公共云边缘节点服务)、线下自建边缘网关节点, GPU 节点等。获取了强大的资源弹性和业务混编带来的灵活性;并通过 ACK@Edge 提供的边缘云原生 Al 解决方案,构建云、边、端一体化协同的天眼 Al 系统,充分发挥了边缘计算就近访问,实时处理的优势,轻松实现全方位的降本提效,门店计算资源成本节省 50%,新店开服效率提升 70%。

10.png

第二个是我们在一家视频网站客户的案例,使用 ACK@Edge 来管理跨 region、跨类型、跨地域的边缘算力,用于部署视频加速服务,通过对异构资源的支持,客户在边缘计算场景获得了强大的资源弹性能力;有一个数字分享给大家,通过边缘容器的弹性和异构资源管理能力,能够节省 50% 左右的成本。

11.png

第三个案例是 ACK@Edge 在 loT 智慧楼宇项目中的落地,其中 loT 网关设备作为边缘节点托管在 ACK@Edge 的云端管控,网关设备上的业务和楼宇的智能设备交互;网关和端设备的运维都统一收编到中心云,效率大大提升。

在和社区同学的充分讨论下,OpenYurt 社区也发布了 2021 roadmap,欢迎有兴趣的同学来一起贡献。

OpenYurt 社区 2021 roadmap:
https://github.com/openyurtio/openyurt/blob/master/docs/roadmap.md

连续三年入围 Gartner 容器竞争格局,阿里云容器服务新布局首次公开

alicloudnative阅读(174)评论(0)

来源 | 阿里巴巴云原生公众号

近日,国际知名信息技术咨询机构 Gartner 发布 2021 年容器竞争格局报告,阿里云成为国内唯一连续三年入选的中国企业,产品丰富度与成熟度持续保持全球领先水平。

与往年相比,在 Kubernetes 支持、容器镜像、Serverless 容器、服务网格等传统维度基础上,本次报告新增了集群部署形态和管控平面两个维度,阿里云容器产品再次获得国际高度认可。

Gartner 指出容器已经发展成熟并跻身主流市场,不仅涌现了更加丰富的容器企业落地场景,同时多家容器厂商也开始并购与整合。Gartner 称为了方便更多大众行业采用容器,厂商需要不断丰富各类企业级应用镜像市场、增加对 aPaaS(应用平台即服务)的支持、实现多种云形态的部署与管控等等。

阿里云容器服务当前产品的布局,与此次 Gartner 的行业洞悉不谋而合。

阿里云为企业级容器规模化生产推出大量新品,容器服务企业版 ACK Pro 与容器镜像服务企业版 ACR EE,满足可靠性、安全性的强烈需求;同时也在 Serverless 容器、机器学习、边缘计算以及分布式云等方向提供了相应功能,并已经在如互联网、新零售、教育、医疗等企业落地。

Serverless 容器,简约管控、不简单的海量扩容

Serverless 无服务化成为日益关注的热点,其宗旨在于帮助云上运用减轻如服务器运维管理等与开发代码无关的工作量,转而更多地关注业务构建;并且于此同时还会尽可能地帮助客户优化应用启动速度。

在面向事件驱动应用的函数计算(FC)、面向微服务应用的 Serverless 应用引擎(SAE)之外,阿里云还提供了 Serverless 容器产品:Serverless Kubernetes(ASK),在提供标准的 Kubernetes 界面的同时,不但可以让用户享受到极致的弹性能力,并且实现免运维,客户可以快速创建 Serverless 集群而无需管理 Kubernetes 节点和服务器,不必精心的规划容量,也无需关心底层服务器。

Serverless Kubernetes 集群中的 Pod 基于阿里云弹性容器实例(ECI)运行在安全隔离的容器运行环境中。每个 Pod 容器实例底层通过轻量级虚拟化安全沙箱技术完全强隔离,容器实例间互不影响。基于阿里云深度优化的 Serverless 容器架构,使得 ASK 集群可以轻松获得极大的弹性能力,而不必受限于集群的节点计算容量。当前 ASK 弹性能力已经达到 30s 启动 500 运行的 Pod,单集群轻松支持 20K Pod 容量。

移动医疗设备研发商越光医疗通过 Serverless 容器进行将 AI 模型预测准确率提升到 99.99%,微博则通过 Serverless 容器实现全自动的业务弹性伸缩将业务端到端的扩容时间缩小 70%。

1.png

两大前沿应用场景,机器学习(云原生AI)与边缘计算

Gartner 认为容器技术及周边生态的发展日趋成熟,已经可以胜任如机器学习、边缘计算等新型应用场景。

1. 云原生量身定制,为 AI 工程效率提供更多优化空间

阿里云容器服务沉淀数年云原生 AI 实践场景,在异构资源管理、AI 应用生命周期管理、AI 任务调度和弹性,AI 数据管理和加速,AI 和大数据统一编排等方向提供了很多工具、基础服务和解决方案。已帮助很多客户提升 AI 生产工程效率,优化 GPU 资源利用率,加速 AI 平台建设等。并且推动 K8s 社区本身,向 AI、大数据等大规模数据计算类任务领域拓展。

好未来在线教育把大量的 AI + 教育下的重要业务服务通过阿里云容器服务部署,并在图像、语音、自然语言处理方面沉淀出覆盖“教、学、测、练、评”各教学环节的 100 余项 AI 能力、10 余项教育场景应用 AI 解决方案,不仅提高 AI 整体的开发部署效率,实现高效的 MLOPS;同时解决 AI 服务的高并发、高性能、高资源的场景下资源复用率低的顽疾,平台能力调用稳定性达 99.99%。

2.png

在刚刚结束的 2021 阿里云计算峰会上,阿里云重磅发布云原生 AI 套件,此新品提供了从底层资源运维和优化,多租户配额管理,AI 任务管理和智能调度,大数据服务集成,到支撑上层 AI 引擎加速和领域算法应用等多种能力。同时,提供可视化界面,命令行工具和 SDK,简单易用,方便扩展与集成。广大 AI 服务生产者,包括数据科学家、AI 算法工程师、AI 平台建设和运维者,都可自由组合使用各部分优化能力,选择在 Kubernetes 之上定制自己的 AI 平台。

申请获得测试资格,请点击链接填写表单:
https://page.aliyun.com/form/act181046685/index.htm

2. 边缘云原生,将 Kubernetes 运行在云之外

传统云计算中心集中存储与计算模式已经无法满足边缘设备对于时效、容量、算力的需求,如何打造边缘基础设施成了一个新课题。

云边端协同的云原生架构已然显形:在中心(云),原生的云原生管控和产品化能力得以保存,同时,海量边缘节点和边缘业务摇身一变成为云原生体系的工作负载。为了实现业务、运维、生态的一体化,通过边缘云原生提供更好的服务治理和流量管控,统一的应用管理运维体验,并且还能带来更好的隔离性、安全性与效率。

阿里云于 2019 年在业内率先发布边缘计算容器产品 ACK@Edge,主打“云端标准管控,边缘适度自治”的服务理念:在云端提供强大而丰富的云原生管控能力,向上可实现如城市大脑、工业大脑、CDNPaaS,IoTPaaS 等的业务集成,向下通过多规格、多链路方案承载流量完成云边运维管控;边缘侧,在原生的 K8s 能力基础上叠加如边缘自治、单元化管理,流量拓扑,边缘算力状态精细化检测等能力。

融创集团基于 ACK@edge 搭建社区客户服务数智化平台,统一管理道闸系统、信息大屏等社区场景和电视、智能空调、天猫精灵等家居场景两类智能设备,如对社区停车场的一站式管理,实现云边端一体化智能协同。优酷通过 ACK@Edge 统一管理其公共云上十多个 region 和众多边缘节点,通过弹性扩容节省 50% 以上的机器成本、端到端网络延迟降低 75%。

2.png

分布式云打破边界,统一而精细的管控

2020 年容器管理竞争格局的重大变化,主流云服务提供商都发布分布式云的容器管理方案。Gartner 预测 81% 的企业将采用多云/混合云战略,“大多数企业采用多云策略是为了避免供应商锁定或利用最佳解决方案“,多云战略实现企业采购的敏捷性,在可用性,性能,数据主权,和监管要求和劳动力成本得到平衡。

阿里云容器服务 ACK 2019 年 9 月份发布了混合云支持,2020 年 9 月,ACK 带来了完备的分布式云应用管理能力升级,不仅可以管理阿里云 K8s 集群之外,还可以纳管用户在 IDC 的自有 K8s 集群和其他云的 K8s 集群,实现统一的集群管理、IT 治理、安全防护、应用管理和备份管理。今年阿里云容器服务还全新发布了统一的应用中心交付能力,开发者可以通过 GitOps 方式可以将应用安全、一致、稳定地发布在多个不同的云环境中,确保整个过程安全、可控,提升应用交付效率和稳定性。

同时,阿里云容器服务 ACK 还可以与托管服务网格 ASM 结合使用 ,作为业界首个兼容 Istio 的托管式服务网格平台,服务网格 ASM 为运行在不同计算基础设施上的服务提供统一的能力,通过流量控制、网格观测以及服务间通信安全等功能,实现服务就近访问、故障转移、灰度发布等功能。全方位地简化服务治理,适用于如 Kubernetes 集群、Serverless Kubernetes 集群、ECS 虚拟机以及自建集群。

3.png

阿里云服务网格 ASM 坚持打磨“托管式、标准化、安全稳定、更易用、易扩展”的产品特性,目前已经覆盖了 12 个地域, 持续保持产品完整度、市场占有率领先,不仅对内承载了业界最大规模的网格集群,服务于阿里巴巴集团重点核心业务如电商、钉钉等,而且在公有云客户规模持续领先, 覆盖在线教育/职业培训、电商、物流、供应链、游戏以及车联网、IoT 等行业。通过服务网格技术将服务治理与业务解耦,并下沉到基础设施层, 让业务开发更聚焦于业务本身,以体系化、规范化的方式解决微服务软件架构下的多语言多编程框架及各种服务治理挑战。在超大规模的应用场景下,保证系统的稳定性的同时, 通过技术手段提升了可观测性、可诊断性、完善的服务治理能力以及性能的优化。

6 张图带你彻底搞懂分布式事务 XA 模式

alicloudnative阅读(121)评论(0)

头图.png

作者 | 朱晋君
来源 | 阿里巴巴云原生公众号

XA 协议是由 X/Open 组织提出的分布式事务处理规范,主要定义了事务管理器 TM 和局部资源管理器 RM 之间的接口。目前主流的数据库,比如 oracle、DB2 都是支持 XA 协议的。

mysql 从 5.0 版本开始,innoDB 存储引擎已经支持 XA 协议,今天的源码介绍实验环境使用的是 mysql 数据库。

两阶段提交

分布式事务的两阶段提交是把整个事务提交分为 prepare 和 commit 两个阶段。以电商系统为例,分布式系统中有订单、账户和库存三个服务,如下图:

1.png

第一阶段,事务协调者向事务参与者发送 prepare 请求,事务参与者收到请求后,如果可以提交事务,回复 yes,否则回复 no。

第二阶段,如果所有事务参与者都回复了 yes,事务协调者向所有事务参与者发送 commit 请求,否则发送 rollback 请求。

两阶段提交存在三个问题:

  • 同步阻塞,本地事务在 prepare 阶段锁定资源,如果有其他事务也要修改 xiaoming 这个账户,就必须等待前面的事务完成。这样就造成了系统性能下降。
  • 协调节点单点故障,如果第一个阶段 prepare 成功了,但是第二个阶段协调节点发出 commit 指令之前宕机了,所有服务的数据资源处于锁定状态,事务将无限期地等待。
  • 数据不一致,如果第一阶段 prepare 成功了,但是第二阶段协调节点向某个节点发送 commit 命令时失败,就会导致数据不一致。

三阶段提交

为了解决两阶段提交的问题,三阶段提交做了改进:

  • 在协调节点和事务参与者都引入了超时机制。
  • 第一阶段的 prepare 阶段分成了两步,canCommi 和 preCommit。

如下图:

2.png

引入 preCommit 阶段后,协调节点会在 commit 之前再次检查各个事务参与者的状态,保证它们的状态是一致的。但是也存在问题,那就是如果第三阶段发出 rollback 请求,有的节点没有收到,那没有收到的节点会在超时之后进行提交,造成数据不一致。

XA 事务语法介绍

xa 事务的语法如下:

  1. 三阶段的第一阶段:开启 xa 事务,这里 xid 为全局事务 id:
XA {START|BEGIN} xid [JOIN|RESUME]

结束 xa 事务:

XA END xid [SUSPEND [FOR MIGRATE]]
  1. 三阶段的第二阶段,即 prepare:
XA PREPARE xid
  1. 三阶段的第三阶段,即 commit/rollback:
XA COMMIT xid [ONE PHASE]
XA ROLLBACK xid
  1. 查看处于 PREPARE 阶段的所有事务:
XA RECOVER XA RECOVER [CONVERT XID]

seata XA 简介

seata 是阿里推出的一款开源分布式事务解决方案,目前有 AT、TCC、SAGA、XA 四种模式。

seata 的 XA 模式是利用分支事务中数据库对 XA 协议的支持来实现的。我们看一下 seata 官网的介绍:[1]

3.png

从上面的图可以看到,seata XA 模式的流程跟其他模式一样:

  1. TM 开启全局事务
  2. RM 向 TC 注册分支事务
  3. RM 向 TC 报告分支事务状态
  4. TC 向 RM 发送 commit/rollback 请求
  5. TM 结束全局事务

这里介绍一下 RM 客户端初始化关联的 UML 类图:[2]

4.png

这个图中有一个类是 AbstractNettyRemotingClient,这个类的内部类 ClientHandler 来处理 TC 发来的请求并委托给父类 AbstractNettyRemoting 的 processMessage 方法来处理。processMessage 方法调用 RmBranchCommitProcessor 类的 process 方法。

需要注意的是,「seata 的 xa 模式对传统的三阶段提交做了优化,改成了两阶段提交」:

  • 第一阶段首执行 XA 开启、执行 sql、XA 结束三个步骤,之后直接执行 XA prepare。
  • 第二阶段执行 XA commit/rollback。

mysql 目前是支持 seata xa 模式的两阶段优化的。

「但是这个优化对 oracle 不支持,因为 oracle 实现的是标准的 xa 协议,即 xa end 后,协调节点向事务参与者统一发送 prepare,最后再发送 commit/rollback。这也导致了 seata 的 xa 模式对 oracle 支持不太好。」

seata XA 源码

seata 中的 XA 模式是使用数据源代理来实现的,需要手动配置数据源代理,代码如下:

@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DruidDataSource druidDataSource() {
    return new DruidDataSource();
}

@Bean("dataSourceProxy")
public DataSource dataSource(DruidDataSource druidDataSource) {
    return new DataSourceProxyXA(druidDataSource);
}
  • 也可以根据普通 DataSource 来创建 XAConnection,但是这种方式有兼容性问题(比如 oracle),所以 seata 使用了开发者自己配置 XADataSource。
  • seata 提供的 XA 数据源代理,要求代码框架中必须使用 druid 连接池。

1. XA 第一阶段

当 RM 收到 DML 请求后,seata 会使用 ExecuteTemplateXA来执行,执行方法 execute 中有一个地方很关键,就是把 autocommit 属性改为了 false,而 mysql 默认 autocommit 是 true。事务提交之后,还要把 autocommit 改回默认。

下面我们看一下 XA 第一阶段提交的主要代码。

1)开启 XA

上面代码标注[1]处,调用了 ConnectionProxyXA 类的 setAutoCommit 方法,这个方法的源代码中,XA start 主要做了三件事:

  • 向 TC 注册分支事务
  • 调用数据源的 XA Start
xaResource.start(this.xaBranchXid, XAResource.TMNOFLAGS);
  • 把 xaActive 设置为 true

RM 并没有直接使用 TC 返回的 branchId 作为 xa 数据源的 branchId,而是使用全局事务 id(xid) 和 branchId 重新构建了一个。

2)执行 sql

调用 PreparedStatementProxyXA 的 execute 执行 sql。

3)XA end/prepare

public void commit() throws SQLException {
    //省略部分源代码
    try {
        // XA End: Success
        xaResource.end(xaBranchXid, XAResource.TMSUCCESS);
        // XA Prepare
        xaResource.prepare(xaBranchXid);
        // Keep the Connection if necessary
        keepIfNecessary();
    } catch (XAException xe) {
        try {
            // Branch Report to TC: Failed
            DefaultResourceManager.get().branchReport(BranchType.XA, xid, xaBranchXid.getBranchId(),
                BranchStatus.PhaseOne_Failed, null);
        } catch (TransactionException te) {
            //这儿只打印了一个warn级别的日志
        }
        throw new SQLException(
            "Failed to end(TMSUCCESS)/prepare xa branch on " + xid + "-" + xaBranchXid.getBranchId() + " since " + xe
                .getMessage(), xe);
    } finally {
        cleanXABranchContext();
    }
}

从这个源码我们看到,commit 主要做了三件事:

  • 调用数据源的 XA end
  • 调用数据源的 XA prepare
  • 向 TC 报告分支事务状态

到这里我们就可以看到,seata 把 xa 协议的前两个阶段合成了一个阶段。

2. XA commit

这里的调用关系用一个时序图来表示:

5.png

看一下 RmBranchCommitProcessor 类的 process 方法,代码如下:

@Override
public void process(ChannelHandlerContext ctx, RpcMessage rpcMessage) throws Exception {
    String remoteAddress = NetUtil.toStringAddress(ctx.channel().remoteAddress());
    Object msg = rpcMessage.getBody();
    if (LOGGER.isInfoEnabled()) {
        LOGGER.info("rm client handle branch commit process:" + msg);
    }
    handleBranchCommit(rpcMessage, remoteAddress, (BranchCommitRequest) msg);
}

从调用关系时序图可以看出,上面的 handleBranchCommit 方法最终调用了 AbstractRMHandler 的 handle 方法,最后通过 branchCommit 方法调用了 ResourceManagerXA 类的 finishBranch 方法。
ResourceManagerXA 类是 XA 模式的资源管理器,看下面这个类图,也就是 seata 中资源管理器(RM)的 UML 类图:

6.png

上面的 finishBranch 方法调用了 connectionProxyXA.xaCommit 方法,我们最后看一下 xaCommit 方法:

public void xaCommit(String xid, long branchId, String applicationData) throws XAException {
    XAXid xaXid = XAXidBuilder.build(xid, branchId);
 //因为使用mysql,这里xaResource是MysqlXAConnection
    xaResource.commit(xaXid, false);
    releaseIfNecessary();
}

上面调用了数据源的 commit 方法,提交了 RM 分支事务。

到这里,整个 RM 分支事务就结束了。Rollback 的代码逻辑跟 commit 类似。

最后要说明的是,上面的 xaResource,是 mysql-connector-java.jar 包中的 MysqlXAConnection 类实例,它封装了 mysql 提供的 XA 协议接口。

总结

seata 中 XA 模式的实现是使用数据源代理完成的,底层使用了数据库对 XA 协议的原生支持。

mysql 的 java 驱动库中,MysqlXAConnection 类封装类 XA 协议的底层接口供外部调用。

跟 TCC 和 SAGA 模式需要在业务代码中实现 prepare/commit/rollback 逻辑相比,XA 模式对业务代码无侵入。

Reference

[1]:http://seata.io/zh-cn/docs/overview/what-is-seata.html
[2]:https://github.com/seata/seata

What’s new in dubbo-go v1.5.6

alicloudnative阅读(176)评论(0)

头图.png

作者 | 铁城  dubbo-go 社区 committer
来源 | 阿里巴巴云原生公众号

dubbogo 社区近期发布了 dubbogo v1.5.6。该版本和 dubbo 2.7.8 对齐,提供了命令行工具,并提供了多种加载配置的方式。

相关改进实在太多,本文只列出相关重大 feature 和 性能提升项。

1. 命令行工具

熟悉dubbo 的朋友可能知道 dubbo 支持 telnet 命令行在线调试。

本次发布也增加了 dubbo-go 的 cli 命令行工具,可以方便用户直连特定服务,通过编写 json 文件来定义传输结构和数据,发起调用进行在线调试,打印返回数据和耗时情况。

目前支持嵌套 struct,但是只支持单个参数的请求包和回包。数据类型由于需要在 json 中定义,只支持 golang 基本数据类型:字符串、整形、浮点。

社区后续会再发一篇文章,着重讲解其原理和实现。相关 pr 为 https://github.com/apache/dubbo-go/pull/818,由 dubbogo 最年轻的 00 后 apache committer 李志信同学实现。

2. 代理实现扩展

重构 Proxy,添加 ImplementFunc 函数,允许项目对 Proxy 的代理进行重新实现。在使用 ProxyFactory 自定义注册的场景下,创建的 proxy.Proxy 也自定义实现,可以对返回数据进行修改。

主要应用场景为在网关泛化调用场景下。懂得的人自然懂。

相关 pr  https://github.com/apache/dubbo-go/pull/1019,由本文作者亲自操刀。

3. 启动时指定配置文件的路径

用户使用之前版本的 dubbogo 时,一直吐槽其只提供环境变量的方式,加载指定的配置文件。

export CONF_PROVIDER_FILE_PATH="../profiles/dev/server.yml"
export CONF_CONSUMER_FILE_PATH="../profiles/dev/server.yml"
export APP_LOG_CONF_FILE="../profiles/dev/log.yml"

v1.5.6 提供了新的配置文件加载接口:在启动命令行通过  proConf、conConf、logConf三个 flag 设定配置文件路径。

服务提供方:

go run . -proConf ../profiles/dev/server.yml -logConf ../profiles/dev/log.yml

服务消费方:

go run . -conConf ../profiles/dev/client.yml -logConf ../profiles/dev/log.yml

相关 pr https://github.com/apache/dubbo-go/pull/1039,由南京信息工程大学大三学生 陈家鹏实现。

4. 自定义加载 ServerConfig 和 ReferenceConfig

新增 ConfigPostProcessor 接口,用户可以依据该接口提供两个的方法,在部署 dubbogo 服务时加载自定义的配置。

// 服务提供方配置
PostProcessServiceConfig(*common.URL)

// 服务消费方配置
PostProcessReferenceConfig(*common.URL)

相关 pr  https://github.com/apache/dubbo-go/pull/943,由即将奔五十的 dubbo chairman 北纬亲自操刀实现,chairman 同志老当益壮,号召大家向 chairman 筒子学习。

5. 扩展 URL 的比较

在common/url.go里面提供 CompareURLEqualFunc,可以让用户自定义 URL 比较,提高比对效率。相关技术细节见如下链接。

common/url.go:
https://github.com/apache/dubbo-go/pull/854/files#diff-5111f14762c010c3029a67743796fea97ab1015d35c96670a4cfa25f30145464

目前的 URL 实现并未达到最终状态。未来的 dubbogo 3.x 版本中,将借鉴 dubbo 的 URL 实现,将 common.URL 拆分为ServiceConfigURL、ServiceAddressURL和InstanceAddressURL,分别对应配置中心、注册中心和元数据中心的 schema,尽量将变更压力降低到最低粒度。

该功能对应的 pr  https://github.com/apache/dubbo-go/pull/854 由阿里双十一中间件大队长展图同学实现。展图同学一直奋战在编程一线。

6. 注册中心优化

复用了 zookeeper 链接以及优化了服务发现中心逻辑,大大减少了与 zookeeper 的 tcp 链接数目,减少了使用的 goroutine 数目,降低了 dubbo-go 的内存占用量。

我们会把同样的逻辑服用到 nacos、etcd、consul 等各个注册中心,通过减少 goroutine 数目,减轻注册中心压力,并减少 consumer 和 provider 内存的使用。

该功能对应的 pr https://github.com/apache/dubbo-go/pull/1010 由现在蚂蚁中间件工作的 王文学 同学在涂鸦工作时实现。

7. API 形式进行配置

以前版本的 dubbogo 只提供了从配置文件读取配置选项,该功能增加以 API 的方式进行配置,用户可以通过调用相关 API 初始化配置。

用户可以通过 API 进行相关参数设定,无需再加载配置文件。

可以参考示例: https://github.com/apache/dubbo-go-samples/tree/master/config-api

相关 pr https://github.com/apache/dubbo-go/pull/1020 也是由李志信实现。

8. grpc 优化

  • 打通 dubbo-go中 consumer config 的超时时间 connect_timeout 和 gRPC server 的超时时间,用户可以自定义 gRPC 超时时间机制。
# connect timeout
connect_timeout: "3s"

# application config
application:
  organization: "dubbo.io"
  name: "GreeterGrpcConsumer"
  module: "dubbo-go greeter grpc client"
  version: "0.0.1"
  environment: "dev"
  • 将处理注册中心服务变更事件的机制改为同步,防止 provider 端服务频繁重启导致上下线事件处理顺序出错。
  • 使用 gRPC 协议时,异步等待 dubbo-go 的 service 都暴露完后,才将所有 dubbo-go service 对应的 gRPC service 注册到 gRPC server 上并启动 gRPC server。以此修复 provider 端的只能注册一个 service 的问题。

总体功能由 https://github.com/apache/dubbo-go/pull/1056 等多个 pr 构成,由 All In 了 dubbogo 的 上海识装信息科技有限公司【知名 APP 得物所在公司】工程师 柯瞻、 dubbogo 社区负责人 于雨、阿里工程师云兴 以及 南京某公司的张天同学 共同负责实现。

9. hessian2 go 最新 feature

除了  dubbo-go 自身的改进外,dubbo-go-hessian2 项目截止目前最新版本 v1.9.2 也做了如下重大改进:

dubbo-go-hessian2:https://github.com/apache/dubbo-go-hessian2

总体 pr 由 dubbo-go-hessian2 项目负责人 望哥、李志信、张艳明等同学完成。

10. 回顾与展望

dubbogo 目前处于一个比较稳定成熟的状态,1.5 版本会被持续维护,以修复 BUG 和进行一些必要的最低幅度的优化。

更多信息:https://github.com/apache/dubbo-go/releases/tag/v1.5.6

目前最新的朝云原生方向的发展3.0 版本基于 v1.5.x,在兼容 dubbo 3.0 的同时,将向后兼容 v2.7.x,计划于 4 月底发布第一个版本。

如果你有任何疑问,欢迎钉钉扫码加入交流群【钉钉群号 31363295】

作者简介

铁城 (Github ID cityiron),dubbo-go 社区 committer,主要参与 dubbo-go 1.5 版本迭代、 dubbo-go 3.0 服务路由和云原生方面工作、以及 dubbo-go-pixiu 项目负责人。目前就职于阿里盒马事业群,从事交易流程工作,擅长使用 Java/Go 语言,专注于云原生和微服务等技术方向。

独家对话阿里云函数计算负责人不瞋:你所不知道的 Serverless

alicloudnative阅读(282)评论(0)

头图.png

作者 | 杨丽
来源 | 雷锋网(ID:leiphone-sz)

Serverless 其实离我们并没有那么遥远。

如果你是一名互联网研发人员,那么极有可能了解并应用过 Serverless 这套技术体系。纵观 Serverless 过去十年,它其实因云而生,也在同时改变云的计算方式。如果套用技术成熟度曲线来描述的话,那么它已经走过了萌芽期、认知破灭期,开始朝着成熟稳定的方向发展。未来,市场对 Serverless 的接受程度将越来越高。

不要惊讶,阿里云团队在真正开始构建 Serverless 产品体系的最开始的一两年里,也曾遭遇内部的一些争议。而今,单从阿里集团内部的很多业务线来看,已经在朝着 Serverless 化的方向发展了。

日前,阿里云凭借函数计算产品能力全球第一的优势,入选 Forrester 2021 年第一季度 FaaS 平台评估报告,成为比肩亚马逊成为全球前三的 FaaS 领导者。这也是首次有国内科技公司进入 FaaS 领导者象限。

1.png

在与雷锋网的访谈中,阿里云 Serverless 负责人不瞋阐释了 Serverless 的演进历程、引入 Serverless 面临的难点与挑战、以及有关云原生的趋势预判。

“一定要想明白做这件事的终局是什么,包括产品体系的定位,对开发者、对服务商的价值等等这些问题。这要求我们不断通过实践和认识的深化,让这些问题的回答能够逐渐清晰起来。这也是我们这么多年实践积累的宝贵经验。”不瞋指出。

尽管企业的实践还存在种种疑惑和挑战,但 Serverless 实际上离我们并没有那么遥远。举一个最近的例子,新冠疫情让远程办公、在线教育、在线游戏的应用需求短期内增加。业务规模的爆发式增长,对每一个需求的响应需要更加及时,这对应用架构的弹性,对底层计算的速度,对研发效率的提升等,都要求业务加速向新技术架构演进。

而不瞋的理想就是,帮助更广泛的客户实现向新技术架构的平滑迁移,让 Serverless 渗透到所有的云应用中。

不瞋作为阿里云 Serverless 产品体系的负责人,也是国内 Serverless 的早期实践者。以下将呈现是对这次访谈的完整总结。

Serverless 的定义

在讨论之前,我们先明确 Serverless 的定义,确保大家对 Serverless 的认知是一致的。

现在 Serverless 越来越热,无论是工业界还是学术界,都将 Serverless 视为云计算发展的下一阶段。Serverless 有很多种表述,其中伯克利大学的定义相对严谨一些。

注:2019 年 2 月,加州大学伯克利分校发表的《Cloud Programming Simplified: A Berkerley View on Serverless Computing》论文,曾在业界引发诸多讨论和关注。

大致来讲,Serverless 实际对应的是一整套的产品体系,而不是单独一两个产品;同时,这些产品/服务之间还具备以下特征:服务之间彼此配合、全托管、用户通过 API 调用就可完成整个功能或应用的开发而无需关注底层基础设施。

这套产品体系目前可分为两类:一类是计算,即 FaaS(Function as a Service);还有一类是 BaaS(Backend as a Service),比如消息中间件、对象存储,都可以看做是 Serverless 化的 BaaS 服务。

Serverless 的演进

一个新技术通常会经历几个阶段:

  • 第一个阶段,是因为其巨大潜力引起广泛关注的阶段。
  • 第二阶段,是认知破灭的阶段,在这个阶段由于产品初期本身能力不是很强健,或案例不全等因素,导致用户在使用过程中往往会遇到挫败感。
  • 第三个阶段,是伴随实践的增加和产品能力本身的发展,又会逐步提升认知,进而进入一个稳健增长的阶段。

2.png

需要明确的是,Serverless 并不是一个非常新的技术。像阿里云的 OSS、AWS 的 S3 对象存储,它们都是最早发布的产品之一,一开始其实就是 Serverless 的形态。

但业界对 Serverless 的认知,确实是因 AWS 的 Lambda 带起来的,2014 年 AWS 推出了 Lambda。

2017 年到 2019 年上半年,这段时间,业界对 Serverless 的讨论很多同时又有很多困扰,不知道如何落地,或者用了之后才突然觉得跟自己想象的不太一样。

国内外技术发展保持着相似的节奏,国外相对来讲更快一些。从去年开始,国内也开始进入到了稳定发展的阶段。现在国际上主流云供应商提供的新功能或新产品,80% 以上都是 Serverless 的形态。

阿里云从 2017 年开始打造 Serverless,并于当年正式启动商业化。

目前在阿里集团内部已经开始落地 Serverless 了,例如飞猪、淘宝、高德等等。在企业赋能方面,尤其是疫情之后,能够看到用户对 Serverless 的认知比之前确实深入了许多,在很多场景下,切换到 Serverless 架构确实能够为用户带来明显的收益,用户也认可这项技术。

举一项数据来看,目前阿里云 Serverless 已经服务了上万家付费客户,拥有 100+ 的典型案例,函数日调用量超过 120 亿次、函数总量达到 100 万。

新旧观念的转变

对于阿里云自身而言,在最开始构建 Serverless 之初,其实最大的挑战不仅仅是技术层面的,更多的还有观念上的不对称。

首先,Serverless 本身的形态跟以往的计算形态差异比较大,整个研发和运维的体系跟传统应用是割裂的。如果开发 Serverless 应用,其研发运维的流程和工具跟虚拟化(VM)或容器化的方式不太一样,很多用户会担心供应商锁定(lock-in)的问题,不太希望自身的技术栈跟某个供应商绑定

其次,AWS 的 Lambda 最开始做了一个榜样,但它也实际也只适合于 AWS 的产品体系,如果放在其他的产品体系里会面临非常大的挑战,不易于被用户接受,且限制条件也很多,应用场景也有限。这就要求在技术层面,包括资源调度、安全隔离、多租户管理、流控等方面有很高要求,做起来非常辛苦。因为在此之前没有一个产品的计算形态是如此细粒度、动态的使用资源。

这种挑战,一开始即便在阿里内部,也曾面临过许多争议。

我们这么多年实践积累的宝贵经验是:一定要想明白做这件事的终局是什么,包括在产品体系中的定位,对开发者、对云服务商的价值等等这些问题。这要求我们不断通过实践和认识的深化,让这些问题的回答能够逐渐清晰起来。

3.png

引入 Serverless 的顾虑

站在客户层面,不同类型的客户对引入第三方的 Serverless 技术其实会有不同层面的考虑。

对于超大型企业,比如 Facebook、字节跳动,企业本身就有非常强的基础设施团队,通常他们会选择自己内部开发这方面技术。

还有一些企业,没有采用 Serverless 并不是说他们对这个技术有什么抵触,而是当下的落地实践或本身的工具链还无法做到完全消除供应商锁定的问题,又或者是因为工具链跟传统开发太过割裂,企业自身无法同时维护两套开发框架

这种情况下,用户的系统架构一定会面临一个中间状态:既有老的又有新的。如果整个迁移的过程不是那么平滑的话,供应商的这部分优势在客户那里是不存在的, 因为老的系统实际是需要维护的。如此,对用户的吸引力其实就没有那么大了。

阿里云最近开源的 Serverless Devs 解决的就是这样的问题。其定位是帮助用户更简单地开发和运维自己的 Serverless 化和容器化应用,提供应用全生命周期管理的能力。

本质上,Serverless 的环境是在远端,跟用户本地开发环境是天然割裂的,那么在这个过程中,从调试、部署、发布、监控等各个环节,Serverless Devs 都希望能为用户提供更好的体验。但用户可自由使用其中一个或几个功能,不需要将已有的研发运维的流程完全迁移到我们定义的这套规范里。

过去一年的重大升级

2020 年,疫情的背景下,其实也是阿里云 Serverless 技术升级的关键一年。这一年里,团队做了很多大的升级,包括:

  • 架构层面,已经升级到神龙裸金属服务器+袋鼠安全容器的下一代架构。好处是能够带来非常高的计算密度,进一步提升弹性能力和性能。
  • 缓存方面,发布容器镜像加速技术,能够让GB级别的容器镜像非常快地实现秒级启动。目前已经演进到了下一代,通过阿里内部大规模业务场景进行打磨。
  • 运行时方面,去年阿里云重写整个语言运行时,使得更具有可扩展性,启动速度更快。

4.png
阿里云函数计算全景图

总结起来,两方面因素推动阿里云Serverless在过去一年做出重大技术升级:

一是来自用户本身的诉求。比如在教育场景中,老师对开课这件事是有时效性要求的,这就要求后台能够短时间内启动可能数千个实例进行响应。

二是来自内部对产品效能的要求。对于云服务商而言,Serverless 最核心的一个定位,是能够将云上资源更好地利用起来。整个计算架构确实需要通过新的虚拟化技术、容器技术,同时跟新的硬件结合起来,从而提供一个非常细粒度的、启动非常快、非常弹性的计算模型。这也是为什么我们要进行架构升级,从原来的虚拟机架构演进到神龙裸金属服务器+袋鼠安全容器的架构,将对整体产品的发展产生一个核心推力。

攻克下一城

阿里云采用“三位一体”的策略打造整个 Serverless 产品矩阵——自身实践-开源-商业化。即通过集团内部超大规模、超复杂的业务场景来锤炼技术,将技术不断打磨产品化,然后对云上客户提供商业化服务,在这个过程中,还会将一些技术、工具进行开源,遵循开源开放的标准,跟开源生态融合。

只有对客户的业务产生价值和帮助,客户才会认可 Serverless。

短期来看,无论是业务规模,还是产品、技术层面,阿里云 Serverless 都在以非常稳健地方式按照自身的节奏向前演进。

  • 一是业务规模会更大,预计每年会有三倍以上的增长。
  • 二是产品层面,以客户为中心,解决用户痛点仍然是首要的。今年将在产品细节体验上继续补强,在工具链、可观测性等方面为用户提供更好的体验。
  • 三是技术层面,包括计算、网络、缓存、运行时等核心部分,继续夯实技术细节,实现极致性能。

云时代的新机遇

在应用场景上来看,Serverless 不再仅仅是小程序,还有电商大促、音视频转码、AI 算法服务、游戏应用包分发、文件实时处理、物联网数据处理、微服务等场景。

Serverless 将继续和容器、微服务等生态融合,降低开发者使用 Serverless 技术的门槛,反过来也将促进传统应用的云原生化。

Serverless 另一个核心要素是“被集成”,被集成的对象有两类:

  • 一类跟一方云服务进行接入,阿里云函数计算已被 30 多个一方云服务产品集成。
  • 第二类是通过 EventBridge 事件总线和三方生态被集成。例如和钉钉等 SaaS 应用集成。钉钉的业务中常常需要以简洁、轻量的方式完成用户的定制化需求,这和 Serverless 的应用形态是高度匹配的。

5.png
不瞋,阿里云 Serverless 负责人

今天,我们可以非常明确地看到,整个云的未来一定是 Serverless 形态的。阿里云内部对这个也没有争议,因为这么多年来,整个产品体系就是朝着 Serverless 方向发展的。

不是因为有了 Serverless 计算,云才向 Serverless 演进。恰恰相反,因为云的产品体系已经向 Serverless 演进,才催生了 Serverless 计算。单纯的 Serverless 计算并不能实现很多功能,前提一定是跟其他云服务及其生态配合,才能体现出其自身的优势。

无论是工业界还是学术界,都已经认可这样一个趋势。

罗美琪和春波特的故事…

alicloudnative阅读(203)评论(0)

头图.png

作者 | 辽天
来源 | 阿里巴巴云原生公众号

导读:rocketmq-spring 经过 6 个多月的孵化,作为 Apache RocketMQ 的子项目正式毕业,发布了第一个 Release 版本 2.0.1。这个项目是把 RocketMQ 的客户端使用 Spring Boot 的方式进行了封装,可以让用户通过简单的 annotation 和标准的 Spring Messaging API 编写代码来进行消息的发送和消费。

在项目发布阶段我们很荣幸的邀请了 Spring 社区的原创人员对我们的代码进行了 Review,通过几轮 slack 上的深入交流感受到了 Spring 团队对开源代码质量的标准,对 SpringBoot 项目细节的要求。本文是对 Review 和代码改进过程中的经验和技巧的总结,希望从事 Spring Boot 开发的同学有帮助。我们把这个过程整理成 RocketMQ 社区的贡献者罗美琪和 Spring 社区的春波特(SpringBoot)的故事。

故事的开始

故事的开始是这样的,罗美琪美眉有一套 RocketMQ 的客户端代码,负责发送消息和消费消息。早早的听说春波特小哥哥的大名,通过 Spring Boot 可以把自己客户端调用变得非常简单,只使用一些简单的注解(annotation)和代码就可以使用独立应用的方式启动,省去了复杂的代码编写和参数配置。

聪明的她参考了业界已经实现的消息组件的 Spring 实现了一个 RocketMQ Spring 客户端:

  • 需要一个消息的发送客户端,它是一个自动创建的 Spring Bean,并且相关属性要能够根据配置文件的配置自动设置, 命名它为:RocketMQTemplate, 同时让它封装发送消息的各种同步和异步的方法。
@Resourceprivate RocketMQTemplate rocketMQTemplate;
...
SendResult sendResult = rocketMQTemplate.syncSend(xxxTopic, "Hello, World!");
  • 需要消息的接收客户端,它是一个能够被应用回调的 Listener, 来将消费消息回调给用户进行相关的处理。
@Service@RocketMQMessageListener(topic = "xxx", consumerGroup = "xxx_consumer")
public class StringConsumer implements RocketMQListener<String> {
   @Override   public void onMessage(String message) {
       System.out.printf("------- StringConsumer received: %s \n", message);
   }
}

特别说明一下:这个消费客户端 Listener 需要通过一个自定义的注解@RocketMQMessageListener 来标注,这个注解的作用有两个:

  • 定义消息消费的配置参数(如: 消费的 topic, 是否顺序消费,消费组等)。
  • 可以让 spring-boot 在启动过程中发现标注了这个注解的所有 Listener, 并进行初始化,详见 ListenerContainerConfiguration 类及其实现 SmartInitializingSingleton 的接口方法 afterSingletonsInstantiated()。

通过研究发现,Spring-Boot 最核心的实现是自动化配置(auto configuration),它需要分为三个部分:

  • AutoConfiguration 类,它由 @Configuration 标注,用来创建 RocketMQ 客户端所需要的 SpringBean,如上面所提到的 RocketMQTemplate 和能够处理消费回调 Listener 的容器,每个 Listener 对应一个容器 SpringBean 来启动 MQPushConsumer,并将来将监听到的消费消息并推送给 Listener 进行回调。可参考 RocketMQAutoConfiguration.java  (编者注: 这个是最终发布的类,没有 review 的痕迹啦)。
  • 上面定义的 Configuration 类,它本身并不会“自动”配置,需要由 META-INF/spring.factories 来声明,可参考 spring.factories 使用这个 META 配置的好处是上层用户不需要关心自动配置类的细节和开关,只要 classpath 中有这个 META-INF 文件和 Configuration 类,即可自动配置。
  • 另外,上面定义的 Configuration 类,还定义了 @EnableConfiguraitonProperties 注解来引入 ConfigurationProperties 类,它的作用是定义自动配置的属性,可参考 RocketMQProperties.java,上层用户可以根据这个类里定义的属性来配置相关的属性文件(即 META-INF/application.properties 或 META-INF/application.yaml)。

故事的发展

罗美琪美眉按照这个思路开发完成了 RocketMQ SpringBoot 封装并形成了 starter 交给社区的小伙伴们试用,nice~大家使用后反馈效果不错。但是还是想请教一下专业的春波特小哥哥,看看他的意见。

春波特小哥哥相当负责地对罗美琪的代码进行了 Review, 首先他抛出了两个链接:

然后解释道:

“在 Spring Boot 中包含两个概念 – auto-configuration 和 starter-POMs,它们之间相互关联,但是不是简单绑定在一起的:

  • auto-configuration 负责响应应用程序的当前状态并配置适当的 Spring Bean。它放在用户的 CLASSPATH 中结合在 CLASSPATH 中的其它依赖就可以提供相关的功能。
  • Starter-POM 负责把 auto-configuration 和一些附加的依赖组织在一起,提供开箱即用的功能,它通常是一个 maven project,里面只是一个 POM 文件,不需要包含任何附加的 classes 或 resources。

换句话说,starter-POM 负责配置全量的 classpath,而 auto-configuration 负责具体的响应(实现);前者是 total-solution,后者可以按需使用。

你现在的系统是单一的一个 module 把 auto-configuration 和 starter-POM 混在了一起,这个不利于以后的扩展和模块的单独使用。”

罗美琪了解到了区分确实对日后的项目维护很重要,于是将代码进行了模块化:

|— rocketmq-spring-boot-parent  父 POM
|— rocketmq-spring-boot              auto-configuraiton 模块
|— rocketmq-spring-stater           starter 模块(实际上只包含一个 pom.xml 文件)
|— rocketmq-spring-samples         调用 starter 的示例样本

“很好,这样的模块结构就清晰多了”,春波特小哥哥点头,“但是这个 AutoConfiguration 文件里的一些标签的用法并不正确,帮你注释一下,另外,考虑到 Spring 官方到 2020 年 8 月 Spring Boot 1.X 不再提供支持,所以建议实现直接支持 Spring Boot 2.X。”

@Configuration
@EnableConfigurationProperties(RocketMQProperties.class)
@ConditionalOnClass(MQClientAPIImpl.class)
@Order  ~~春波特: 这个类里使用Order很不合理呵,不建议使用,完全可以通过其他方式控制runtime是Bean的构建顺序
@Slf4j
public class RocketMQAutoConfiguration {
   @Bean
   @ConditionalOnClass(DefaultMQProducer.class) ~~春波特: 属性直接使用类是不科学的,需要用(name="类全名") 方式,这样在类不在classpath时,不会抛出CNFE
   @ConditionalOnMissingBean(DefaultMQProducer.class)
   @ConditionalOnProperty(prefix = "spring.rocketmq", value = {"nameServer", "producer.group"}) ~~春波特: nameServer属性名要写成name-server [1]
   @Order(1) ~~春波特: 删掉呵   public DefaultMQProducer mqProducer(RocketMQProperties rocketMQProperties) {
       ...
   }
   @Bean
   @ConditionalOnClass(ObjectMapper.class)
   @ConditionalOnMissingBean(name = "rocketMQMessageObjectMapper") ~~春波特: 不建议与具体的实例名绑定,设计的意图是使用系统中已经存在的ObjectMapper, 如果没有,则在这里实例化一个,需要改成
    @ConditionalOnMissingBean(ObjectMapper.class)
   public ObjectMapper rocketMQMessageObjectMapper() {
       return new ObjectMapper();
   }
   @Bean(destroyMethod = "destroy")
   @ConditionalOnBean(DefaultMQProducer.class)
   @ConditionalOnMissingBean(name = "rocketMQTemplate") ~~春波特: 与上面一样
   @Order(2) ~~春波特: 删掉呵 
   public RocketMQTemplate rocketMQTemplate(DefaultMQProducer mqProducer,
       @Autowired(required = false)              ~~春波特: 删掉
       @Qualifier("rocketMQMessageObjectMapper") ~~春波特: 删掉,不要与具体实例绑定              
          ObjectMapper objectMapper) {
       RocketMQTemplate rocketMQTemplate = new RocketMQTemplate();
       rocketMQTemplate.setProducer(mqProducer);
       if (Objects.nonNull(objectMapper)) {
           rocketMQTemplate.setObjectMapper(objectMapper);
       }
       return rocketMQTemplate;
   }
   @Bean(name = RocketMQConfigUtils.ROCKETMQ_TRANSACTION_ANNOTATION_PROCESSOR_BEAN_NAME)
   @ConditionalOnBean(TransactionHandlerRegistry.class)
   @Role(BeanDefinition.ROLE_INFRASTRUCTURE) ~~春波特: 这个bean(RocketMQTransactionAnnotationProcessor)建议声明成static的,因为这个RocketMQTransactionAnnotationProcessor实现了BeanPostProcessor接口,接口里方法在调用的时候(创建Transaction相关的Bean的时候)可以直接使用这个static实例,而不要等到这个Configuration类的其他的Bean都构建好 [2]
   public RocketMQTransactionAnnotationProcessor transactionAnnotationProcessor(     
   TransactionHandlerRegistry transactionHandlerRegistry) {
     return new RocketMQTransactionAnnotationProcessor(transactionHandlerRegistry);
  }
   @Configuration  ~~春波特: 这个内嵌的Configuration类比较复杂,建议独立成一个顶级类,并且使用
   @Import在主Configuration类中引入 
   @ConditionalOnClass(DefaultMQPushConsumer.class)
   @EnableConfigurationProperties(RocketMQProperties.class)
   @ConditionalOnProperty(prefix = "spring.rocketmq", value = "nameServer") ~~春波特: name-server
   public static class ListenerContainerConfiguration implements ApplicationContextAware, InitializingBean {
      ...
      @Resource ~~春波特: 删掉这个annotation, 这个field injection的方式不推荐,建议使用setter或者构造参数的方式初始化成员变量
      private StandardEnvironment environment;
       @Autowired(required = false)  ~~春波特: 这个注解是不需要的
       public ListenerContainerConfiguration(
           @Qualifier("rocketMQMessageObjectMapper") ObjectMapper objectMapper) { ~~春波特: @Qualifier 不需要
           this.objectMapper = objectMapper;
       }

注[1]:在声明属性的时候不要使用驼峰命名法,要使用-横线分隔,这样才能支持属性名的松散规则(relaxed rules)。

注[2]:BeanPostProcessor 接口作用是:如果需要在 Spring 容器完成 Bean 的实例化、配置和其他的初始化的前后添加一些自己的逻辑处理,就可以定义一个或者多个 BeanPostProcessor 接口的实现,然后注册到容器中。为什么建议声明成 static的,春波特的英文原文:

If they don’t we basically register the post-processor at the same “time” as all the other beans in that class and the contract of BPP is that it must be registered very early on. This may not make a difference for this particular class but flagging  it as static as the side effect to make clear your BPP implementation is not supposed to drag other beans via dependency injection.

AutoConfiguration 里果真很有学问,罗美琪迅速的调整了代码,一下看起来清爽了许多。不过还是被春波特提出了两点建议:

@Configuration
public class ListenerContainerConfiguration implements ApplicationContextAware, SmartInitializingSingleton {
    private ObjectMapper objectMapper = new ObjectMapper(); ~~春波特: 性能上考虑,不要初始化这个成员变量,既然这个成员是在构造/setter方法里设置的,就不要在这里初始化,尤其是当它的构造成本很高的时候。
   private void registerContainer(String beanName, Object bean) {   Class<?> clazz = AopUtils.getTargetClass(bean);
   if(!RocketMQListener.class.isAssignableFrom(bean.getClass())){
       throw new IllegalStateException(clazz + " is not instance of " + RocketMQListener.class.getName());
   }
   RocketMQListener rocketMQListener = (RocketMQListener) bean;     RocketMQMessageListener annotation = clazz.getAnnotation(RocketMQMessageListener.class);
   validate(annotation);   ~~春波特: 下面的这种手工注册Bean的方式是Spring 4.x里提供能,可以考虑使用Spring5.0 里提供的 GenericApplicationContext.registerBean的方法,通过supplier调用new来构造Bean实例 [3]
    BeanDefinitionBuilder beanBuilder = BeanDefinitionBuilder.rootBeanDefinition(DefaultRocketMQListenerContainer.class);
   beanBuilder.addPropertyValue(PROP_NAMESERVER, rocketMQProperties.getNameServer());
   ...
   beanBuilder.setDestroyMethodName(METHOD_DESTROY);
   String containerBeanName = String.format("%s_%s", DefaultRocketMQListenerContainer.class.getName(), counter.incrementAndGet());
   DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getBeanFactory();
   beanFactory.registerBeanDefinition(containerBeanName, beanBuilder.getBeanDefinition());
   DefaultRocketMQListenerContainer container = beanFactory.getBean(containerBeanName, DefaultRocketMQListenerContainer.class);   ~~春波特: 你这里的启动方法是通过 afterPropertiesSet() 调用的,这个是不建议的,应该实现SmartLifecycle来定义启停方法,这样在ApplicationContext刷新时能够自动启动;并且避免了context初始化时由于底层资源问题导致的挂住(stuck)的危险
   if (!container.isStarted()) {
       try {
           container.start();
       } catch (Exception e) {
         log.error("started container failed. {}", container, e);           throw new RuntimeException(e);
       }
   }
   ...
 }
}

注[3]:使用 GenericApplicationContext.registerBean 的方式。

public final < T > void registerBean(
Class< T > beanClass, Supplier< T > supplier, BeanDefinitionCustomizer… ustomizers)

“还有,还有”,在罗美琪采纳了春波特的意见比较大地调整了代码之后,春波特哥哥又提出了 Spring Boot 特有的几个要求:

  • 使用 Spring 的 Assert 在传统的 Java 代码中我们使用 assert 进行断言,Spring Boot 中断言需要使用它自有的 Assert 类,如下示例:
import org.springframework.util.Assert;
...
Assert.hasText(nameServer, "[rocketmq.name-server] must not be null");
  • Auto Configuration 单元测试使用 Spring 2.0 提供的 ApplicationContextRunner:
public class RocketMQAutoConfigurationTest {
   private ApplicationContextRunner runner = new ApplicationContextRunner()           .withConfiguration(AutoConfigurations.of(RocketMQAutoConfiguration.class));

   @Test(expected = NoSuchBeanDefinitionException.class)   public void testRocketMQAutoConfigurationNotCreatedByDefault() {
       runner.run(context -> context.getBean(RocketMQAutoConfiguration.class));   }
   @Test
   public void testDefaultMQProducerWithRelaxPropertyName() {
       runner.withPropertyValues("rocketmq.name-server=127.0.0.1:9876",               "rocketmq.producer.group=spring_rocketmq").
               run((context) -> {
                   assertThat(context).hasSingleBean(DefaultMQProducer.class);                   assertThat(context).hasSingleBean(RocketMQProperties.class);               });
   }
  • 在 auto-configuration 模块的 pom.xml 文件里,加入 spring-boot-configuration-processor 注解处理器,这样它能够生成辅助元数据文件,加快启动时间。

详情见这里:
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-auto-configuration.html#boot-features-custom-starter-module-autoconfigure

最后,春波特还相当专业地向罗美琪美眉提供了如下两方面的意见:

1. 通用的规范,好的代码要易读易于维护

1)注释与命名规范

我们常用的代码注释分为多行(/ … /)和单行(// …)两种类型,对于需要说明的成员变量,方法或者代码逻辑应该提供多行注释; 有些简单的代码逻辑注释也可以使用单行注释。在注释时通用的要求是首字母大写开头,并且使用句号结尾;对于单行注释,也要求首字母大写开头*;并且不建议行尾单行注释。

在变量和方法命名时尽量用词准确,并且尽量不要使用缩写,如: sendMsgTimeout,建议写成 sendMessageTimeout;包名 supports,建议改成 support。

2)是否需要使用 Lombok

使用 Lombok 的好处是代码更加简洁,只需要使用一些注释就可省略 constructor,setter 和 getter 等诸多方法(bolierplate code);但是也有一个坏处就是需要开发者在自己的 IDE 环境配置 Lombok 插件来支持这一功能,所以 Spring 社区的推荐方式是不使用 Lombok,以便新用户可以直接查看和维护代码,不依赖 IDE 的设置。

3)对于包名(package)的控制

如果一个包目录下没有任何 class,建议要去掉这个包目录。例如:org.apache.rocketmq.spring.starter 在 spring 目录下没有具体的 class 定义,那么应该去掉这层目录(编者注: 我们最终把 package 改为 org.apache.rocketmq.spring,将 starter 下的目录和 classes 上移一层)。我们把所有 Enum 类放在包 org.apache.rocketmq.spring.enums 下,这个包命名并不规范,需要把 Enum 类调整到具体的包中,去掉 enums 包;类的隐藏,对于有些类,它只被包中的其它类使用,而不需要把具体的使用细节暴漏给最终用户,建议使用 package private 约束,例如:TransactionHandler 类。

4)不建议使用 Static Import, 虽然使用它的好处是更少的代码,坏处是破坏程序的可读性和易维护性。

2. 效率,深入代码的细节

  • static + final method:一个类的 static 方法不要结合 final,除非这个类本身是 final 并且声明 private 构造(ctor),如果两者结合以为这子类不能再(hiding)定义该方法,给将来的扩展和子类调用带来麻烦。
  • 在配置文件声明的 Bean 尽量使用构造函数或者 Setter 方法设置成员变量,而不要使用@Autowared,@Resource等方式注入。
  • 不要额外初始化无用的成员变量。
  • 如果一个方法没有任何地方调用,就应该删除;如果一个接口方法不需要,就不要实现这个接口类。

注[4]:下面的截图是有 FieldInjection 转变成构造函数设置的代码示例。

1.png

转换成:

2.png

故事的结局

罗美琪根据上述的要求调整了代码,使代码质量有了很大的提高,并且总结了 Spring Boot 开发的要点:

  • 编写前参考成熟的 spring boot 实现代码。
  • 要注意模块的划分,区分 autoconfiguration 和 starter。
  • 在编写 autoconfiguration Bean 的时候,注意 @Conditional 注解的使用;尽量使用构造器或者 setter 方法来设置变量,避免使用 Field Injection 方式;多个 Configuration Bean 可以使用 @Import 关联;使用 Spring 2.0 提供的 AutoConfigruation 测试类。
  • 注意一些细节:static 与 BeanPostProcessor;Lifecycle 的使用;不必要的成员属性的初始化等。

通过本次的 Review 工作了解到了 spring-boot 及 auto-configuration 所需要的一些约束条件,信心满满地提交了最终的代码,又可以邀请 RocketMQ 社区的小伙伴们一起使用 rocketmq-spring 功能了,广大读者可以在参考代码库查看到最后修复代码,也希望有更多的宝贵意见反馈和加强,加油!

后记

开源软件不仅仅是提供一个好用的产品,代码质量和风格也会影响到广大的开发者,活跃的社区贡献者罗美琪还在与 RocketMQ 社区的小伙伴们不断完善 spring 的代码,并邀请春波特的 Spring 社区进行宣讲和介绍,下一步将 rocketmq-spring-starter 推进到 Spring Initializr,让用户可以直接在 start.spring.io 网站上像使用其它 starter(如: Tomcat starter)一样使用 rocketmq-spring。