K8S MetalLB LoadBalancer

1. 简介

kubernetes集群没有L4负载均衡,对外暴漏服务时,只能使用nodePort的方式,比较麻烦,必须要记住不同的端口号。

LoadBalancer:使用云提供商的负载均衡器向外部暴露服务,外部负载均衡器可以将流量路由到自动创建的 NodePort 服务和 ClusterIP 服务上。

img

MetalLB 是裸机 Kubernetes 集群的负载均衡器实现,使用标准路由协议。

它提供了两个功能:

  • 地址分配(address allocation):当创建 LoadBalancer Service 时,MetalLB 会为其分配 IP 地址。这个 IP 地址是从预先配置的 IP 地址库获取的。同样,当 Service 删除后,已分配的 IP 地址会重新回到地址库。
  • 对外公告(external announcement):分配了 IP 地址之后,需要让集群外的网络知道这个地址的存在。使用了标准路由协议实现:
    • Layer2 模式:ARP(ipv4)、NDP(ipv6)
    • BGP 模式

不管是Layer2模式还是BGP模式,两者都不使用Linux的网络栈,即无法使用诸如ip命令准确的查看VIP所在的节点和相应的路由,相对应的是在每个节点上面都能看到一个kube-ipvs0网卡接口上面的IP。同时,两种模式都只是负责把VIP的请求引到对应的节点上面,之后的请求怎么到达pod,按什么规则轮询等都是由kube-proxy实现的。

对应的的两种工作负载:

  • ControllerDeployment,用于监听 Service 的变更,分配/回收 IP 地址。
  • SpeakerDaemonSet,对外广播 Service 的 IP 地址。把服务类型为LoadBalancer的服务的EXTERNAL-IP公布到网络中去,确保客户端能够正常访问到这个IP。

2. 部署

2.1 测试服务

apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-app
spec:replicas: 3selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:1.21.4ports:- name: httpcontainerPort: 80
---
apiVersion: v1
kind: Service
metadata:name: nginx-svc
spec:ports:- name: httpport: 8080protocol: TCPtargetPort: 80selector:app: nginxtype: LoadBalancer

2.2 MetalLB

# 1. ipvs 开启严格 arp模式
$ kubectl edit configmap -n kube-system kube-proxy
...
ipvs:strictARP: true# 2. 安装组件
$ mkdir -p $HOME/metallb && cd $_
$ wget https://raw.githubusercontent.com/metallb/metallb/v0.13.10/config/manifests/metallb-native.yaml$ kubectl apply -f metallb-native.yaml$ kubectl get pod -n metallb-system
NAME                          READY   STATUS    RESTARTS      AGE
controller-6f5c46d94b-b7psv   1/1     Running   1 (29s ago)   80s
speaker-6v8hn                 1/1     Running   0             80s
speaker-nzkb6                 1/1     Running   0             79s
speaker-wjqxx                 1/1     Running   0             79s

组件说明:

  • metallb-system/controller:负责IP地址的分配,以及service和endpoint的监听
  • metallb-system/speaker:负责保证service地址可达,在Layer 2模式下,speaker会负责ARP请求应答

3. Layer2 模式

  • 每个service会有集群中的一个node来负责。当服务客户端发起ARP解析的时候,对应的node会响应该ARP请求,之后,该service的流量都会指向该node(看上去该node上有多个地址)。

  • 并不是真正的负载均衡,因为流量都会先经过一个node后,再通过kube-proxy转给多个endpoints。如果该node故障,MetalLB会迁移 IP到另一个node,并重新发送ARP告知客户端迁移。

  • 更为通用,不需要用户有额外的设备;但由于Layer 2模式使用ARP/NDP,地址池分配需要跟客户端在同一子网,地址分配略为繁琐。

img

3.1 工作原理

  • Speaker 工作负载类型是 DeamonSet ,在每台节点上都调度一个 Pod。首先,几个 Pod 会先进行选举,选举出 LeaderLeader 获取所有 LoadBalancer 类型的 Service,将已分配的 IP 地址绑定到当前主机到网卡上。即所有 LoadBalancer 类型的 Service 的 IP 同一时间都是绑定在同一台节点的网卡上。

  • 当外部主机有请求要发往集群内的某个 Service,需要先确定目标主机网卡的 mac 地址。这是通过发送 ARP 请求,Leader 节点的会以其 mac 地址作为响应。外部主机会在本地 ARP 表中缓存下来,下次会直接从 ARP 表中获取。

  • 请求到达节点后,节点再通过 kube-proxy 将请求负载均衡目标 Pod。所以说,假如Service 是多 Pod 这里有可能会再跳去另一台主机。

img

3.2 试验

配置 layer2 IP池 (layer2.yaml):

apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:name: layer2-poolnamespace: metallb-system
spec:addresses:- 192.168.3.170-192.168.3.179
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:name: layer2-lbnamespace: metallb-system
spec:ipAddressPools:- layer2-pool

查看结果:

# 获取
$ kubectl get svc nginx-svc
NAME        TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)          AGE
nginx-svc   LoadBalancer   10.96.155.95   192.168.3.170   8080:31717/TCP   9m34s$ kubectl get ep nginx-svc
NAME        ENDPOINTS                                           AGE
nginx-svc   10.244.172.62:80,10.244.172.63:80,10.244.46.53:80   9m38s$ ipvsadm -Ln | grep 192.168.3.170 -A 3
TCP  192.168.3.170:8080 rr-> 10.244.46.53:80              Masq    1      0          0-> 10.244.172.62:80             Masq    1      0          0-> 10.244.172.63:80             Masq    1      0          0# 每个节点自动增加配置
$ ip addr show kube-ipvs0 | grep 192.168.3.170 -A 1inet 192.168.3.170/32 scope global kube-ipvs0valid_lft forever preferred_lft forever

查询实际的工作代理节点:

$ curl -I 192.168.3.170:8080
HTTP/1.1 200 OK
Server: nginx/1.21.4
Date: Thu, 10 Aug 2023 06:44:21 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Tue, 02 Nov 2021 14:49:22 GMT
Connection: keep-alive
ETag: "61814ff2-267"
Accept-Ranges: bytes$ arp 192.168.3.170
Address                  HWtype  HWaddress           Flags Mask            Iface
192.168.3.170            ether   52:54:00:63:8f:d3   C                     br0

根据mac地址,查询实际的节点:

$ ip addr | grep 52:54:00:63:8f:d3 -A 1 -B 1
2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000link/ether 52:54:00:63:8f:d3 brd ff:ff:ff:ff:ff:ffinet 192.168.3.105/24 brd 192.168.3.255 scope global ens3

3.3 清理

kubectl delete -f layer2.yamlkubectl get pod -n metallb-system | grep Running | awk '{print $1}' | xargs kubectl delete pod -n metallb-system

4. BGP 模式

  • 所有node都会跟上级路由器建立BGP连接,并会告知路由器应该如何转发service流量
  • 是真正的 Load Balancer

在这里插入图片描述

4.1 工作原理

BGP模式不限于一个二层网络里,各个节点都会与交换机建立BGP Peer,宣告Service External IP的下一跳为自身,这样通过ECMP实现了一层负载。客户端请求通过交换机负载到后端某个节点后,再由Kube-proxy进行转发

img

4.2 路由配置

通过 openwrt 旁路由实现 BGP。使用命令 vtysh 进行 AS 配置

  • 本地:AS 65000

  • 远端:AS 65001

$ vtysh
OpenWrt# conf t
OpenWrt(config)# router bgp 65000
OpenWrt(config-router)# neighbor 192.168.3.103 remote-as 65001
OpenWrt(config-router)# neighbor 192.168.3.103 description master-01
OpenWrt(config-router)# neighbor 192.168.3.104 remote-as 65001
OpenWrt(config-router)# neighbor 192.168.3.104 description worker-01
OpenWrt(config-router)# neighbor 192.168.3.105 remote-as 65001
OpenWrt(config-router)# neighbor 192.168.3.105 description worker-02
OpenWrt(config-router)# exit
OpenWrt(config)# exitOpenWrt# show ip bgp summary
BGP router identifier 192.168.3.180, local AS number 65000
RIB entries 0, using 0 bytes of memory
Peers 3, using 27 KiB of memoryNeighbor        V         AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down  State/PfxRcd
192.168.3.103   4 65001       0       6        0    0    0 never    Active
192.168.3.104   4 65001       0       4        0    0    0 never    Active
192.168.3.105   4 65001       0       3        0    0    0 never    ActiveTotal number of neighbors 3OpenWrt# exit

查看 bgpd 端口监听 179 是否已打开:

$  netstat -lantp | grep -E 'zebra|bgpd'
tcp        0      0 0.0.0.0:179             0.0.0.0:*               LISTEN      5355/bgpd
tcp        0      0 0.0.0.0:2601            0.0.0.0:*               LISTEN      5350/zebra
tcp        0      0 0.0.0.0:2605            0.0.0.0:*               LISTEN      5355/bgpd
tcp        0      0 :::179                  :::*                    LISTEN      5355/bgpd
tcp        0      0 :::2601                 :::*                    LISTEN      5350/zebra
tcp        0      0 :::2605                 :::*                    LISTEN      5355/bgpd

4.3 试验

配置BPG IP池 (bgp.yaml):

apiVersion: metallb.io/v1beta2
kind: BGPPeer
metadata:name: samplenamespace: metallb-system
spec:myASN: 65001peerASN: 65000peerAddress: 192.168.3.180
---
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:name: first-poolnamespace: metallb-system
spec:addresses:- 192.168.0.10-192.168.0.99
---
apiVersion: metallb.io/v1beta1
kind: BGPAdvertisement
metadata:name: examplenamespace: metallb-system
spec:ipAddressPools:- first-pool

查看结果:

$ kubectl get svc nginx-svc
NAME        TYPE           CLUSTER-IP      EXTERNAL-IP    PORT(S)          AGE
nginx-svc   LoadBalancer   10.96.167.171   192.168.0.10   8080:31323/TCP   25h$ kubectl get ep nginx-svc
NAME        ENDPOINTS                                           AGE
nginx-svc   10.244.172.59:80,10.244.172.60:80,10.244.46.52:80   25h# 每个节点均添加
$ ip addr show kube-ipvs0 | grep 192.168.0.10 -A 1inet 192.168.0.10/32 scope global kube-ipvs0valid_lft forever preferred_lft forever$ curl -I 192.168.0.10:8080
HTTP/1.1 200 OK
Server: nginx/1.21.4
Date: Thu, 10 Aug 2023 03:39:37 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Tue, 02 Nov 2021 14:49:22 GMT
Connection: keep-alive
ETag: "61814ff2-267"
Accept-Ranges: bytes$ ipvsadm -Ln | grep 192.168.0 -A 3
TCP  192.168.0.10:8080 rr-> 10.244.46.52:80              Masq    1      0          0-> 10.244.172.59:80             Masq    1      0          0-> 10.244.172.60:80             Masq    1      0          0

客户端(windows, 192.168.3.3)添加路由:

route add 192.168.0.0 MASK 255.255.0.0 192.168.3.180

访问:https://192.168.0.10:8080 ok

4.4 清理

kubectl delete -f bgp.yamlkubectl get pod -n metallb-system | grep Running | awk '{print $1}' | xargs kubectl delete pod -n metallb-system

5. IP地址共享

默认情况下,MetalLB只会将一个IP地址分配到一个LoadBalancer Service上,用户可以通过spec.loadBalancerIP来指定自己想用的IP,如果用户指定了已被分配了的IP会,则会报错。但MetalLB也提供了方式去支持多个Service共享相同的IP,主要为了解决:K8S不支持对LoadBalancer Service中的Port指定多协议;有限的IP地址资源。

具体的方式是:创建两个Service,并加上metallb.universe.tf/allow-shared-ip为Key的annotation,表明Service能容忍使用共享的LoadBalancerIP;然后通过spec.loadBalancerIP给两个Service指定共享的IP。

IP地址共享也有限制:

1)两个Service的metallb.universe.tf/allow-shared-ip值是一样的。

2)两个Service的“端口”(带协议)不同,比如tcp/53udp/53是属于不同的“端口”。

3)两个Service对应的后端Pod要一致,如果不一致,那么他们的externalTrafficPolicy需要都是Cluster,不然会无法进行正确的BGP。

6. 总结

6.1 nodeport

在创建LoadBalancer服务时,会默认创建一个nodeport服务,可通过配置allocateLoadBalancerNodePorts来关闭。

不同的loadbalancer实现原理不同,有的需要依赖nodeport来进行流量转发,有些则直接转发请求到pod中。

对于MetalLB而言,是通过kube-proxy将请求的流量直接转发到pod,因此可以关闭nodeport。

apiVersion: v1
kind: Service
metadata:name: nginx-svc
spec:allocateLoadBalancerNodePorts: falseexternalTrafficPolicy: ClusterinternalTrafficPolicy: Clusterports:- name: httpport: 8080protocol: TCPtargetPort: 80selector:app: nginxtype: LoadBalancerloadBalancerIP: 192.168.0.20  

验证:

$ kubectl delete svc nginx-svc
$ kubectl apply -f nginx-svc-disable-nodeport.yaml$ kubectl get svc nginx-svc
NAME        TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)    AGE
nginx-svc   LoadBalancer   10.96.54.226   192.168.0.20   8080/TCP   3s

6.2 Layer2

优点:

  • 通用性强,不需要BGP路由器支持,几乎可以适用于任何网络环境,云厂商例外

缺点:

  • 所有的流量都会在同一个节点上,该节点的容易成为流量的瓶颈;
  • 当VIP所在节点宕机之后,需要较长时间进行故障转移(一般在10s),主要是因为MetalLB使用了memberlist来进行选主,当VIP所在节点宕机之后重新选主的时间要比传统的keepalived使用的vrrp协议要更长;
  • 难以定位VIP所在节点,没有提供一个简单直观的方式查看到底哪一个节点是VIP所属节点,只能通过抓包或者查看pod日志来确定,当集群规模变大的时会非常麻烦

6.3 BGP

优点:

  • 无单点故障,在开启ECMP的前提下,k8s集群内所有的节点都有请求流量,都会参与负载均衡并转发请求

缺点:

  • 条件苛刻,需要有BGP路由器支持,配置起来也更复杂;
  • ECMP的故障转移(failover)并不是特别地优雅,这个问题的严重程度取决于使用的ECMP算法;当集群的节点出现变动导致BGP连接出现变动,所有的连接都会进行重新哈希(使用三元组或五元组哈希),这对一些服务来说可能会有影响;

7. 附录

7.1 BGP

BGP,Border Gateway Protocol,边界网关协议

BGP是互联网上一个核心的去中心化自治路由协议。它通过维护IP路由表或“前缀”表来实现自治系统(AS)之间的可达性,属于矢量路由协议。BGP不使用传统的内部网关协议(IGP)的指标,而使用基于路径、网络策略或规则集来决定路由。因此,它更适合被称为矢量性协议,而不是路由协议。

BGP的邻居关系(或称通信对端/对等实体,peer)是通过人工配置实现的,对等实体之间通过TCP端口179建立会话交换数据。BGP路由器会周期地发送19字节的保持存活(keep-alive)消息来维护连接(默认周期为60秒)。在各种路由协议中,只有BGP使用TCP作为传输层协议。

同一个AS自治系统中的两个或多个对等实体之间运行的BGP被称为iBGP(Internal/Interior BGP)。归属不同的AS的对等实体之间运行的BGP称为eBGP(External/Exterior BGP)。在AS边界上与其他AS交换信息的路由器被称作边界路由器(border/edge router),边界路由器之间互为eBGP对端。在Cisco IOS中,iBGP通告的路由距离为200,优先级比eBGP和任何内部网关协议(IGP)通告的路由都低。其他的路由器实现中,优先级顺序也是eBGP高于IGP,而IGP又高于iBGP。

iBGP和eBGP的区别主要在于转发路由信息的行为。例如,从eBGP peer获得的路由信息会分发给所有iBGP peer和eBGP peer,但从iBGP peer获得的路由信息仅会分发给所有eBGP peer。所有的iBGP peer之间需要全互联。

在这里插入图片描述

三个核心名词:

  • 自治系统(AS)
  • 内部网关协议(IGP)
  • 外部网关协议(EGP)

7.1.1 自治系统 AS

自制系统(Autonomous system,缩写 AS),是指在互联网中,一个或多个实体管辖下的所有IP 网络和路由器的组合,它们对互联网执行共同的路由策略。自治系统编号都是16位长的整数,这最多能被分配给65536个自治系统。自治系统编号被分成两个范围。第一个范围是公开的ASN,从1到64511,它们可在互联网上使用;第二个范围是被称为私有编号的从64512到65535的那些,它们仅能在一个组织自己的网络内使用。

简单理解,电信、移动、联通都有自己的 AS 编号,且不只一个。除了互联网公开的 ASN 以外,私有的编号可以在内部使用。比如我可以我的家庭网络中使用私有编号创建几个 AS。

7.1.2 内部路由协议 IGP

内部路由协议(Interior Gateway Protocol,IGP)是指在一个自治系统(AS)内部所使用的一种路由协议。

7.1.3 外部网关协议 EGP

外部网关协议(Exterior Gateway Protocol,EGP)是一个已经过时互联网路由协议。已由 BPG 取代。

7.1.4 BGP

BPG 是为了替换 EGP 而创建的,而除了应用于 AS 外部,也可以应用在 AS 内部。因此又分为 EBGP 和 IBGP。

7.2 OpenWrt

7.2.1 安装

wget https://mirrors.aliyun.com/openwrt/releases/19.07.4/targets/x86/64/openwrt-19.07.4-x86-64-combined-ext4.img.gzgunzip openwrt-19.07.4-x86-64-combined-ext4.img.gz
cp openwrt-19.07.4-x86-64-combined-ext4.img  openwrt.img# 双网口(wan+lan)
virt-install --name=openwrt --vcpus=1 --ram=512 --os-type=generic --disk path=/root/eli/openwrt.img,bus=ide --autostart --network bridge=br0,model=e1000 --network bridge=br0,model=e1000 --import --noautoconsole --graphics vnc,listen=0.0.0.0,password=123456# 单网口(lan)
virt-install --name=openwrt --vcpus=1 --ram=512 --os-type=generic --disk path=/root/eli/openwrt.img,bus=ide --autostart --network bridge=br0,model=e1000 --import --noautoconsole --graphics vnc

修改网络配置:

# 改成与宿主机在同一网络下
$ vi /etc/config/network
...
config interface 'lan'option type 'bridge'option ifname 'eth0'option proto 'static'option ipaddr '192.168.3.180'option netmask '255.255.255.0'option ip6assign '60'option gateway '192.168.3.1'option dns '114.114.114.114'$ service network restart

登录配置页面:http://192.168.3.180

7.2.2 Quagga

为了让 OpenWrt 支持 BGP,需要安装路由软件套件 Quagga。它提供了 OSPFv2、OSPFv3、RIP v1 v2、RIPng 和 BGP-4 的实现。

Quagga 架构由核心守护进程和 zebra 组成,后者作为底层 Unix 内核的抽象层,并通过 Unix 或者 TCP 向 Quagga 客户端提供 Zserv API。正是这些 Zserv 客户端实现了路由协议,并将路由的更新发送给 zebra 守护进程。当前 Zserv 的实现:

img

Quagga 的守护进程可以通过网络可访问的 CLI(简称 vty)进行配置。 CLI 遵循与其他路由软件类似的风格。还额外提供了一个工具 vtysh,充当了所有守护进程的聚合前端,允许在一个地方管理所有 Quagga 守护进程的所有功能。

$ opkg update && opkg install quagga quagga-zebra quagga-bgpd quagga-vtysh$ netstat -lantp | grep -E 'zebra|bgpd'
tcp        0      0 0.0.0.0:2601            0.0.0.0:*               LISTEN      5350/zebra
tcp        0      0 0.0.0.0:2605            0.0.0.0:*               LISTEN      5355/bgpd
tcp        0      0 :::2601                 :::*                    LISTEN      5350/zebra
tcp        0      0 :::2605                 :::*                    LISTEN      5355/bgpd

参考资料:

https://metallb.universe.tf/configuration/

https://tinychen.com/20220519-k8s-06-loadbalancer-metallb/

https://atbug.com/load-balancer-service-with-metallb-bgp-mode/

https://ieevee.com/tech/2019/06/30/metallb.html

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

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

相关文章

Leaflet入门,Leaflet如何自定义版权信息,以vue2-leaflet修改自定义版权为例

前言 本章讲解使用Leaflet的vue2-leaflet或者vue-leaflet插件来实现自定义版权信息的功能。 # 实现效果演示 见图片右下角版权信息 vue如何使用Leaflet vue2如何使用:《Leaflet入门,如何使用vue2-leaflet实现vue2双向绑定式的使用Leaflet地图,以及初始化后拿到leaflet对象…

Java获取指定文件夹下目录下所有视频并复制到另一个地方

import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.StandardCopyOption;public class VideoCopier {public static void main(String[] args) {// 指定源文件夹路径和目标文件夹路径String sourceFolderPath "path/to…

OSI参考模型及TCP/IP协议栈

一、网络概述 1.1、什么是网络&#xff1f; 1、网络的本质就是实现资源共享 2、将各个系统联系到一起&#xff0c;形成信息传递、接收、共享的信息交互平台 1.2、典型的园区网拓扑 1.3、网络历史发展&#xff0c;ARPA和ARPANET 1、1969年&#xff0c;美国国防部高级研究计…

8.10论文阅读

文章目录 The multimodal MRI brain tumor segmentation based on AD-Net摘要本文方法损失函数 实验结果 max-vit - unet:多轴注意力医学图像分割摘要本文方法实验结果 The multimodal MRI brain tumor segmentation based on AD-Net 摘要 基于磁共振成像(MRI)的多模态胶质瘤…

JavaEE——网络编程(UDP套接字编程)

文章目录 一、简单理解Socket 套接字二、UDP 数据报套接字编程三、编写简单的 UDP 版本服务器客户端1. 编写 UDP 版本的回显服务器回显服务器整体代码罗列 2. 编写 UDP 版本的回显客户端回显客户端整体代码罗列 四、总结与代码运行结果解释 一、简单理解Socket 套接字 概念&am…

100天精通Golang(基础入门篇)——第18天:深入解析Go语言中的结构体

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to Golang Language.✨✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1…

半导体芯片介质膜层膜层膜厚测量仪

镀膜是半导体芯片制备过程中的重要步骤。在一个完整的CMOS工艺流程中&#xff0c;介质膜层(保护层、外延层、光刻胶和栅极氧化物等)与金属沉积层交替出现。随着芯片工艺节点不断进步&#xff0c;介质膜层也变得越来越复杂&#xff0c;在7nm工艺中&#xff0c;所需测量的介质膜堆…

AppStream下载元数据失败

错误&#xff1a;为仓库 AppStream 下载元数据失败 : Cannot prepare internal mirrorlist: No URLs in mirrorlist 目录 一、域名解析 二、CentOS-AppStream.repo 三、CentOS-Base.repo 四、CentOS-Extras.repo 五、rpm更新 一、域名解析 先验证 ping www.baidu.com 不…

STM32基于CubeIDE和HAL库 基础入门学习笔记:物联网项目开发流程和思路

文章目录&#xff1a; 第一部分&#xff1a;项目开始前的计划与准备 1.项目策划和开发规范 1.1 项目要求文档 1.2 技术实现文档 1.3 开发规范 2.创建项目工程与日志 第二部分&#xff1a;调通硬件电路与驱动程序 第三部分&#xff1a;编写最基础的应用程序 第四部分&…

基于dbn+svr的交通流量预测,dbn详细原理

目录 背影 DBN神经网络的原理 DBN神经网络的定义 受限玻尔兹曼机(RBM) DBN+SVR的交通流量预测 基本结构 主要参数 数据 MATALB代码 结果图 展望 背影 DBN是一种深度学习神经网络,拥有提取特征,非监督学习的能力,是一种非常好的分类算法,本文将DBN+SVR用于交通流量预测…

怎样才能免费使用Qt开发闭源商业软件?

Qt 是一个跨平台的应用程序开发框架&#xff0c;其使用遵循 GNU Lesser General Public License&#xff08;LGPL&#xff09;开源许可协议。根据 LGPL 许可协议&#xff0c;您可以将 Qt 用于闭源商业软件&#xff0c;但是您需要满足以下条件&#xff1a; 1. 在您的软件中使用…

③ vue组件

vue组件创建 在App.vue中添加。 技巧&#xff1a;先import&#xff0c;把vue组件地址写出来。然后在template中写名字。剩下的就自动生成。要看下import有没有多生成什么。 注意1&#xff1a; 注意2&#xff1a; 不只是能在App.vue中引入组件。任意组件中都可以引用其他组件…

SRE之前端服务器的负载均衡

写在前面 今天和小伙伴们分享一些前端服务器的负载均衡技术内容为结合《 SRE Google运维解密》 整理&#xff1a; 涉及DNS 负载均衡VIP 负载均衡反向代理负载均衡 理解不足小伙伴帮忙指正 傍晚时分&#xff0c;你坐在屋檐下&#xff0c;看着天慢慢地黑下去&#xff0c;心里寂寞…

Zabbix监控系统详解及配置

前言 作为一个运维&#xff0c;需要会使用监控系统查看服务器状态以及网站流量指标&#xff0c;利用监控系统的数据去了解上线发布的结果&#xff0c;和网站的健康状态。利用一个优秀的监控软件&#xff0c;我们可以&#xff1a; 通过一个友好的界面进行浏览整个网站所有的服务…

把大模型装进手机,分几步?

点击关注 文 | 姚 悦 编 | 王一粟 大模型“跑”进手机&#xff0c;AI的战火已经从“云端”烧至“移动终端”。 “进入AI时代&#xff0c;华为盘古大模型将会来助力鸿蒙生态。”8月4日&#xff0c;华为常务董事、终端BG CEO、智能汽车解决方案BU CEO 余承东介绍&#xff0c…

由于目标计算机积极拒绝,无法连接。 Could not connect to Redis at 127.0.0.1:6379

项目在启动时候报出redis连接异常 然后查看是redis 连接被计算机拒绝 解决方法 打开redis安装文件夹 先打开redis-servce.exe挂着&#xff0c;再打开redis-cli.exe 也不会弹出被拒接的问题了。而且此方法不用每次都去cmd里输入命令。

【黑马头条之app端文章搜索ES-MongoDB】

本笔记内容为黑马头条项目的app端文章搜索部分 目录 一、今日内容介绍 1、App端搜索-效果图 2、今日内容 二、搭建ElasticSearch环境 1、拉取镜像 2、创建容器 3、配置中文分词器 ik 4、使用postman测试 三、app端文章搜索 1、需求分析 2、思路分析 3、创建索引和…

C++多线程场景中的变量提前释放导致栈内存异常

多线程场景中的栈内存异常 在子线程中尝试使用当前函数的资源&#xff0c;是非常危险的&#xff0c;但是C支持这么做。因此C这么做可能会造成栈内存异常。 正常代码 #include <iostream> #include <thread> #include <windows.h>// 线程函数&#xff0c;用…

每日一题——对称的二叉树

题目 给定一棵二叉树&#xff0c;判断其是否是自身的镜像&#xff08;即&#xff1a;是否对称&#xff09; 例如&#xff1a; 下面这棵二叉树是对称的 下面这棵二叉树不对称。 数据范围&#xff1a;节点数满足 0≤n≤1000&#xff0c;节点上的值满足 ∣val∣≤1000 要求&…

Java课题笔记~ SpringMVC概述

1.1 SpringMVC简介 SpringMVC 也叫Spring web mvc。是Spring 框架的一部分&#xff0c;在Spring3.0 后发布的。 1.2 SpringMVC的优点 基于MVC 架构 基于 MVC 架构&#xff0c;功能分工明确。解耦合。 容易理解&#xff0c;上手快&#xff0c;使用简单 就可以开发一个注解…