当前位置: 首页 > news >正文

kubeneters-循序渐进Ingress

文章目录

  • overview
  • Ingress 是什么?
  • 为什么使用 Ingress?
  • 我们会在这里做些什么?
  • HTTP 服务器(Nginx)还能做什么?
  • Kubernetes 中的简单示例:
    • A) 使用 Service ClusterIP
    • B) 手动配置 Nginx 服务作为代理
    • C) 使用 Kubernetes Ingress
  • Kubernetes Ingress配置示例
  • Kubernetes Ingress 示例 / 不同的命名空间
  • 如何优化 Ingress Nginx 配置?
  • 检查日志 / Nginx
  • 使用 Curl 测试配置
  • 重定向方法 / Ingress 规则
  • SSL / HTTPS
  • 总结

overview

在了解ingress之前,首先要先了解service的概念,可以阅读我之前的文章
循序渐进kubenetes Service(Cluster ip、Nodeport、Loadbalancer)

Ingress 是什么?

Kubernetes Ingress 并不是 Kubernetes Service,而是一种配置方式,用于管理外部请求到集群内部服务(如 ClusterIP 类型服务)的路由。简单来说,Ingress 通过配置规则,将外部流量引导至内部的服务。而作为流量入口的 Nginx Pod,通常需要依赖 Kubernetes Service(通常是 LoadBalancer 类型)来实现对外暴露的功能。

理解 Ingress 的工作原理是配置和使用的基础。理清这些概念有助于明确实际需求,从而判断是否需要使用 Ingress。

接下来的示例将展示 Ingress 的配置方法,并以实际应用为基础展开说明。

为什么使用 Ingress?

使用 Ingress 是为了让内部服务能够从集群外部访问。这可以节省宝贵的静态 IP 地址,因为我们不需要为多个服务声明 LoadBalancer 类型的服务。此外,Ingress 还支持更丰富的配置选项,并提供更简便的管理方式,正如我们接下来将看到的那样。

我们会在这里做些什么?

A) 简要介绍 HTTP 服务器的基本概念,特别是 Nginx 的功能及其常见用途。
B) 演示如何手动配置 Ingress,不依赖 Kubernetes 提供的 Ingress 资源实现类似功能。
C) 解析 Kubernetes Ingress 的实质,它本质上是一个预先配置好的 Nginx 服务器,用于简化路由配置和请求转发。

为了更好地理解这些概念,接下来的内容将以分步方式说明。
A) 探索简单的 HTTP 服务器世界
在容器化技术、Kubernetes 和现代云计算普及之前,HTTP 服务器在网络架构中扮演了基础角色。以 Nginx 为例,其主要功能包括:

  • 接收通过 HTTP 协议发送的请求。
  • 检查系统中的文件路径是否匹配请求内容。
  • 如果匹配文件存在,将其作为响应返回给客户端。
    这种简单高效的处理方式,构成了后续复杂服务和云技术发展的基础。
    在这里插入图片描述
    在 Nginx 中,我们可以通过如下配置来做到这一点:
location /folder {root /var/www/;index index.html;
}

HTTP 服务器(Nginx)还能做什么?

它可以接受针对某些文件路径的请求,并将这些请求转发到其他服务器(这意味着 Nginx 可以充当代理),然后将该服务器的响应重定向回客户端。对客户端来说,一切都没有变化,接收到的结果仍然是请求的文件(如果存在)。
在这里插入图片描述
在 Nginx 中,可以使用如下示例配置重定向代理:

location /folder {proxy_pass http://second-nginx-server:8000;
}

这意味着 Nginx 可以通过充当代理来提供文件系统中的文件或将响应重定向到其他服务器并返回它们的响应。

Kubernetes 中的简单示例:

A) 使用 Service ClusterIP

再次强调,从这一点开始,我们需要理解 Kubernetes 中的 Service。假设我们有两个 worker 节点,这里暂时忽略 master 节点。我们有两个 Service:service-nginx 和 service-python,它们分别指向不同的 Pod。

Service 并不运行在特定的节点上,可以说它在我们集群的“任何地方都可用”。
在这里插入图片描述
你需要理解这里发生的事情。在我们的集群内部,我们可以通过它们的 Service 访问 Nginx 和 Python 的 Pod。接下来,我们还希望让它们能够从集群外部访问。因此,我们将它们转换为 Service LoadBalancer。
使用 Service LoadBalancer
你可以看到,我们将 Service ClusterIP 转换为 Service LoadBalancer。假设我们的 Kubernetes 集群托管在云提供商上,因为要使用 Service LoadBalancer,Kubernetes 集群必须托管在支持外部负载均衡功能的云提供商(如 Gcloud、AWS、DigitalOcean 等)上。

转换后,它会创建两个外部负载均衡器,将请求引导到我们的外部 Node IP,然后再进一步将其引导到内部的 Service ClusterIP。
在这里插入图片描述
我们看到有两个 LoadBalancer,每个都有自己的公共 IP。如果我们向 22.33.44.55 发送请求,它会被转发到内部的 service-nginx。如果我们向 77.66.55.44 发送请求,它会被转发到内部的 service-python。
但是公共 IP 地址非常稀缺,而负载均衡器的成本取决于云服务提供商。现在想象一下,如果我们不仅有两个而是更多的内部服务需要创建 LoadBalancer,那么费用将会大幅增加。
有没有其他解决方案可以让我们只使用一个 LoadBalancer(带一个 IP 地址),但仍然能够直接访问我们所有的内部服务?
我们先通过一种手动方法(非 Kubernetes)来探讨这个问题。

B) 手动配置 Nginx 服务作为代理

B) 手动配置 Nginx 服务作为代理
正如之前提到的,Nginx 可以作为一个代理。在下图中,我们看到一个名为 service-nginx-proxy 的新 Service,它曾是我们唯一的 Service LoadBalancer。
service-nginx-proxy 仍然会指向一个或多个 Nginx Pod 端点,但为了简化,这里没有在图中显示这些端点。
在这里插入图片描述
我们可以看到,我们现在只使用了一个 LoadBalancer(11.22.33.44),但通过不同的 HTTP URL 来区分请求。请求用黄色表示,目标相同,只是内容(请求的 URL)不同。

service-nginx-proxy 会根据请求的 URL 使用 Nginx 的代理功能决定将请求转发到哪个服务。

在这种情况下,我们有两个选项:

  • 红色请求重定向到 service-nginx。
  • 蓝色请求重定向到 service-python。
location /folder {proxy_pass http://service-nginx:3001;
}
location /other {proxy_pass http://service-python:3002;
}

目前,我们需要手动配置 service-nginx-proxy,例如创建 Nginx 配置文件并指向我们的 Service ClusterIP。
由于这是一个通用的解决方案,Kubernetes 提供了 Ingress,以使配置更加简单且易于管理。

C) 使用 Kubernetes Ingress

对比下图与之前的图。变化并不大,在这里,我们使用了通过 YAML 文件预先配置好的 Kubernetes Ingress。
与手动方式相比,这种方法可以节省大量的工作量。
在这里插入图片描述
现在让我们继续看一些配置示例。

安装 Kubernetes Ingress 控制器
Kubernetes Ingress 是一个可以通过以下方式安装的 Kubernetes 附加资源:
部署 Ingress NGINX 控制器的基本组件

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/cloud/deploy.yaml

使用以下命令,我们可以看到安装在 ingress-nginx 命名空间中的 k8s 资源:

kubeuser@k8smaster:~/yaml$ kubectl get svc,pod --namespace=ingress-nginx
NAME                                         TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
service/ingress-nginx-controller             LoadBalancer   10.106.67.131   172.19.6.5    80:31463/TCP,443:31658/TCP   53m
service/ingress-nginx-controller-admission   ClusterIP      10.107.97.6     <none>        443/TCP                      53mNAME                                            READY   STATUS      RESTARTS   AGE
pod/ingress-nginx-admission-create-8nr4v        1/1     Running     0          53m
pod/ingress-nginx-admission-patch-hkqc7         1/1     Running     2          53m
pod/ingress-nginx-controller-7d56585cd5-28bhl   1/1     Running     0          53m

注意,如果是在内网环境,service的externalIP会返回为空,那是因为没有云端环境提供loadbalancer IP,这种情况下,可以为Service指定externalIP

kubectl patch svc ingress-nginx-controller -n ingress-nginx -p '{"spec":{"externalIPs":["172.19.6.5"]}}'

同时,我们为了ingress controller能够跨节点路由,也需要修改路由策略

kubectl patch svc ingress-nginx-controller  -n ingress-nginx -p '{"spec":{"externalTrafficPolicy":"Cluster"}}'

我们可以看到一个正常工作的 Service LoadBalancer,它具有外部 IP,并且相关的 Pod 正在运行。我们甚至可以通过执行以下命令运行 kubectl exec 进入该 Pod,查看其中的配置内容,发现它已经预先配置了一个 Nginx 服务器:

kubectl exec -it -n ingress-nginx ingress-nginx-controller-7d56585cd5-28bhl -- /bin/bash
Mem: 2833712K used, 393868K free, 8076K shrd, 135072K buff, 1887712K cached
CPU:   1% usr   0% sys   0% nic  97% idle   0% io   0% irq   0% sirq
Load average: 0.05 0.06 0.09 1/454 67PID  PPID USER     STAT   VSZ %VSZ CPU %CPU COMMAND25    19 www-data S     126m   4%   0   0% nginx: worker process7     1 www-data S    1246m  39%   0   0% /nginx-ingress-controller --publish-service=ingress-nginx/ingress-nginx-controller --election-id=ingress-nginx-leader --controller-class=k8s.io60     0 www-data S    1026m  32%   0   0% /bin/bash67    60 www-data R    1025m  32%   0   0% top19     7 www-data S     114m   4%   0   0% nginx: master process /usr/bin/nginx -c /etc/nginx/nginx.conf26    19 www-data S     112m   4%   0   0% nginx: cache manager process1     0 www-data S      220   0%   0   0% /usr/bin/dumb-init -- /nginx-ingress-controller --publish-service=ingress-nginx/ingress-nginx-controller --election-id=ingress-nginx-leader --c

在 nginx.conf 中,我们将看到各种重定向代理设置和其他相关配置。

Kubernetes Ingress配置示例

准备测试环境:
创建deployment
service-python deployment yaml示例内容:

cat <<EOF | kubectl apply -n default --dry-run=server -f  -
apiVersion: apps/v1
kind: Deployment
metadata:name: service-python
spec:replicas: 1selector:matchLabels:app: service-pythontemplate:metadata:labels:app: service-pythonspec:containers:- name: nginximage: nginx:latestports:- containerPort: 80volumeMounts:- name: web-contentmountPath: /usr/share/nginx/htmlvolumes:- name: web-contentconfigMap:name: service-python-config
---
apiVersion: v1
kind: ConfigMap
metadata:name: service-python-config
data:index.html: |<html><head><title>Hello service-python</title></head><body><h1>Hello, world!</h1></body></html>
EOF

service-nginx deployment yaml示例内容:

cat <<EOF | kubectl apply -n default -f  -
apiVersion: apps/v1
kind: Deployment
metadata:name: service-nginx
spec:replicas: 1selector:matchLabels:app: service-nginxtemplate:metadata:labels:app: service-nginxspec:containers:- name: nginximage: nginx:latestports:- containerPort: 80volumeMounts:- name: web-contentmountPath: /usr/share/nginx/htmlvolumes:- name: web-contentconfigMap:name: service-nginx-config
---
apiVersion: v1
kind: ConfigMap
metadata:name: service-nginx-config
data:index.html: |<html><head><title>Hello service-nginx</title></head><body><h1>Hello, service-nginx!</h1></body></html>
EOF

创建service
python-service service yaml示例内容

cat <<EOF |kubectl apply -n default -f -
apiVersion: v1
kind: Service
metadata:name: python-service
spec:selector:app: service-pythonports:- protocol: TCPport: 81targetPort: 80
EOF

nginx-service service yaml示例内容

cat <<EOF |kubectl apply -n default -f -
apiVersion: v1
kind: Service
metadata:name: nginx-service
spec:selector:app: service-nginxports:- protocol: TCPport: 81targetPort: 80
EOF

创建ingress
我们正在使用的示例的 Ingress yaml 示例如下所示:

cat << EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:annotations:kubernetes.io/ingress.class: nginxnginx.ingress.kubernetes.io/rewrite-target: "/"namespace: defaultname: test-ingress
spec:ingressClassName: nginxrules:- http:paths:- path: /folderpathType: Prefixbackend:service:name: nginx-service  port:number: 81- http:paths:- path: /otherpathType: Prefixbackend:service:name: python-service  port:number: 81    
EOF

注意nginx.ingress.kubernetes.io/rewrite-target: "/"选项,那是因为上面的示例deployment中部署的nginx pod,均只保留了默认设定,故这里使用此选项做转向设定以便示范过程简单化,当然,你也可以不使用nginx.ingress.kubernetes.io/rewrite-target: “/”,同时kubelet exec进入到pod内部,自定义nginx的路径

    location / {root   /usr/share/nginx/html;index  index.html index.htm;}

测试1:

kubeuser@k8sworker1:~$ curl http://172.19.6.5/folder
<html>
<head><title>Hello service-nginx</title></head>
<body>
<h1>Hello, service-nginx!</h1>
</body>
</html>

测试2:

kubeuser@k8sworker1:~$ curl http://172.19.6.5/other
<html>
<head><title>Hello service-python</title></head>
<body>
<h1>Hello,service-python!</h1>
</body>
</html>

上述两个测试将分别返回"Hello, service-nginx!"与”Hello,service-python!“
上面的例子中两个服务 nginx-service 和 python-service,它们都在 default 命名空间中。所以我们可以创建一个 Ingress 配置文件来路由请求:
这里,http://172.19.6.5/folder会路由到 nginx-service,而 http://172.19.6.5 会路由到 python-service。所有流量会使用同一个loadbalancer的 IP 地址。
假如感兴趣,也可以使用kubectl exec 进入到ingress controller的pod内部,查看nginx的设定内容

kubectl exec -it -n ingress-nginx ingress-nginx-controller-7d56585cd5-mvwsq -- /bin/bash

将会看到,之前ingress内设定的路径已经注册到ingress controller的pod内

ingress-nginx-controller-7d56585cd5-mvwsq:/etc/nginx$ cat /etc/nginx/nginx.conf|grep "location"location ~* "^/folder" {set $location_path  "/folder";location ~* "^/other" {set $location_path  "/other";location ~* "^/" {set $location_path  "";

Kubernetes Ingress 示例 / 不同的命名空间

在 Kubernetes 中,Ingress 是用来管理外部访问服务的入口。前面的示例,ingress都是引用同namespace中的service,但是,Ingress 配置中默认只能引用与它在同一个命名空间内的服务。如果有一个服务位于不同的命名空间,而你希望通过 Ingress 转发流量到这个服务,就会遇到限制。
因此,需要找到一种方法来解决这个问题,使得 Ingress 可以访问其他命名空间中的服务。
基于这个原因,我们需要创建两个 Ingress 配置文件。例如:
service-nginx 仍然位于default命名空间:

cat << EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:annotations:kubernetes.io/ingress.class: nginxnginx.ingress.kubernetes.io/rewrite-target: "/"namespace: defaultname: ingress1
spec:ingressClassName: nginxrules:- http:paths:- path: /folderpathType: Prefixbackend:service:name: nginx-service  port:number: 81 
EOF

然后service-python位于命名空间web中:

cat <<EOF |kubectl apply -f -
apiVersion: v1
kind: Service
metadata:name: python-servicenamespace: web
spec:selector:app: service-pythonports:- protocol: TCPport: 81targetPort: 80
EOF

在这里插入图片描述

cat <<EOF | kubectl apply  -f  -
apiVersion: apps/v1
kind: Deployment
metadata:name: service-pythonnamespace: web
spec:replicas: 1selector:matchLabels:app: service-pythontemplate:metadata:labels:app: service-pythonspec:containers:- name: nginximage: nginx:latestports:- containerPort: 80volumeMounts:- name: web-contentmountPath: /usr/share/nginx/htmlvolumes:- name: web-contentconfigMap:name: service-python-config
---
apiVersion: v1
kind: ConfigMap
metadata:name: service-python-confignamespace: web
data:index.html: |<html><head><title>Hello service-python</title></head><body><h1>Hello, service-python</h1></body></html>
EOF
cat <<EOF |kubectl apply -f -
apiVersion: v1
kind: Service
metadata:name: python-servicenamespace: web
spec:selector:app: service-pythonports:- protocol: TCPport: 81targetPort: 80
EOF

在这里插入图片描述

如何优化 Ingress Nginx 配置?

我们可以利用 Kubernetes Ingress 资源中的annotations添加注解来实现。例如,我们可以配置一些通常在 Nginx 中可以直接配置的选项:

kind: Ingress
metadata:name: ingressannotations:kubernetes.io/ingress.class: nginxnginx.ingress.kubernetes.io/proxy-connect-timeout: '30'nginx.ingress.kubernetes.io/proxy-send-timeout: '500'nginx.ingress.kubernetes.io/proxy-read-timeout: '500'nginx.ingress.kubernetes.io/send-timeout: "500"nginx.ingress.kubernetes.io/enable-cors: "true"nginx.ingress.kubernetes.io/cors-allow-methods: "*"nginx.ingress.kubernetes.io/cors-allow-origin: "*"

甚至可以制定非常具体的规则,例如:

nginx.ingress.kubernetes.io/configuration-snippet: |if ($host = 'www.test.com' ) {rewrite ^ https://test.com$request_uri permanent;}

这些注解(Annotations)随后会被转换为 Nginx 的配置。我们可以通过使用 kubectl exec 命令手动进入 Nginx 的 Pod 中查看这些配置。

检查日志 / Nginx

要排查问题或错误,也可以查看 Ingress 的日志:

kubectl logs ingress-nginx-controller-7d56585cd5-mvwsq -n ingress-nginx
10.0.0.169 - - [02/Jan/2025:10:13:27 +0000] "GET /other HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36" 557 0.001 [web-python-service-81] [] 10.0.1.135:80 0 0.001 304 2317f913f2a6a56c9bce94749fde97ec

使用 Curl 测试配置

如果我们想测试 Ingress / Nginx 的重定向规则,建议使用 curl -v yourhost.com 而不是使用浏览器,以避免缓存等问题。

重定向方法 / Ingress 规则

在之前的示例中,我们使用了类似 /folder 或 /other/directory 的路径,将其重定向到不同的服务。这被称为“路径列表(A list of paths)”。

我们也可以使用域名或子域名来区分各个请求的重定向。例如,将 api.myurl.com 和 web.myurl.com 分别指向不同的内部 ClusterIP 服务。看起来可以像这样:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:annotations:kubernetes.io/ingress.class: nginx # 使用 NGINX Ingress 控制器nginx.ingress.kubernetes.io/rewrite-target: /name: ingress-host-samplenamespace: web
spec:ingressClassName: nginxrules:- host: api.test.com   #測試用域名,或使用 IP 地址(需要設置 hosts 文件)- http:paths:- backend:service:name: python-serviceport:number: 81path: /otherpathType: Prefix
status:loadBalancer:ingress:- ip: 172.19.6.5

此示例展示了如何针对特定域名,将不同的 HTTP 路径路由到不同的内部服务。

SSL / HTTPS

SSL 是一种常见的加密协议,可用于实现安全的 HTTPS 访问。Kubernetes Ingress 提供了 “TLS Termination" 功能,负责处理所有 SSL 通信,解密或终止 SSL 请求,并将解密后的请求转发至内部服务。

当多个内部服务共享相同的 SSL 证书(包括通配符证书)时,该功能尤为高效。只需在 Ingress 上配置一次 SSL 证书,无需在每个内部服务上单独配置。Ingress 支持使用预先配置的 Kubernetes TLS Secret 来存储和管理 SSL 证书。
本例使用自签名证书与密钥

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:annotations:nginx.ingress.kubernetes.io/rewrite-target: /name: ingress-host-samplenamespace: web
spec:ingressClassName: nginxtls:- hosts:- api.test.comsecretName: test-tls-secretrules:- host: api.test.comhttp:paths:- path: /otherpathType: Prefixbackend:service:name: python-serviceport:number: 81

我们只需要确保,如果在不同的命名空间中有多个Ingress 资源,那么TLS Secret(金钥)也必须在所有定义了使用该金钥的Ingress 资源的命名空间中可用。

总结

Kubernetes Ingress 的核心功能是提供一种高效的方式来配置 Nginx 等反向代理服务器,从而将外部请求路由到集群内部的服务。这种机制能够减少对静态 IP 和负载均衡器资源的需求,有助于节省成本和资源。
Ingress 本身并不是 Kubernetes 服务的一种,而是一种管理外部访问的规则集合。它通常与负载均衡器类型的服务协同工作,借助服务将请求引导至目标应用。此外,除了基于 Nginx 的实现,还有一些其他类型的 Ingress 控制器,它们可能使用不同的代理技术来实现类似功能。

相关文章:

kubeneters-循序渐进Ingress

文章目录 overviewIngress 是什么&#xff1f;为什么使用 Ingress&#xff1f;我们会在这里做些什么&#xff1f;HTTP 服务器&#xff08;Nginx&#xff09;还能做什么&#xff1f;Kubernetes 中的简单示例&#xff1a;A) 使用 Service ClusterIPB) 手动配置 Nginx 服务作为代理…...

Shell控监Kafka积压

1、获取Kafka消息堆积情况 vi check-kafka-lag.sh #&#xff01;/bin/bashTOPIC"total_random" GROUP_ID"etl-dw" BOOTSTRAP_SERVER"node-01:9092,node-02:9092,node-03:9092"# 检查第一个参数是否为数字 if ! [[ $1 ~ ^[0-9]$ ]]; thenecho &…...

USB3020任意波形发生器4路16位同步模拟量输出卡1MS/s频率 阿尔泰科技

信息社会的发展&#xff0c;在很大程度上取决于信息与信号处理技术的先进性。数字信号处理技术的出现改变了信息 与信号处理技术的整个面貌&#xff0c;而数据采集作为数字信号处理的必不可少的前期工作在整个数字系统中起到关键 性、乃至决定性的作用&#xff0c;其应用已经深…...

MongoDB 学习指南与资料分享

MongoDB学习资料 MongoDB学习资料 MongoDB学习资料 在数据爆炸的当下&#xff0c;MongoDB 作为非关系型数据库的佼佼者&#xff0c;以其独特优势在各领域发光发热。无论是海量数据的存储&#xff0c;还是复杂数据结构的处理&#xff0c;MongoDB 都能轻松应对。接下来&#xf…...

Web端实时播放RTSP视频流(监控)

一、安装ffmpeg: 1、官网下载FFmpeg: Download FFmpeg 2、点击Windows图标,选第一个:Windows builds from gyan.dev 3、跳转到下载页面: 4、下载后放到合适的位置,不用安装,解压即可: 5、配置path 复制解压后的\bin路径,配置环境变量如图: <...

23- TIME-LLM: TIME SERIES FORECASTING BY REPRO- GRAMMING LARGE LANGUAGE MODELS

解决问题 用LLM来解决时序预测问题&#xff0c;并且能够将时序数据映射&#xff08;reprogramming&#xff09;为NLP token&#xff0c;并且保持backbone的大模型是不变的。解决了时序序列数据用于大模型训练数据稀疏性的问题。 方法 Input Embedding 输入&#xff1a; X …...

【Go】Go数据类型详解—数组与切片

1. 前言 今天需要学习的是Go语言当中的数组与切片数据类型。很多编程语言当中都有数组这样的数据类型&#xff0c;Go当中的切片类型本质上也是对 数组的引用。但是在了解如何定义使用数组与切片之前&#xff0c;我们需要思考为什么要引入数组这样的数据结构。 1.1 为什么需要…...

微服务中引入消息队列的利弊

微服务中引入消息队列的利弊 1、微服务架构中引入消息队列(Message Queue)的主要优势&#xff1a; 1.1 解耦(Decoupling) 服务之间不需要直接调用&#xff0c;通过消息队列实现松耦合 生产者和消费者可以独立扩展和维护 降低系统间的依赖性 1.2 异步处理(Asynchronous Proc…...

如何使用策略模式并让spring管理

1、策略模式公共接口类 BankFileStrategy public interface BankFileStrategy {String getBankFile(String bankType) throws Exception; } 2、策略模式业务实现类 Slf4j Component public class ConcreteStrategy implements BankFileStrategy {Overridepublic String ge…...

骑砍2霸主MOD开发(11)-可编程渲染管线Shader编程

一.固定渲染管线&可编程渲染管线 固定渲染管线:GPU常规渲染算法,将3D模型经过四大变换计算得到2D屏幕图像 可编程渲染管线:定制化GPU渲染算法,需要提交Shader至GPU中,GPU根据定制化算法得到2D屏幕图像 二.CoreShader&TerrainShader CoreShader:游戏中使用的静态shader…...

【PowerQuery专栏】PowerQuery 函数之CSV文件处理函数

CSV.Document 函数是进行CSV文件解析功能的函数,函数目前包含4个参数: 参数1为文件的数据源,数据类型为二进制类型,值为需要读取的文本数据参数2为列名称,数据类型为字符串类型,值为分割后的列名称参数3为分隔符,数据类型为任意类型,值为分割数据的分隔符参数4为文件编…...

【FAQ】HarmonyOS SDK 闭源开放能力 —Map Kit(4)

1.问题描述&#xff1a; 添加了很多的marker点&#xff0c;每个marker点都设置了customInfoWindow&#xff0c;但是每次只能显示一个customInfoWindow吗&#xff1f; 解决方案&#xff1a; Marker的InfoWindow每次只能显示一个。 2.问题描述&#xff1a; 在地图选型中&…...

通过ffmpeg将FLV文件转换为MP4

使用 ffmpeg 将 FLV 文件转换为 MP4 文件是一个常见的操作。ffmpeg 是一个强大的多媒体处理工具&#xff0c;支持多种格式的转换、剪辑、合并等操作。以下是详细的步骤和命令示例&#xff0c;帮助你完成这一任务。 安装 FFmpeg 如果你还没有安装 ffmpeg&#xff0c;可以根据你…...

深入分析Java中的重载与重写:理解多态的两个面向

深入分析Java中的重载与重写&#xff1a;理解多态的两个面向 之前其实写过一篇文章来探讨Java当中的方法重载与方法重写但当时学的还不够通透&#xff0c;分析有点片面&#xff0c;这次我从多态的角度对其进行分析&#xff0c;有问题欢迎大家来评论区一起探讨 在Java编程中&a…...

STM32的集成开发环境STM32CubeIDE安装

STM32CubeIDE - STM32的集成开发环境 - 意法半导体STMicroelectronics...

【狂热算法篇】探秘图论之 Floyd 算法:解锁最短路径的神秘密码(通俗易懂版)

&#xff1a; 羑悻的小杀马特.-CSDN博客羑悻的小杀马特.擅长C/C题海汇总,AI学习,c的不归之路,等方面的知识,羑悻的小杀马特.关注算法,c,c语言,青少年编程领域.https://blog.csdn.net/2401_82648291?spm1010.2135.3001.5343 在本篇文章中&#xff0c;博主将带大家去学习所谓的…...

25/1/13 嵌入式笔记 继续学习Esp32

PWM&#xff08;Pulse Width Modulation&#xff0c;脉宽调制&#xff09; 是一种通过快速切换高低电平来模拟中间电压值的技术。它广泛应用于控制 LED 亮度、电机速度、音频生成等场景。 analogWrite函数:用于在微控制器&#xff08;如 Arduino&#xff09;上生成模拟信号。 …...

C语言的语法糖

C语言的语法糖 引言 在程序开发的过程中&#xff0c;语言的设计和编写风格往往会直接影响开发效率和代码可读性。C语言作为一种广泛应用于系统编程和嵌入式开发的编程语言&#xff0c;其设计虽然追求简洁与高效&#xff0c;但在某些方面同样存在可以提高编程体验的“语法糖”…...

客户案例:致远OA与携程商旅集成方案

一、前言 本项目原型客户公司创建于1992年,主要生产并销售包括糖果系列、巧克力系列、烘焙系列、卤制品系列4大类,200多款产品。公司具有行业领先的生产能力,拥有各类生产线100条,年产能超过10万吨。同时,经过30年的发展,公司积累了完善的销售网络,核心经销商已经超过1200个,超…...

浔川 AI 翻译已修复,可正常使用

浔川 AI 翻译已修复&#xff0c;可正常使用 亲爱的用户们&#xff1a; 大家好&#xff01;经过技术团队的不懈努力&#xff0c;浔川 AI 翻译平台已完成修复&#xff0c;目前各项功能均已恢复正常&#xff0c;可流畅使用。在此&#xff0c;我们向一直以来关心和支持浔川 AI 翻译…...

【Python】深入探讨Python中的单例模式:元类与装饰器实现方式分析与代码示例

《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门&#xff01; 解锁Python编程的无限可能&#xff1a;《奇妙的Python》带你漫游代码世界 单例模式&#xff08;Singleton Pattern&#xff09;是一种常见的设计模式&#xff0c;它确保一个类只有一个实例&…...

D. Paint the Tree

https://codeforces.com/problemset/problem/1975/D 分析&#xff1a; 观察样例可以发现&#xff0c;对于PB第一次在位置 r 接触到红点之后&#xff0c;接下来的怎么走完全可以有PB说了算&#xff0c;情况不会更差。同时还能发现&#xff0c;大部分边都是需要走两遍的&#xff…...

ScratchLLMStepByStep:训练自己的Tokenizer

1. 引言 分词器是每个大语言模型必不可少的组件&#xff0c;但每个大语言模型的分词器几乎都不相同。如果要训练自己的分词器&#xff0c;可以使用huggingface的tokenizers框架&#xff0c;tokenizers包含以下主要组件&#xff1a; Tokenizer: 分词器的核心组件&#xff0c;定…...

【Linux】Socket编程-TCP构建自己的C++服务器

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;Linux 目录 一&#xff1a;&#x1f525; Socket 编程 TCP &#x1f98b; TCP socket API 详解&#x1f98b; 多线程远程命令执行&#x1f98b; 网络版计算器&#xff08;应用层自定义协议与序列化…...

数据结构——线性表和顺序表

1、线性表的基本概念 1.1 定义 线性结构是简单且常用的数据结构&#xff0c;而线性表则是一种典型的线性结构 存储数据&#xff0c;最简单&#xff0c;最有效的方法是吧它们存储在一个线性表中 一个线性表是n个元素的有限序列。每个元素在不同的情况下有不同的含义&#xff0c…...

FunASR 在Linux/Unix 平台编译

第一步拉取镜像并生成容器&#xff1a; ### 镜像启动 通过下述命令拉取并启动FunASR软件包的docker镜像&#xff1a; shell sudo docker pull \ registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-online-cpu-0.1.12 mkdir -p ./funasr-runtime-…...

AIP-200 先例

编号200原文链接AIP-200: Precedent状态批准创建日期2018-06-28更新日期2018-06-28 很多时候&#xff0c;API的编写方式会违反新的指导原则。此外&#xff0c;有时出于特定原因也需要打破标准&#xff0c;例如与现有系统保持一致、满足严格的性能要求或其他因素。最后&#xf…...

SAP五大核心模块:塑造企业数字化未来

在数字化转型的浪潮中&#xff0c;SAP&#xff08;Systems, Applications and Products in Data Processing&#xff09;以其强大的企业资源规划&#xff08;ERP&#xff09;系统&#xff0c;成为众多企业信赖的伙伴。SAP系统通过五大核心模块&#xff0c;即财务管理&#xff0…...

【UE5.3】fix DONET报错

新的机器 4070 gpu 运行ue项目, 可能是epic 启动器是vs安装的, vs安装的epic 启动器自己更新了一波,导致了.NET的问题? ue项目是拷贝远程的windows的电脑里面的,应该不会导致ue源码里的cs出问题? 【UE5.3】UnrealLink 安装:fix Detected compiler newer than Visual Stu…...

【0393】Postgres内核 checkpointer process ③ 构建 WAL records 工作缓存区

1. 初始化 ThisTimeLineID、RedoRecPtr 函数 InitXLOGAccess() 内部会初始化 ThisTimeLineID、wal_segment_size、doPageWrites 和 RedoRecPtr 等全局变量。 下面是这四个变量初始化前的值: (gdb) p ThisTimeLineID $125 = 0 (gdb) p wal_segment_size $126 = 16777216 (gdb…...

pc 端 TensorRT API 实现 YOLOv11 的 C++ 小白部署经验

标题1 模型转化 python 先下载项目 https://github.com/ultralytics/ultralytics 同时下载模型 https://github.com/ultralytics/assets/releases/download/v8.3.0/yolo11n.pt pythonconda虚拟环境&#xff0c;主要是以下三个&#xff0c;其余缺什么直接pip anaconda…...

LLM - 大模型 ScallingLaws 的 C=6ND 公式推导 教程(1)

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/145185794 Scaling Laws (缩放法则) 是大模型领域中&#xff0c;用于描述 模型性能(Loss) 与 模型规模N、数据量D、计算资源C 之间关系的经验规律…...

【机器学习实战】kaggle 欺诈检测---使用生成对抗网络(GAN)解决欺诈数据中正负样本极度不平衡问题

【机器学习实战】kaggle 欺诈检测---如何解决欺诈数据中正负样本极度不平衡问题https://blog.csdn.net/2302_79308082/article/details/145177242 本篇文章是基于上次文章中提到的对抗生成网络&#xff0c;通过对抗生成网络生成少数类样本&#xff0c;平衡欺诈数据中正类样本极…...

C++ 之多线程相关总结

C 之多线程相关总结 1.多线程相关基础知识 1.1 线程的创建和管理 1. std::thread 类&#xff1a; 用于创建和管理线程。通过将可调用对象&#xff08;如函数、函数对象、lambda 表达式&#xff09;作为参数传递给 std::thread 的构造函数&#xff0c;可以创建一个新的线程。…...

基于机器学习随机森林算法的个人职业预测研究

1.背景调研 随着信息技术的飞速发展&#xff0c;特别是大数据和云计算技术的广泛应用&#xff0c;各行各业都积累了大量的数据。这些数据中蕴含着丰富的信息和模式&#xff0c;为利用机器学习进行职业预测提供了可能。机器学习算法的不断进步&#xff0c;如深度学习、强化学习等…...

性能测试 - Locust WebSocket client

Max.Bai 2024.10 0. 背景 Locust 是性能测试工具&#xff0c;但是默认只支持http协议&#xff0c;就是默认只有http的client&#xff0c;需要其他协议的测试必须自己扩展对于的client&#xff0c;比如下面的WebSocket client。 1. WebSocket test Client “”“ Max.Bai W…...

量子计算将彻底改变商业分析

虽然量子计算听起来颇具未来感&#xff0c;但这项技术正迅速走向成熟 —— 就如同 ChatGPT 这类人工智能&#xff08;AI&#xff09;工具一样。我相信&#xff0c;量子计算技术所产生的连锁反应很快就会对业务分析领域产生巨大影响。 什么是量子计算&#xff1f; 尽管名字听起…...

爬山算法与模拟退火算法的全方面比较

一、基本概念与原理 1. 爬山算法 爬山算法是一种基于启发式的局部搜索算法,通过不断地向当前解的邻域中搜索更优解来逼近全局最优解。它的核心思想是,从当前解出发,在邻域内找到一个使目标函数值更大(或更小)的解作为新的当前解,直到找不到更优的解为止。 2.模拟退火算…...

【深度学习】用RML2018训练好模型去识别RML2016的数据会遇到输入维度不匹配的问题,如何解决?

文章目录 问题解决办法1. 调整输入数据长度2. 修改模型结构(我个人比较推崇的方法)3. 迁移学习4. 重新训练模型5. 数据增强6. 其他差异问题 经常会有人问的一个问题: 我用RML2018跑的调制识别模型,用RML2016数据集能直接识别吗?(2018数据集信号样本的长度是1024,2016数据集…...

2025年1月17日(点亮一个 LED)

系统信息&#xff1a; Raspberry Pi Zero 2W 系统版本&#xff1a; 2024-10-22-raspios-bullseye-armhf Python 版本&#xff1a;Python 3.9.2 已安装 pip3 支持拍摄 1080p 30 (1092*1080), 720p 60 (1280*720), 60/90 (640*480) 已安装 vim 已安装 git 学习目标&#xff1a;…...

商用车电子电气零部件电磁兼容条件和试验(8)—辐射抗干扰(ALSE)和便携式发射机抗干扰(HPT)

写在前面 本系列文章主要讲解商用车电子/电气零部件或系统的传导抗干扰、传导发射和辐射抗干扰、电场辐射发射以及静电放电等试验内容及要求,高压试验项目内容及要求。 若有相关问题,欢迎评论沟通,共同进步。(*^▽^*) 目录 商用车电子电气零部件电磁兼容条件和试验—目录…...

NumPy;NumPy在数据分析中的应用;NumPy与其他库的搭配使用

NumPy&#xff1b;NumPy在数据分析中的应用&#xff1b;NumPy与其他库的搭配使用 NumPy&#xff1a;Python 数据分析的核心工具什么是 NumPy&#xff1f;NumPy 的主要优势 NumPy 在数据分析中的应用1. 数据处理与清洗2. 数学和统计分析3. 数组变换与矩阵运算 NumPy 与其他库的搭…...

机器学习经典无监督算法——聚类K-Means算法

目录 算法原理 算法步骤 算法API 算法导入 API参数理解 算法实现 算法原理 Kmeans 算法是一种无监督的聚类算法&#xff0c;目的是将数据集中的样本划分到 K 个不同的簇中。 聚类&#xff1a;将数据集中相似的数据点归为一组或一个簇的过程。 数据集&#xff1a;一组相…...

网络变压器的分类

网络变压器是局域网(LAN)中各级网络设备中必备的元件。它们的主要功能是传输数据&#xff0c;增强信号&#xff0c;并提供电气隔离&#xff0c;以防雷保护和匹配阻抗。网络变压器也被称为数据泵或网络隔离变压器。它们广泛应用于网络交换机、路由器、网卡、集线器等设备中。 网…...

【MySQL】复合查询+表的内外连接

复合查询表的内外连接 1.基本查询回顾2.多表查询3.自连接4.子查询4.1单列子查询4.2多列子查询 5.在from子句中使用子查询6.合并查询7.表的内连和外连7.1内连接7.2外连接7.2.1左外连接7.2.2右外连接 点赞&#x1f44d;&#x1f44d;收藏&#x1f31f;&#x1f31f;关注&#x1f…...

创建模式、结构模式及行为模式

谁在什么地方提供什么功能&#xff1f; 要设计几个类?这些类各个是什么功能&#xff1f;相互间的关系是什么&#xff1f; 创建模式指的是对象那么多&#xff0c;怎么把它"生"出来&#xff1f;生几个&#xff1f;从这个角度上来说数组就是一种另类的创建模式。主要…...

警惕IDEA 2024版重大Bug问题:LomBok失效、Gradle冲突、Spring Boot启动错误

一直以来我认为工具类的软件是越新越好&#xff0c;因为工具代表着一定的先进性&#xff1b;但是IDEA 2024好好的给我上了一课&#xff0c;比如lombok 不起作用、比如Spring Boot 3.4.x 启动报错、再比如MyBatis log plus冲突、再比如Gradle插件冲突. 一、Lombok 失效问题 请不…...

C语言中char str和char str[]的区别

char* str和char* str[]的区别&#xff1a;C语言中char *str[] 和char *str有什么区别-CSDN博客 char str 和 char str[] 在 C 语言中也有不同的含义和用途&#xff0c;以下是它们的区别&#xff1a; 1. char str 类型&#xff1a;这是一个单一的字符变量。 用途&#xff1a…...

(学习总结20)C++11 可变参数模版、lambda表达式、包装器与部分新内容添加

C11 可变参数模版、lambda表达式、包装器与部分新内容添加 一、可变参数模版基本语法及原理包扩展emplace系列接口 二、lambda表达式lambda表达式语法捕捉列表lambda的原理lambda的应用 三、包装器bindfunction 四、部分新内容添加新的类功能1.默认的移动构造和移动赋值2.声明时…...

备份和容灾之区别(The Difference between Backup and Disaster Recovery)

备份和容灾之区别 备份和容灾都是数据安全常见的保障手段&#xff0c;但是一般在正常业务运行时是无需用到这两个技术手段的。只有在业务已经崩溃&#xff0c;需要进行业务恢复时&#xff0c;这两种技术的价值才能真正体现。所以&#xff0c;备份和容灾可以说是数据安全最后两…...