docker 网络(单机环境)

news2024/11/26 8:32:49

文章目录

    • 深入理解 Namespace
      • 什么是Namespace
      • Namespace当中的 Network Namespace
    • Libcontainer
    • docker 网络基础
      • 创建两个命名空间
      • 创建网络接口 veth pair
      • 命名空间添加 veth 接口
      • 为 veth 接口分配 IP
      • 启动 veth 接口
      • 相互 ping
    • bridge 网络
      • 搭建网络环境
      • 查看docker0 网桥
      • 创建网桥 bridge2
      • 创建容器并连接网络
      • 查看容器详情
      • 查看网络详情
      • 容器之间相互ping
      • ping 容器名
      • 创建定向连接容器
      • 创建共享网络命名空间容器
    • none 网络
      • 创建 none 网络容器
      • 查看容器详情
    • host 网络
      • 创建 host 网络容器
      • 查看容器详情
      • 查看容器的IP信息

深入理解 Namespace

什么是Namespace

  1. 先来看看那种比较正式的定义。Namespace是将内核的全局资源做封装,使得每个Namespace都有一份独立的资源,因此不同的进程在各自的Namespace内对同一种资源的使用不会互相干扰。

  2. 这样的解释可能不清楚。举个例子:在Linux系统上,你想要改变系统的主机名,这个主机名就是一个内核的全局资源。但是内核通过实现UTS Namespace,可以将不同的进程分隔在不同的UTS Namespace中,在某个Namespace修改主机名时,另一个Namespace的主机名还是保持不变。

  3. 所以说Namespace是用来隔离进程对系统资源的访问。每一个 Namespace 都有一套自己的系统资源(例如进程ID、主机名、网络接口等),进程只能看到和操作同一个 Namespace 中的资源。这样就可以在逻辑上隔离不同的进程,让它们在各自的 “空间” 中运行,互不干扰。

  4. 在 Linux 系统中,每个进程都与一组 Namespace 关联。这些 Namespace 决定了进程可以看到和影响哪些系统资源。例如,进程的网络 Namespace 决定了进程可以看到和使用哪些网络接口。

  5. 当一个进程被创建时,它会继承其父进程所在的所有 Namespace。但是,也可以在创建新进程时指定其所在的 Namespace,或者将已有的进程移动到新的Namespace。在 Linux 的 /proc 文件系统中,可以查看进程的 Namespace 信息。例如,/proc/[pid]/ns/ 目录下的每个文件都代表了一个 Namespace,这些文件是该进程所在 Namespace 的符号链接。通过查看和比较这些文件,可以确定进程的 Namespace 信息。

image-20230914194056001

看完上面5段话,对于Namespace就会有一个基本的认识。

Namespace当中的 Network Namespace

目前Linux内核总共实现了6种 Namespace。

  • IPC:隔离System V IPC和 POSIX消息队列。
  • Network:隔离网络资源。
  • Mount:隔离文件系统挂载点。
  • PID:隔离进程ID。
  • UTS:隔离主机名和域名。
  • User:隔离用户ID和组ID。

Network Namespace 对网络相关的系统资源进行隔离,每个Network Namespace都有自己的网络设备、IP地址、路由表、/proc/net目录、端口号等。网络隔离的必要性是很明显的举一个例子,在没有隔离的情况下,如果两个不同的容器都想运行同一个Web应用,而这个应用又需要使用80端口,那就会有冲突了。

Libcontainer

Libnetwork是由Go语⾔编写的一个开源工具,该工具具有跨平台性,主要处理Docker网络相关的工作。下图是Libnetwork的整体结构。

image-20230914205054633
  • 沙盒:沙盒是一个隔离的网络运行环境,保存了容器网络栈的配置,包括了对网络接口、路由表和 DNS配置的管理。在 Linux平台上,沙盒是用Linux NetworkNamespace实现的。一个沙盒可以包括来自多个网络的多个Endpoint(网络接口)。
  • 网络接口:Endpoint(网络接口)将沙盒加入一个网络,Endpoint 的实现可以是一对 veth pair或者OVS内部端口,当前的Libnetwork 使用的是veth pair。一个 Endpoint 只能属于一个沙盒及一个网络。通过给沙盒增加多个Endpoint可以将一个沙盒加入多个网络。
  • 网络:网络包括一组能互相通信的Endpoint。网络的实现可以是bridge ,host,none等。
  • 可拔插接口:可拔插接口指的是允许开发者将自定义的网络驱动接入到 Libnetwork 中,使得 Docker 容器可以使用这些自定义的网络驱动进行网络通信。这种接口的设计使得 Libnetwork 具备了极高的灵活性和可扩展性。
  • 服务发现:Libnetwork 的网络控制层和管理层负责创建和管理网络以及网络接口。这些网络接口可以被绑定Docker 容器上,使得这些容器可以在同一个网络中相互通信。通过这种方式,容器可以实现本地服务发现,即在同一个网络中的容器可以通过容器名称或者其他标识来找到其他容器,从而实现相互通信。
  • 负载均衡:Libnetwork 的网络控制层和管理层可以创建和管理网络,这些网络可以配置为支持负载均衡。例如,可以使用 Overlay 网络驱动创建一个跨多个 Docker 宿主机的虚拟网络,然后在这个虚拟网络中的容器之间实现负载均衡。另外,Libnetwork 还可以与 Docker Swarm 集群管理工具集成,通过 Docker Swarm,可以实现在集群范围内的容器负载均衡。

docker 网络基础

有了上面的一些基础知识做铺垫,理解docker 网络的底层原理可能会轻松一点。下面就用一些linux命令创建两个命名空间,最后让这两个命名空间之间能相互通信。

创建两个命名空间

分别创建两个命名空间 namespace1 与 namespace2。
image-20230914212514298

因为每个网络空间都是独立的,所以每个 Network Namespace 都具有一个回环网络适配器 lo。可以看到这个接口的最大传输单元(MTU)是65536字节,其中MTU是网络接口可以接受的最大数据包大小。并且还可以看到state DOWN表示这个接口目前没有启用。而qlen 1000则表示这个接口的发送队列的长度,即接口可以缓存的待发送数据包的数量。
image-20230914212645538

创建网络接口 veth pair

如果要让两个命名空间连通,则需要用到虚拟设备接口技术 veth pair。该技术需要一对网络接口分别置于两个命名空间中。

以下命令用于创建一对网络接口 veth-ns1 与 veth-ns2。
image-20230914214137570

对于ip link add veth-ns1 type veth peer name veth-ns2 这个命令的解释如下:

  • ip link add:这是用于创建网络设备的命令。
  • veth-ns1:这是你要创建的第一个veth设备的名称。
  • type veth:这表示你要创建的设备的类型是 veth。
  • peer name veth-ns2:这表示你要创建的第二个veth设备的名称。peer关键字表示这两个设备是一对,互为对方的端点。

而 ip link show veth-ns1命令和 ip link show veth-ns2 命令展示了两个虚拟网络接口的信息。通过 veth-ns1@veth-ns2 和 veth-ns2@veth-ns1 可以发现这两个网络接口是一对接口。除此之外,还能看到网络接口的状态和MAC地址等等信息。

命名空间添加 veth 接口

通过 ip link set 命令,将这两个网络接口分别分配给两个命名空间。
image-20230914214853868

为 veth 接口分配 IP

前面创建的两个网络接口是没有 IP 的。下面要通过 ip netns exec 命令,为每个指定的命名空间执行 IP 添加命令 ip addr add [ip] dev [网络接口]。为 namespace1 的 veth-ns1 网络接口分配的 IP 为 192.168.1.1,掩码为 24;为 namespace2 的 veth-ns2 网络接口分配的 IP 为 192.168.1.2,掩码为 24。
image-20230914221425967

启动 veth 接口

以上两个命名空间中的 veth 接口已经具有了 IP,但其状态仍为 DOWN,还没有开启。下面要通过 ip link set dev [接口] up 来启动指定的网络接口。
image-20230914222945394

相互 ping

此时可以通过在两个命名空间中执行 ping 命令来与对方进行连通性测试了。
image-20230914223132727

bridge 网络

通过 docker network ls 命令可以查看当前主机所连接的网络及网络类型。
image-20230915093834017

bridge 网络,也称为单机桥接网络,是 Docker 默认的网络模式。该网络模式只能存在于单个 Docker 主机上,其只能用于连接所在 Docker 主机上的容器。

搭建网络环境

需求:搭建如下的网络环境。
image-20230915101209888

查看docker0 网桥

image-20230915102335813
  1. 网络接口名称(docker0)及其状态(UP,表示启动并运行)。
  2. docker0 的 MAC 地址(02:42:36:20:cc:8b)。
  3. docker0 的 IP 地址(172.17.0.1)和子网掩码(/16,表示子网的地址范围是 172.17.0.0 到 172.17.255.255)。
  4. docker0 的广播地址(172.17.255.255)。
  5. docker0 的 IPv6 地址(fe80::42:36ff:fe20:cc8b/64)。
  6. docker0 的 MTU(Maximum Transmission Unit,最大传输单元)是 1500。这是 Ethernet 的标准 MTU。

创建网桥 bridge2

image-20230915103033257

-d 选项用于指定要创建网络时所使用的驱动,即创建的网络类型。最后的 bridge2 则是新创建网络的名称。查看bridge2网桥的相关信息:

image-20230915111942451

可以看到bridge2网桥的IP地址为172.18.0.1。

创建容器并连接网络

创建busybox1容器并连接bridge网桥:--network bridge 告诉 Docker 使用 bridge 网桥来运行 busybox1 容器。
image-20230915111648319

可以看到busybox1的IP地址为172.17.0.2。现在创建busybox2容器并连接bridge网桥。
image-20230915112458290

可以看到busybox2容器的IP地址为172.17.0.3。现在要将busybox2连接到bridge2网桥上。
image-20230915112959629

使用docker network connect命令就可以让busybox2容器连接到bridge2网桥上。可以发现busybox2的IP地址又多了一个172.18.0.2/16。说明这个IP地址在172.18.0.0这个网段上,也就是bridge2网桥所在的网段。现在创建busybox3容器并连接到bridge2网桥上。
image-20230915113535516

可以看到busybox3的IP地址为172.18.0.3。

查看容器详情

这里以busybox2容器为例,查看该容器的网络详情。

docker inspect busybox2

# 查看容器的网络配置信息:NetworkSettings
{
    "Bridge": "", 
    "SandboxID": "145b13df0a94364eda70a3dd93a10b171f23159ddff200313f4a0c558505b9e6", 
    "HairpinMode": false, 
    "LinkLocalIPv6Address": "", 
    "LinkLocalIPv6PrefixLen": 0, 
    "Ports": { }, 
    "SandboxKey": "/var/run/docker/netns/145b13df0a94", 
    "SecondaryIPAddresses": null, 
    "SecondaryIPv6Addresses": null, 
    "EndpointID": "2af54e966620633d28dfc91e54816e4a85a4c105c0213a7ef41d2c9fdcf2f3df", 
    "Gateway": "172.17.0.1", 
    "GlobalIPv6Address": "", 
    "GlobalIPv6PrefixLen": 0, 
    "IPAddress": "172.17.0.3", 
    "IPPrefixLen": 16, 
    "IPv6Gateway": "", 
    "MacAddress": "02:42:ac:11:00:03", 
    "Networks": {
        "bridge": {
            "IPAMConfig": null, 
            "Links": null, 
            "Aliases": null, 
            "NetworkID": "5f417d52f8fdae77a94202c473b03e1998de09f7509363e03826c01a3f669f14", 
            "EndpointID": "2af54e966620633d28dfc91e54816e4a85a4c105c0213a7ef41d2c9fdcf2f3df", 
            "Gateway": "172.17.0.1", 
            "IPAddress": "172.17.0.3", 
            "IPPrefixLen": 16, 
            "IPv6Gateway": "", 
            "GlobalIPv6Address": "", 
            "GlobalIPv6PrefixLen": 0, 
            "MacAddress": "02:42:ac:11:00:03", 
            "DriverOpts": null
        }, 
        "bridge2": {
            "IPAMConfig": { }, 
            "Links": null, 
            "Aliases": [
                "8be8f43ccd8d"
            ], 
            "NetworkID": "5f4893ee055e6a11841ff89b5a6b8d088d8d80362deac9f4c1ff0ee9d6974b96", 
            "EndpointID": "c29ec9f1b1a75010c70a5f908175101bcbfc21b0159b3475fe7d7e50f86c3741", 
            "Gateway": "172.18.0.1", 
            "IPAddress": "172.18.0.2", 
            "IPPrefixLen": 16, 
            "IPv6Gateway": "", 
            "GlobalIPv6Address": "", 
            "GlobalIPv6PrefixLen": 0, 
            "MacAddress": "02:42:ac:12:00:02", 
            "DriverOpts": { }
        }
    }
}

可以看到busybox2这个容器有两个网段,分别是172.17.0.1和172.18.0.1;并且busybox2这个容器有两个IP地址,分别是172.17.0.3和172.18.0.2。

查看网络详情

# 查看网桥的相关信息
docker network inspect bridge2

"Containers": {
        "8be8f43ccd8d1177bab90f81f3499f2448bfdc046c06db298f3e39f3943a5147": {
            "Name": "busybox2",
            "EndpointID": "a7ecc7cf1092e7c7601ac14b560a43b648cde38d02ffe770ba9ec77a33b0de95",
            "MacAddress": "02:42:ac:12:00:02",
            "IPv4Address": "172.18.0.2/16",
            "IPv6Address": ""
        },
        "97cbf3344e7b5587ce84ac0141af9a4b40692dd14407fc2ac40f20bf5f02456c": {
            "Name": "busybox3",
            "EndpointID": "29cc4737c14c54b1b8a4698c66faa833e6262b4163152ee50b3ef6c7969228c0",
            "MacAddress": "02:42:ac:12:00:03",
            "IPv4Address": "172.18.0.3/16",
            "IPv6Address": ""
        }
    }

查看 bridge2 的网络详情中的容器情况,发现 busybox2 与 busybox3 都在该网络上。

容器之间相互ping

image-20230915141611179

发现busybox1能ping通busybox2;busybox2能Ping通busybox3;而busybox1不能ping通busybox3。说明只有在同一段网络下的容器之间才能相互ping通。

ping 容器名

image-20230915152009127

该方式在生产中非常重要。因为生产中容器的 IP 可能会发生变化,但容器名称一般是不会变的。如果某服务总是直接通过 IP 与容器相连接,那么一旦容器 IP 变化,则该服务将连接不上容器。但如果是通过容器名称相连接的,那么无论容器 IP 如何变化,都将不影响服务与容器的连接。

创建定向连接容器

对于自定义的 bridge 网络,其具有一个特性:该网络上的容器可以通过容器名互 ping。但默认的 bridge 网络是不行的。如果在默认的 bridge 网络上实现通过容器名进行的连接,则需要创建容器时通过–link 选项指定。
image-20230915152906961

但是容器 busybox4 是无法通过容器名称来连接 busybox2 的。然后 busybox1 也无法通过容器名称连接 busybox4。所以,–link 指定的连接是一种定向连接,是带有指向性与方向性的。

image-20230915153308134

创建共享网络命名空间容器

在创建容器时可以指定其与某已经存在的容器共享 Network Namespace,但要求该已经存在的容器采用的是 bridge 网络模式。

docker run -it --name busybox-1 --network container:busybox1 busybox /bin/sh

上面的命令创建了一个 busybox-1 的容器,其共享了 busybox1 容器的 Network Namespace。查看两个容器的接口情况,发现完全相同。

image-20230915153824101

查看容器 busybox-1 的详情,可以发现,其没有自身的网络设置。因为其共享的 bb1 容器的网络设置。
image-20230915154040200
image-20230915154015021

none 网络

none 网络,即没有网络。容器仍是一个独立的 Network Namespace,但没有网络接口,没有 IP。

创建 none 网络容器

在 docker run 命令中,通过–network none 选项指定创建的容器没有网络功能。

docker run -it --name busybox5 --network none busybox /bin/sh

查看容器详情

# 查看容器详情的命令
docker inspect busybox5

# 下面是busybox5关于网络部分的信息
"NetworkSettings": {
    "Bridge": "",
    "SandboxID": "400b397e12ca82bc791f5fd4d194a05289445e489a121e2fce06ca54817f2f86",
    "HairpinMode": false,
    "LinkLocalIPv6Address": "",
    "LinkLocalIPv6PrefixLen": 0,
    "Ports": {

    },
    "SandboxKey": "/var/run/docker/netns/400b397e12ca",
    "SecondaryIPAddresses": null,
    "SecondaryIPv6Addresses": null,
    "EndpointID": "",
    "Gateway": "",
    "GlobalIPv6Address": "",
    "GlobalIPv6PrefixLen": 0,
    "IPAddress": "",
    "IPPrefixLen": 0,
    "IPv6Gateway": "",
    "MacAddress": "",
    "Networks": {
    "none": {
      "IPAMConfig": null,
      "Links": null,
      "Aliases": null,
      "NetworkID": "3b0eaed4d1d8ff72e62cc883d3a97639284fbd8eec96d6919322acbb4acd8d17",
      "EndpointID": "61ed43896cfc51adf35120c16f335ba58dcb124103cb0bb6f17b7b9eee2ca355",
      "Gateway": "",
      "IPAddress": "",
      "IPPrefixLen": 0,
      "IPv6Gateway": "",
      "GlobalIPv6Address": "",
      "GlobalIPv6PrefixLen": 0,
      "MacAddress": "",
      "DriverOpts": null
    	}
    }
}

通过 docker inspect 命令查看该容器的详情,发现其没有 IP,没有网关,没有 MAC 地址。这种none网络的主要用途是为那些不需要或不希望有任何网络通信功能的容器提供一个安全的运行环境,例如一些只需要进行本地计算或处理本地数据的应用。

host 网络

host 网络,即与宿主机 host 共用一个 Network Namespace。该网络类型的容器没有独立的网络空间,没有独立的 IP,全部与 host 共用。

创建 host 网络容器

在 docker run 命令中,通过–network host 选项指定创建的容器为 host 网络。

docker run -it --name busybox6 --network host busybox /bin/sh

查看容器详情

# 查看容器详情的命令
docker inspect busybox6

# 下面是busybox5关于网络部分的信息
"NetworkSettings": {
    "Bridge": "",
    "SandboxID": "d16a68fa18c745642fe4a7833e89bb2ee7351c06291cb5441dc3c35f7c350321",
    "HairpinMode": false,
    "LinkLocalIPv6Address": "",
    "LinkLocalIPv6PrefixLen": 0,
    "Ports": {

    },
    "SandboxKey": "/var/run/docker/netns/default",
    "SecondaryIPAddresses": null,
    "SecondaryIPv6Addresses": null,
    "EndpointID": "",
    "Gateway": "",
    "GlobalIPv6Address": "",
    "GlobalIPv6PrefixLen": 0,
    "IPAddress": "",
    "IPPrefixLen": 0,
    "IPv6Gateway": "",
    "MacAddress": "",
    "Networks": {
    "host": {
        "IPAMConfig": null,
        "Links": null,
        "Aliases": null,
        "NetworkID": "16501fad09abfb197b94593aa27568c6c91cfbebb2c521553da481552fa3ad1f",
        "EndpointID": "7cdf57ebf08f15fe7069b7f03f46a711b6b283ae8aff85ed614b6b5524dc9035",
        "Gateway": "",
        "IPAddress": "",
        "IPPrefixLen": 0,
        "IPv6Gateway": "",
        "GlobalIPv6Address": "",
        "GlobalIPv6PrefixLen": 0,
        "MacAddress": "",
        "DriverOpts": null
        }
    }
}

通过 docker inspect 命令查看该容器的详情,发现其没有 IP,没有网关,没有 MAC 地址。

查看容器的IP信息

通过 docker exec busybox6 ip addr 命令查看容器的IP信息可以发现该容器的IP与宿主机的IP信息一模一样。所以在host模式下,容器直接使用宿主机的网络接口、IP和路由规则。这意味着在host网络模式下运行的容器可以直接监听宿主机上的所有网络端口,也正是因为容器与宿主机共用网络端口,所以在host模式下的运行容器不需要进行端口映射就能直接对外提供服务。

这种模式的主要用途是为那些需要直接访问宿主机网络环境或者需要高性能网络通信的容器提供一个高效的运行环境。但是,由于它会让容器直接暴露在宿主机的网络环境中,所以在某些需要隔离或安全的场景中可能不适用。

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

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

相关文章

95.qt qml-诺谦通用可扩展多功能QML界面

支持如下所示: 1.可扩展多功能交互,用户可以根据自己喜欢使用常用功能,针对多功能项目非常有用!2.登录用户信息显示,历史消息显示,皮肤黑白风格切换 如下图所示: 自带一个功能界面,可以通过功能界面添加不…

视频转gif制作如何操作?分享一个三步视频转GIF方法

视频如何制作成gif格式图片?工作生活中常常会用到gif格式。那么,自己如何利用视频来制作gif动图呢?下面,给大家分享一款gif动态图片制作(https://www.gif.cn/)神器,无需下载软件,上传…

ARM 相关概念2

一、汇编中三种符号(汇编指令、伪指令、伪操作) 二、汇编基本格式 三、数据操作指令 3.1 数据搬移指令mov/mvn ① 示例 ② 立即数 0xff000000 >判断的数 1111 1111 0000 0000 0000 0000 0000 0000 >判断的数 0000 0000 0000 0000 0000 0000 1111…

开源项目-SeaTunnel-UI数据集成系统

哈喽,大家好,今天给大家带来一个开源项目-SeaTunnel-UI数据集成系统 系统主要有任务配置,任务实例,数据源,虚拟表,用户管理等功能 登录 数据源 mysql数据源配置参数说明 kafka参数配置 mysqlcdc配置参数说明 虚拟表

LeetCode算法动态规划—斐波那契数列

目录 剑指 Offer 10- I. 斐波那契数列 - 力扣(LeetCode) 题解: 代码: 运行结果: 写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项(即 F(N)&#…

VUE3写后台管理(3)

VUE3写后台管理(3) 1.环境1.node2.vite3.Element-plus4.vue-router5.element icon6.less7.vuex8.vue-demi9.mockjs10.axios11.echarts 2.首页1.布局Main2.头部导航栏CommonHeader3.左侧菜单栏CommonLeft4.首页Home1.从后端获取数据显示到前端table的三种…

linux内核分析:进程与调度

lec12, 13, 14 : 进程数据结构 实际上进程和线程都是有一个统一的内部结构------task_struct 这是因为,上面的进程和线程到了内核这里,统一变成了任务,这就带来两个问题:信息展示和命令下达(有的是进程,有的是线程下达) pid 是 process id,tgid 是 thread group ID …

【小数点】C#使用Math.Round方法保留指定小数点位数,并且整数也同样保持统一的2位

2023年,第38周。给自己一个目标,然后坚持总会有收货,不信你试试! 在实际开发项目中,特别是涉及金额之类的字段,一般都会用到小数,有些是保留1、2、3小数点。 本篇文章主要简单讲讲,如…

csp 202212-2 训练计划

题目链接:计算机软件能力认证考试系统http://118.190.20.162/view.page?gpidT159 思路: 最早开始时间是受之前依赖的项目限制,若无依赖,第一天即可开始。若有依赖,等待前置项目完成才能开始,累加即可。 …

linux( CentOs)对mysql基本操作和密码修改

1.mysql登录 mysql -uroot -p 2.显示所有数据库 Show databases; 3.生产过程中改密码 use mysql ; 查看user表中的user、host、password信息。 select user,host,password from user; select host,user from user;使用“GRANT ALL PRIVILEGES ON *.* TO root% IDENTIFIE…

企业为何刚需CRM软件系统

CRM系统一直被誉为客户关系管理的“神器”,很多企业对它爱之入骨。那么,CRM系统是否为企业刚需?它对企业有哪些好处?下面我们就来说一下。 CRM系统对企业的好处 提高工作效率:通过CRM系统的自动化工作流,…

Python之pycurl

pycurl简介 pycurl是一个用于访问URL的Python模块。它可以使用libcurl来访问各种互联网资源。libcurl支持HTTP、HTTPS、FTP、GOPHER、DICT、TFTP、TELNET和FILE等许多协议。pycurl是将libcurl封装成Python模块的结果,因此,它既可以在Python脚本中直接使…

竞赛选题 基于深度学习的中文情感分类 - 卷积神经网络 情感分类 情感分析 情感识别 评论情感分类

文章目录 1 前言2 情感文本分类2.1 参考论文2.2 输入层2.3 第一层卷积层:2.4 池化层:2.5 全连接softmax层:2.6 训练方案 3 实现3.1 sentence部分3.2 filters部分3.3 featuremaps部分3.4 1max部分3.5 concat1max部分3.6 关键代码 4 实现效果4.…

多线程回顾、集合Collection、Set、List等基本知识

多线程回顾 问: 多线程的两种创建方式? 继承Thread类实现Runnable接口线程池Callable 问:多线程通常会遇到线程安全问题? 什么情况下会遇到线程安全问题? 答:一个数据被多个线程访问(有读有写) 解决这个问题的方式? SE:同步锁 synchronized A : 同步代码块 B : 同步方法…

Prometheus+Grafana可视化监控【Redis状态】

文章目录 一、安装Docker二、安装Redis数据库(Docker容器方式)三、安装Prometheus四、安装Grafana五、Pronetheus和Grafana相关联六、安装redis_exporter七、Grafana添加Redis监控模板 一、安装Docker 注意:我这里使用之前写好脚本进行安装Docker,如果已…

零碳联盟:为气候创新而生的全球合作

全球气候危机正逼近,而在这个关键时刻,红杉全球携手零碳联盟,共同致力于推动绿色科技的创新和应用,助力低碳经济的崛起。这一合作的宣布在红杉全球执行合伙人、红杉中国创始及执行合伙人沈南鹏的一番深思熟虑下得以实现。他强调&a…

Leetcode 剑指 Offer II 044. 在每个树行中找最大值

题目难度: 中等 原题链接 今天继续更新 Leetcode 的剑指 Offer(专项突击版)系列, 大家在公众号 算法精选 里回复 剑指offer2 就能看到该系列当前连载的所有文章了, 记得关注哦~ 题目描述 给定一棵二叉树的根节点 root ,请找出该二叉树中每一…

【JavaEE】多线程(二)

多线程(二) 文章目录 多线程(二)第一个多线程程序观察线程sleep创建线程继承Thread类,重写run方法实现Runnable, 重写run继承Thread,重写run实现Runnable,重写run基于lambda表达式 T…

ETL与ELT理解

ETL ETL( Extract-Transform-Load),用来描述将数据从来源端经过抽取(Extract)、转换(Transform)、加载(Load)至目的端的过程。ETL模式适用于小数据量集。如果在转换过程…

利用hutool工具类实现验证码功能

hutool工具类实现验证码 一.生成验证码二.校验验证码三.使用案例1.引入hutool工具类2.VerifyCodeResp接口响应体3.VerifyCodeController验证码工具类4.测试验证5.项目结构及源码下载 利用hutool工具类,可以很方便生成不同类型的验证码。这里简单记录下使用过程。 一…