Kong Gateway 指南

Kong Gateway 是一个轻量、快速、灵活的云原生API网关,其本质是一个运行在 Nginx中的Lua应用程序。

概述

Kong是Mashape开源的高性能高可用的API网关,可以水平扩展。它通过前置的负载均衡配置把请求分发到各个server,来应对大批量的网络请求。

由于Kong 的成功,Mashape 于 2017 年重组并更名为 Kong Inc.,将业务重点全面转移到 API 网关及相关技术上。如今,已成为 API 网关和服务网格的领先提供商。

主要功能

Kong提供了诸如HTTP基本认证、密钥认证、CORS、TCP、UDP、日志记录、请求限流、请求转发以及NGINX监控等基本功能。除此之外,它还可以通过插件(lua编写)来扩展已有的功能。其示意图如下:

在这里插入图片描述

Kong的核心功能如下:

API路由与反向代理

  • Kong Gateway作为API请求的入口,将请求从客户端路由到相应的服务。
  • 支持动态路由,可以根据URL、请求头、参数等条件来决定将请求转发到哪个服务端点。

认证与授权

  • 提供多种认证方式,如OAuth 2.0、JWT、Basic Auth、Key Auth等,确保API只能被经过认证的客户端访问。
  • 支持对用户进行授权控制,确保不同的用户只能访问他们被授权使用的API服务。

安全保护

  • Kong Gateway可以保护API免受常见攻击,如DDos、SQL注入、跨站请求伪造等。
  • 通过API限流,IP白名单/黑明单机制,防止恶意访问。

负载均衡

  • Kong可以在多个服务之间分配流量,确保负载均衡分布,并具备健康检查功能,可以动态监测服务节点的健康状况。
  • 支持协议的转换,比如从HTTP转换为HTTPS、从HTTP2转换为HTTP1.1。

限流与速度限制

  • Kong提供了高级的速率限制功能,你可以为每个API路由配置速率限制策略,限制客户端在一定时间内发送的请求数量,防止资源滥用。

监控与日志记录

  • Kong集成了多种监控工具,支持Prometheus、Datalog、Grafana等监控系统。
  • 提供了详细的日志记录功能,记录API的访问日志,包括响应时间,请求来源等信息。

插件架构

  • 支持通过插件来扩展功能,官方和社区提供了丰富的插件生态系统,覆盖认证、限流、缓存、日志记录等多方面。
  • 开发者还可以自定义插件来满足特定的业务需求。

多协议支持

  • 支持多种协议,如HTTP、HTTPS、gRPC、WebSocket等,允许在API层支持不同类型的服务通信。

服务网格集成

  • Kong Gateway与Kong Mesh无缝集成,支持在更复杂的微服务架构中管理服务间的通信、提供服务发现、负载均衡以及自动化的安全策略。

Kong gateway是与OpenResty一起分发的,而OpenRestry是一个扩展于lua-nginx-module的模块。OpenRestry主要解决Nginx无法动态扩展功能的问题,它将Lua JIT内嵌到了 Nginx 的内部,以支持通过 lua 语言对 Nginx 的能力进行方便地扩展开发。

版本和模式

Kong Gateway的部署方式有两种:使用Kong Konnect进行托管和自主管理。

Konnect提供了实用Kong Gateway的最简单的方法。全局控制平面由Kong托管在云上,你只需要管理各个数据平面节点即可, 但Konnect是收费方案。另一种部署方式就是自管理。

自管理

Kong gateway有两个不同的版本,开源版和企业版。开源版包括基本的API网关功能和开源插件,企业版附加了一些额外功能,包括RBAC和企业插件。企业版是收费的。

开源版和企业版的功能比较:

功能描述开源版企业版
API基础设施现代化
API网关
端对端自动化
Kong Ingress Controller
网关Mocking
admin界面管理器
流量管理和转换
基础流量管控插件
简单数据转换
gRPC转换
GraphQL
请求验证
jq转换
高级缓存
高级qps限制
安全管控
认证和基本授权(Bot检测,CORS,ACLs)
高级认证
基于角色的访问控制(RBAC)
高级授权(OPA)
证书管理
FIPS 140-2 支持
Signed Kong镜像
AI网关
多种大语言模型支持
AI流量控制
AI prompt安全
AI 可观测性
企业支持与服务

Kong Admin API 和 Kong Manager

Kong 网关的所有实体包括服务,路由,插件,消费者等等,都可以通过admin api来访问和配置。

Kong Manager是Kong 网关的图形化管理界面,实际上还是通过Admin API来调用接口进行管理。

Kubernetes

前文说过Kong Gateway是云原生网关,主要体现为它可以通过其ingress controller运行在k8s中。

工作原理

本节将从路由,负载均衡方面来介绍Kong Gateway的工作原理。

路由规则

Kong Gateway对外暴露多个接口,体现在如下的配置属性中:

  • proxy_listen:这个属性定义了一系列地址/端口,通过这些地址和端口来接受公开的HTTP, gRPC, WebSocket等请求,随后将这些请求代理到服务(默认8000端口)。
  • admin_listen: 这个属性也定义了一系列地址和端口,但这个属性指定的是Admin API 的地址,提供给管理员来对Kong进行配置(默认8001端口)。
  • stream_listen: 这个属性与proxy_listen作用类似,只不过它是适用于4层的代理(如TCP、TLS)。默认情况下是关闭的。

从顶层来看,Kong Gateway既可以监听7层的HTTP请求,也可以监听4层的请求(分别通过proxy_listenstream_listen指定)。然后根据配置的路由,将匹配的请求代理到对应的服务。路由条件是根据子系统(HTTP/HTTPS, gRPC/gRPCS, TCP/TLS)来区分的,主要有下列条件:

  • http: methods, hosts, headers, paths (对于https请求还有snis)
  • tcp: sources, destinations(对于tls还有snis)
  • grpc: hosts, headers, paths(对于grpcs还有snis)

假设现在我们创建了一个路由如下:

curl -i -X POST http://localhost:8001/routes/ \-d 'hosts[]=test.com' \-d 'hosts[]=foo-service.com' \-d 'headers.region=north'

该路由规定了hosts和header参数,只有满足条件的请求才能被路由接受。

域名通配符

设置路由属性时既可以指定完整的域名,也可以使用域名通配符。

路径正则表达式

设置路由属性时既可以指定完整的路径,也可以使用正则表达式来表示路径。当路径是正则表达式时,需要用~作为前缀,如

paths: ["~/foo/bar$"]

没有~前缀会被当成纯文本,如

"paths": ["/users/\d+/profile", "/following"]

如果一个请求的路径同时满足两个路径条件,那应该如何路由呢?这时候就需要考虑路径优先级了。优先级是根据regex_priority 来判断的。该值越大,则优先级越高。如果没有设置regex_priority , 则要根据其他规则来判断优先级:具体路径 > 前缀匹配 > 正则匹配。

捕获组

在Kong中,捕获组是正则表达式的一种功能,用于在路由中提取特定部分的请求路径。假设有一个正则表达式路由配置如下:

routes:- name: user-routepaths:- ~^/users/(\d+)/details$service:id: user-service

这里的(\d+)就是一个捕获组。请求/users/123/details可以匹配到该路径,其中的123就是捕获组参数。后端服务可以通过动态路径来接受该参数,如Springboot中的@GetMapping("/users/{id}/details")

除此之外,还可以通过插件来对捕获组参数进行其他处理。例如request-transformer插件可以将参数作为请求头放进去:

plugins:- name: request-transformerservice: user-serviceconfig:add:headers:- "X-User-ID: $1"

preserve_host

Kong Gateway在代理请求时,会默认将Kong中配置的服务域名作为Host发送给服务。如果将preserve_host 设为true,则会将原始客户端请求的host发送给服务。

举个例子,假设原始客户端请求的域名为service.com, 该请求将被路由到域名为api.internal.service的服务。如果不设置preserve_host , 则服务收到的请求的Host将是api.internal.service。如果将preserve_host 设为true,则服务收到的请求的Host为原始的service.com

负载均衡

Kong gateway提供了多种负载均衡方式,默认的是基于DNS的方式。

默认情况下,DNS负载均衡器是开启的,并且仅限于轮询的负载均衡的算法中。换句话说,默认使用DNS负载均衡器时,Kong不提供其他负载均衡算法,如最少连接,随机等。因此,尽管支持多种负载均衡策略,但是DNS负载均衡的上下文中,轮询是唯一可用的选择。

开启Kong Gateway之旅

安装方式有多种,既可以下载安装包,也可以通过docker来安装。本文以docker安装为例进行介绍。

安装kong gateway

首先创建一个docker网络:

docker network create kong-net

然后启动一个postgresql容器:

 docker run -d --name kong-database \--network=kong-net \-p 5432:5432 \-e "POSTGRES_USER=kong" \-e "POSTGRES_DB=kong" \-e "POSTGRES_PASSWORD=kongpass" \postgres:12

用户名和数据库名设置为kong是Kong gateway的默认值。密码则无要求。

接下来准备初始化数据

docker run --rm --network=kong-net \
-e "KONG_DATABASE=postgres" \
-e "KONG_PG_HOST=kong-database" \
-e "KONG_PG_PASSWORD=kongpass" \
kong:3.8.0 kong miigrations bootstrap

如果docker的镜像仓库访问不了,可以用docker pull public.ecr.aws/docker/library/kong:3.8.0从aws的免费仓库拉取, 然后重新打标签: docker tag public.ecr.aws/docker/library/kong:3.8.0 kong:3.8.0

这里KONG_DATABASE指定数据库类型,KONG_PG_HOST就是上一步创建的postgres容器,密码也是上一步的密码。kong migrations bootstrap 是数据初始化命令。--rm参数表示这是一个一次性任务,完成之后即删除容器。

启动容器:

docker run -d --name kong-gateway \--network=kong-net \-e "KONG_DATABASE=postgres" \-e "KONG_PG_HOST=kong-database" \-e "KONG_PG_USER=kong" \-e "KONG_PG_PASSWORD=kongpass" \-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" \-e "KONG_ADMIN_GUI_URL=http://localhost:8002" \-p 8000:8000 \-p 8443:8443 \-p 127.0.0.1:8001:8001 \-p 127.0.0.1:8002:8002 \-p 127.0.0.1:8444:8444 \kong:3.8.0

KONG_ADMIN_LISTEN指定admin api监听的端口

验证是否安装成功:

 curl -i -X GET --url http://localhost:8001/services

如果成功安装,你可以看到返回200状态码。通过http://localhost:8002查看管理界面。

Kong gateway还可以以无数据库模式启动,此时通过配置文件来加载配置。这种方式虽然更简单,但只适合独立的网关实例或小规模环境。这里就不介绍了。

服务与路由

服务和路由是Kong的流量管理策略中的两个重要组件。

服务管理

创建服务

先通过Admin API创建一个服务,该服务将映射到https://httpbin.konghq.com

curl -i -s -X POST http://localhost:8001/services \--data name=example_service \--data url='https://httpbin.konghq.com'

查看服务

查看服务配置:

curl -X GET http://localhost:8001/services/example_service

输出如下:

{"host": "httpbin.konghq.com","name": "example_service","enabled": true,...
}

更新服务

将retries参数从5改成6:

curl --request PATCH --url localhost:8001/services/example_service --data retries=6

列出服务

curl -X GET http://localhost:8001/services

路由管理

创建路由

创建关联服务的路由,请求该路由地址的流量将被转发到关联的服务:

curl -i -X POST http://localhost:8001/services/example_service/routes --data 'paths[]=/mock'  --data name=example_route

查看路由配置

路由查看地址:

/services/{service name or id}/routes/{route name or id}
/routes/{route name or id}

以前者为例:

curl -X GET http://localhost:8001/services/example_service/routes/example_route

更新路由

curl --request PATCH --url localhost:8001/services/example_service/routes/example_route --data tags="tutorial"

列出路由

curl http://localhost:8001/routes

除了Admin API之外,也可以通过Manager查看和管理。

请求代理

根据上面创建的路由可知,当向/mock发送请求时,将会被路由到example_service

发送请求如下:

curl -X GET http://localhost:8000/mock/anything

可以看到服务返回的响应结果。

请求速率限制

Rps限制可以针对全局,可以针对服务和路由,还可以针对消费者。速率限制插件是默认安装的。

全局限制

curl -i -X POST http://localhost:8001/plugins --data name=rate-limiting --data config.minute=5 --data config.policy=local

local表示当个kong节点计数,cluster表示多节点部署时,计数共享。

我们执行一个命令来发送6条请求,看看是否会触发rate limit:

for _ in {1..6}; do curl -s -i localhost:8000/mock/anything; echo; sleep 1; done

前面5次请求正常输出,最后一条请求输出:

{"message":"API rate limit exceeded","request_id":"c9e6a941e6217c3011b8b86146081a72"
}

说明触发了速率限制。

服务限制

服务级别的rate limiting需要请求具体服务的plugins

curl -X POST http://localhost:8001/services/example_service/plugins --data "name=rate-limiting" --data config.minute=5 --data config.policy=local

路由限制

curl -X POST http://localhost:8001/routes/example_route/plugins --data "name=rate-limiting" --data config.minute=5 --data config.policy=local

消费者限制

所谓消费者即服务的调用方。

先创建一个消费者:

curl -X POST http://localhost:8001/consumers/ --data username=jsmith

再开启消费速率限制

curl -X POST http://localhost:8001/plugins --data "name=rate-limiting" --data "consumer.username=jsmith" --data "config.second=5"

在生产环境中,消费者通常是基于API密钥或者JWT等方式来识别的。

速率限制只是Kong Gateway的其中一个功能,其他的,如缓存、认证、负载均衡等,都是以类似的方式来进行配置的,并且这些基础功能,都可以通过Manger来操作。这里就不一一列举了,具体可以参见网上资料。

生产实践

部署方式

Kong Gateway一共有四种部署方式,分别是:

  • Konnect(托管控制平面)
  • Hybrid
  • Traditional(database)
  • DB-less and declarative

不通的模式都有各自的特点,需要在生产环境中需要根据具体情况来考虑。

Konnect

Konnect是一种混合模式的部署,它提供了使用Kong Gateway的最简单方法。全局控制平面由Kong托管在云上,而你可以在自己的网络环境中管理各个数据平面节点。

Hybrid

在混合模式中,Kong Gateway节点分成两种角色,一种是控制平面(CP),一种是数据平面(DP)。控制平面负责管理配置信息并提供Admin API接口。数据平面负责请求路由。控制平面访问数据库,数据平面连接到控制平面节点,获取最新的配置信息。如下图所示:

在这里插入图片描述
Traditional (database)

传统模式中,Kong Gateway在数据库中存储配置信息。所有的kong gateway节点均连接到数据库,每个节点自己管理配置信息。示意图如下:
在这里插入图片描述

与混合模式相比,传统模式没有控制平面。因此每个节点既有控制平面的作用,也有数据平面的作用。这意味着如果您的任何节点被泄露,则整个运行中的网关配置也会被泄露。相比之下,混合模式具有不同的CP和DP节点,减小了被攻击的暴露面。

DB-less and declarative mode

无数据库模式通过配置文件来读取配置信息,并将配置信息保存在节点的内存中。

此种模式下,Kong Gateway不能完全发挥所有功能。

Admin API 安全保护

通过Admin API 可以对Kong Gateway进行完全的控制,所以对Admin API 的访问控制就尤为显得重要。

网络层的访问限制

默认情况下,Kong只能通过本地接口访问,其admin_listen的设置如下:

admin_listen = 127.0.0.1:8001

这个值是可以修改的,但不要扩大暴露面,比如0.0.0.0:8081是不行的。

L3/4 的访问控制

如果必须将Admin API 的接口暴露给非本地接口,那也要从网络层面上做尽可能多的访问限制。假设现在有这样一个场景:Admin API 暴露在某个私有网络中,但只能给某个IP范围段的部分地址访问。在这种情况下,就必须配置基于主机的防火墙(例如 iptables)。

grep admin_listen /etc/kong/kong.conf
admin_listen 10.10.10.3:8001# 显示设置只允许来自自身8001端口的TCP包
iptables -A INPUT -s 10.10.10.3 -m tcp -p tcp --dport 8001 -j ACCEPT# 显示设置只允许来自以下地址的8001端口的TCP包
iptables -A INPUT -s 10.10.10.4 -m tcp -p tcp --dport 8001 -j ACCEPT
iptables -A INPUT -s 10.10.10.5 -m tcp -p tcp --dport 8001 -j ACCEPT# 其他地址发送过来的包全部丢弃
iptables -A INPUT -m tcp -p tcp --dport 8001 -j DROP

灰度部署

蓝绿部署

“Blue” Environment

先创建upstream:

curl -X POST http://localhost:8001/upstreams --data "name=address.v1.service"

添加两个目标地址:

curl -X POST http://localhost:8001/upstreams/address.v1.service/targets --data "target=192.168.34.15:80" --data "weight=100"
curl -X POST http://localhost:8001/upstreams/address.v1.service/targets --data "target=192.168.34.16:80" --data "weight=50"

创建一个服务,将其关联到上面的upstream:

curl -X POST http://localhost:8001/services/ --data "name=address-service" --data "host=address.v1.service" --data "path=/address"

添加服务路由:

curl -X POST http://localhost:8001/services/address-service/routes/ --data "hosts[]=address.mydomain.com"

当请求的域名符合路由规则时,该请求将被转发到service对应的upstream上,并根据服务器实例的权重值进行负载均衡。三分之二的请求被转发到http://192.168.34.15:80/address,三分之一的请求转发到另一台机器。

“Green” Environment

同样地再创建一个"Green"环境。

# 创建upstream
curl -X POST http://localhost:8001/upstreams --data "name=address.v2.service"# 添加targets
curl -X POST http://localhost:8001/upstreams/address.v2.service/targets --data "target=192.168.34.17:80" --data "weight=100"
curl -X POST http://localhost:8001/upstreams/address.v2.service/targets --data "target=192.168.34.18:80" --data "weight=100"

服务和路由已经有了,接下来只需要修改一下服务的域名:

curl -X PATCH http://localhost:8001/services/address-service --data "host=address.v2.service"

此时再次发送请求curl http://address.mydomain.com/address时,请求将被转发到服务对应的域名address.v2.service关联的upstream上,并根据每台服务器的权重来做负载均衡。

通过Admin API 更改的Kong Gateway 配置实时生效,无需重载或者重启,当前正在处理中的请求也不会受到影响。

金丝雀部署

在上文的基础上,我们更新域名address.v2.service关联的targets的权重值。假设192.168.34.17:80为原机器,192.168.34.18:80为新机器。

# 获取upstreams
curl http://localhost:8001/upstreams/# 获取指定upstream关联的targets
curl http://localhost:8001/upstreams/{upstream_id}/targets# 修改target(原机器ip)的权重
curl -X PATCH http://localhost:8001/upstreams/{upstream_id}/targets/{target_id} --data "weight=1000"
# 修改target(新机器ip)权重
curl -X PATCH http://localhost:8001/upstreams/{upstream_id}/targets/{target_id} --data "weight=0"

所有admin api的操作均可在manager console上操作

修改完权重后,因为新服务实例的权重为0,因此所有请求将被全部转发原服务实例上。接下来修改两个服务实例的权重值,其中一个降低为900,另一个增长为100。修改完成后10%的请求将被转发到新服务实例上。以此类推,直到所有请求全部被转发到新机器上。

区别

蓝绿部署和金丝雀部署都是用于发布和部署更新的策略,但两者的方式和目标有所不同。

蓝绿部署是一种发布策略,将应用的两个完整版本(蓝色和绿色)分别部署在独立的环境中。通常,“蓝色”表示旧版本,“绿色”表示新版本。其流程是:蓝色环境承载生产流量,新版本在绿色环境中完全准备好后,流量从蓝色环境切换到绿色环境,使所有用户瞬间访问到新版本,如果需要回滚,可以快速切换回蓝色环境。

金丝雀部署是一种渐进式发布策略,将新版本逐步推送给一小部分用户,进行验证后再逐步增加流量直到全部用户使用新版本。其流程是:新版本部署到少量节点,并分配一部分流量,根据监控的指标和反馈验证新版本的稳定性,逐渐增加流量。如果发生问题,可以快速将流量恢复到旧版本节点。

可以看到,蓝绿部署需要两套完整的生产环境,适用于发布较大更新的场景。而金丝雀部署需要复杂的流量控制和监控机制,适合频繁的小版本更新。

K8S中金丝雀部署

在k8s环境中,我们无法直接指定具体的服务实例,因此不能将流量控制到服务器级别,但可以控制到service级别。

假设现在有两个服务如下:

apiVersion: v1
kind: Service
metadata:name: app-v1
spec:selector:app: your-appversion: v1ports:- port: 80targetPort: 80
---
apiVersion: v1
kind: Service
metadata:name: app-v2
spec:selector:app: your-appversion: v2ports:- port: 80targetPort: 80

创建一个ingress用来进行流量路由:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: app-ingressannotations:konghq.com/ingress.class: "kong"konghq.com/plugins: "traffic-split"
spec:rules:- host: your-hosthttp:paths:- path: /pathType: Prefixbackend:service:name: app-v1port:number: 80

再创建一个KongIngress来分配流量:

apiVersion: configuration.konghq.com/v1
kind: KongIngress
metadata:name: app-ingress-confignamespace: your-namespace
proxy:protocols:- http- httpsroute:splits:- weight: 90service:name: app-v1port: 80- weight: 10service:name: app-v2port: 80

此时10%的流量将被转发到app-v2服务,继续更新KongIngress配置,逐步将流量导入到v2版本的服务,直至全部切到v2为止。这个过程即k8s下的canary部署。

参考资料

[1]. https://docs.konghq.com/gateway/latest/
[2]. https://zhuanlan.zhihu.com/p/698162981

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

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

相关文章

简单的kafkaredis学习之kafka

简单的kafka&redis学习整理之kafka 1. kafka 1.1 什么是消息队列 在学习Kafka之前我们先来看一下什么是消息队列,消息队列(Message Queue):可以简称为MQ 例如:Java中的Queue队列,也可以认为是一个消息队列 消息队列&#x…

AprilTag在相机标定中的应用简介

1. AprilTag简介 相机标定用的标靶类型多样,常见的形式有棋盘格标靶和圆形标靶。今天要介绍的AprilTag比较特别,它是一种编码形式的标靶。其官网为AprilTag,它是一套视觉基准系统,包含标靶编解码方法(Tag生成)和检测算法(Tag检测),可用于AR、机器人、相机标定等领域。…

java开发等一些问题,持续更新

微服务和单服务的区别 微服务(Microservices)和单体服务(Monolithic Architecture)是两种不同的软件架构风格,各有其特点和适用场景。 微服务架构: 模块化: 微服务架构将应用程序分解为一系列小…

分类算法——XGBoost 详解

XGBoost 的底层原理与实现 XGBoost(eXtreme Gradient Boosting)是一种高效的梯度提升算法(Gradient Boosting),它通过组合多个弱学习器(通常是决策树)来构建强大的模型。XGBoost 在算法层面上优…

C语言 | Leetcode C语言题解之第523题连续的子数组和

题目&#xff1a; 题解&#xff1a; struct HashTable {int key, val;UT_hash_handle hh; };bool checkSubarraySum(int* nums, int numsSize, int k) {int m numsSize;if (m < 2) {return false;}struct HashTable* hashTable NULL;struct HashTable* tmp malloc(sizeo…

在MacOS玩RPG游戏 - RPGViewerPlus

背景知识 由于我一直使用Mac电脑&#xff0c;所以一直对Mac如何玩RPGMV/RPGMZ游戏的方式有进一步的想法。 网上能给出的方案都是自行启动一个HTTP服务进行&#xff0c;进行服务加载。这个方法有效&#xff0c;但兼容性较差。涉及到自定义功能模块的游戏&#xff0c;都会有报错…

【算法】【优选算法】双指针(上)

目录 一、双指针简介1.1 对撞指针&#xff08;左右指针&#xff09;1.2 快慢指针 二、283.移动零三、1089.复写零3.1 双指针解题3.2 暴力解法 四、202.快乐数4.1 快慢指针4.2 暴力解法 五、11.盛最多⽔的容器5.1 左右指针5.2 暴力解法 一、双指针简介 常⻅的双指针有两种形式&…

集成学习(2)

AdaBoost 基本概念 AdaBoost&#xff08;Adaptive Boosting&#xff0c;自适应增强&#xff09;&#xff0c;其自适应在于&#xff1a;前一个基本分类器分错的样本会得到加强&#xff0c;加权后的全体样本再次被用来训练下一个基本分类器。同时&#xff0c;在每一轮中加入一个…

多线程案例---单例模式

单例模式 什么是设计模式呢&#xff1f; 设计模式就好比棋手中的棋谱。在日常开发中&#xff0c;会会遇到很多常见的“问题场景”&#xff0c;针对这些问题场景&#xff0c;大佬们就设计了一些固定套路&#xff0c;按照这些固定套路来实现代码或应对这些问题场景&#xff0c;也…

第十九章 Vue组件之data函数

目录 一、引言 二、示例代码 2.1. 工程结构图 2.2. main.js 2.3. App.vue 2.4. BaseCount.vue 三、运行效果 一、引言 在Vue CLI脚手架中一个组件的data选项必须是一个函数&#xff0c;以此保证每个组件实例&#xff0c;维护独立的一份数据对象。每次创建新的组件实…

mabtisx突然不起作用:mapper跳转不到xml

解决&#xff1a;进入官方下载&#xff1a;JetBrains Marketplace 选择和你idea对应的版本号 切内网下载

ComfyUI正式版来袭!一键安装无需手动部署!支持所有电脑系统

ComfyUI V1重磅发布&#xff1a;迈向AI图像处理新时代 近日&#xff0c;ComfyUI团队正式推出了备受期待的ComfyUI V1版本&#xff0c;为图像生成和处理的AI用户带来了全新的生态体验。这一版本不仅彻底解决了以往版本中繁琐的安装和兼容问题&#xff0c;还大幅提升了易用性&…

pycharm设定代码模板

1、在文件点击设置 ​​​​​​​ ​​​​​​​ 2、点击编辑器--实时模板--找到需要插入模板的位置如我要插入HTML的模板---选择--点击实时模板 3、如图&#xff1a; 4、添加模板内容&#xff0c;如果模板有变量可以在编辑变量处点击编辑 5、编辑变量 6、点…

蘑菇书(EasyRL)学习笔记(2)

1、序列决策 1.1、智能体和环境 如下图所示&#xff0c;序列决策过程是智能体与环境之间的交互&#xff0c;智能体通过动作影响环境&#xff0c;环境则返回观测和奖励。智能体的目标是从这些反馈中学习出能最大化长期奖励的策略&#xff0c;这一过程通过不断试错和调整实现强化…

SQL进阶技巧:如何利用三次指数平滑模型预测商品零售额?

目录 0 问题背景 1 数据准备 2 问题解决 2.1 模型构建 &#xff08;1&#xff09;符号规定 &#xff08;2&#xff09;基本假设 &#xff08;3&#xff09;模型的分析与建立 2.2 模型求解 3 小结 0 问题背景 1960年—1985年全国社会商品零售额如图1 所示 表1全国社…

Rsync远程同步详细介绍

一、rsync介绍 rsync是一款开源的、快速的、多功能的、可实现全量及增量的本地或远程数据同步备份的优秀工具。并且可以不进行改变原有数据的属性信息&#xff0c;实现数据的备份迁移特性。 rsync软件支持跨平台&#xff0c;适用于unix/ linux/windows等多种操作系统平台。rsyn…

无人机之自动控制原理篇

一、飞控系统 无人机飞控是指无人机的飞行控制系统&#xff0c;是无人机的大脑。飞控系统通过传感器、控制器和执行机构三部分实现对无人机的自动控制。 传感器&#xff1a;传感器负责收集无人机的姿态、速度、高度等信息。常见的传感器包括陀螺仪、加速度计、磁力计、气压计、…

得物App获评新奖项,正品保障夯实供应链创新水平

近日&#xff0c;得物App再度获评新奖项——“2024上海市供应链创新与应用优秀案例”。 本次奖项为上海市供应链领域最高奖项&#xff0c;旨在评选出在供应链创新成效上处于领先地位、拥有成功模式和经验的企业。今年以来&#xff0c;得物App已接连获得“上海市质量金奖”、“科…

STM32F103C8T6学习笔记3--按键控制LED灯

1、实验内容 S4、S5分别接PB12和PB13&#xff0c;实验要求&#xff0c;按下S4&#xff0c;D1亮&#xff0c;D2灭&#xff1b;按下S5&#xff0c;D2亮&#xff0c;D1灭。 由于按键学习的是GPIO口的输入功能&#xff0c;和输出功能的配置略有区别。本次通过按键触发相应功能没有…

10.27复习day —— 药销系统分页前(上)

登陆界面 1.auto 水平方向 —— 占据尽量多的空间 margin:auto —— 水平居中 2.块状&#xff1a;block main、div、p 特点&#xff1a; 独占一行 水平方向占满父元素可用空间&#xff08;所以得设置宽度&#xff09; 垂直方向占据空间由其内容大小决定 行内&#xff1a;inlin…