Docker-swarm 介绍,集群,多服务部署实战

2023-11-19

一、什么是Docker Swarm?

Swarm是Docker公司推出的用来管理docker集群的平台,几乎全部用GO语言来完成的开发的,代码开源在https://github.com/docker/swarm, 它是将一群Docker宿主机变成一个单一的虚拟主机,Swarm使用标准的Docker API接口作为其前端的访问入口,换言之,各种形式的Docker

Client(compose,docker-py等)均可以直接与Swarm通信,甚至Docker本身都可以很容易的与Swarm集成,这大大方便了用户将原本基于单节点的系统移植到Swarm上,同时Swarm内置了对Docker网络插件的支持,用户也很容易的部署跨主机的容器集群服务。

  Docker Swarm 和 Docker Compose 一样,都是 Docker 官方容器编排项目,但不同的是,Docker Compose 是一个在单个服务器或主机上创建多个容器的工具,而 Docker Swarm 则可以在多个服务器或主机上创建容器集群服务,对于微服务的部署,显然 Docker Swarm 会更加适合。

从 Docker 1.12.0 版本开始,Docker Swarm 已经包含在 Docker 引擎中(docker swarm),并且已经内置了服务发现工具,我们就不需要像之前一样,再配置 Etcd 或者 Consul 来进行服务发现配置了。

  Swarm deamon只是一个调度器(Scheduler)加路由器(router),Swarm自己不运行容器,它只是接受Docker客户端发来的请求,调度适合的节点来运行容器,这就意味着,即使Swarm由于某些原因挂掉了,集群中的节点也会照常运行,放Swarm重新恢复运行之后,他会收集重建集群信息。

二、Docker Swarm基本构图展示

在结构图可以看出 Docker Client使用Swarm对 集群(Cluster)进行调度使用。

上图可以看出,Swarm是典型的master-slave结构,通过发现服务来选举manager。manager是中心管理节点,各个node上运行agent接受manager的统一管理,集群会自动通过Raft协议分布式选举出manager节点,无需额外的发现服务支持,避免了单点的瓶颈问题,同时也内置了DNS的负载均衡和对外部负载均衡机制的集成支持

三、Swarm几个关键概念

1.Swarm
集群的管理和编排是使用嵌入docker引擎的SwarmKit,可以在docker初始化时启动swarm模式或者加入已存在的swarm
 
2.Node
一个节点是docker引擎集群的一个实例。您还可以将其视为Docker节点。您可以在单个物理计算机或云服务器上运行一个或多个节点,但生产群集部署通常包括分布在多个物理和云计算机上的Docker节点。
要将应用程序部署到swarm,请将服务定义提交给 管理器节点。管理器节点将称为任务的工作单元分派 给工作节点。
Manager节点还执行维护所需群集状态所需的编排和集群管理功能。Manager节点选择单个领导者来执行编排任务。
工作节点接收并执行从管理器节点分派的任务。默认情况下,管理器节点还将服务作为工作节点运行,但您可以将它们配置为仅运行管理器任务并且是仅管理器节点。代理程序在每个工作程序节点上运行,并报告分配给它的任务。工作节点向管理器节点通知其分配的任务的当前状态,以便管理器可以维持每个工作者的期望状态。
 
3.Service
一个服务是任务的定义,管理机或工作节点上执行。它是群体系统的中心结构,是用户与群体交互的主要根源。创建服务时,你需要指定要使用的容器镜像。
 
4.Task
任务是在docekr容器中执行的命令,Manager节点根据指定数量的任务副本分配任务给worker节点
 
------------------------------------------使用方法-------------------------------------
docker swarm:集群管理,子命令有init, join, leave, update。(docker swarm --help查看帮助)
docker service:服务创建,子命令有create, inspect, update, remove, tasks。(docker service--help查看帮助)
docker node:节点管理,子命令有accept, promote, demote, inspect, update, tasks, lsrm。(docker node --help查看帮助)
   
node是加入到swarm集群中的一个docker引擎实体,可以在一台物理机上运行多个node,node分为:
manager nodes,也就是管理节点
worker nodes,也就是工作节点
 
1)manager node管理节点:执行集群的管理功能,维护集群的状态,选举一个leader节点去执行调度任务。
2)worker node工作节点:接收和执行任务。参与容器集群负载调度,仅用于承载task。
3)service服务:一个服务是工作节点上执行任务的定义。创建一个服务,指定了容器所使用的镜像和容器运行的命令。
   service是运行在worker nodes上的task的描述,service的描述包括使用哪个docker 镜像,以及在使用该镜像的容器中执行什么命令。
4)task任务:一个任务包含了一个容器及其运行的命令。task是service的执行实体,task启动docker容器并在容器中执行任务。

四、Swarm的工作模式

1.node

2.Service

3.任务与调度

4.服务副本与全局服务

 

五、Swarm的调度策略

Swarm在调度(scheduler)节点(leader节点)运行容器的时候,会根据指定的策略来计算最适合运行容器的节点,目前支持的策略有:spread, binpack, random.
1)Random
顾名思义,就是随机选择一个Node来运行容器,一般用作调试用,spread和binpack策略会根据各个节点的可用的CPU, RAM以及正在运
行的容器的数量来计算应该运行容器的节点。
  
2)Spread
在同等条件下,Spread策略会选择运行容器最少的那台节点来运行新的容器,binpack策略会选择运行容器最集中的那台机器来运行新的节点。
使用Spread策略会使得容器会均衡的分布在集群中的各个节点上运行,一旦一个节点挂掉了只会损失少部分的容器。
  
3)Binpack
Binpack策略最大化的避免容器碎片化,就是说binpack策略尽可能的把还未使用的节点留给需要更大空间的容器运行,尽可能的把容器运行在
一个节点上面。

六、Swarm cluster 模式特性

1)批量创建服务
建立容器之前先创建一个overlay的网络,用来保证在不同主机上的容器网络互通的网络模式
   
2)强大的集群的容错性
当容器副本中的其中某一个或某几个节点宕机后,cluster会根据自己的服务注册发现机制,以及之前设定的值--replicas n,
在集群中剩余的空闲节点上,重新拉起容器副本。整个副本迁移的过程无需人工干预,迁移后原本的集群的load balance依旧好使!
不难看出,docker service其实不仅仅是批量启动服务这么简单,而是在集群中定义了一种状态。Cluster会持续检测服务的健康状态
并维护集群的高可用性。
   
3)服务节点的可扩展性
Swarm Cluster不光只是提供了优秀的高可用性,同时也提供了节点弹性扩展或缩减的功能。当容器组想动态扩展时,只需通过scale
参数即可复制出新的副本出来。
   
仔细观察的话,可以发现所有扩展出来的容器副本都run在原先的节点下面,如果有需求想在每台节点上都run一个相同的副本,方法
其实很简单,只需要在命令中将"--replicas n"更换成"--mode=global"即可!
  
复制服务(--replicas n)
将一系列复制任务分发至各节点当中,具体取决于您所需要的设置状态,例如“--replicas 3”。
  
全局服务(--mode=global)
适用于集群内全部可用节点上的服务任务,例如“--mode global”。如果大家在 Swarm 集群中设有 7 台 Docker 节点,则全部节点之上都将存在对应容器。
   
4. 调度机制
所谓的调度其主要功能是cluster的server端去选择在哪个服务器节点上创建并启动一个容器实例的动作。它是由一个装箱算法和过滤器
组合而成。每次通过过滤器(constraint)启动容器的时候,swarm cluster 都会调用调度机制筛选出匹配约束条件的服务器,并在这上面运行容器。
   
------------------Swarm cluster的创建过程包含以下三个步骤----------------------
1)发现Docker集群中的各个节点,收集节点状态、角色信息,并监视节点状态的变化
2)初始化内部调度(scheduler)模块
3)创建并启动API监听服务模块
   
一旦创建好这个cluster,就可以用命令docker service批量对集群内的容器进行操作,非常方便!
   
在启动容器后,docker 会根据当前每个swarm节点的负载判断,在负载最优的节点运行这个task任务,用"docker service ls" "docker service ps + taskID"
可以看到任务运行在哪个节点上。容器启动后,有时需要等待一段时间才能完成容器创建。

七、案例展示

环境:

准备:

三台装有docker环境的虚拟机,选择的系统是Centos8

最好将三台环境用docker-machine联系起来(不一定需要,但是联系好了,方便操作,所有操作只需要在一个窗口操作即可)

三台主机的地址分别为:

        ip                               hostName

172.16.9.115                     manager

172.16.9.118                    docker118

172.16.9.169                    docker169

①、创建Swarm集群

docker swarm init --advertise-addr 172.16.9.115       (你得告诉它在哪个环境上创建这个集群)

注意: 这个会创建一个集群token,获取全球唯一的 token,作为集群唯一标识。后续将其他节点加入集群都会用到这个token值。

其中,--advertise-addr参数表示其它swarm中的worker节点使用此ip地址与manager联系。命令的输出包含了其它节点如何加入集群的命令。

切换到118环境上的docker环境。这个就是docker-machine的好处了


创建node节点

这样就创建好了,我们来查看一下,可以看大我们当前创建集群的node被选为主导者,

参数:

ID:指的是当前节点唯一唯一值

HOSTNAME:各个节点的名称

STATUS:当前节点状态

AVAILABILITY:当前节点的运行活跃性,这里AVAILABILITY还有Drain,down

active状态下,node可以接受来自manager节点的任务分派;
drain状态下,node节点会结束task,且不再接受来自manager节点的任务分派(也就是下线节点)

down状态下,node节点就意味着自己主动离开了这个集群

②、创建一个nginx容器,然后用集群分布(单服务集群)

1)创建网络,创建网络的目的之前也说了,用来保证容器在不同主机下网络互通的网络模式

 docker network create -d overlay my_network


 保证当前节点上有nginx镜像,我提前pull一个镜像到我的主机

 

2)创建容器(服务部署)

 docker service create --replicas 1 --network my_network  -d --name myNginx -p 8080:80 nginx:1.14-alpine    

--replicas 1 只创建一个副本容器

-d 后台运行

--name 给容器起个名字

-p 外部端口:内部端口

最后就是镜像

查看当前运行服务列表:

docker service ls

查看在哪些节点运行了该容器

 docker service ps myNginx

3)在swarm中扩展服务

 docker service scale myNginx=3

我们登录到docker118上,查看一下容器

同时改命令也可以缩容

docker service scale myNginx=1

4)模拟docker宕机情况,看一下swarm把当前的服务到底该怎么分布

可以看到我们集群118环境上状态已经为dowm

然后我们看一下swarm如何处理服务器单机情况

可以看到我们服务器上已经服务自动被分配到manager服务上,所以现实生活中,如果一台服务器宕机,我们集群服务也不会有问题,用户是无感的

重启我们docker118上的docker服务

然后将之前分配到manager上的task关闭

 docker stop myNginx.2.qzfehketo9igugqulqp2xodrm

可以看到服务器恢复了,服务又跑到docker118上

③、多服务swarm集群

1)准备工作:

swarm集群搭建好

准备一个以上的镜像,这里我准备了三个镜像,nginx:1.14-alpine,redis:latest,tomcat:latest

2)创建docker-compose文件

前面也说了docker-compose主要是编排和管理单个节点服务

这里我就将docker-compose.yml与docker swarm整合

docker-compose.yml

version: "3"
services:
nginx:
image: nginx:1.14-alpine
ports:
- "8899:80"
deploy:
mode: replicated
replicas: 3

redis:
image: redis:latest
ports:
- "63790:6379"
deploy:
mode: replicated
replicas: 3

tomcat:
image: tomcat:latest
ports:
- "8999:8080"
deploy:
mode: replicated
replicas: 3

注意:

docker service部署的是单个服务,我们可以使用docker stack进行多服务编排部署

执行:docker stack deploy -c docker-compose.yml my_service

 

看看效果:

nginx:

manager:

 nginx

 tomcat:

redis:进入到其容器进入其库中

进入容器:

docker exec -it 846b773fd1f8 bash

找到redis安装客户端(这里我用的是免密的)

执行./redis-cli

我们登录到118和169节点查看一下容器 

 

可以看到容器完美的启动起来了,内容和manager一模一样

八、docker swarm 容器网络

在Docker版本1.12之后swarm模式原生支持覆盖网络(overlay networks),可以先创建一个覆盖网络,然后启动容器的时候启用这个覆盖网络,
这样只要是这个覆盖网络内的容器,不管在不在同一个宿主机上都能相互通信,即跨主机通信!不同覆盖网络内的容器组之间是相互隔离的(相互ping不通)。便于管理

swarm模式的覆盖网络包括以下功能:
1)可以附加多个服务到同一个网络。
2)默认情况下,service discovery为每个swarm服务分配一个虚拟IP地址(vip)和DNS名称,使得在同一个网络中容器之间可以使用服务名称为互相连接。
3)可以配置使用DNS轮循而不使用VIP
4)为了可以使用swarm的覆盖网络,在启用swarm模式之间你需要在swarm节点之间开放以下端口:
  --TCP/UDP端口7946 – 用于容器网络发现
  --UDP端口4789 – 用于容器覆盖网络

例:

在我本地的swarm集群创建我自定义的覆盖网络

命令:

docker network create --driver overlay --opt encrypted --subnet 10.0.6.0/24 server_net

参数:

 --opt encrypted      默认情况下swarm中的节点通信是加密的。在不同节点的容器之间,可选的–opt encrypted参数能在它们的vxlan流量启用附加的加密层。

 --subnet                 命令行参数指定overlay网络使用的子网网段。当不指定一个子网时,swarm管理器自动选择一个子网并分配给网络。

查看一下当前网络

docker  network ls

由上可知,Swarm当中拥有2套覆盖网络。其中"ngx_net"网络正是我们在部署容器时所创建的成果。而"ingress"覆盖网络则为默认提供。
Swarm 管理节点会利用 ingress 负载均衡以将服务公布至集群之上。
在将服务连接到这个创建的网络之前,网络覆盖到manager节点。上面输出的SCOPE为 swarm 表示将服务部署到Swarm时可以使用此网络。
在将服务连接到这个网络后,Swarm只将该网络扩展到特定的worker节点,这个worker节点被swarm调度器分配了运行服务的任务。
在那些没有运行该服务任务的worker节点上,网络并不扩展到该节点。

现在以该网络为例,建一个新的server,用该网络分配

 docker service create --replicas 5 --network server_net --name mynginx -p 80:80 nginx:1.14-alpine

下面看一下该网络内部情况

当前节点是manager查看结果:

[root@manager _data]# docker network inspect server_net
[
{
"Name": "server_net",
"Id": "bd2nid7zcmkku8s3d6tnsqpk2",
"Created": "2021-10-20T15:30:24.055441695+08:00",
"Scope": "swarm",
"Driver": "overlay",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "10.0.6.0/24",
"Gateway": "10.0.6.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"34e684acf212c77b58757313e979c73df109ff4976ed35c73cdc6734b86b9cd7": {
"Name": "server_nginx.3.5vo89iserzv8d2r9gx6viebm1",
"EndpointID": "7faa16cdec61c504cab8db9a32d911919169a8acd8b46029c6e2f6b55d6f1d9c",
"MacAddress": "02:42:0a:00:06:06",
"IPv4Address": "10.0.6.6/24",
"IPv6Address": ""
},
"c78698449a5a409274829784474f2ebc4fae6361e655f42a624e20d1aaf77088": {
"Name": "server_nginx.5.7w8gg9i0gh5yjqrmon84zkj05",
"EndpointID": "dc7014a45dd56b9eb4f02220a45a0b552ec638727a28b2f3195acf58c487ecfb",
"MacAddress": "02:42:0a:00:06:03",
"IPv4Address": "10.0.6.3/24",
"IPv6Address": ""
},
"lb-server_net": {
"Name": "server_net-endpoint",
"EndpointID": "b8f5246e67bf3663c8a62569303aaf28610647b613987f2e644f444712046c1f",
"MacAddress": "02:42:0a:00:06:09",
"IPv4Address": "10.0.6.9/24",
"IPv6Address": ""
}
},
"Options": {
"com.docker.network.driver.overlay.vxlanid_list": "4104",
"encrypted": ""
},
"Labels": {},
"Peers": [
{
"Name": "09f254b7f1d9",
"IP": "172.16.9.115"
},
{
"Name": "1cc453463e4f",
"IP": "172.16.9.169"
},
{
"Name": "c21e759ab233",
"IP": "172.16.9.118"
}
]
}
]

结果是有两个容器被随机分配了一个子网地址

再切换到docker118节点上查看

[root@manager _data]# docker-machine ssh docker118
Activate the web console with: systemctl enable --now cockpit.socket

Last login: Wed Oct 20 15:02:11 2021 from 172.16.9.115
[root@docker118 ~]# docker network inspect server_net
[
{
"Name": "server_net",
"Id": "bd2nid7zcmkku8s3d6tnsqpk2",
"Created": "2021-10-20T15:30:24.056724875+08:00",
"Scope": "swarm",
"Driver": "overlay",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "10.0.6.0/24",
"Gateway": "10.0.6.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"95bfcdd73501e868feaf366e8b15c12933b3286e56127ff7d7272e24ab3469af": {
"Name": "server_nginx.1.v88vupd2coea51jh0jlru9c2x",
"EndpointID": "3eb04f0cac93e7196d85a955e9ef822efef057b0f528ca1a54fbff8da8968507",
"MacAddress": "02:42:0a:00:06:04",
"IPv4Address": "10.0.6.4/24",
"IPv6Address": ""
},
"lb-server_net": {
"Name": "server_net-endpoint",
"EndpointID": "bbac6cddee071057fb9788165636f86a391aae41127fe56f6c8465f23dc3845e",
"MacAddress": "02:42:0a:00:06:0a",
"IPv4Address": "10.0.6.10/24",
"IPv6Address": ""
}
},
"Options": {
"com.docker.network.driver.overlay.vxlanid_list": "4104",
"encrypted": ""
},
"Labels": {},
"Peers": [
{
"Name": "c21e759ab233",
"IP": "172.16.9.118"
},
{
"Name": "09f254b7f1d9",
"IP": "172.16.9.115"
},
{
"Name": "1cc453463e4f",
"IP": "172.16.9.169"
}
]
}
]

结论:从上面信息来看,在manager-node模式下   一个名为 server_nginx的服务有两个分别为server_nginx.3.5vo89iserzv8d2r9gx6viebm1和server_nginx.5.7w8gg9i0gh5yjqrmon84zkj05的task连接到名为server_net网络上

切换到node节点docker118上也是发现一个名为 server_nginx的服务有一个server_nginx.1.v88vupd2coea51jh0jlru9c2x 的task任务连接到名为server_net网络上

想要弄清楚这整个网络结构的话,先查看一下该网络对应的虚拟地址

[root@manager _data]# docker service inspect --format='{{json .Endpoint.VirtualIPs}}' server_nginx


[{"NetworkID":"k1aonfxs861nbd65nbzif5l7a","Addr":"10.0.0.38/24"},{"NetworkID":"bd2nid7zcmkku8s3d6tnsqpk2","Addr":"10.0.6.2/24"}]

虚拟地址(v-ip)为10.0.6.2

然后 我们随便进入一个服务的容器中,查看一下该服务的容器的网段

[root@manager _data]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c78698449a5a nginx:1.14-alpine "nginx -g 'daemon of…" 29 minutes ago Up 29 minutes 80/tcp server_nginx.5.7w8gg9i0gh5yjqrmon84zkj05
34e684acf212 nginx:1.14-alpine "nginx -g 'daemon of…" 30 minutes ago Up 29 minutes 80/tcp server_nginx.3.5vo89iserzv8d2r9gx6viebm1
7a1e754dc2a7 portainer/portainer "/portainer" 4 weeks ago Up 2 hours 0.0.0.0:9000->9000/tcp prtainer
[root@manager _data]# docker exec -it c78698449a5a bash
OCI runtime exec failed: exec failed: container_linux.go:349: starting container process caused "exec: \"bash\": executable file not found in $PATH": unknown
[root@manager _data]# docker exec -it c78698449a5a sh
/ # ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
97: eth0@if98: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1450 qdisc noqueue state UP
link/ether 02:42:0a:00:00:27 brd ff:ff:ff:ff:ff:ff
inet 10.0.0.39/24 brd 10.0.0.255 scope global eth0
valid_lft forever preferred_lft forever
99: eth2@if100: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
link/ether 02:42:ac:13:00:04 brd ff:ff:ff:ff:ff:ff
inet 172.19.0.4/16 brd 172.19.255.255 scope global eth2
valid_lft forever preferred_lft forever
101: eth1@if102: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1424 qdisc noqueue state UP
link/ether 02:42:0a:00:06:03 brd ff:ff:ff:ff:ff:ff
inet 10.0.6.3/24 brd 10.0.6.255 scope global eth1
valid_lft forever preferred_lft forever
/ # ping 10.0.6.2
PING 10.0.6.2 (10.0.6.2): 56 data bytes
64 bytes from 10.0.6.2: seq=0 ttl=64 time=0.220 ms
64 bytes from 10.0.6.2: seq=1 ttl=64 time=0.075 ms
64 bytes from 10.0.6.2: seq=2 ttl=64 time=0.071 ms
64 bytes from 10.0.6.2: seq=3 ttl=64 time=0.073 ms

很清楚的发现这个之间毫无阻碍的访问

网络结构图

总结:

默认情况下,当创建了一个服务并连接到某个网络后,swarm会为该服务分配一个VIP。此VIP根据服务名映射到DNS。在网络上的容器共享该服务的DNS映射,
所以网络上的任意容器可以通过服务名访问服务。
  
在同一overlay网络中,不用通过端口映射来使某个服务可以被其它服务访问。Swarm内部的负载均衡器自动将请求发送到服务的VIP上,然后分发到所有的
active的task上。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Docker-swarm 介绍,集群,多服务部署实战 的相关文章

随机推荐

  • 帮程序员减压放松的10个良心网站

    同学们工作之余 不妨放下微博跟朋友圈 来这10个网站感受一下看着就醉了的情境 念完往上一推音乐键 我往后一靠 潮乎乎的软皮耳机里头 音乐排山倒海 今天推荐的网站 利用代入感强的图片与音频 迅速帮你抹平焦虑 获得平和心态 特别献需求改千遍的程
  • LeetCode-3. 无重复字符的最长子串 -- Python解

    原题描述 给定一个字符串 s 请你找出其中不含有重复字符的 最长子串 的长度 示例 1 输入 s abcabcbb 输出 3 解释 因为无重复字符的最长子串是 abc 所以其长度为 3 示例 2 输入 s bbbbb 输出 1 解释 因为无
  • 2011年中的macmini 系统安装,简直作死

    不想再爱mac了 再不要爱了 完结 这几天真的时间就耗在这系统上了 之前一直用的是win10系统 直接把苹果系统整个的推掉了 由于是真的不知道能直接U盘装10 13版本 索性理所当然的直接一步到位到10 14最新版 所以花了半天时间找镜像d
  • HTML中Form表单的使用

    1 form表单标记 表单标记以
  • 金融圈:Hoping Club华英会将重金注资收购REVA

    近期 金融圈有消息传出 华英会或将注资收购REVA提高其所持有的股份 来获取REVA中国大陆区ArtStreet质押平台的运营权 这一消息受到了很多业内人士的关注 一旦此次收购坐实成功也就意味着华英会将获得 中国大陆REVA质押平台的运营权
  • Mybatis-plusMybatis 通过获取sqlSession执行原生sql(执行程序代码中sql字符串)

    Mybatis plus Mybatis通过获取sqlSession执行原生jdbc执行sql 此处demo只写了执行查询sql 有需要可以执行增删改查都可 与原生jdbc调用方式一样 Component Slf4j public clas
  • 178、锐捷交换机恢复出厂和各种基本配置

    锐捷最详细的基础命令 一 锐捷交换机配置原理 我们来看下锐捷的日常配置命令原理 1 进入特权模式 Ruijie gt enable 进入特权模式 2 查看设备flash当前文件列表 Ruijie dir 查看flash当前文件列表 3 将配
  • faster RCNN 的细节理解

    1 anchors不同的大小但是采用了ROI pooling一样的策略 都映射到3 3的卷积核上 最后通过1 1的卷积核 相当与全连接分成了18类 9个anchors的话 2 分类的时候 reshape 两次 第一次为了softmax分类
  • Go的并发的退出

    有时候我们需要通知goroutine停止它正在干的事情 比如一个正在执行计算的web服务 然而它的客户端已经断开了和服务端的连接 Go语言并没有提供在一个goroutine中终止另一个goroutine的方法 由于这样会导致goroutin
  • #452. 序列操作

    序列操作 题目 Daimayuan Online Judge 问题描述 思路 首先想的是第二次操作的y可以将前面所以操作进行抵消 只需要第二次操作的最大值即可 但是发现 对于第一个操作 它是单点修改 每修改一次对于第二次操作都是有影响的 导
  • 最简单的区块链实现,不到50行代码!(一)

    什么是区块链 Blockchain 一个电子记账本 以比特币和其他密码加密货币进行的交易公开地 按照日期顺序记录其中 总的来说 它是一个公开的数据库 新的数据存储在一个称为区块的容器中 并且附加到一个 不可变 的链条 即区块链 上 链条上还
  • 《基于Python的大数据分析基础及实战》第二章

    第二章 个人信息 kwd info kwd info kwd info ipynb等文件下载 https wwm lanzouf com iklXf023qeef 对数据进行分析首先得对数据进行处理 本章主要介绍P thon在数据处理方面的
  • 5.2 主机扫描:主机探测

    目录 一 预备知识 主机扫描方法 二 实验环境 三 实验步骤 一 预备知识 主机扫描方法 主机扫描 Host Scan 是指通过对目标网络 一般为一个或多个IP网段 中主机IP地址的扫描 以确定目标网络中有哪些主机处于运行状态 主机扫描的实
  • Ubuntu下,Java中利用JNI调用codeblocks c++生成的动态库的使用步骤

    1 打开新立得包管理器 搜索JDK 选择openjdk 6 jdk安装 2 打开Ubuntu软件中心 搜索Eclipse 选择Eclipse集成开发环境 安装 3 打开Eclipse File gt New gt Java Project
  • 剑指Offer 22. 链表中倒数第k个节点(Easy)/ 19. 删除链表的倒数第 N 个结点(Medium)/ ListNode调用!!!

    LeetCode 19 删除链表的倒数第 N 个结点 Medium 题目链接 题解 链表中倒数第 k 个节点 双指针 清晰图解 思路 代码 Definition for singly linked list class ListNode d
  • Unity 音频卡顿 静帧 等待等问题的解决方案

    是否遇到过在Unity中加载音频文件卡顿 也就是画面卡住 的现象 特别是加载外部音频文件时 虽然时间很短 但这终归不是什么好现象 尤其是打游戏的话 影响很大 但是一些有牌面的Boss也不能不配音乐 当然也可以通过其它方式解决 比如特定条件统
  • 《人工智能导论》 第7章 机器学习

    机器学习 机器学习的基本概念 机器学习 Machine learning 使计算机能模拟人的学习行为 自动地通过学习来获取知识和技能 不断改善性能 实现自我完善 机器学习主要研究以下三个问题 学习机理 人类获取知识 技能和抽象概念的天赋能力
  • win7安装PS2019CC启动时报d3dcompiler_47.dll的问题解决

    原先安装的PS2017太卡顿了 有些功能用的也不习惯 卸载准备重装一下PS2019 在安装时发现报错 具体如下图所示 因此在网上下载了D3DCOMPILER 47 dll程序 放到了指定文件夹还是不行 百度参考这个解决了 WIN7缺少D3D
  • 全局光照算法:reflective shadow maps

    1 技术理解 RSM的全称是reflective shadow maps 受到Instant Radiosity这个离线技术的启发 其思想和ShadowMap的思想近似 在正式介绍和了解这个技术之前 我需要确定RSM用处何在 我想 RTR4
  • Docker-swarm 介绍,集群,多服务部署实战

    一 什么是Docker Swarm Swarm是Docker公司推出的用来管理docker集群的平台 几乎全部用GO语言来完成的开发的 代码开源在https github com docker swarm 它是将一群Docker宿主机变成一