我所在的公司是一家做直播和视频通话APP的公司,我主要负责服务端。最开始我们的架构很简单,就是单体PHP,全部用lumen写成。Redis缓存都用的少,后端人员也只有两人。
此时最大的问题主要是慢,单机扛不住多少并发。
大概2年前想要做直播,开始引进声望、腾讯IM,但是直播房间需要大量的缓存处理,swoole开始进入我的视野。将架构拆分成了API和服务,服务使用的swoft1.0。将原来的lumen还是作为API层保留了。
此时的问题主要是curl请求依然是一条通道,导致注册IM的时候卡顿,一旦推广人数多了,会卡在注册接口。虽然swoole在后面的版本添加了curl的请求。
其次是swoft1.0还是雏形,很多高级点的功能并不成熟。大多数的业务都用的Redis在抗。
随着业务场景的不断扩大,加上GO的火热,我开始考虑将架构中需要集中运算和追求并发的模块用GO重写,于是有了对微服务的研究。准确的说还称不上微服务,只是业务有针对性地选择语言,进行了一些业务模块的拆分。
那么怎样从PHP到GO,又不影响既有业务?让我们慢慢聊。
对于微服务的讨论网上已经足够多了。其实微服务是一种思想,和分层一样。
像以前,网络架构、操作系统架构,大多数采用的是分层的思想,因为大家的视野都集中在一台机器上。我们一直在考虑怎样将事情分散给不同的人,比如用户态和管态,比如网络协议的7层架构,包括MVC,都是为了将事情分散。也都是基于大家在一起。
到了现在,用户数飞速增长,单机再厉害也不可能抗住业务请求了,于是产生了一个新的观念,那就分而治之。
从横向上来看,可以将全国乃至全球的用户分片,湖北就湖北的机房,杭州就杭州的机房,这样分到每个机房的请求数大大减少。这也就是大家所说的“多活”。
从纵向来看,可以将不同的业务采用不同的技术,不同数量的集群,不同的处理方式,分而治之,比如账号服务,可以用最优的机器,最好的管理,保证服务永不中断,而采集服务,可以放到每个CND节点,将其分散到全国各地,进行打包汇总了再上传到数据中心进行分析,而数据中心采用CPU密集型的机器,进行分析和存储。这样分工明确,好钢使在刀刃上。
听上去很美好,是真的很美好么?
每个公司都是从单体应用过来的,如果有人上来就是集群和微服务,分库分表都已经做好了,那一定是土豪级公司。
业务都不是一蹴而就的,而是慢慢演化的。
我也经历过单体应用,其实作为一个人开发是很爽的,没有那么多问题,只用关心MySQL优化一下,该套缓存套一下,然后上线的时候注意下兼容,写起来好爽好快。运维起来也爽,直接上服务器看日志,PHP脚本语言,改了就生效,贼爽。
其实PHP确实是一个试错最好的语言,对于一个新项目,就是要开发快、上线快,好维护、好运维。
别上来就微服务,几个开发人员的小公司,去追求微服务、去追求中台架构,这是追求完美吗?不是,是找死。
但是渐渐的,业务量上来了,开发人员也变多了,问题就显现了:
架构的演进一定是源于痛点,所以在小公司说把集群、微服务玩到很溜是不可能的,那都是实验室的玩具。如果想要当架构师,一定要在业务量足够大的公司。但是在小公司并不妨碍我们对技术的学习。
最开始由于技术不足和为了方便,我们采用了纵向拆分,就是将业务分块,按路由分组,采用NGINX反向代理,重构一个模块就上一个模块,最后实现了重构。我称为纵向拆分。
好处是:
问题:
后来我开始考虑横向拆分。也就是业界采用比较多的方式。
就是用户中心、通话中心、直播中心这样分,一个服务只做好一件事。
其实最主要的因素是人员的增加,现在后端有5个人了,虽然还是小团队,但是对于现在的业务量可以开始探索这种重构方式了。
凡事有利就有弊,没有银弹,也没有不变的架构。往往分久必合,合久必分。
天然的复杂性:
面对问题:
问题肯定是层不不穷的,发现了慢慢优化即可,保持热情,不畏艰险吧。
其实我们公司的业务量,基于现在的PHP架构完全扛得住,我完全可以悠哉喝茶写写业务代码。
首先源于我本来就是一个闲不住的人,其次对于新技术有些热情。
换句话说,我就是在作死。
没有把握,千万别这样,真的是吃力可能还不讨好。架构演进必然会带来线上系统的不稳当,如果不是扛不住业务量了,不要轻易尝试。搞不好到最后头发少了,工资还降了。
我也是小步试错,逐步修改,慢慢演进的。
后面我会继续慢慢分享演进中的学习和经历,欢迎大家指点和讨论。