• 37、api网关-kong


    一、API网关简介

    • 什么是api 网关
      • 我们知道在微服务架构中,大型服务都被拆分成了独立的微服务,每个微服务通常会以RESTFUL API的形式对外提供服务
      • 但是在UI方面,我们可能需要在一个页面上显示来自不同微服务的数据,此时就会需要一个统一的入口来进行API的调用
      • API Gateway就在此场景下充当了多个服务的大门,系统的统一入口
    • api 网关应该具备的功能
      • 服务路由
        • 动态路由:API Gateway可以与微服务注册中心连接,实现微服务无感知动态扩容
        • 负载均衡
      • 服务发现
      • 熔断降级:API Gateway对于无法访问的服务,可以做到自动熔断,无需人工参与
      • 黑白名单过滤
    • api网关技术选型
    API网关KongAPISIXTrkApigeeAliyun
    部署模式单机和集群单机和集群单机和集群不支持单机RaaS
    数据存储Postgres或者CassandraetcdRedisPostgres、Cassandra和ZookeeperRaaS
    是否开源Apache 2.0协议Apache 2.0协议MPL协议
    核心技术Nginx+LuaNginx+LuaGolang未知未知
    私有部署
    自定义插件
    社区活跃度
    支持yaml

    二、kong的安装和配置


    三、动态路由

    1 - kong的端口说明

    • 8001:kong的管理端口
    • 8000:用户访问的端口
    • 1337:konga地址

    在这里插入图片描述

    2 - 动态路由实现

    • SERVICES
      • Service顾名思义就是我们自己定义的上游服务,通过kong匹配到相应的请求要转发的地方
      • Service可以与下面的Router进行关联,一个Service可以有很多Router,匹配到的Router就会转发到Service中
      • 当然中间也会通过Plugin的处理,增加或者减少一些相应的Header或者其他信息
    • ROUTERS
      • Router路由相当于nginx配置中的location
      • Router实体定义匹配客户端请求的规则,每个路由都与一个服务相关联,而服务可能有多个与之相关联的路由
      • 每一个匹配给定路线的请求都将被提交给它的相关服务
      • 路由和服务的组合(以及它们之间的关注点分离)提供一种强大的理由基址,可以在kong中定义细粒度的入口点
      • 从而引导访问到不同的upstream服务
    • 添加Service

    在这里插入图片描述
    在这里插入图片描述

    • 为Service添加Router
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
    • 测试kong的路由服务:开启goods_srv、goods_web,http://192.168.124.51:8000/g/v1/goods
      在这里插入图片描述
    • goods_web/initialize/init_router.go:修改下路由规则,去掉/g
    package initialize
    
    import (
    	"github.com/gin-gonic/gin"
    
    	"web_api/goods_web/middlewares"
    	"web_api/goods_web/router"
    )
    
    func Routers() *gin.Engine {
    	Router := gin.Default()
    
    	//配置跨域
    	Router.Use(middlewares.Cors())
    	//ApiGroup := Router.Group("/g/v1")
    	ApiGroup := Router.Group("/v1")
    
    	router.InitGoodsRouter(ApiGroup)
    	router.InitCategoryRouter(ApiGroup)
    	router.InitBannerRouter(ApiGroup)
    	router.InitBrandRouter(ApiGroup)
    
    	return Router
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • konga的router中添加/g:记得回车并提交
      在这里插入图片描述
      在这里插入图片描述

    3 - service、rouer、upstream请求过程

    • kong三种访问服务的方式
      • 硬编码方式:这个在之前的动态路由里面实现的
      • 通过upstream实现
      • 通过consul实现
    • 额外说明
      • routers路由匹配客户端的请求规则,匹配成功后分配到service层,一个路由指向一个service,一个service可以被多个不同规则的路由router指向
      • 访问地址:kong网关地址+代理端口(默认http=8000,https=8443)
      • service服务是一个抽象服务层,可以用于指向具体物理服务(target),也可以指向upstream用于实现物理服务的负载效果,一个service对于upstream、target都是一对一的关系

    在这里插入图片描述

    4 - kong集成consul服务发现与负载均衡

    在这里插入图片描述
    在这里插入图片描述

    • 浏览器访问:开启goods_srv、goods_web,[http://192.168.124.51:8000/g/v1/goods];我们可以看到依然可以访问
      在这里插入图片描述
    • 测试负载均衡
      • goods_web/main.go:修改为port随机,之前我们是写死的,flag = 5 // 这里为了测试kong的负载均衡
      • 开启2个goods_web服务,然后浏览器访问2次,我们可以看到每个服务各请求了一次
        在这里插入图片描述
        在这里插入图片描述

    四、kong配置jwt实现登录校验

    1 - 原理分析

    • 需求分析:之前我们已经做了jwt的验证,为什么还要在kong中使用jwt?
      • 很简单,因为api网关是统一的入口,我们只需要在网关中实现jwt验证,那么在业务中我们就不需要在做jwt校验了
    • 通用认证:一般情况下,上游api服务器都需要客户端有身份认证,且不允许错误的认证或无法认证的请求通过;认证插件可以实现这一需求
    • 通用认证插件的方案/流程
      • ①.向一个api或全局添加AUTH插件(此插件不作用域consumers)
      • ②.创建一个consumers对象
      • ③.为consumer提供指定的验证插件方案的身份验证凭据
      • ④.现在,只要有请求进入kong,都将检查其提供的身份验证凭据(取决于auth类型),如果该请求无法被验证或者验证失败,则请求会被锁定,不执行向上游服务转发的操作
      • 但是,上述的一般流程并不是总是有效的;比如,当使用了外部验证方案(比如LDAP)时,kong就不会(不需要)对consumer进行身份验证
    • Counsumers
      • 最简单的理解和配置consumer的方式,将其与“用户”进行一一隐射,即一个consumer代表一个“用户”(这里指的是应用,不要理解成登录的用户)
      • 但是对于kong而言,这些都无所谓;
      • consumer的核心原则是你可以为其添加插件,从而自定义它的请求行为;
      • 所以,或许你会有一个手机APP应用,并为他的每个版本都定义个consumer,又或者你有一个应用或几个应用,并为这些应用定义同一个consumer,这些都无所谓
      • 注意:这是一个模糊的概念,它叫做consumer,而不是user,要区分清楚

    2 - kong配置jwt

    • 添加1个consumer
      在这里插入图片描述

    • 为这个consumer添加JWT
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述

    • 配置全局的PLUGIN:设置header为x-token
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述

    • 生成tokenhttps://jwt.io/,添加key和secret

    在这里插入图片描述

    • 没有配置x-tocken时:返回"message": “Unauthorized”
      在这里插入图片描述
    • 配置x-token:将刚才在https://jwt.io/中生成token复制进来,并且前面要加上Bearer(这个是kong的要求)
      • 此时提示未登陆

    在这里插入图片描述

    • 未登陆的原因分析
      • jwt的nacos配置中我们设置过secret了
      • jwt的验证要确认key是不是“imooc”,也就是之前未consumer添加JWT验证时候key和secret要和gin对应
      • 之前在用户服务时user_web/api/api_user.go,生成token的时候我们Issuer设置为的是“imooc”

    在这里插入图片描述

    • 这时候还有一个非常重要的修改:之前我们在token中因为kong的要求添加了前缀Bearer,所以在jwt中我们就需要分割去掉Bearer
    • goods_web/middlewares/jwt.go
    func JWTAuth() gin.HandlerFunc {
    	return func(c *gin.Context) {
    		// 我们这里jwt鉴权取头部信息 x-token 登录时回返回token信息 这里前端需要把token存储到cookie或者本地localSstorage中 不过需要跟后端协商过期时间 可以约定刷新令牌或者重新登录
    		token := c.Request.Header.Get("x-token")
    		if token == "" {
    			c.JSON(http.StatusUnauthorized, map[string]string{
    				"msg": "请登录",
    			})
    			c.Abort()
    			return
    		}
    		token = strings.Split(token, " ")[1]
    		j := NewJWT()
    		// parseToken 解析token包含的信息
    		claims, err := j.ParseToken(token)
    		//省略
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    在这里插入图片描述


    五、kong实现反爬和ip黑名单

    1 - 反爬

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    2 - ip黑名单

    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

  • 相关阅读:
    复习计算机网络——第一章
    Java面向对象
    暂停Windows更新方法
    【mysql】Mysql自定义变量 @rownum使用
    MuziDB数据库-0.项目描述
    分享68个ASP.NET源码总有一个是你想要的
    Vue 3 学习 源码解读
    LeetCode(力扣)40. 组合总和 IIPython
    如何搭建自己的图床
    TCP/IP协议到底在讲什么?
  • 原文地址:https://blog.csdn.net/qq23001186/article/details/126357834