咱们用一个系列来解说从需要到上线、从代码到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-zerostar 反对咱们!

微信交换群

关注『微服务实际』公众号并点击 交换群 获取社区群二维码。