一个失败的微服务项目,这是我项目的总结.失败的主要原因是对微服务的滥用,本文将总结微服务在本项目中暴露出的缺点
项目简介
这是一个休息游戏项目,主线是喂养一只可爱的小狗, 通过玩内置小游戏,或者做任务积累狗粮.在整个过程中会随机掉落红包, 红包可以之间兑换少量RMB,游戏以用户点击广告作为主要收入, 用户转化是另一部分收入
项目概况
项目分游戏端和管理端 游戏端:
- 游戏大厅(主界面,包含:玩家信息\邀请\站内信\成长记录\签到等)
- 排行榜
- 幸运大盘
- 成长任务
- 多款小游戏 管理端:
- 基础权限管理
- 用户管理
- 提现
- 报表
- 版本管理
- 广告与渠道
- 维护
人员配置
策划 x2 美术 x3 音效 x1 游戏前端(Cocos) x3 游戏后端(java) x2 管理前端(vue) x2 管理后端(java) x4 测试 x2 运维 x2 运营 x1
后端架构
- spring-cloud Hoxton.SR3作为微服务框架
- nacos 做服务注册发现以及配置中心
- swagger2 生成doc
- redis 做缓存
- mysql
- mybatis + mybatis-plus 做持久层
- kafka 做消息中间件
- jwt 生成token
- elasticsearch 做报表
每个微服务由两个模块组成,一个模块api接口,一个模块对接口进行实现, api接口用@FeignClient进行注解,其它模块引用本模块即可方便调用
@FeignClient(value = "gb-user", contextId = "userFeign")
public interface UserFeign {
@GetMapping("findUserInfoByUserId")
UserDetailResultDTO findUserInfoByUserId(Long userId);
}
用户信息绑定在线程上,在整个调用链条上共享.
public class LoginUserContext {
private static ThreadLocal<LoginUser> userThread = new ThreadLocal();
public LoginUserContext() {
}
public static LoginUser get() {
return userThread.get() == null ? LoginUser.builder().build() : (LoginUser)userThread.get();
}
public static void set(Long userId, Integer userType) {
userThread.set(LoginUser.builder().userId(userId).userType(userType).build());
}
public static void set(LoginUser loginUser) {
userThread.set(loginUser);
}
public static void clear() {
userThread.remove();
}
}
项目就介绍到这里.接下来说明微服务架构的缺点以及遇到的问题:
优点:
- 每个微服务基本由一个人负责,可以提供更大的自由度
- 通过在项目实现中引入api层,可以让远程调用像本地调用一样简单
- 架构师对框架进行了深度的封装,只需要关注业务实现也能写出基本合格的代码
问题:
- 整体来说项目不大,或者说这是一个很小的项目,游戏端和管理端一共也就7人开发.况且游戏端和管理端几乎完全独立.也就是单个子项目3~4人开发.使用微服务技术就显得非常笨重.
- 项目设计要100w并发(吹牛),但实际并发非常小,首先管理端就不可能有太高的并发,游戏端由于需要第延时,也不可能有太高的并发.我看过腾讯游戏的相关资料,单台服务器的并发最高2w,游戏的低延时又不可能使用多台服务器.所以设计的100w并发是吹牛,即使需要游戏支持100w并发,也只能通过分区分服来实现.这些都和微服务没有关系.
- 我在项目中实际负责一款小游戏的后端开发,刚开始使用kafka + 网关进行前后端通讯实现,实测下来小游戏的操作延迟非常大,完全不满足设计需要.后来之间让游戏服务提供websocket服务才解决问题.
- 微服务自身的缺点也在本项目中暴露无遗 -- 开发中的烦恼,开发过程中难免遇到api设计不合理,即使设计合理,中途的需求变更也会造成api修改,api修改带来各种的版本冲突伴随开发的前中期 -- 项目管理的烦恼,多模块开发经常出现maven依赖的莫名错误,即使不影响开发那条红线也让程序员抓狂 -- 调试困难,需要启动一堆服务才能进行调试,springboot项目本身占用内存大,有时候需要启动8个服务进行调试,我的小本本表示压力巨大. -- 其它困难1,由于我们这个项目涉及到提现模块,分布式事务的一致性又来了.容错\幂等难度指数上升. -- 其它困难2,架构师过多过死的封装用于项目中,没有经过大量实战项目检验,被大家亲切的称为demo架构师
总体来说是技术选型出了问题,迷信微服务,堆砌新技术.
游戏界面设计稿
来源:oschina
链接:https://my.oschina.net/u/4661459/blog/4600674