乐趣区

关于golang:微服务从代码到k8s部署应有尽有系列二网关

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

微信交换群

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

退出移动版