【云原生 | Kubernetes 实战】12、K8s 四层代理 Service 入门到企业实战应用(上)

news2024/11/16 7:33:06

目录

一、Service 四层代理基本介绍

1.1 四层负载均衡 Service:概念、原理解读

1 为什么要有Service?

2 Service 概述

3 Service 工作原理

4 kubernetes 集群中有三类 IP 地址

二、创建 Service 资源

2.1 Service 的四种类型

2.2 Service 的端口

三、 创建 Service:type 类型是 ClusterIP

3.1 创建 Pod

3.2  创建 Service

3.3 service 名称解析 


一、Service 四层代理基本介绍

1.1 四层负载均衡 Service:概念、原理解读

1 为什么要有Service?

        在 kubernetes 中,Pod 是有生命周期的,如果 Pod 重启它的 IP 很有可能会发生变化。如果我们的服务都是将 Pod 的 IP 地址写死,Pod 挂掉或者重启,和刚才重启的pod相关联的其他服务将会找不到它所关联的 Pod,为了解决这个问题,在 kubernetes 中定义了 service 资源对象,Service 定义了一个服务访问的入口,客户端通过这个入口即可访问服务背后的应用集群实例,service 是一组 Pod 的逻辑集合,这一组 Pod 能够被 Service 访问到,通常是通过 Label Selector实现的。

  1. pod ip 经常变化,service 是 pod 的代理,我们客户端访问,只需要访问 service,就会把请求代理到 Pod。
  2. pod ip 在 k8s 集群之外无法访问,所以需要创建 service,这个 service 可以在 k8s 集群外访问到。 

2 Service 概述

        service 是一个固定接入层,客户端可以通过访问 service 的 ip 和端口访问到 service 关联的后端 pod,这个 service 工作依赖于在 kubernetes 集群之上部署的一个附件,就是 kubernetes 的dns 服务(不同 kubernetes 版本的 dns 默认使用的也是不一样的,1.11 之前的版本使用的是kubeDNs,较新的版本使用的是 coredns),service 的名称解析是依赖于 dns 附件的,因此在部署完 k8s 之后需要再部署 dns 附件,kubernetes 要想给客户端提供网络功能,需要依赖第三方的网络插件(flannel,calico等)。

        每个 K8s 节点上都有一个组件叫做 kube-proxy,kube-proxy 这个组件将始终监视着 apiserver 中有关 service 资源的变动信息,需要跟 master 之上的 apiserver 交互,随时连接到apiserver 上获取任何一个与 service 资源相关的资源变动状态,这种是通过 kubernetes 中固有的一种请求方法 watch(监视)来实现的,一旦有 service 资源的内容发生变动(如创建,删除),kube-proxy 都会将它转化成当前节点之上的能够实现 service 的资源调度,把我们请求调度到后端特定的 pod 资源之上的规则,这个规则可能是 iptables,也可能是 ipvs,取决于 service 的实现方式。 

3 Service 工作原理

        k8s 在创建 Service 时,会根据标签选择器 selector(lable selector) 来查找 Pod,据此创建与Service 同名的 endpoint 对象,当 Pod 地址发生变化时,endpoint 也会随之发生变化,service 接收前端 client 请求的时候,就会通过 endpoint,找到并转发到对应 Pod 进行访问的地址。(至于转发到哪个节点的 Pod,由负载均衡 kube-proxy 决定)。

4 kubernetes 集群中有三类 IP 地址

1、Node Network(节点网络):物理节点或者虚拟节点的网络。如 ens32 接口上的网路地址:

[root@k8s-master01 ~]# ip addr
 ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:b3:2c:79 brd ff:ff:ff:ff:ff:ff
    inet 192.168.78.133/24 brd 192.168.78.255 scope global noprefixroute ens32
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:feb3:2c79/64 scope link 
       valid_lft forever preferred_lft forever

2、Pod network(pod 网络),创建的 Pod 具有的 IP 地址:

[root@k8s-master01 ~]# kubectl get pods -n blue-green -o wide 
NAME                        READY   STATUS    RESTARTS   AGE   IP               NODE        NOMINATED NODE   READINESS GATES
myapp-v1-7bb47f975c-4bsst   1/1     Running   0          59m   10.244.36.117    k8s-node1   <none>           <none>
myapp-v1-7bb47f975c-767m7   1/1     Running   0          42m   10.244.169.139   k8s-node2   <none>           <none>
myapp-v1-7bb47f975c-xz9d5   1/1     Running   0          42m   10.244.169.140   k8s-node2   <none>           <none>

        Node Network 和 Pod network 这两种网络地址是我们实实在在配置的,其中节点网络地址是配置在节点接口之上,而 pod 网络地址是配置在 pod 资源之上的,因此这些地址都是配置在某些设备之上的,这些设备可能是硬件,也可能是软件模拟的。 

3、Cluster Network(集群地址,也称为service network),这个地址是虚拟的地址(virtual ip),没有配置在某个接口上,只是出现在 service 的规则当中:

[root@k8s-master01 ~]# kubectl get service
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   50d

二、创建 Service 资源

查看定义 Service 资源需要的字段有哪些?

[root@k8s-master01 ~]# kubectl explain service
KIND:     Service
VERSION:  v1

DESCRIPTION:
     Service is a named abstraction of software service (for example, mysql)
     consisting of local port (for example 3306) that the proxy listens on, and
     the selector that determines which pods will answer requests sent through
     the proxy.

FIELDS:
   apiVersion	<string>            # service 资源使用的 api 组


   kind	<string>                    # 创建的资源类型


   metadata	<Object>                # 定义元数据


   spec	<Object>


   status	<Object>


# 查看 service 的 spec 字段如何定义?
[root@k8s-master01 ~]# kubectl explain service.spec
KIND:     Service
VERSION:  v1

RESOURCE: spec <Object>

DESCRIPTION:
     Spec defines the behavior of a service.
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

     ServiceSpec describes the attributes that a user creates on a service.

FIELDS:
   allocateLoadBalancerNodePorts	<boolean>
    

   clusterIP	<string>            # 动态分配的地址,也可以自己在创建的时候指定,创建之后就改不了了
    
······
   ports	<[]Object>              # 定义 service 端口,用来和后端 pod 建立联系


   publishNotReadyAddresses	<boolean>


   selector	<map[string]string>    # 通过标签选择器选择关联的 pod 有哪些
    

   sessionAffinity	<string>       # 会话联系,默认是 none,随机调度的(基于 iptables 规则调度的);如果我们定义 sessionAffinity 的 client ip,那就表示把来自同一客户端的 IP 请求调度到同一个 pod 上 

     Possible enum values:
     - `"ClientIP"` is the Client IP based.
     - `"None"` - no session affinity.

   sessionAffinityConfig	<Object>
     sessionAffinityConfig contains the configurations of session affinity.

   type	<string>                   # 定义 service 的类型

     Possible enum values:
     - `"ClusterIP"` means a service will only be accessible inside the cluster,
     via the cluster IP.
     - `"ExternalName"` means a service consists of only a reference to an
     external name that kubedns or equivalent will return as a CNAME record,
     with no exposing or proxying of any pods involved.
     - `"LoadBalancer"` means a service will be exposed via an external load
     balancer (if the cloud provider supports it), in addition to 'NodePort'
     type.
     - `"NodePort"` means a service will be exposed on one port of every node,
     in addition to 'ClusterIP' type.

2.1 Service 的四种类型

查看定义 Service.spec.type 需要的字段有哪些?

[root@k8s-master01 ~]# kubectl explain service.spec.type
KIND:     Service
VERSION:  v1

FIELD:    type <string>

     Possible enum values:
     - `"ClusterIP"` means a service will only be accessible inside the cluster,
     via the cluster IP.
     - `"ExternalName"` means a service consists of only a reference to an
     external name that kubedns or equivalent will return as a CNAME record,
     with no exposing or proxying of any pods involved.
     - `"LoadBalancer"` means a service will be exposed via an external load
     balancer (if the cloud provider supports it), in addition to 'NodePort'
     type.
     - `"NodePort"` means a service will be exposed on one port of every node,
     in addition to 'ClusterIP' type.

参考官方文档:服务(Service) | Kubernetes 

2.2 Service 的端口

查看 service 的 spec.ports 字段如何定义? 

[root@k8s-master01 ~]# kubectl explain service.spec.ports
KIND:     Service
VERSION:  v1

RESOURCE: ports <[]Object>

DESCRIPTION:
     The list of ports that are exposed by this service. More info:
     https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies

     ServicePort contains information on service's port.

FIELDS:
   appProtocol	<string>


   name	<string>                    # 定义端口的名字


   nodePort	<integer>               # service 在物理机映射的端口,默认在 30000-32767 之间


   port	<integer> -required-        # service的端口,这个是 k8s 集群内部服务可访问的端口
     The port that will be exposed by this service.

   protocol	<string>


   targetPort	<string>            # targetPort 是 pod 上的端口,从 port 和 nodePort 上来的流量,经过 kube-proxy 流入到后端 pod 的 targetPort 上,最后进入容器。

三、 创建 Service:type 类型是 ClusterIP

3.1 创建 Pod

[root@k8s-master01 ~]# vim pod_test.yaml
spec:
  selector:
    matchLabels:
      run: my-nginx
  replicas: 2
  template:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-nginx
spec:
  selector:
    matchLabels:
      run: my-nginx
  replicas: 2
  template:
    metadata:
      labels:
        run: my-nginx
    spec:
      containers:
      - name: my-nginx
        image: nginx:latest
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80          # pod 中的容器需要暴露的端口
        startupProbe:
           periodSeconds: 5
           initialDelaySeconds: 60
           timeoutSeconds: 10
           httpGet:
             scheme: HTTP
             port: 80
             path: /
        livenessProbe:
           periodSeconds: 5
           initialDelaySeconds: 60
           timeoutSeconds: 10
           httpGet:
             scheme: HTTP
             port: 80
             path: /
        readinessProbe:
           periodSeconds: 5
           initialDelaySeconds: 60
           timeoutSeconds: 10
           httpGet:
             scheme: HTTP
             port: 80
             path: /

[root@k8s-master01 ~]# kubectl apply -f pod_test.yaml 
deployment.apps/my-nginx created

# 查看刚才创建的 Pod ip 地址
[root@k8s-master01 ~]# kubectl get pods -o wide 
NAME                        READY   STATUS    RESTARTS   AGE   IP               NODE        NOMINATED NODE   READINESS GATES
my-nginx-584946c8df-hwgnd   1/1     Running   0          99s   10.244.169.144   k8s-node2   <none>           <none>
my-nginx-584946c8df-w5cnh   1/1     Running   0          99s   10.244.36.122    k8s-node1   <none>           <none>

# 请求 pod ip 地址,查看结果:
[root@k8s-master01 ~]# curl 10.244.169.144
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>

[root@k8s-master01 ~]# curl 10.244.36.122
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>

# 进入容器内部请求另一个 pod
[root@k8s-master01 ~]# kubectl exec -it my-nginx-584946c8df-hwgnd -- bash
root@my-nginx-584946c8df-hwgnd:/# curl 10.244.36.122
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>

        需要注意的是,pod 虽然定义了容器端口,但是不会使用调度到该节点上的 80 端口,也不会使用任何特定的 NAT 规则去路由流量到 Pod 上。 这意味着可以在同一个节点上运行多个 Pod,使用相同的容器端口,并且可以从集群中任何其他的 Pod 或节点上使用 IP 的方式访问到它们。

# 误删除其中一个 Pod
[root@k8s-master01 ~]# kubectl delete pods my-nginx-584946c8df-hwgnd 
pod "my-nginx-584946c8df-hwgnd" deleted

[root@k8s-master01 ~]# kubectl get pods -o wide 
NAME                        READY   STATUS    RESTARTS   AGE     IP               NODE        NOMINATED NODE   READINESS GATES
my-nginx-584946c8df-982ff   1/1     Running   0          73s     10.244.169.147   k8s-node2   <none>           <none>
my-nginx-584946c8df-w5cnh   1/1     Running   0          8m25s   10.244.36.122    k8s-node1   <none>           <none>

        通过上面可以看到重新生成了一个 pod :my-nginx-5b56ccd65f-7xzr4,ip 是10.244.187.102,在 k8s 中创建 pod,如果 pod 被删除了,重新生成的 pod ip 地址会发生变化,所以需要在 pod 前端加一个固定接入层。接下来创建 service。

3.2  创建 Service

# 查看 pod 标签:
[root@k8s-master01 ~]# kubectl get pods --show-labels
NAME                        READY   STATUS    RESTARTS   AGE     LABELS
my-nginx-584946c8df-982ff   1/1     Running   0          2m8s    pod-template-hash=584946c8df,run=my-nginx
my-nginx-584946c8df-w5cnh   1/1     Running   0          9m20s   pod-template-hash=584946c8df,run=my-nginx

# 创建 service
[root@k8s-master01 ~]# vim service_test.yaml
apiVersion: v1
kind: Service
metadata:
  name: my-nginx
  labels:
    run: my-nginx
spec:
  type: ClusterIP
  ports:
  - port: 80           # service 的端口,暴露给 k8s 集群内部服务访问
    protocol: TCP
    targetPort: 80     # pod 容器中定义的端口
  selector:
    run: my-nginx      # 关联拥有 run=my-nginx 标签的 pod

[root@k8s-master01 ~]# kubectl apply -f service_test.yaml 
service/my-nginx created

[root@k8s-master01 ~]# kubectl get svc
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP   51d
my-nginx     ClusterIP   10.110.2.134   <none>        80/TCP    10s

        上述 yaml 文件将创建一个 Service,具有标签 run=my-nginx 的 Pod,目标 TCP 端口 80,并且在一个抽象的 Service 端口(targetPort:容器接收流量的端口;port:抽象的 Service 端口,可以使任何其它 Pod 访问该 Service 的端口)上暴露。

# 在 k8s 控制节点访问 service 的 ip:端口 就可以把请求代理到后端 pod
[root@k8s-master01 ~]# curl 10.110.2.134:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>

        通过上面可以看到请求 service IP:port 跟直接访问 pod ip:port 看到的结果一样,这就说明service 可以把请求代理到它所关联的后端 pod。

        注意:上面的 10.110.2.134:80 地址只能是在 k8s 集群内部可以访问,在外部无法访问,比方说我们想要通过浏览器访问,那么是访问不通的,如果想要在 k8s 集群之外访问,是需要把service type 类型改成 nodePort。

# 查看 service 详细信息
[root@k8s-master01 ~]# kubectl describe svc my-nginx
Name:              my-nginx
Namespace:         default
Labels:            run=my-nginx
Annotations:       <none>
Selector:          run=my-nginx
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.110.2.134
IPs:               10.110.2.134
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.169.147:80,10.244.36.122:80
Session Affinity:  None
Events:            <none>

[root@k8s-master01 ~]# kubectl get ep my-nginx
NAME       ENDPOINTS                            AGE
my-nginx   10.244.169.147:80,10.244.36.122:80   6m39s

        service 可以对外提供统一固定的 ip 地址,并将请求重定向至集群中的 pod。其中“将请求重定向至集群中的 pod ”就是通过 endpoint 与 selector 协同工作实现。selector 是用于选择 pod,由selector 选择出来的 pod 的 ip 地址和端口号,将会被记录在 endpoint 中。endpoint 便记录了所有关联的 pod 的 ip 地址和端口号。当一个请求访问到 service 的 ip 地址时,就会从 endpoint 中选择出一个ip 地址和端口号,然后将请求重定向至 pod 中。具体把请求代理到哪个 pod,需要的就是 kube-proxy 的轮询实现的。service 不会直接到 pod,service 是直接到 endpoint 资源,就是地址加端口,再由 endpoint 再关联到 pod。

3.3 service 名称解析 

        service 只要创建完成,我们就可以直接解析它的服务名,每一个服务创建完成后都会在集群dns 中动态添加一个资源记录,添加完成后我们就可以解析了,资源记录格式是:

  • SVC_NAME.NS_NAME.DOMAIN.LTD.
  • 服务名.命名空间.域名后缀
  • 集群默认的域名后缀是:svc.cluster.local.

就像我们上面创建的 my-nginx 这个服务,它的完整名称解析就是:my-nginx.default.svc.cluster.local

# 只能进入 pod 内部解析域名,集群外部不行
[root@k8s-master01 ~]# kubectl exec -it my-nginx-584946c8df-w5cnh -- bash
root@my-nginx-584946c8df-w5cnh:/# curl my-nginx.default.svc.cluster.local
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>

上一篇文章:【云原生 | Kubernetes 实战】11、K8s 控制器 Deployment 入门到企业实战应用(下)_Stars.Sky的博客-CSDN博客

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

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

相关文章

k8s编程operator实战之云编码平台——①架构设计

文章目录1、想法来源2、初步设想2.1 通过反向代理的方式访问后端Pod3、架构设计3.1 技术栈3.2 架构设计k8s编程operator系列&#xff1a;k8s编程operator——(1) client-go基础部分k8s编程operator——(2) client-go中的informerk8s编程operator——(3) 自定义资源CRDk8s编程op…

SpringSecurity管理接口权限

使用SpringSecurity管理具体接口访问权限。 需要先有授权服务器和资源服务器 Springboot利用Security做OAuth2授权验证_LO嘉嘉VE的博客-CSDN博客 Springboot利用Security做OAuth2资源服务器_LO嘉嘉VE的博客-CSDN博客 配置接口具体访问权限再有以上两个的基础上就比较简单了…

antd-vue 累加表单编辑和删除(完善版)

一、业务场景&#xff1a; 最近在使用Antd-Vue组件库的时候&#xff0c;发现在累加表单 时没有直接可以用的&#xff0c;必须自己在官网上手动合并几个才能实现&#xff0c;为了大家后面遇到和我一样的问题&#xff0c;给大家分享一下 二、具体实现步骤&#xff1a; <temp…

新一代最强开源UI自动化测试神器Playwright(Java版)环境搭建

Playwright 是专门为满足端到端测试的需要而创建的。Playwright 支持所有现代渲染引擎&#xff0c;包括 Chromium、WebKit 和 Firefox。在 Windows、Linux 和 macOS 上进行本地测试或在 CI 上进行测试&#xff0c;无外设或带本机移动仿真。 一.安装 在JAVA中&#xff0c;使用…

嵌入式技术之IAP,自从有了它老板再也不担心我的代码了!(上)

1.惨痛的教训 那是一个严寒的冬日&#xff0c;客户在现场使用我们公司新研发的设备&#xff0c;设备最初设计可以允许最多连接20个温湿度传感器&#xff0c;但是由于现场空间非常大&#xff0c;客户要求连接30个温湿度传感器。这个需求修改非常简单&#xff0c;只用修改程序中…

帮公司面试了个要25K的测试,我问了他这些问题...

深耕IT行业多年&#xff0c;我们发现&#xff0c;对于一个程序员而言&#xff0c;能去到一线互联网公司&#xff0c;会给我们以后的发展带来多大的影响。 很多人想说&#xff0c;这个我也知道&#xff0c;但是进大厂实在是太难了&#xff0c;简历投出去基本石沉大海&#xff0…

spring security安全认证登录全流程分析

文章目录前言一、登录时序图二、配置与代码1.引入库2.代码文件参考文档前言 本文章主要从spring security安全认证登录内部调用流程来流程分析登录过程。 一、登录时序图 时序原图 二、配置与代码 1.引入库 pom.xml&#xff1a; <!-- Spring框架基本的核心工具 -->&…

截至到2022年12月12日,知网最新改进 YOLO 核心论文合集 | 22篇创新点速览

截至到2022年12月12日&#xff0c;知网最新改进YOLO核心论文合集 本篇博文仅供学习交流&#xff0c;不对文章质量进行评价&#xff0c;请尊重每一位同学的科研成果&#x1f91d;。 文章目录截至到2022年12月12日&#xff0c;知网最新改进YOLO核心论文合集引言&#x1f4a1;0. 什…

Vue.use()的用法详解

目录 &#x1f53d; 前言 &#x1f53d; 官方解释 &#x1f53d; Demo演示 &#x1f388; Object对象 &#x1f449; 创建项目 &#x1f449; 创建组件 &#x1f449; 使用组件 &#x1f388; function函数 &#x1f449; 创建函数 &#x1f449; 引入 &#x1f449…

机器人与视觉,基于坐标系的运动偏移

基于可移动坐标系的机器人坐标偏移 在生产过程中&#xff0c;当需要建造多个坐标系的时候&#xff0c;我们可以采用基于坐标系偏移&#xff0c;可以实现使用机器人坐标系直接完成多个坐标系的联动。 由于实现多个坐标系的联动情况&#xff0c;那么通常都会伴随着坐标系的移动和…

力扣1781. 子字符串的美丽值之和(cpp实现+解析)

文章目录1781.子字符串的美丽值之和完整代码1781.子字符串的美丽值之和 力扣传送门&#xff1a; https://leetcode.cn/problems/sum-of-beauty-of-all-substrings/description/ 题目描述&#xff1a; 一个字符串的 美丽值 定义为&#xff1a;出现频率最高字符与出现频率最低字…

CMake中add_compile_options/target_compile_options的使用

CMake中的add_compile_options命令用于向源文件的编译添加选项&#xff0c;其格式如下&#xff1a; add_compile_options(<option> ...) 将选项添加到COMPILE_OPTIONS目录属性。从当前目录及以下目录编译target时&#xff0c;将使用这些选项。 add_compile_option…

48-90-Scala-函数式编程基础特性等

48-Scala-函数式编程&#xff1a; 函数式编程 1、完全面向对象编程 2、函数式编程&#xff0c;万物皆函数&#xff0c;程序语句的集合&#xff0c;称为函数。类中的函数称之方法。函数无重载重写概念&#xff0c;方法可以。函数可以嵌套 3、函数的定义def test3(s:String):…

电子书资源:分享10个非常好用的免费书籍资源网站

❤️作者主页&#xff1a;IT技术分享社区 ❤️作者简介&#xff1a;大家好,我是IT技术分享社区的博主&#xff0c;从事C#、Java开发九年&#xff0c;对数据库、C#、Java、前端、运维、电脑技巧等经验丰富。 ❤️个人荣誉&#xff1a; 数据库领域优质创作者&#x1f3c6;&#x…

Qt扫盲-QCheckBox 理论总结

QCheckBox 理论总结1. 简述2. 分组3. 状态&信号4. 外观&快捷键1. 简述 QCheckBox是一个选项按钮&#xff0c;可以 选中 或 未选中。复选框通常用于表示应用程序中可以启用或禁用的功能&#xff0c;而不会影响其他功能。可以实现不同类型的行为。一般是很多个联用的。 …

Cookie、Session、Token比较

1 Cookie cookie 指的就是浏览器里面能永久存储的一种数据&#xff0c;仅仅是浏览器实现的一种数据存储功能。 cookie由服务器生成&#xff0c;发送给浏览器&#xff0c;浏览器把cookie以 key-value 形式保存到某个目录下的文本文件内&#xff0c;下一次请求同一网站时会把该…

基于适应度-距离平衡的人工生态系统优化算法解决瞬态稳定性约束最优潮流问题(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

Awaitility同步异步工具介绍与RocketMQ中实战

在编写测试用例的时候遇到有异步或者队列处理的时候经常会用到 Thread.sleep() 等待来进行测试。例如&#xff1a;DLedger 测试选举的过程。当DLedger Leader下线。此时DLedger会重新发起选举&#xff0c;这个选举的过程是需要一定时间。很多时候在测试代码中就会使用 Thread.s…

b站黑马的Vue4小时快速入门案例代码——计数器

目录 目标效果&#xff1a; 重点原理&#xff1a; 1.创建Vue实例的时候&#xff1a; 2.v-on——为元素绑定事件 3.v-text——【解析文本用】设置标签的文本值 v-text【简写】为{{}} 实现步骤&#xff1a; 代码部分&#xff1a; 1.计数器模板.html(全是重点&#xf…

m基于粒子群算法的分布式电源DG的优化配置

目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 随着科技的发展&#xff0c;人民生活水平的不断提高&#xff0c;使得当今社会的发展对能源环保性和供电的可靠性的要求也不断提高。集中式供电系统由于污染大、可靠性差及操作难度大等缺陷越来越…