微服务初探
前言
生产力就是王道,谁能够更短时间做出更多工作,谁就能胜利。
保障生产力持续在线的最佳方案就是:将琐事交给工作流
需求
搭建一个在线小说阅读编写网站
功能如下:
- 实现登录、注册
- 实现小说编写、阅读、查询、收藏
- 实现评论查看、发布
依赖如下:
- 使用 SpringBoot、Vue 框架,实现前后端分离
- 使用 Spring Cloud 构建微服务
技术要点
业务逻辑明确、简单,不做赘述,我们讲讲微服务。
什么是微服务
我们在没有接触技术之前,或仅仅道听途说,很容易产生畏难心理。
实际上,微服务就是把我们具有多种功能的单体服务,拆分成内聚性强的个体,方便解耦。
就拿我们的项目举例,用户登录注册逻辑连贯,共享用户表格,可以拆分。
又如评论模块,尽管使用了用户模块的 ID、小说模块的 ID,但其功能独立,可以拆分。
这样我们通过拆分,就得到了多个服务,每个服务放到一个服务器上,这样就能将原本的单体服务高压力,分散到多个服务器上,从而提升服务可用性。
服务注册与发现
如果是单体服务,我们在前端只需注明它的 IP 地址就好了,但是微服务有多个 IP 地址,我们怎么管理?
如果我们没法预知服务器 IP,那么我们可以让服务器自己来我们这注册。
Nacos
是一个服务注册与发现系统,只需要在每个服务的配置文件中添加 Nacos
服务器的 IP,Nacos
就能找到我们的服务,并将其写入它的数据库。
服务分发与登录校验
服务分发
我们可以在 Nacos
上看到服务列表,但是我们怎么从前端发送请求呢,到底要发给谁?
我们自然而然会想到 Nginx
,根据路径分发服务。
好想法!不过 Nacos
有自己的小团体,Gateway
就能帮助Nacos
做服务分发。
所以为什么不用 Nginx
? 我们考虑有多个相同服务的场景,如果服务上线后需要添加和删除服务,那么 Nginx
配置文件就要手动修改,非常麻烦。
登录校验
Gateway
还能做什么? 把登录校验放进去吧,加个拦截器,神人才去写配置文件。
用户发送请求后,某些服务需要获取当前用户信息,比如 userId
。
如果前后端发送的时候都携带 userId
,首先是要改接口,其次不安全。
不安全好说,加密 userId
就 ok,这就是 token
,可以使用 JWT (JSON Web Tokens)
来生成。
改接口也不需要,直接在请求头部添加 Authorization = token
即可。
然后在服务侧解密 token,获取 userId,存入 threadLocal
中,方便后续使用。
那我们抽取这一过程 解密->获取userId
,到 Gateway
中完成。
此时,我们在 vue 中就可以访问 GateWay
来发送请求了,它会为我们自动转发到配置好的分发地址指向的服务。
一些小问题
如果你和我一样使用了云服务器,那么大概率在 Nacos
上注册的服务列表项中的 IP 是内网地址。
此时 Gateway
会将请求转发到内网地址,而内网地址不直接可达。
我们还得在配置文件中添加 spring.cloud.nacos.discovery.ip
配置项,指定外网地址。
工作流
微服务多了之后,部署起来就很麻烦。
尤其是我们这种小作坊,还是敏捷开发。
万幸 github
有 actions
,可以通过编写一个 workflow
脚本,我们可以很轻松的将触发更新的代码编译成 jar 包,并部署到服务器上。
下面是 novel-service
的 workflow
脚本,我一共做了 4 个脚本,是因为 secrets
有不同的命名,所以需要分开,大概率有更好的写法。
1 | name: Build and Deploy Novel Service |
几个要点
- 使用
scp
将jar
包推送到远程服务器上 - 通过
ssh
连接远程服务器,执行命令,并把命令的输出重定向到文件中。 secrets
用来保存敏感信息,比如密码,用户名,ssh
密钥等。- 如果你不写
2>&1
,最后一步脚本会超时。