学不动了 古典、SOA、传统、K8S、ServiceMesh

十几年前就有一些公司开始践行服务拆分以及SOA,六年前有了微服务的概念,于是大家开始思考SOA和微服务的关系和区别 。最近三年Spring Cloud的大火把微服务的实践推到了高潮,而近两年K8S在容器编排的地位确定之后大家又开始实践起以K8S为核心的云原生思想和微服务的结合如何去落地,2018年又多出一个ServiceMesh服务网格的概念,大家又在思考如何引入落地ServiceMesh,ServiceMesh和K8S以及Spring Cloud的关系如何等等 。
确实有点乱了,这一波又一波的热潮,几乎每两年都会来一波有关微服务架构理念和平台,许多公司还没完成微服务的改造就又提出了服务+容器道路,又有一些公司打算从微服务直接升级成ServiceMesh 。本文尝试总结一下我见过的或实践过的一些微服务落地方式,并且提出一些自己的观点,希望抛砖引玉,大家可以畅谈一下自己公司的微服务落地方式 。
1、微服务v0.1——古典玩法

学不动了 古典、SOA、传统、K8S、ServiceMesh

文章插图
 
(图中灰色部分代表元数据存储区域,也就是Service和Endpoint关系所保存的地方,之后所有的图都是这样)
其实在2006年在使用.NET Remoting做服务拆分的时候(其实当时我们没有意识到这叫服务拆分,这是打算把一些逻辑使用独立的进程来承载,以windows服务形式安装在不同服务器上分散压力),我们使用了F5来做服务的负载均衡 。没有所谓的服务发现,针对每一个服务,我们直接在程序配置文件中写死F5的IP地址和端口,使用Excel来记录所有服务在F5的端口地址以及服务实际部署的IP:端口,然后在F5进行配置 。F5在这里做了负载均衡、简单的路由策略(相同的客户端总是优先路由到相同的后端)以及简单的白名单策略等等 。
2、微服务v0.2——改进版古典玩法
学不动了 古典、SOA、传统、K8S、ServiceMesh

文章插图
 
之后尝试过这种改进版的古典玩法 。相比v0.1的区别是,不再使用硬件F5了,而是使用几组软件反向代理服务器,比如Nginx来做服务负载均衡(如果是TCP的负载均衡的话可以选择HaProxy),Nginx的配置会比F5更方便而且还不花钱 。由于生产环境Nginx可能是多组,客户端不在配置文件中写死Nginx地址而是把地址放到了配置中心去,而Nginx的配置由源码仓库统一管理,运维通过文件同步方式或其它方式从源码仓库拉取配置文件下发到不同的Nginx集群做后端服务的配置(Nginx的配置也不一定需要是一个大文件放所有的配置,可以每一组服务做一个配置文件更清晰) 。
【学不动了 古典、SOA、传统、K8S、ServiceMesh】虽然我的标题说这是古典玩法,但是可以说很多公司如果没有上RPC,没有上Spring Cloud,也没有上K8S的话很可能就是这样的玩法 。无论是v0.2还是v0.1,本质上服务是固定在虚拟机或实体机部署的,如果需要扩容,需要迁移,那么肯定需要修改反向代理或负载均衡器的配置 。少数情况下,如果调整了反向代理或负载均衡器的IP地址,那么还可能会需要修改客户端的配置 。
3、微服务v0.5——SOA ESB玩法
学不动了 古典、SOA、传统、K8S、ServiceMesh

文章插图
 
SOA的一个特点是使用了服务总线,服务总线承担了服务的发现、路由、协议转换、安全控制、限流等等 。2012年我参与了一个大型MMO游戏《激战2》项目的技术整合工作,这个游戏整个服务端就是这种架构 。它有一个叫做Portal的服务总线,所有游戏的十几个子服务都会把自己注册到服务总线,不管是什么服务需要调用什么接口,都是在调用服务总线,由服务总线来进行服务的寻址路由和协议转换,服务总线也会做服务的精细化限流,每一个用户都有自己的服务请求队列 。这种架构的好处是简单,服务总线承担了所有工作,但是服务总线的压力很大,承担了所有的服务转发工作 。同时需要考虑服务总线本身如何进行扩容,如果服务总线是有状态的,显然要进行扩容不是这么简单 。对于游戏服务器来说,扩容可能不是一个强需求,因为游戏服务天然会按照大区进行分流,一个大区的最大人数上限是固定的 。
貌似互联网公司这样玩的不多,传统企业或是游戏服务端是比较适合服务总线这种架构的,如果服务和服务之间的协议不统一的话,要在客户端做协议转换的工作比较痛苦,如果可以由统一的中间层接入所有协议统一进行转换的话,客户端会比较轻量,但是这种架构的很大问题在于服务总线的扩容和可靠性 。


推荐阅读