移动云平台的基础架构之旅-云应用篇

背景

当下10后都能在手机键盘上敲字如飞,60后的均可以坦然的摇微信,移动互联网可谓煊赫一时。随着智能手机的快速发展,移动APP做为登入移动互联网最便捷的方式,扼守着移动互联网的入口。如今这类软件被愈来愈多的人所青睐,在没有大量资金的状况下,手机APP是中小企业发展方向的一个很好选择。对于我的和企业移动APP 已是创业和发展的必备工具。移动互联网APP开发,对于企业来讲面临着项目周期,资源投入,推广等诸多问题,而对于我的更是望而却步。html

传统移动开发技术方案:java

maxwon_chuangtong

难题
  1. 终端移动平台太多:Android,IOS,Windows Phone,微信 …. 并且不一样平台还有版本差别,对于开发调试简直是一场噩梦,要想实现统一覆盖没有雄厚的资本支持是很是困难的。node

  2. 开发成本:招人难,找到合适的更难,成本高,移动开发门槛障碍git

  3. 捡了芝麻丢了西瓜:企业把精力投入到本身不擅长的领域大多时候并非一件好事情,对于我的来讲更是如此。github

  4. 全站解决方案:一个优秀的APP除了核心业务同时也须要其余优秀的组件,如:推送,用户行为分析,市场活动,数据统计等等。web

  5. 运维困难:要保证APP的稳定可靠运行,运维是必不可少的一部分,这些工做须要专业的运维团队来作。这样也加剧了企业的负担。sql

如今是一个屌丝逆袭的时代,为了帮助企业和我的无门槛拥有属于本身的APP,MaxWon 应运而生。docker

MaxWon 是基于MaxLeap SaaS 云服务,集成不一样行业模块,集 APP 生成,运营,分析,自动化运维与一体的服务,用户只须要关心本身的业务,彻底摆脱上面的各类难题。shell

maxwon_jiahua

用户组合本身想要的模块,点击生成APP,就能够生成本身想要的不一样平台的APP,包括Android,IOS,微官网,PC官网。数据库

须要解决的的问题
  1. 差别化服务。因为是面向多租户的服务,不一样的APP产生的流量可能差别很大,系统要能作到服务隔离和水平扩展。

  2. 数据隔离与扩展。为了保证数据安全,每个APP 都会有一个独立的DB,数据只能被本身的APP访问,防止数据hack,保证数据安全。对于大数据量的APP,DB 可以支持无限扩展。

  3. 快速部署与自动化运维。

  4. 服务的监控。因为服务遍及在集群的不一样机器上,须要可以监控全部租户服务的健康状态,保证服务的高可用行,而且可以水平扩展。

  5. 支持服务和数据的迁移

能独立运行的1.0

因为MaxWon 须要支持不一样行业,业务就会比复杂,比较多。项目业务层是按模块来划分,经过不一样模块的组合来不一样知足行业的需求。

maxwon_yewu2

初版架构遵循两个原则:第一, 以业务实现为目标,尽快作出产品原型。因为MaxLeap已经有不少基础的中间件能够直接拿来使用,如:推送,FAQ&Issue,支付,IM&社交等。如今只须要把精力放在MaxWon 本身的业务中去。第二,快速响应产品的需求,产品指导研发,不少场景、不少的玩法必须帮助产品实现,并且速度要很是快,要快速迭代。

主要技术栈
描述 名称
平台 JDK 1.8
Web框架 vertx-jersey(异步)
ORM JOOQ
RDS Mysql
NoSql Mongo

对于大部分人来讲 Vert.x可能会有点陌生,它是基于Netty实现的异步架构,和node.js 极其类似。因为以前作MaxLeap服务,一直在用Vert.x作为基础架构,整个团队对Vert.x 也很熟悉,该踩得坑也都踩过了,经过Verx-Rpc 能够直接访问的MaxLeap 的微服务。在使用Vert.x 时最大的感觉就是不能写同步代码,不然就会阻塞,致使致使服务不可用,因此咱们的服务全是基于异步的方式来写的。因为它是一个轻量级高性能JVM应用平台,支持多语言开发,它的简单actor-like 机制能帮助脱离直接基于多线程编程,天生支持分布式,之后对于服务扩展也是水到渠成的事情。

对于ORM 并无使用主流的 Hibernate或者IBATIS,而是使用小众的JOOQ。JOOQ 相对于其余ORM算是很轻量,提供了强大的DSL 来访问数据库,灵活,上手很容易,代码很是接近sql。

JOOQ runtime schema mapping 对于多租户应用程序有很好的支持,能够很容易的实现为每一个租户分配独立的DB。

还有一个重要的缘由就是 JOOQ 已经和Java8 的Stream API 彻底融合,cool!!。函数式编程表达性强,而且很是通用。它是数据及数据流处理的核心。Java开发人员如今也都知道函数式编程,并且你们又都用过SQL。想象一下,你用SQL来声明表来源,把数据转化成新的元组流,而后要么将它们做为派生表提供给其它更高级的SQL语句来使用,要么将它们交给你的应用程序来处理。

下面就是一段典型的Java代码

DSLContext create = DSL.using(connection, dialect);
create.select(AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME, count())
      .from(AUTHOR)
      .join(BOOK).on(BOOK.AUTHOR_ID.equal(AUTHOR.ID))
      .where(BOOK.LANGUAGE.equal("DE"))
      .and(BOOK.PUBLISHED.greaterThan("20017-01-01"))      
      .limit(2)
      .offset(1)     
      .fetch(record -> transfer(record))
      .stream()
      .filter(ele -> null != ele)
      .collect(Collectors.toList());

有了JOOQ,Java 8以及Streams API,你能够写出强大的数据转化的API,并且简单易懂。

maxwon_001

架构特色

将架构特色划分为优势和缺点进行描述。那么优势是:

  • 简单,易于实现,不须要额外的基础支撑

  • 利于业务的功能快速实现

  • 服务都是以Docker Container 启动,能够实现快速发布与部署

缺点:

  • 不一样租户的应用没法隔离,全部的APP 都使用相同的Container,这样会带来APP之间相互影响,致使服务不稳定的风险。

  • 缺乏服务健康检查。

  • 运维成本过大。

1.0的架构就是一个简单的Web系统。负载均衡使用Nignx,并无细化到租户级别。业务系统经过代码模块的形式组织各类业务就是一个简单的Web系统,后面直接挂了数据库,好比商品、订单、会员、客服,等等。能够看到,咱们这个基础的架构,对外就是HTTP。当时两我的的小团队开发各类业务,咱们考虑只能用最简单、最粗暴的方式实现,能快速地实现业务。当时的流量不是第一重要的问题,也不是最主要的矛盾。

对于这个阶段,总结了三点。第一,技术来源于业务同时提高业务发展,业务发展又反过来推进技术的前进,他们是一个相互影响相互促进的关系。和业务共同发展的技术才是有生命力的。第二,成熟简单的技术就是最合适的,这个理念一直贯穿始终。不要把事情复杂的形态呈现给你们,脑子要保持简单,不要想那么复杂的事儿。第三,要把能遇到的场景尽可能到考虑到,之后架构升级不至于很被动。你们看到初始的架构等于没有架构,可是这种形式在这时是最符合业务需求的一个,能快速迭代,能很是方便上线。

面向多租户的2.0

在MaxWon1.0时代的时候,咱们的关注点更偏向业务的实现,随着用户增加,性能和稳定性问题逐渐浮上水面,做为一个多租户的应用系统,系统不稳定,是很是致命的,2.0解决这些问题也迫在眉睫。

要解决的问题

首先要解决的就是服务分离。其中有两种方案 :

  1. 每个租户APP都有属于本身的 服务 Container,这样就解决了租户之间的相互影响。可是 大部分 APP 访问点可能很小,甚至是僵尸应用。虽然Docker 容器使用的资源很小,可是大量的不活跃应用仍是会浪费掉太多的系统资源,资源利用率低。

  2. 按租户的真实的访问量划分为不一样的组,普通规模应用或者是僵尸应用都公用同一组Container,中等规模应用 某几个使用一组Container,对于大量数据流量的应用 独占 同一组Container,这样的话资源利用率就会很高。缺点就是 普通规模和中等规模应用 服务之间仍是会有影响,因为这两种规模的数据访问的会少不少,出现慢查询而致使拖慢整个系统的可能性会很小。

对比上面的两个方案优缺点,基于现实的考虑最终选择了第二种方案。这就须要可以随时监控APP的数据访问量,当某个APP访问量快速上升时可以随时独立出服务来,这样就能够最大限度的防止租户以前相互影响而产生的服务抖动。

对于服务监控,则采用心跳检测的方式,每一个服务Container对外暴露一组健康检查的接口,监控系统会定时的巡视全部服务的健康状态,若是因为某种缘由被Kill掉,则重启对应Container的并产生告警。

对于数据存储分离 也采用了一样的思路。对于Mongo ,Pandora自己就支持按不一样App 数据分治。对于Mysql代理则采用 MaxLeap 研发的 Circe组件,能够实现不一样App数据的隔离。使用AWS ELB 解决了Circe的负载均衡与高可用。

2.0的采用了服务和数据分离的思想,如今回顾也并不复杂,对于码农来讲这种思想已是很是熟悉的了。若是你的产品功能很少,迭代不是很快,能够放慢一下脚步,停下来一段时间来集中一次重构。但对于MaxWon来讲这一版本的迭代就像是鸟枪换炮,知足了大部分的应用场景。对于业务快速迭代,上线时间紧迫的系统来讲,此次重构也是一个不小的挑战。

优点
  • 继承了原有1.0的特色,保留了其优点

  • 解决了数据和服务隔离与扩容的问题

  • 实现不一样租户的差别化服务

  • 添加了服务监控与检查

Docker 构建和发布

使用docker 构建能够完美的解决环境冲突的问题,也能够方便快速部署和扩容。

FROM 10.10.10.160:8010/maxleap/vertx:3.2.1
MAINTAINER ben.ma <cma@maxleap.com>
#----------------------------Copy 项目目录到容器里------------------------------------------
RUN \
mkdir -p /opt/maxwon
#覆盖vert.x 相关配置
ADD lib/ $VERTX_HOME/lib/
ADD log4j2.xml $VERTX_HOME/conf/
ADD zookeeper.properties $VERTX_HOME/conf/
ADD config.json /opt/maxwon/
WORKDIR /opt/maxwon
ENTRYPOINT ["vertx", "run", "java-hk2:as.leap.ama.module.jersey.JerseyVerticle", "--conf", "config.json"]

经过spotify docker-maven-plugin 插件,根据事先定义在项目中的DockerFile能够轻松的把项目打包成可执行的docker Image并push到生产环境中。

$ mvn clean deploy -DpushImage -Pcn
好用的中间件

Hydra: 海德拉 古希腊神话人物,是一种传说中有九个头的大蛇,为冥王看守门户。在这里Hydra 做为 MaxWon的API网关,管理来自不一样端的请求,根据请求的来源转发到相应的的MaxWon的服务容器组中。同时它也会管理和监控容器状态以及对服务的动态扩容。

hydra

Circe:希腊神话里一个能制造幻觉的女巫,这里用来隐喻可以制造Mysql服务的代理的项目.经过它能够实现不一样租户的数据隔离,过滤非法,有毒的sql语句,保证数据隐私和安全。

Pandora:访问MongoDB的基础组件,也是MaxLeap 核心组件之一,提供了同步和异步的两种接口。Pandora最为核心的功能是实现了资源限制和数据库访问的路由策略,这对数据库进行平滑的动态扩展及迁移提供了可靠的支持。感兴趣的能够参考同事写的MONGO 集群设计

总结

脱离业务谈架构都是扯淡,利用技术手段提高工做效率是好事,别陷进去,产品最终拿出来讲话的仍是有没有解决用户的问题,而不是解决你本身的问题。对于MaxWon 这种快速迭代的系统,系统也会考虑更多的业务场景,体积也愈来愈庞大,遇到棘手的问题也会愈来愈多,作好优化的准备。

系统要尽可能保持简单,技术架构的选型建议是寻找当前最短路径,而后进行不断优化迭代,想一口吃个大胖子不太可能。

代码不要写死。

本文做者来自 MaxLeap 团队_数据服务组 成员:马传林
马传林,从事开发工做已经有5年。当前在MaxLeap数据服务组担任开发工程师,主要负责MaxWon服务器开发。
本文连接:https://blog.maxleap.cn/archives/734

欢迎关注微信订阅号:从移动到云端欢迎加入咱们的MaxLeap活动QQ群:555973817,咱们将不按期作技术分享活动。

相关文章
相关标签/搜索