U8SDK——U8Server架构思考

作者: 分类: U8SDK 发布时间: 2016-12-23 21:43 64条评论

随着越来越多的同学使用U8Server,关于U8Server的性能如何,如何分布式部署、扩展性如何,如何保证稳定性,如何处理高并发的情况等问题,被越来越多的同学问及。这些问题,不仅仅是U8Server会遇到,可能很多的访问量大的Web应用都会遇到。

1、现有的架构:

现有架构

在当前U8Server的版本中,我们将所有的业务逻辑都写在同一个项目工程中。除了各个渠道SDK的登录认证,下单,渠道SDK的支付回调等业务处理逻辑,还包括后台管理和数据统计分析等业务逻辑。

在现有的工程中,对不太常变动且访问量比较频繁的“渠道”、“渠道商”、“游戏数据”进行了本地缓存。因为这部分数据量不大,所以在应用启动的时候,将这些数据就全部load到缓存中了。后台管理系统中,添加、编辑、或者删除这些数据的时候,会同时进行缓存中数据的同步。

这样的架构,当我们在考虑部署多个U8Server实例的时候, 会遇到一些矛盾的地方:

比如,我们将U8Server部署到3个tomcat中时, 我们会遇到如下问题:

当我们在后他管理中,添加一个渠道、渠道商、或者游戏数据的时候,我设置的是哪个Tomcat中部署的u8server呢?

显然这种方式,并不能适应扩展性。 所以,我们有必要对U8Server的架构进行一定的调整。如下是我们的优化步骤

2、分离业务逻辑

进行架构调整的第一步,就是拆分业务逻辑。 将U8Server主体业务逻辑拆分为两部分。一部分仅仅负责前端业务逻辑部分(用户登录认证,下单,支付回调处理),我们姑且称这一部分为U8Server,另一部分负责后台管理和统计分析业务逻辑,我们称这一部分为U8Manager。

拆分之后,部署的方式,也发生了变化。

U8Server 处理核心业务逻辑, 处理高并发的业务请求,部署的时候,随着业务量的需要,可以部署多个实例。

U8Manager 处理后台管理和统计分析逻辑, 访问量小,实时性要求不高, 内部工作人员使用,部署一台即可。

所以,整套的部署结构,就变成了,多个U8Server实例 + 一个U8Manager的部署方式。

分离之后的架构

但是,还是没有解决上面我们提到的问题,后台管理中修改了数据, 我们需要及时同步给所有U8Server实例。

3、去除本地缓存,引入分布式共享缓存组件

解决数据同步问题,虽然我们也可以使用分布式消息组件,但是同时我们为了减少数据库操作,增加业务响应速度等,我们这里准备引入分布式共享缓存服务了。经过调研,我们这里使用Redis来担当我们的共享缓存组件(我们暂时不使用他的持久化特性,仅仅用于缓存数据)

引入Redis之前,我们将之前代码中的“本地缓存”组件给干掉了。去除本地缓存还是比较简单的,直接将之前缓存的接口给移除即可。但是移除之后,所有之前通过缓存API获取数据的地方,都需要重构下了。

Spring框架已经有对Redis的封装组件了,有兴趣的同学可以了解下:Spring Data Redis,他对Redis所有操作命令进行了API级别的抽象和封装,使得应用代码中的使用还是比较简单的。

我们在数据操作层(DAO层,增加了一个统一缓存操作接口,负责从缓存中取数据,或者将数据存入更新到缓存中)。

每个U8Server实例和U8Manager实例,都会连接到Redis缓存层, 后台管理中管理员添加、修改、删除渠道、渠道商、游戏等数据,会及时同步到Redis缓存中。每个U8Server实例中业务逻辑处理的时候,需要这些数据,会从Redis缓存中获取。

加了Redis缓存之后,为了进一步提高缓存效率, 我们将用户数据和订单数据也一并加入Redis缓存。 这里使用的场景,还有一点需要注意下:

渠道商、渠道和游戏数据, 是所有业务逻辑的共用数据,会被频繁使用,所以他们是永久存在于缓存中,并不会有超时失效的限制。

而对于用户和订单数据,我们则没有必要将他们长期地留在缓存中。

对于用户数据, 客户端登录认证的时候,会将数据同步到Redis中(如果缓存中没有的话),根据现有的流程,用户会接着登录游戏服务器,游戏服务器来U8Server进行二次登录认证(从上一次数据存储到这一次数据获取,时间很短,一般不会超过一分钟),所以,对于用户缓存数据,我们设置一个超时失效时间,比如5分钟,或者10分钟。

同样的道理,也适用于订单数据。 从支付之前客户端或者游戏服务器来U8Server下单到SDK支付完成异步通知U8Server,整个过程的时间,一般不会超过5分钟(排除渠道SDK订单重发的情况),所以,我们一样给订单缓存数据,设置一个超时失效时间。

加了redis缓存层之后, 我们现在的架构,已经可以支持真正意义上的分布式部署了。现在的架构,会变成这样:

引入Redis之后的架构

4、引入nginx反向代理,实现tomcat负载均衡

有了上面的架构调整,现在我们的应用,已经完全具备分部署部署能力。 为了让Tomcat实例的增加,对于前段业务请求透明,同时,实现多个tomcat的负载均衡,我们使用nginx来做代理。

有了上面的拆分, 使用nginx代理,可以设置代理规则, 简单的话,根据业务需要,我们就直接部署多个tomcat实例。但是,也可以更加细分一些, 比如某些tomcat实例只处理用户相关的请求,某些tomcat实例只处理支付相关的请求。

5、Mysql数据库优化

我们的数据都存储在mysql中, 除了基本的数据表根据业务逻辑建立了相关索引之外,我们还可以在部署层面上,进行一定的优化。 通过上面Redis缓存的引入,也给Mysql减去了很大一部分负担,前期我们可以简单地通过主从复制,让Msyql避免出现单点故障。

后面随着业务量的增加,数据库这块可能面临的问题,主要是订单表的数据量会超出单表限制,我们后面需要考虑的优化方向,继续拆分U8Server业务逻辑,分离用户登录和支付逻辑,将支付业务作为一个独立的系统。当订单表达到业务瓶颈之后,我们会考虑对订单表进行水平切分。

后台管理系统中,统计分析这块的业务,后面也可以考虑作为一个独立的系统来开发。使用日志组件来收集日志,然后输入到另一个离线计算服务来整理分析,最后将产生的分析之后的数据,再持久化到Mysql中。

数据库这块的优化,还有很大空间。后面根据实际业务需求,可以再仔细分析业务场景,进行优化处理。最终优化后的架构图可能如下:

最终的架构

总结:

这次对U8Server优化的思考,主要的目的还是让U8Server具备分布式部署和集群能力,不管tomcat的处理性能如何,也不管代码中如何优化,当业务量达到一定程度之后,分布式和集群部署会成为必然需求。

目前这些仅仅是思考的内容, 希望已经在使用U8Server,或者有过类似经验的小伙伴,可以一起和我们进行交流和沟通。U8SDK技术交流群:207609068

本文出自 U8SDK技术博客,转载时请注明出处及相应链接。

本文永久链接: http://www.uustory.com/?p=2118

评论功能已经关闭,请加入U8SDK技术群进行讨论和咨询:207609068
Ɣ回顶部
U8SDK技术群 x
技术同学请加入
点击加入