• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

37、api网关-kong

武飞扬头像
无休止符
帮助1

一、API网关简介

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

学新通
  • 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)
		//省略
学新通

学新通


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

1 - 反爬

学新通
学新通
学新通

2 - ip黑名单

学新通
学新通

学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgekefe
系列文章
更多 icon
同类精品
更多 icon
继续加载