在毕业论文答辩完成后,我开始学习微服务这一块的内容,加上工作中也接触到了实际应用的微服务项目,因此想从零搭建一套项目学习这方面的内容,于是就把之前毕设的电商拿来改造重构,从去年7月至今,由于工作繁忙,经过半年左右终于基本完成。
这里附上之前SpringBoot版本的电商项目介绍:微信小程序+Vue+SpringBoot实现B2C电商系统(毕业论文)
下面简单介绍下,由于项目比较庞大,感兴趣的可以前往gitee仓库下载到本地。
gitee仓库地址
注意:这个项目我并没有完全启动所有服务运行过,只是保证了正常登录、可以获取token访问接口,由于是微服务架构,需要同时启动多个服务,对电脑性能要求较高,需要完整运行的建议电脑内存至少达到16GB,有条件的也可以购买云服务器进行部署。另外仓库只包括后端项目,vue和小程序项目除了登录授权和接口路径变化基本没有改动,所以不放在仓库了。
以下为主要技术框架工具
技术 | 版本 | 说明 |
---|---|---|
SpringCloud | Hoxton.SR5 | 微服务框架 |
SpringCloud Gateway | 2.2.3 | 网关 |
SpringCloud OpenFeign | 2.2.3 | 服务调用 |
SpringBoot | 2.3.0 | MVC框架 |
SpringCloud Security | 2.3.0 | 安全框架 |
SpringCloud Oauth2 | 2.2.2 | 认证授权框架 |
Mybatis | 3.4.6 | ORM框架 |
Mybatis Generator | 1.3.3 | 代码生成工具 |
PageHelper | 5.1.8 | 分页查询工具 |
Druid | 1.2.0 | 数据库连接池 |
Lombok | 1.18.20 | 对象封装工具 |
FastJson | 1.2.3 | json转换工具 |
JWT | 0.9.0 | 访问令牌工具 |
Eureka | 2.2.3 | 注册中心 |
所有客户端请求先访问网关,由网关和认证服务统一处理认证授权后下发登录令牌token,客户端再携带token访问用户、订单等服务,每个服务都连接同一个数据库(目前没有分库),网关和其它服务均注册到Eureka,服务之间使用OpenFeign互相调用。
Eureka服务端目前只用了8761,有需要以集群方式运行可以配置8861
新建数据库my_mall,导入doc/my_mall_cloud.sql文件,数据库账号密码需要配置到每个服务的application.yml
启动eureka8761
启动用户服务,因为网关和认证服务需要调用用户服务,所以先启动user
启动网关
启动认证服务
有需要可以启动剩下服务
打开postman,调用用户服务的login接口获取token
调用其它服务接口,在请求头设置Authorization=Bearer空格然后加上token
以下为postman调用示例
另外为了降低内存占用,可以在每个服务配置启动参数
-Xms128m -Xmx512m
参考IntelliJ IDEA开发多个微服务非常占用内存很卡_idea 跑微服务特卡_广铁小多多的博客-CSDN博客
和之前SpringBoot版本不同的地方主要包括
登录日志和操作日志合并到sys_api_log,异常日志迁移到sys_error_log,另外增加了token、服务类型标识等字段
用户角色关联改为ums_user_role_relation,因为前台用户也要处理角色权限
角色ums_role添加value字段作为校验标志
权限ums_permission不再关系到前端页面的菜单展示,而是只表示用户权限,因此删掉了一些字段,也添加value字段作为校验标志
其它一些表去掉了冗余其他服务的字段,避免数据不一致
一些表加上了updateTime代表更新时间
由于之前的SpringBoot版本开发的时候比较赶,controller和service层代码比较混乱,包括接口返回的格式也不够统一,因此本次微服务版本在mall-common模块进行了一些简单的封装,比如BaseDTOMapper,BaseService,BaseMapper
BaseDTOMapper:处理实体转换为dto,再返回给前端,而不是像之前直接返回实体
BaseMapper:封装常用的增删改查方法
BaseService:在BaseMapper基础上加入了before, after的业务处理,可以理解成对增删改操作的切面
针对查询操作,controller层向service层传递参数加入了ListParam这个类,方便处理条件过滤、分页、排序
针对接口返回和错误码把原本的ErrorCode, ErrorResponse改造成ApiCode,ApiResponse,ApiResponse提供了多种接口返回的方式,以及兼容OpenFeign调用返回的结果处理
登录这里之前用的是SpringSecurity和JWT,但是在微服务项目中是不够的,因为每个服务都是独立的,如果只在用户服务登录了,把token拿去访问其它服务是会失败的,因此这时候需要使用单点登录去实现统一认证授权。
我是参考这位技术大佬的方案的
微服务权限终极解决方案,Spring Cloud Gateway + Oauth2 实现统一认证和鉴权! | mall学习教程
大致原理就是使用auth服务作为认证服务,对每个客户端进行身份认证,认证通过的颁发token,然后网关服务作为资源服务器,对客户端校验权限以及处理路由转发,可以把网关理解成防火墙,所有请求包括对auth服务的请求都是先经过网关再转发到各自服务。
不过我和大佬在权限校验这里做法有点不同,大佬是在AuthorizationManager处理权限校验,但是需要在数据库保存每个接口和权限的关联,而我觉得这种做法不易于维护,扩展性较差,因此采用了自定义注解的方式处理,下面会介绍到。
主要用了RequireRoles和RequirePermissions两个注解定义每个接口需要的角色或权限,然后每个服务定义了AuthenticationAspect进行接口的前置通知,在这里进行拦截,比对token中的用户角色或权限以及接口定义的角色或权限,来判断是否拥有接口的访问权限,这部分的实现放在mall-common的BaseAuthenticationHandler。
另外角色和权限是首次运行用户服务就会初始化到数据库,可以看看用户服务的InitRunner,角色权限数据放在resources下面的rolepermission.json文件。
虽然这个项目不会很复杂,但是在开发过程中也是学到了很多,包括运行起来各种报错踩坑,然后要一个一个排查解决,总的来说也是收获较多,接下来还会进一步丰富完善这个项目,作为微服务架构的一个动手实践。
如果这篇文章有帮助到你就点个赞吧~