详讲api网关之kong的基本概念及安装和使用(二)

consul的服务注册与发现
如果不知道consul的使用,可以点击上方链接,这是我写的关于consul的一篇文档。

upstream+consul实现负载均衡

我们知道,配置upstream可以实现负载均衡,而consul实现了服务注册与发现,那么接下来我们就来看看利用这两个组件怎么实现负载均衡吧。

安装consul

  • docker安装consul,注意端口,注意将consul的网络加入到kong的网络中,即--network=kong-ee-net
docker run -d --name consul \--network=kong-ee-net \-p 8500:8500 \-p 8300:8309 \-p 8301:8301 \-p8302:8302 \-p 8600:8600/udp \hashicorp/consul consul agent -dev -client=0.0.0.0

gin服务注册到consul

  • 我们启动3个gin服务,并注册到consul中,相关代码如下,注意,服务端口是随机获取的,并注册到consul中,我们几乎不需要关心端口是多少
package main
import ("fmt""gin-demo/config""gin-demo/db""gin-demo/route""gin-demo/utils""github.com/fvbock/endless"consulapi "github.com/hashicorp/consul/api"
)
// 定义服务注册的信息
type ServiceConfig struct {ID      stringName    stringTags    []stringPort    intAddress string
}// consul的服务地址
var consulIp = "127.0.0.1:8500"// 注册
func RegisterSevice(s ServiceConfig) error {consulConfig := consulapi.DefaultConfig()consulConfig.Address = consulIp//获取到客户端client, err := consulapi.NewClient(consulConfig)if err != nil {fmt.Printf("create consul client : %v\n", err.Error())return err}registration := &consulapi.AgentServiceRegistration{ID:      s.ID,Name:    s.Name,Port:    s.Port,Tags:    s.Tags,Address: s.Address,}if err := client.Agent().ServiceRegister(registration); err != nil {fmt.Printf("register to consul error: %v\n", err.Error())return err}return nil
}func main() {//配置文件config.InitConfig()//sql初始化db.NewDb().InitAllSql()//启动r := route.InitRoute()//随机获取一个可用端口_, port := utils.RandomPort()//注册到consulconsulPort := fmt.Sprintf("%d", port)service := ServiceConfig{ID:      consulPort,Name:    "blog_service",Tags:    []string{"blog"},Port:    port,Address: "192.168.11.20",}err := RegisterSevice(service)if err != nil {fmt.Printf("register to consul error: %v\n", err.Error())}//启动gin服务addr := fmt.Sprintf(":%d", port)err = endless.ListenAndServe(addr, r)if err != nil {return}
}
  • 启动完毕之后,我们访问consul的web页面已注册成功http://127.0.0.1:8500/ui/dc1/services/blog_service/instances
    在这里插入图片描述

  • 我们使用dns的方式访问一下

dig @127.0.0.1 -p 8600 blog_service.service.consul

在这里插入图片描述

kong里面配置consul

  • 通过docker network inspect kong-ee-net 查看consul的ip为172.23.0.4
  • 这里我们需要删除原来的kong容器,并使用以下命令创建一个新看kong,需要注意的是,由于你指定了KONG_DNS_RESOLVER,那么原来指定的KONG_PG_HOST就不可以再用dns的方式,因为consul里面并没有这个域名,会导致服务启动报错。所以要直接指定ip。
docker run -d --name kong \--network=kong-ee-net \-e "KONG_DATABASE=postgres" \-e "KONG_DNS_RESOLVER=192.168.11.20:8600" \-e "KONG_PG_HOST=172.23.0.2" \-e "KONG_PG_USER=kong" \-e "KONG_PG_PASSWORD=kong" \-e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" \-e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \-e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \-e "KONG_PROXY_ERROR_LOG=/dev/stderr" \-e "KONG_ADMIN_ERROR_LOG=/dev/stderr" \-e "KONG_ADMIN_LISTEN=0.0.0.0:8001, 0.0.0.0:8444 ssl" \-p 8000:8000 \-p 8443:8443 \-p 8001:8001 \-p 8444:8444 \kong-oss:latest
  • 启动之后,我们会再konga里面看到下面这行,这个时候,我们在kong里面配置的域名都会被 consul解析
    在这里插入图片描述

  • 我们配置blog_service.service.consul给service,就是咱们原来创建的blog的service
    在这里插入图片描述

  • 我们现在多访问几次接口 http://127.0.0.1:8000/v1/blog/detail?id=12,返回数据正常,我们多访问几次,查看三台服务的日志,均收到了请求
    在这里插入图片描述

在这里插入图片描述

jwt实现权限校验

一般情况下,上游api服务都需要客户端有身份验证,并且不影响错误的请求或者无认证的请求通过,那么此时,我们可以利用kong的jwt插件来实现,直接在网关这一层过滤掉请求

consumers

一个consumer可以代表一个微服务或者一个应用。为什么?因为你想给一个应用配置插件服务的话,比如说jwt认证,这个插件怎么样才能作用到这个应用上面呢?就是需要创建一个consumer,插件作用于consumer,consumer绑定应用。

  • 接下来我们创建一个consumer
    在这里插入图片描述
  • 添加jwt认证
    在这里插入图片描述
  • 全局配置jwt,配置header头的token名
    在这里插入图片描述
  • 此时我们再来访问http://127.0.0.1:8000/v1/blog/detail?id=12,已经不通过了
    在这里插入图片描述
  • 那么我们先手动构造一个token来验证一下,有两点需要注意,一个是jwt,是我们配置的验证名称,一个是iss
    在这里插入图片描述
  • 我们通过https://jwt.io/生成token,payload如下,注意secret去consumer中获取
{"sub": "1234567890","name": "John Doe","iat": 1516239022,"iss":"jwt"
}

项目中引入jwt

  • 关于怎么使用jwt,我在jwt讲解这篇文章中说过。
  • 注意两个地方,一个是jwt的秘钥kong和gin必须保持一致
  • 一个是issuer必须保持一致,相关代码如下
package middlewareimport ("gin-demo/service""github.com/gin-gonic/gin""github.com/golang-jwt/jwt/v5""log""strings""time"
)// 定义自己的秘钥 所有的服务必须用一个秘钥才能正确解析token
// 注意注意:这个秘钥必须和kong保持一致
var privateKey = []byte("FLHzZzGqZPlSzKgNyq4wXg4bKUhFRsH1")// UserClaims 我们声明一个结构体,里面包含我们想要保存的信息
type UserClaims struct {Uid                  int64jwt.RegisteredClaims // 内嵌标准的声明
}// GenToken 生成token
func GenToken(uid int64) (string, error) {//初始化结构体claims := UserClaims{Uid: uid,RegisteredClaims: jwt.RegisteredClaims{//设置过期时间ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Second * 3600)),//颁发时间IssuedAt: jwt.NewNumericDate(time.Now()),//主题Subject: "Token",//注意这里 发行人要和kong保持一致Issuer: "jwt",},}//生成token  使用hs256 加密 结构体,然后再用秘钥对其做数字签名return jwt.NewWithClaims(jwt.SigningMethodHS256, claims).SignedString(privateKey)
}// 解析token
func ParseToken(c *gin.Context) {claims := new(UserClaims)xtoken := c.GetHeader("x-token")tokenString := strings.Split(xtoken, " ")if len(xtoken) == 0 || len(tokenString) < 2 {service.ErrorResponse(c, 9999, "请先登录!")return}log.Printf("解析到的token是:%v", tokenString)token, err := jwt.ParseWithClaims(tokenString[1], claims, keyFunc)log.Printf("解析到的token是:%v", err)if err != nil {c.Abort()service.ErrorResponse(c, 9999, "用户名密码错误!")return}//建议token是否有效if token.Valid {log.Printf("解析到的uid是:%d", claims.Uid)c.Set("uid", claims.Uid)c.Next()} else {c.Abort()service.ErrorResponse(c, 9999, "用户名密码错误!")return}
}func keyFunc(token *jwt.Token) (interface{}, error) {return privateKey, nil
}

在这里插入图片描述

  • 结果
    在这里插入图片描述

  • 失败结果,kong直接拦截,并未到达服务层实例在这里插入图片描述

流量控制

  • 我们现在来配置一个每秒接收5个请求的限制
    在这里插入图片描述
  • 然后我们用jmeter测试一下,一秒内模拟10个用户发送10个请求
    在这里插入图片描述
  • 查看结果
    在这里插入图片描述

黑白名单

  • 我们可以选择指定给service或者route添加插件,下图我给route添加了插件
    在这里插入图片描述
  • 再次访问接口
    在这里插入图片描述

总结

kong的相关功能就演示完毕了,其他功能比如反爬策略,协议转换感兴趣的小伙伴们可以自己探索一下。

相关参考

相关参考
相关参考
官方文档
中文文档
相关文档
相关文档

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/661175.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

leetcode209长度最小的子数组|滑动窗口算法详细讲解学习

滑动窗口是一种基于双指针的一种思想&#xff0c;两个指针指向的元素之间形成一个窗口。 分类&#xff1a;窗口有两类&#xff0c;一种是固定大小类的窗口&#xff0c;一类是大小动态变化的窗口。 简而言之&#xff0c;滑动窗口算法在一个特定大小的字符串或数组上进行操作&…

DevEco Studio 保存自动格式化代码

目标&#xff1a;保存后自动格式化代码 单次快捷键&#xff1a;Ctrl Alt L 步骤一 步骤二

7.2、子集求和问题与背包密码系统

7.2、子集求和问题与背包密码系统 一、数学描述 1.1、第一种描述 20 世纪 70 年代末&#xff0c;默克尔和赫尔曼首次尝试将密码系统建立在一个 NP-完全问题上。他们使用了以下数学问题的一个版本&#xff0c;该问题是对经典knapsack问题的概括。 子集和问题 假设你有一个正…

【Midjourney】AI绘画案例(1)龙年吉祥神兽

说明&#xff1a; 1、文中图片版权均为Midjourney所有&#xff0c;请勿用作商业用途。 2、文中图片均经过 Upscale x 4 处理。 3、由于模型原因&#xff0c;某些图片存在暇玼。 1、吉祥神兽——天马&#xff08;独角兽&#xff09; 天马消灾星。 提示词 Prompt: Sky Unicor…

2023强网杯复现

强网先锋 SpeedUp 要求2的27次方的阶乘的逐位之和 在A244060 - OEIS 然后我们将4495662081进行sha256加密 就得到了flag flag{bbdee5c548fddfc76617c562952a3a3b03d423985c095521a8661d248fad3797} MISC easyfuzz 通过尝试输入字符串判断该程序对输入字符的验证规则为9…

Prometheus+grafana配置监控系统

使用docker compose安装 方便拓展, 配置信息都放在在 /docker/prometheus 目录下 1.目录结构如下 . ├── conf │ └── prometheus.yml ├── grafana_data ├── prometheus_data └── prometheus_grafana.yaml2.创建目录文件 mkdir /docker/prometheus &&am…

【unity小技巧】FPS简单的射击换挡瞄准动画控制

文章目录 射击动画控制换弹动画瞄准动画完结 射击动画控制 换弹动画 调用 瞄准动画 问题&#xff1a;瞄准时&#xff0c;但是动画会卡住&#xff0c;不会播放瞄准的待机动画 修改 调用 动画如果太快可以去修改播放速度 播放速度变慢了&#xff0c;可能导致切换待机动画也…

【PyQt】01-PyQt下载

文章目录 前言静态库 一、PyQt是什么&#xff1f;二、安装1.Windows环境下安装安装PyQt5Designer 2.Liunx环境下安装 总结 前言 拜吾师 PyQt5 快速入门 静态库 补充一点知识&#xff1a; Windows&#xff1a; .lib Linux: .a .so(动态库) 简单描述PyQt就是python调用C的Qt文…

《区块链简易速速上手小册》第4章:区块链与加密货币(2024 最新版)

文章目录 4.1 比特币与区块链4.1.1 比特币基础4.1.2 比特币交易的工作流程&#xff1a;4.1.3 拓展案例 1&#xff1a;闪电网络4.1.4 拓展案例 2&#xff1a;比特币ATM 4.2 其他主要加密货币4.2.1 加密货币的多样性4.2.2 以太坊的案例4.2.3 拓展案例 1&#xff1a;非同质化代币&…

郑庆科老师字体正版商用官方授权,字觅网为您提供官方授权渠道

近日,字觅网宣布成为郑庆科老师字体的签约字体品牌,并提供了官方正版商用授权渠道。庆科字体以其独特的风格和设计备受欢迎,现在通过字觅网,用户可以轻松获取该字体的正版商用授权。 用户只需访问庆科字体官网,即可查看庆科字体的详细列表,并选择所需字体进行下载。 在字觅网…

Unity3d Shader篇(一)— 顶点漫反射着色器解析

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、顶点漫反射着色器是什么&#xff1f;1. 顶点漫反射着色器的工作原理 二、编写顶点漫反射着色器1. 定义属性2. 创建 SubShader3. 编写着色器程序段4. 完成顶…

《Pandas 简易速速上手小册》第5章:Pandas 数据合并与重塑(2024 最新版)

文章目录 5.1 数据合并&#xff1a;Concatenate 和 Merge5.1.1 基础知识5.1.2 重点案例&#xff1a;客户订单数据合并5.1.3 拓展案例一&#xff1a;产品目录和销售数据合并5.1.4 拓展案例二&#xff1a;员工信息和部门数据合并 5.2 数据透视和重塑5.2.1 基础知识5.2.2 重点案例…

如何使用Cloudreve搭建私有云盘并发布公网访问无需购买域名服务器

文章目录 1、前言2、本地网站搭建2.1 环境使用2.2 支持组件选择2.3 网页安装2.4 测试和使用2.5 问题解决 3、本地网页发布3.1 cpolar云端设置3.2 cpolar本地设置 4、公网访问测试5、结语 1、前言 自云存储概念兴起已经有段时间了&#xff0c;各互联网大厂也纷纷加入战局&#…

路由重定向和别名

聚沙成塔每天进步一点点 本文内容 ⭐ 专栏简介1. 路由重定向实例场景&#xff1a;路由重定向的应用场景&#xff1a; 2. 路由别名实例场景&#xff1a;路由别名的应用场景&#xff1a; ⭐ 写在最后 ⭐ 专栏简介 Vue学习之旅的奇妙世界 欢迎大家来到 Vue 技能树参考资料专栏&…

备战蓝桥杯---数据结构与STL应用(进阶2)

本文将主要围绕有关map的今典应用展开&#xff1a; 下面我用图进行分析&#xff1a; 下面为AC代码&#xff1a; #include<bits/stdc.h> using namespace std; struct Point {int x,y;bool operator < (const Point & r) const {return x < r.x || ( x r.x &a…

Windows IIS服务如何配置并制作web站点结合内网穿透实现公网访问

文章目录 1. 安装IIS必要WebDav组件2. 客户端测试3. cpolar内网穿透3.1 打开Web-UI管理界面3.2 创建隧道3.3 查看在线隧道列表3.4 浏览器访问测试 4. 安装Raidrive客户端4.1 连接WebDav服务器4.2 连接成功4.2 连接成功总结&#xff1a; 自己用Windows Server搭建了家用NAS主机&…

【网络】:网络套接字(TCP)

网络套接字&#xff08;TCP&#xff09; 一.编写TCP服务器二.编写Tcp客户端三.多进程四.多线程版本五.线程池版完整源代码六.使用示例 一.编写TCP服务器 1.先搭一个架子 2.创建sockfd domain参数依然是AF_INET(因为是IPV4) type方式选择SOCK_STREAM&#xff08;提供可靠的连接…

从零开始学Linux之chkconfig命令

首先我们要知道Linux系统有以下7种运行级别&#xff0c;分别用0到6数字表示&#xff0c;这里使用红帽6系统做演示 0&#xff1a;关机 1&#xff1a;单用户模式&#xff0c;root用户免密登录&#xff0c;用于系统维护&#xff0c;例如忘记用户密码可以切换到该模式直接使用roo…

查看本地mysql的密码

1.导出链接 在数据库连接工具找到导出链接 导出到桌面即可&#xff0c;注意导出密码 2.复制密码 3.解密 复制如下代码到网址&#xff1a;代码在线运行 - 在线工具 (tool.lu) <?php namespace FatSmallTools; class NavicatPassword {protected $version 0;protected $a…

YOLOv5算法进阶改进(14)— 即插即用的动态卷积之ODConv | 助力涨点

​ 前言:Hello大家好,我是小哥谈。动态卷积(Dynamic Convolution)是一种用于目标检测的卷积神经网络模块,其中ODConv(Object Detection Convolution)是其一种具体实现。动态卷积在传统的卷积操作上引入了动态权重,以适应不同目标的形状和尺度变化。本文将YOLOv5的主干网…