项目微服务化

记得不久之前,我曾经计划将本项目改造成微服务的形式,原因在于探索了Graal VM以后,我发觉曾经梦想的将自己的项目微服务化并不是一个天方夜谭,而是一些切实可行的,只需要工作量堆砌的事情。于是这段时间我就集中精力把这件事情做了一下。但是实际做完的感觉尽管非常舒心,非常有成就感,但是确实还是几经波折。而且,把一个项目从单体服务改造成微服务所需的工作量也大大出乎我的意料,其实工作量还是相当不小的。

当时这个单体项目,我的项目结构是这样的:

原则上来讲,这个项目实际上已经按照功能模块去划分了,但是划分的结果并没有让迁移工作变得一键完成那么容易,因为存在一部分公共使用的代码需要拆分,这个过程学问就大了。你永远不知道那些耦合着的部分被撕开时是多么让你惊讶。哦?原来这样也行?哦?为啥原来好好的现在就报错了?

按照之前的构想,做了些许微调后,项目架构图如下:

flowchart TD 前端 --流量--> Nginx外网网关 --转发--> 内网鉴权网关 内网鉴权网关 --未登录流量--> 展示服务-本地缓存 消息队列 --投递消息--> 展示服务-本地缓存 消息队列 --投递消息--> 用户中心-本地缓存 消息队列 --投递消息--> 搜索中心 内容中心 --缓存变更消息--> 消息队列 用户中心-本地缓存 --缓存变更消息--> 消息队列 内网鉴权网关 --获取权限--> 用户中心-本地缓存 内网鉴权网关 --分流--> 用户中心-本地缓存 内网鉴权网关 --分流--> 用户中心-本地缓存 内网鉴权网关 --分流--> 内容中心 内网鉴权网关 --分流--> 搜索中心 内网鉴权网关 --转发--> websocket服务 内容中心 --数据变更--> 消息队列 内容中心 --数据获取/变更--> MariaDB 用户中心-本地缓存 --数据获取/变更--> MariaDB 用户中心-本地缓存 --数据获取/变更--> 消息队列 搜索中心 --数据获取/变更--> ElasticSearch 用户中心-本地缓存 --数据获取/变更--> 中心化缓存Redis 展示服务-本地缓存 --数据获取/变更--> 中心化缓存Redis 展示服务-本地缓存 --数据获取--> 内容中心

外网网关主要负责代理证书,证书用的腾讯云免费的,但由于服务器在境外故添加域名上无需备案的。所谓内网其实指docker的内网。我自己实现的内网网关本质上就是一个普通的服务,只是负担了鉴权外加流量转发的作用。

这里有点难度的地方是内网网关到websocket服务这条,此时内网网关既需要作为一个websocket客户端又需要作为一个websocket服务端。具体而言是前端直接和内网网关建立websocket连接,然后内网网关在启动时和websocket服务建立一条独特的连接:

flowchart TD 前端 --${userId}通道推送--> Nginx --转发--> 内网网关 --A通道推送--> WebSocket服务 WebSocket服务 --A通道订阅--> 内网网关 内网网关 --转发--> Nginx --${userId}通道订阅--> 前端

本质来看其实和Http转发也差不多,原理一样但设计这个方案并不是太容易。这个A通道需要经过轮训,如果断连要定时重建。

成果如下:

成果时喜人的,终于在囊中羞涩的情况下,单单选对了技术就可以在如此低规格的服务器玩微服务,多么让人开心呢?其实无论对于cpp也好,golang也罢,一个web服务占用不到100M内存都是非常正常的,而Java依赖虚拟机确实实现起来比较困难。如何实现,那也只有去掉虚拟机而完全采用编译为二进制了。

posted @ 2024-06-29 21:34  imissinstagram  Views(3)  Comments(0Edit  收藏  举报