咱们用一个系列来解说从需要到上线、从代码到k8s部署、从日志到监控等各个方面的微服务残缺实际。
整个我的项目应用了go-zero开发的微服务,根本蕴含了go-zero以及相干go-zero作者开发的一些中间件,所用到的技术栈根本是go-zero项目组的自研组件,根本是go-zero全家桶了。
实战我的项目地址:https://github.com/Mikaelemmm...
1. go-zero 网关概念
go-zero架构往大的说次要由两局部组成,一个是api,一个是rpc。api次要是http对外拜访的,rpc次要就是外部业务交互应用的是protobuf+grpc,当咱们我的项目体量还不大的时候,咱们能够应用api来做一个单体我的项目,等后续量上来之后,能够拆分到rpc做微服务,从单体转向微服务非常容易,很像java的springboot转像springcloud,十分不便。
api被很多同学了解成了网关,实际意义上来说当你的我的项目在应用go-zero做微服务时候,你把api当成网关也没什么大的问题,不过这样做导致的问题就是一个api对应前面多个rpc,api充当了网关,这样如果我在更新后续业务代码时候,更新任何业务都要去改变这个api网关,比方我只是改了一个小小的不起眼的服务,那就要从新构建整个api,这样不太正当,效率极低也很不不便。所以,咱们只是把api当成一个聚合服务,能够拆分成多个api,比方用户服务有用户服务的rpc与api,订单服务,有订单服务的rpc与api,这样当我批改用户服务时候,我只须要更新用户的rpc与api,所有的api只是用来聚合后端rpc的业务。那有的同学就会说,我总不能每个服务解析个域名对应你的api吧,当然不能,这时候api后面就要有一个网关了,这个网关才是真正意义上的网关,比方咱们常说的nginx、kong、apisix,很多微服务都内置了网关,比方springcloud提供了springcloud-gateway , go-zero没有提供,理论也用不着独自去写一个网关,市面上的网关曾经够多了,go-zero官网在晓黑板中用的nginx足够用了,当然你如果更相熟kong、apisix都能够替换,实质上没什么不一样的,只是一个对立流量入口,对立鉴权等。
2. nginx网关
【注】:在看这里的时候,倡议先看一下前一节的业务架构图
本我的项目中理论也应用了nginx做为网关,应用nginx的auth_request模块作为对立鉴权,业务外部不做鉴权(设计到资产的最好业务外部做二次鉴权,次要多一层平安),nignx的网关配置在我的项目的data/nginx/conf.d/looklook-gateway.conf
server{ listen 8081; access_log /var/log/nginx/looklook.com_access.log; error_log /var/log/nginx//looklook.com_error.log; location /auth { internal; proxy_set_header X-Original-URI $request_uri; proxy_pass_request_body off; proxy_set_header Content-Length ""; proxy_pass http://identity-api:8001/identity/v1/verify/token; } location ~ /usercenter/ { auth_request /auth; auth_request_set $user $upstream_http_x_user; proxy_set_header x-user $user; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header REMOTE-HOST $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://usercenter-api:8002; } location ~ /travel/ { auth_request /auth; auth_request_set $user $upstream_http_x_user; proxy_set_header x-user $user; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header REMOTE-HOST $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://travel-api:8003; } location ~ /order/ { auth_request /auth; auth_request_set $user $upstream_http_x_user; proxy_set_header x-user $user; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header REMOTE-HOST $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://order-api:8004; } location ~ /payment/ { auth_request /auth; auth_request_set $user $upstream_http_x_user; proxy_set_header x-user $user; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header REMOTE-HOST $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://payment-api:8005; }}
容器外部nginx端口是8081,应用docker裸露进来8888映射端口8081,这样内部通过8888来拜访网关,应用location来匹配每个服务,当然会有人说,每加一个api服务都要来nignx配置太麻烦,你也能够应用confd对立配置,自行百度。
3. 举例
当咱们在拜访用户服务时候, http://127.0.0.1:8888/usercen... , 拜访了内部端口8888,而后映射到nginx外部looklook网关8081上,而后location匹配到了/usercenter/ ,在该模块开始有一行 auth_request /auth, 所以nginx不会间接去申请http://usercenter-api:8002 , 而是会先跳到 location /auth 模块中,auth模块会拜访 http://identity-api:8001/iden...; ,identity-api也是咱们外部的服务,是由咱们本人写的鉴权服务,理论也是用的go-zero的jwt
进入identity-api 只做了2件事件(具体能够看looklook我的项目中的identity-api代码)
1、判断以后拜访的路由(usercenter/v1/user/detail )是否须要登录。这里的路由是否须要登录,能够在identity-api中配置,代码曾经实现好了。
2、解析传递的token到header中
如果以后拜访的路由须要登录:
- token解析失败:就会返回给前端http401错误码;
- token解析胜利:就会将解析进去的userId放入header的x-user中返回给auth模块,auth模块会把header传递给对应拜访的服务(usercenter), 这样咱们在usercenter间接就能够拿到该登录用户的id了
如果以后拜访的路由不须要登录:
前端header中传递了token
- 如果token校验失败:返回http401;
- 如果token校验胜利:就会将解析进去的userId放入header的x-user中返回给auth模块,auth模块会把header传递给对应拜访的服务(usercenter), 这样咱们在usercenter间接就能够拿到该登录用户的id了
- 前端header中没传递token:userid 会传递 0 给后端服务
4、总结
这样咱们就能够对立入口,对立鉴权,也能够对立收集日志上报,用作谬误剖析,或者拜访用户的行为剖析。因为咱们日常对nginx用的比拟多,也比拟相熟,如果各位同学对kong、apisix比拟相熟,在理解了上方go-zero应用网关的概念就能够间接替换也是一样的。
我的项目地址
https://github.com/zeromicro/go-zero
欢送应用 go-zero
并 star 反对咱们!
微信交换群
关注『微服务实际』公众号并点击 交换群 获取社区群二维码。