月度归档:2019年10月

轻量型互联网应用架构方式

轻量型 Web 架构模式

前言

说到互联网应用架构,就绕不开微服务,当下(2019)最热门的微服务架构体系应该还是 Spring Cloud 和 Dubbo,阿里也推出了自己的 Spring Cloud 实现 Spring Cloud Alibaba。这类框架围绕微服务体系提供了大而全的功能,包括服务发现、治理、流量监控、配置管理等,让人向往。

但是其缺点也是比较明显:

  • 限定于 Java 体系,其他编程语言无法享受这个体系
  • 侵入应用,几乎每个 Java 应用都挂载一堆 Spring 相关的 jar 包

所以目前社区发展的新方向是:云原生。

其中的翘楚便是 istio,基于 kubernetes 的 sidecar 模式,把 Sprint Cloud 做的大部分工作下沉到基础应用层面,让应用层无感。
有了 Istio 之后,微服务应用实现了大减负,所以我重新思考了对于小型互联网公司来说,当下最适合的架构模式应该是什么

Web 架构模式

适用场景:小型互联网公司,业务多而小,追求开发效率。
解决方案:把重复工作隐藏起来,让应用层轻量快跑

具体有两个方向
基础架构层面:使用 Kubernetes 和 Istio,提供微服务所需要的功能支持
应用层面:针对 Nodejs 后端编程领域,提供一个最佳实额

整体架构图:

基础架构实践

目前还没有足够的时间完成落地实践,只能说一下理论规划。
现在是云时代,所以直接用 Kubernetes 来做应用编排就可以了。
后期可以落地 Istio,就可以保证微服务们稳定运行。

容器编排

Kubernetes

日志收集

  • 在 k8s 集成 elk
  • 输入日志到阿里云 nas

应用观测

Istio 提供 Grafana 请求分析、 Jaeger链路追踪、告警等

流量控制

  • 权限校验
  • 加密
  • 熔断限流

Web 应用架构

在应用层,我最终选择是使用 Node.js 语言来做主要的业务开发。

使用 Koa + 自研框架。

语言的选择,为什么是 Node.js

主要原因是我目前所在团队技术栈在 Node 积累比较多。

其次原因是有了 typescript 之后,使用 node 编写后端应用变得更加可维护了,而且 node 小而快(开发效率快,当然IO密集型的应用运行效率也不差)非常适合微服务场景。

最后,Node 的上手难度真的很低。

当然要使用其他语言也是可以的,如果有着复杂业务逻辑,可以使用 Kotlin + Spring Boot 这组套件,但不包括 Spring Cloud

Kotlin 能完美复用 JVM 生态,也可以避免 Java 语言的一些繁琐的写法,甚至后期还可以用上 Kotlin 的协程,来替代 Java 目前的多线程并发模型。

当然,本文讨论的是 Web 应用架构,如果你的应用是数据处理方面,本文无法提供任何帮助。而在 Web 领域,Python 和 PHP 对比起 Node,其实并没有优势,所以就不考虑了。

Web 框架如何选

Node 的 Web 框架还挺多的,我比较熟悉的有:

  • Sails.js 大而全,甚至有自己的 orm, node 世界的 ruby on rails
  • Express 基础 web 框架
  • Koa 更基础的 web 框架,甚至两 body-parse 都不自带
  • Thinkjs Thinkphp 吧
  • Egg 阿里出品,挺受欢迎的
  • NestJS node 世界的 Spring MVC

我公司早期使用 sails,看中其集成的丰富功能,但是后期 sails 的成长速度跟不上社区,对一些新特性 Generator 等不能及时兼容,而且太笨重了。

所以团队在 17 年左右转型选择了 Koa,然后自己组装实践各个基础功能,这个做法的好处是高度自定义,非常契合公司发展需要。

社区优秀的框架们

在 17 年之后,相继涌现一些优秀框架,像 egg 和 nestjs,当时我们并没有采用他们。

Egg 本身是优秀的框架,但是它是为中台打造的,但我公司需要用 Node 完成本来是 Java 做的事情,我们会用 Node 做比较重的业务,Egg 在这方便并不适合,例如没有模块划分的概念。

比起 Egg ,NestJS 就更适合我们,当时看它的文档就能感受出来,NestJS 的作者们是真的拿这个框架来做后端业务的,文档里讲到了我们日常碰到的很多痛点:

  • 模块划分
  • 循环引用
  • OpenAPI
  • IOC 依赖注入
  • CRUD

当时感觉像是找到了真爱,但是实践过后,发现一些问题:

  • 编码规范:NestJS 有自己的一套规范,而且它封装得足够多,基本上无法修改这套规范,只能妥协。
  • 集成测试:我们在早期使用 Koa 的过程中,沉淀了一套集成测试方案,特别是对 mongodb,我们做了一些工具可以自动注入和清除测试数据,要在 NestJs 实现这个功能,需要有足够的时间对其改造

基于上面两个原因,NestJS 并没有在团队推广开来。

自研的方向

社区的框架既然不合适,那就博采众长,自己组装一套框架出来,所以我最近捣鼓出了 @akajs, 预期说这个东西是框架,更准确的说法是,Kalengo团队的Node后端开发最近实践集合。就是把后端常用的东西集合打包起来,包含:

  • IOC 依赖注入
  • 注解式路由
  • CRUD 我们很多项目非常简单,重复的 CRUD 工作必须简化
  • Mongoose + Typescript 封装
  • Redis + Redlock 封装
  • 集成测试支持
  • 常用 Util,如日期数字处理等
  • 请求参数校验和全局异常处理

此外还有些最佳实践

  • OpenAPI 文档自动生成
  • Docker 支持
  • UML 设计
  • 模块划分

这些我们则通过项目模板来提供。

有了这套工具,后端可以更加轻量和统一,开发可以短时间内搭建起一个完备的后端服务。

总结

这套架构方式,不论是基础架构层面,还是应用层面,都是通过抽离通用的功能,把服务治理的东西抽出下沉到 Istio,把后端通用的工具和实践抽出放在 @akajs 和项目模板中,以此来简化上层应用。

这样一线的后端开发,可以专注于业务逻辑的实现,不必在为基础设施烦恼。毕竟小公司要生存,“快”是很重要的。