1.架构,架构与业务紧密相关,是有业务驱动的。
2.APP后台演进原则。
App后台的架构是由业务规模驱动而演进的,App后台是为业务服务的,App后台的价值在于能为业务提供其所需要的功能,不应过度设计。
从项目的角度,当App访问量不大时,应该快速搭建App后台,让App尽快上线给用户提供服务,验证商业模式的正确性,同时快速迭代产品。
当App访问量不断上升,这时要在保证快速迭代的前提下,同时兼顾高性能和高可用。
当App访问量达到一定阶段后,增长曲线就会放缓,但业务变得更加复杂,对高性能和高可用的要求也更高,性能问题、模块间的耦合、代码的复杂性会更加突出和明显,这时要使用业务拆分、分布式服务调用,甚至是技术转型等问题。
1.项目启动时,单机部署。
app后台一个极简化的架构:
一开始就使用Redis的好处:
既能用作缓存,又能充当队列服务,而且并发性能高,能在长时间内应对业务压力,非常适合初期的项目。
这里使用Redis验证用户信息,充当消息队列。
而文件服务初期可以选择 文件云存储服务,或者自己搭建一个资源服务器。
2.项目一定规模时,分布式部署:
看一个百万到千万级的架构:
这里新增了专门用于连接内部服务器的SSH服务的外网通道,保证SSH操作随时可用,同时加入了服务器集群,提供负载能力。
随着业务的发展,某些数据表的规模会以几何级增长,当数据达到一定规模时,查询读取性能就下降的厉害,数据库主从的架构不能应对业务上的读写压力,这时架构上要考虑分表(水平拆分/垂直拆分)。
当业务继续不断发展,数据库分表后的读写性能也可能没法满足业务上的需求,这时只能采用进一步的拆分策略——分库。用 Cobar 或者 MyCat 等关系型数据等分布式处理系统后,分库后的架构如下:
3.可供选择的成熟稳定的开源软件
功能 | 可供选择的开源软件 |
---|---|
项目管理软件 | Mantis、BugFree |
代码管理软件 | SVN、Git |
编程语言 | Java、PHP、Python等 |
服务器系统 | CentOS、Ubuntu |
HTTP/HTTPS服务器 | Nginx、Tomcat、Apache |
负载均衡 | Nginx、LVS、HAProxy |
邮件服务 | Postfix、Sendmail |
消息队列 | RabbitMQ、ZeroMQ、Redis |
文件系统 | Fastdfs、mogileFS、TFS |
Android推送 | Androidpn、gopush |
IOS推送 | Javapns、Pyapns |
地理位置查询LBS | MongoDB |
聊天 | Openfire、ejobberd |
监控 | ngiOS、zabbix |
缓存 | Memcache、Redis |
关系型数据库 | MySQL、MariaDB、PostgreSQL |
NoSQL数据库 | Redis、MongoDB、Cassandra |
搜索 | Coreseek、Solr、ElasticSearch |
图片处理 | GraphicsMagick、ImageMagick |
分布式访问服务 | dubbo、dubbox |
4.可供选择的可靠云服务
对于初创公司还是建议尽可能的使用成熟可靠的云服务和开源软件,自身只专注于业务逻辑。
功能 | 可供选择的云服务 |
---|---|
项目管理工具 | Teambition、Tower |
代码托管平台 | GitHub、Gitlab、Bitbucket、CSDN CODE、Coding |
负载均衡 | 阿里云SLB、腾讯云CLB |
邮件服务 | SendCloud、MailGun |
消息队列 | 阿里云MNS、腾讯云CMQ |
文件系统、图片处理 | 七牛云、阿里云对象存储OSS、腾讯云对象存储COS |
Android推送 | 极光、个推、百度推送 |
IOS推送 | 极光、个推、百度推送 |
聊天 | 融云、环信 |
监控 | 监控宝、云服务器自带的监控服务 |
缓存 | 阿里云缓存服务、腾讯云弹性缓存 |
关系型数据库 | 阿里云RDS、腾讯云CDB |
NoSQL数据库 | 阿里云NoSQL产品、腾讯云NoSQL产品 |
搜索 | 阿里云开放搜索、腾讯云搜TCS |
分布式访问服务 | 阿里云EDAS |
防火墙 | 阿里云云盾、腾讯云安全 |
短信发送 | shareSDK、bmob、Luosimao |
社交登录分享 | shareSDK |
5.选择合适的数据库产品和服务器系统
数据库产品:
数据库 | 数据存放位置 | 查找数据的区别 |
---|---|---|
Redis | 内存 | 基于键值对存储,读写速度快 |
MongoDB | 同时使用了硬盘和内存 | 每个数据有一个id(索引),知道id(索引)查询速度快,不知道id(索引)效率低 |
MySQL(MongoDB) | 硬盘 | 每个数据有一个id(索引),知道id(索引)查询速度快,不知道id(索引)效率低 |
然后根据不同的产品需求选择恰当的数据库产品,如果没有特殊的需求,Redis做缓存系统,MySQL 或 MariaDB 做数据库(常见的设置是 数据库默认字符集utf8,默认排序utf8_general_ci) 将会是很好的选择。
软件优化:
硬件优化:
架构优化:
-
分库(把一张表的数据分别存储在不同的数据库,可用MyCat实现,MyCat,关系型数据库分布式处理软件)。
-
MyCat以代理服务器的形式位于App服务器和后台数据库之间,
-
对外开放的接口是MySQL通信协议,将App服务器传过来的sql语句按照路由的规则拆解转发到不同的后台数据库,并把结果汇总返回。
mycat部署模型如下:
服务器系统:
CentOS+Ngnix+tomcat
6.选择合适的消息队列软件:
当后台系统发现完成某些小任务需要花费很多时间,而且迟点晚成也不影响整个任务的完成进度时,就会把这些小任务交给消息队列。例如发送邮件、短信、推送消息等任务都非常适合在消息队列中处理。
把这些任务放在消息队列中,可加快App后台请求都响应时间。同时消息队列也能把大量的并发请求变成串行的请求,来减轻服务器的负担。
常见的消息队列软件有:
消息队列软件 | 说明 |
---|---|
RabbitMQ | 重量级,适合企业级的开发,自带Web监控界面,方便监控队列的情况 |
Redis | 轻量级,是一个key-value系统,但是也支持消息队列这种数据结构,App后台中Redis被广泛使用 |
ZeroMQ | 号称最快,尤其针对大吞吐量的需求场景 |
ActiveMQ | Apache的一个子项目,能够以代理人和点对点的技术实现队列 |
7.使用分布式服务实现服务的复用:
随着业务不断增加,后台系统由一个单一应用膨胀为一个巨无霸系统,系统中聚合了大量的应用和服务,各个模块之间有很多功能重复实现(例如登录模块),造成了开发、运维、部署的麻烦。
解决这些问题的方法就是把重复实现的模块独立部署为远程服务,新增的业务调用远程服务所提供的功能实现相关的业务,不依赖于里面具体的代码实现。
8.实现远程服务可以 参考 REST设计原则 和 RPC远程调用协议。
开源的RPC库有:
开源的RPC库 | 说明 |
---|---|
Hprose | 轻量级、跨语言、跨平台、无侵入式、高性能动态远程对象调用引擎库 |
Dubbo | 分布式服务框架,致力于提供高性能和透明化的RPC远程调用服务和SOA服务治理方案 |
9.用户验证方案最佳实践:
App操作中经常涉及用户登录操作,登录就需要使用到用户名和密码,为了安全起见,在登录过程中暴漏密码的次数越少越好。
1.HTTPS协议是 HTTP协议 和 SSL/TLS协议 的组合。其是一个安全通信通道,基于HTTP开发,用于在客户计算机和App后台之间交换信息。其使用安全套接字层(SSL)进行信息交换,简单来说就是HTTP的安全版。
HTTPS实际上应用了安全套接字层(SSL)作为HTTP应用层的子层。
HTTPS的模型:
HTTP |
---|
SSL/TLS(安全套接字层/传输层安全协议) |
TCP |
IP |
网络传输 |
避免信息的泄漏,最基本的方案是所有涉及安全性的API请求都必须使用HTTPS协议。
2.选择JSON作为数据交换格式
JSON是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,易于编写,也易于机器解析和生成,而且对比XML更省流量,这些特性使得JSON成为理想的数据交换语言。
3.基本的用户验证方案
传统Web网站使用Cookie+Session保持用户的登录状态,App后台则使用token进行验证,流程如下:
此时App已经获取到了token值,为了安全,我们不在网络上传输token,而使用签名校验(这里使用URL签名)的方式,API请求加上URL签名sign和用户id后如下:
test.com/user/update?uid=2&sign=3f1e736bc4ae958ae7e8500b45aefdbb&age=22
这样,token就不需要附在URL上了。App后台签名校验流程如下:
还有的童鞋喜欢设置时间戳,这样时间一长,URL就失效了,也是一种不错的进一步的优化方案。
建议:为了保障数据安全,这里建议 同时使用 HTTPS 和 签名校验。
结束语:在移动互联网项目中,产品的研发讲求 小步快走,快速迭代。 架构的设计也可以遵循同样的思路。