【DevOps】搭建你的第一个 Docker 应用栈

news2024/11/19 17:37:42

搭建你的第一个 Docker 应用栈

  • 1.Docker 集群部署
  • 2.第一个 Hello World
    • 2.1 获取应用栈各节点所需镜像
    • 2.2 应用栈容器节点互联
    • 2.3 应用栈容器节点启动
    • 2.4 应用栈容器节点的配置
      • 2.4.1 Redis Master 主数据库容器节点的配置
      • 2.4.2 Redis Slave 从数据库容器节点的配置
      • 2.4.3 Redis 数据库容器节点的测试
      • 2.4.4 APP 容器节点(Django)的配置
      • 2.4.5 HAProxy 容器节点的配置
      • 2.4.6 应用栈访问测试
  • 3.开发、测试和发布一体化

1.Docker 集群部署

Docker 是一个新兴的轻量级虚拟化技术,其易用、跨平台、可移植的特性使其在集群系统的搭建方面有着得天独厚的优势。Docker 能够标准化封装应用程序所需的整个运行时环境,因此基于 Docker,我们可以实现分布式应用集群的快速、准确、自动化部署。

考虑到读者可能是初次接触 Docker 的新手,我们将降低难度,在一台机器上利用 Docker 自带的命令行工具,搭建一个 Docker 应用栈,利用多个容器来组成一个特定的应用。读者可参考应用栈部署的过程,一步一步搭建你的第一个 Docker 应用栈。对于有一定 Docker 使用经验的读者,也可尝试在多台机器上搭建一个真正的 Docker 集群,相信这个过程将对理解 Docker 相关工作原理大有裨益。

2.第一个 Hello World

在 Docker 中,镜像是容器的基础,可以通过镜像来运行容器。本节将举例说明如何有效地利用 Docker Hub 中已有的镜像资源来搭建一个 Docker 应用栈。

在开始搭建过程前,需要对所要搭建的应用栈进行简单的设计和描述:我们将搭建一个包含 6 6 6 个节点的 Docker 应用栈,其中包括一个代理节点、两个 Web 的应用节点、一个主数据库节点及两个从数据库节点。应用栈具体结构如下图所示。

在这里插入图片描述
上图中,HAProxy 是负载均衡代理节点;Redis 是非关系型的数据库,它由一个主数据库节点和两个从数据库节点组成;App 是应用,这里是使用 Python 语言、基于 Django 架构设计一个访问数据库的基础 Web 应用。

2.1 获取应用栈各节点所需镜像

在搭建过程中,可以从 Docker Hub 获取现有可用的镜像,在这些镜像的基础上启动容器,按照需求进行修改来实现既定的功能。读者能在此过程中体会到 Docker 的高可移植特性所带来的便利,既提高了应用开发的效率,又降低了开发的难度。

依据上文所描述的应用栈结构,需要从 Docker Hub 获取 HAProxy、Redis 及 Django 的镜像。具体的操作示例如下:

$ sudo docker pull ubuntu
$ sudo docker pull django
$ sudo docker pull haproxy
$ sudo docker pull redis
$ sudo docker images

在这里插入图片描述

2.2 应用栈容器节点互联

在搭建第一个 Hello World 应用栈时,将在同一主机下进行 Docker 应用栈搭建。如果是一个真正的分布式架构集群,还需要处理容器的跨主机通信问题,在这里我们将不做介绍。鉴于在同一主机下搭建容器应用栈的环境,只需要完成容器互联来实现容器间的通信即可,这里采用 docker run 命令的 --link 选项建立容器间的互联关系。

这里介绍一下 --link 选项的用法,通过 --link 选项能够进行容器间安全的交互通信,使用格式为 name:alias,其中 name 为连接容器的名称,alias 为连接的别名,可在一个 docker run 中重复使用该参数。使用示例如下:

$ sudo docker run --link redis:redis --name console ubuntu bash

上例将在 ubuntu 镜像上启动一个容器,并命名为 console,同时将新启动的 console 容器连接到名为 redis 的容器上。在使用 --link 选项时,连接通过容器名来确定容器,这里建议启动容器时自定义容器名。

通过 --link 选项来建立容器间的连接,不但可以避免容器的 IP 和端口暴露到外网所导致的安全问题,还可以防止容器在重启后 IP 地址变化导致的访问失效,它的原理类似于 DNS 服务器的域名和地址映射。当容器的 IP 地址发生变化时,Docker 将自动维护映射关系中的 IP 地址,文件示例如下:

# 容器启动命令
$ sudo docker run -it --name redis-slave1 --link redis-master:master redis /bin/bash
# 容器内查看 /etc/hosts 文件
# cat /etc/hosts
172.17.0.6  08df6a2cb468
127.0.0.1   localhost
...
172.17.0.5  master

该容器的 /etc/host 文件中记录了名称为 master 的连接信息,其对应 IP 地址为 172.17.0.5,即 redis-master 容器的 IP 地址。

通过上面的原理可以将 --link 设置理解为一条 IP 地址的单向记录信息,因此在搭建容器应用栈时,需要注意各个容器节点的启动顺序,以及对应的 --link 参数设置。应用栈各节点的连接信息如下:

  • 启动 redis-master 容器节点;
  • 两个 redis-slave 容器节点启动时要连接到 redis-master 上;
  • 两个 APP 容器节点启动时要连接到 redis-master 上;
  • HAProxy 容器节点启动时要连接到两个 APP 节点上。

综上所述,容器的启动顺序应为:
redis-masterredis-slave → APP → HAProxy

此外,为了能够从外网访问应用栈,并通过 HAProxy 节点来访问应用栈中的 APP,在启动 HAProxy 容器节点时,需要利用 -p 参数暴露端口给主机,即可通过主机 IP 加暴露的端口从外网访问搭建的应用栈。

2.3 应用栈容器节点启动

之前已经对应用栈的结构进行了分析,获取了所需的镜像资源,同时描述了应用栈中各个容器之间的互连关系,下面开始利用所获得的镜像资源来启动各个容器。应用栈各容器节点的启动命令如下:

# 启动 Redis 容器
$ sudo docker run -it --name redis-master redis /bin/bash
$ sudo docker run -it --name redis-slave1 --link redis-master:master redis /bin/bash
$ sudo docker run -it --name redis-slave2 --link redis-master:master redis /bin/bash
# 启动 Django 容器,即应用
$ sudo docker run -it --name APP1 --link redis-master:db -v ~/Projects/Django/App1:/usr/src/app django /bin/bash
$ sudo docker run -it --name APP2 --link redis-master:db -v ~/Projects/Django/App2:/usr/src/app django /bin/bash
# 启动 HAProxy 容器
$ sudo docker run -it --name HAProxy --link APP1:APP1 --link APP2:APP2 -p 6301:6301 -v ~/Projects/HAProxy:/tmp haproxy /bin/bash

以上容器启动时,为了方便后续与容器进行交互操作,统一设定启动命令为 /bin/bash,请在启动每个新的容器时都分配一个终端执行。

启动的容器信息可以通过 docker ps 命令查看,示例如下:

$ sudo docker ps
CONTAINER ID    IMAGE             COMMAND                CREATED      STATUS          PORTS                   NAMES   
bcoa13093fd1    haproxy:latest    "/bin/bash"            5 days ago   Up 21 seconds   0.0.0.0:6301->6301/tcp  HAProxy
f92e170d7c3f    django:latest     "/bin/bash"            5 days ago   Up 27 seconds                           APP2
a1705c6e06a8    django:latest     "/bin/bash"            5 days ago   Up 34 seconds                           APP1
7age537b661b    redis:latest      "/entrypoint.sh /bin"  5 days ago   Up 46 seconds   6379/tcp                redis-slave2
08df6a2cb468    redis:latest      "/entrypoint.sh /bin"  5 days ago   Up 57 minutes   6379/tcp                redis-slave1
bc8e79b3e66c    redis:latest      "/entrypoint.sh /bin"  5 days ago   Up 58 minutes   6379/tcp                redis-master

至此,所有搭建应用栈所需容器的启动工作已经完成。

2.4 应用栈容器节点的配置

在应用栈的各容器节点都启动后,需要对它们进行配置和修改,以便实现特定的功能和通信协作,下面按照容器的启动顺序依次进行解释。

2.4.1 Redis Master 主数据库容器节点的配置

Redis Master 主数据库容器节点启动后,我们需要在容器中添加 Redis 的启动配置文件,以启动 Redis 数据库。

需要说明的是,对于需要在容器中创建文件的情况,由于容器的轻量化设计,其中缺乏相应的文本编辑命令工具,这时可以利用 volume 来实现文件的创建。在容器启动时,利用 -v 参数挂载 volume,在主机和容器间共享数据,这样就可以直接在主机上创建和编辑相关文件,省去了在容器中安装各类编辑工具的麻烦。

在利用 Redis 镜像启动容器时,镜像中已经集成了 volume 的挂载命令,所以我们需要通过 docker inspect 命令来查看所挂载 volume 的情况。打开一个新的终端,执行如下命令:

$ sudo docker inspect --format "{{ .Volumes }}" bc8e
map[/data:/var/lib/docker/vfs/dir/f01cd2d7cecba683e74def4ae9c3c6bf5952a8cfafddbe19136d916154afee34]

可以发现,该 volume 在主机中的目录为 /var/lib/docker/vfs/dir/fo1cd2d7cecba683e74def4ae9c3c6bf5952a8cfafddbe19136d916154afee34,在容器中的目录为 /data。此时,可以进入主机的 volume 目录,利用启动配置文件模板来创建我们的主数据库的启动配置文件,执行命令如下:

# cd /var/lib/docker/vfs/dir/f01cd2d7cecba683e74def4ae9c3c6bf5952a8cfafddbe19136d916154afee34
# cp <your-own-redis-dir>/redis.conf redis.conf
# vim redis.conf

其中,<your-own-redis-dir> 可以是本机上任意与 redis 镜像内 redis 版本兼容的 redis 目录,下同。对于 Redis 的主数据库,需要修改模板文件中的如下几个参数:

daemonize yes
pidfile /var/run/redis.pid

在主机创建好启动配置文件后,切换到容器中的 volume 目录,并复制启动配置文件到 Redis 的执行工作目录,然后启动 Redis 服务器,执行过程如下:

# cd /data
# cp redis.conf /usr/local/bin
# cd /usr/local/bin
# redis-server redis.conf

以上就是配置 Redis Master 容器节点的全部过程,在完成配置另外两个 Redis Slave 节点后,再对应用栈的数据库部分进行整体测试。

2.4.2 Redis Slave 从数据库容器节点的配置

与 Redis Master 容器节点类似,在启动 Redis Slave 容器节点后,需要首先查看 volume 信息。

$ sudo docker inspect --format "{{ .Volumes }}" 08df
map[/data:/var/lib/docker/vfs/dir/f74cebbbod5ceea04e6f47a4750053d9f3a013938abc959d019609c4085cbf4e]
# cd /var/lib/docker/vfs/dir/f74cebbbod5ceea04e6f47a4750053d9f3a013938abc959d019609c4085cbf4e
# cp <your-own-redis-dir>/redis.conf redis.conf
# vim redis.conf

对于 Redis 的从数据库,需要修改如下几个参数:

daemonize yes
pidfile /var/run/redis.pid
slaveof master 6379

需要注意的是,slaveof 参数的使用格式为 slaveof <masterip> <masterport>,可以看到对于 masterip 使用了 --link 参数设置的连接名来代替实际 IP 地址。通过连接名互连通信时,容器会自动读取它的 host 信息,将连接名转换为实际 IP 地址。

在主机创建好启动配置文件后,切换到容器中的 volume 目录,并复制启动配置文件到 Redis 的执行工作目录,然后启动 Redis 服务器,执行过程如下:

# cd /data
# cp redis.conf /usr/local/bin
# cd /usr/local/bin
# redis-server redis.conf

同理,可以完成对另一个 Redis Slave 容器节点的配置。至此,便完成了所有 Redis 数据库容器节点的配置。

2.4.3 Redis 数据库容器节点的测试

完成 Redis Master 和 Redis Slave 容器节点的配置以及服务器的启动后,可以通过启动 Redis 的客户端程序来测试数据库。

首先,在 Redis Master 容器内,启动 Redis 的客户端程序,并存储一个数据,执行过程如下:

# redis-cli
127.0.0.1:6379> set master bc8e
OK
127.0.0.1:6379> get master
"bc8e"

随后,在两个 Redis Slave 容器内,分别启动 Redis 的客户端程序,查询先前在 Master 数据库中存储的数据,执行过程如下:

# redis-cli
127.0.0.1:6379> get master
"bc8e"

由此可以看到,Master 数据库中的数据已经自动同步到了 Slave 数据库中。至此,应用栈的数据库部分已搭建完成,并通过测试。

2.4.4 APP 容器节点(Django)的配置

Django 容器启动后,需要利用 Django 框架,开发一个简单的 Web 程序。为了访问数据库,需要在容器中安装 Python 语言的 Redis 支持包,执行如下命令:

# pip install redis

安装完成后,进行简单的测试来验证支持包是否安装成功,执行过程如下:

# python
>>> import redis
>>> print(redis._file__)
/usr/local/lib/python3.4/site-packages/redis/__init__.py

如果没有报错,说明已经可以使用 Python 语言来调用 Redis 数据库。接下来,就开始创建 Web 程序。以 APP1 为例,在容器启动时,挂载了 -v ~/Projects/Django/App1:/usr/src/appvolume,方便进入主机的 volume 目录来对新建 APP 进行编辑。

在容器的 volume 目录 /usr/src/app/ 下,开始创建 APP,执行过程如下:

# 在容器内
# cd /usr/src/app/
# mkdir dockerweb
# cd dockerweb/
# django-admin.py startproject redisweb
# ls
redisweb
# cd redisweb/
# ls
manage.py redisweb
# python manage.py startapp helloworld
# ls
helloworld manage.py redisweb

在容器内创建 APP 后,切换到主机的 volume 目录 ~/Projects/Django/App1,进行相应的编辑来配置 APP,执行过程如下:

# 在主机内
$ cd ~/Projects/Django/App1
$ ls
dockerweb

可以看到,在容器内创建的 APP 文件在主机的 volume 目录下同样可见。之后,我们来修改 helloworld 应用的视图文件 views.py

$ cd dockerweb/redisweb/helloworld/
$ ls
admin.py __init__.py migrations models.py tests.py views.py
# 利用 root 权限修改 views.py
$ sudo su
# vim views.py

为了简化设计,只要求完成 Redis 数据库信息输出,以及从 Redis 数据库存储和读取数据的结果输出。views.py 文件如下:

from django.shortcuts import render
from django.http import HttpResponse

# 创建你自己的 view
import redis

def hello(request):
	str = redis.__file__
	str += "<br>"
	r = redis.Redis(host='db', port=6379, db=0)
	info = r.info()
	str += ("Set Hi <br>")
	r.set('Hi','Helloworld-APP1')
	str += ("Get Hi: %s <br>" % r.get('Hi'))
	str += ("Redis Info: <br>")
	str += ("Key: Info Value")
	for key in info:
		str += ("%s: %s <br>" % (key, info[key]))
	return HttpResponse(str)

需要注意的是,连接 Redis 数据库时,使用了 --link 参数创建 db 连接来代替具体的 IP 地址;同理,对于 APP2,使用相应的 db 连接即可。完成 views.py 文件修改后,接下来修改 redisweb 项目的配置文件 setting.py,添加新建的 helloworld 应用,执行过程如下:

# cd ../redisweb/
# ls
_init__.py __pycache__ settings.py urls.py wsgi.py
# vim setting.py

setting.py 文件中的 INSTALLED_APPS 选项下添加 helloworld,执行过程如下:

# Application definition
INSTALLED_APPS = (
	'django.contrib.admin',
	'django.contrib.auth',
	'django.contrib.contenttypes',
	'django.contrib.sessions',
	'django.contrib.messages',
	'django.contrib.staticfiles',
	'helloworld',
)

最后,修改 redisweb 项目的 URI 模式文件 urls.py,它将设置访问应用的 URL 模式,并为 URL 模式调用视图函数之间的映射表。执行如下命令:

# vim urls.py

urls.py 文件中,引人 helloworld 应用的 hello 视图,并为 hello 视图添加一个 urlpatterns 变量。urls.py 文件内容如下:

from django.conf.urls import patterns, include, url
from django.contrib import admin
from helloworld.views import hello

urlpatterns = patterns('',
	url(r'admin/', include(admin.site.urls)),
	url(r'helloworld$',hello),
)

在主机下修改完成这几个文件后,需要再次进入容器,在目录 /usr/src/app/dockerweb/redisweb 下完成项目的生成。执行过程如下:

# python manage.py makemigrations
No changes detected
# python manage.py migrate
Operations to perform:
	Apply all migrations: sessions, contenttypes, admin, auth
Running migrations:
	Applying contenttypes.0001_initial... OK
	Applying auth.0001_initial... OK
	Applying admin.0001_initial... OK
	Applying sessions.0001_initial... OK
# python manage.py syncdb
Operations to perform:
	Apply all migrations: admin, auth, sessions, contenttypes
Running migrations:
	No migrations to apply.

You have installed Django's auth system, and don't have any superusers defined.
Would you like to create one now? (yes/no): yes
Username (leave blank to use 'root'): admin
Email address: sel@sel.com
Password:
Password (again):
Superuser created successfully.

至此,所有 APP1 容器的配置已经完成,另一个 APP2 容器配置也是同样的过程,只需要稍作修改即可。配置完成 APP1 和 APP2 容器后,就完成了应用栈的 APP 部分的全部配置。

在启动 APP 的 Web 服务器时,可以指定服务器的端口和 IP 地址。为了通过 HAProxy 容器节点接受外网所有的公共 IP 地址访问,实现均衡负载,需要指定服务器的 IP 地址和端口。对于 APP1 使用 8001 端口,而 APP2 则使用 8002 端口,同时,都使用 0.0.0.0 地址。以 APP1 为例,启动服务器的过程如下:

# python manage.py runserver 0.0.0.0:8001
Performing system checks...
System check identified no issues (0 silenced).
January 20, 2015 - 13:13:37
Django version 1.7.2, using settings 'redisweb.settings'
Starting development server at http://0.0.0.0:8001/
Quit the server with CONTROL-C.

2.4.5 HAProxy 容器节点的配置

在完成数据库和 APP 部分的应用栈部署后,最后部署一个 HAProxy 负载均衡代理的容器节点,所有对应用栈的访问将通过它来实现负载均衡。

首先,利用容器启动时挂载的 volume 将 HAProxy 的启动配置文件复制进容器中,在主机的 volume 目录 ~/Projects/HAProxy 下,执行过程如下:

$ cd ~/Projects/HAProxy
$ vim haproxy.cfg

其中,haproxy.cfg 配置文件的内容如下:

global
	log 127.0.0.1 local0                     # 日志输出配置,所有日志都记录在本机,通过 local0 输出
	maxconn 4096	                         # 最大连接数
	chroot /usr/local/sbin	                 # 改变当前工作目录
	daemon	                                 # 以后台形式运行 HAProXy
	nbproc 4	                             # 启动 4 个 HAProxy 实例
	pidfile /usr/local/sbin/haproxy.pid	     # pid 文件位置

defaults
	log 127.0.0.1 local3	        # 日志文件的输出定向
	mode http	                    # {tcp|http|health} 设定启动实例的协议类型
	option dontlognull	            # 保证 HAProXy 不记录上级负载均衡发送过来的用于检测状态没有数据的心跳包
	option redispatch	            # 当 serverId 对应的服务器挂掉后,强制定向到其他健康的服务器
	retries 2	                    # 重试两次连接失败就认为服务器不可用,主要通过后面的 check 检查
	maxconn 2000	                # 最大连接数
	balance roundrobin	            # balance 有两个可用选项:roundrobin 和 source,其中,roundrobin 表示
									# 轮询,而 source 表示 HAProxy 不采用轮询的策略,而是把来自某个 IP 的请求转
									# 发给一个固定 IP 的后端
	timeout connect 5000ms	        # 连接超时时间
	timeout client 50000ms	        # 客户端连接超时时间
	timeout server 50000ms	        # 服务器端连接超时时间

listen redis_proxy 0.0.0.0:6301
	stats enable
	stats uri /haproxy-stats
		server APP1 APP1:8001 check inter 2000 rise 2 fall 5	#你的均衡节点
		server APP2 APP2:8002 check inter 2000 rise 2 fall 5

随后,进入到容器的 volume 目录 /tmp 下,将 HAProxy 的启动配置文件复制到 HAProxy 的工作目录中。执行过程如下:

# cd /tmp
# cp haproxy.cfg /usr/local/sbin/
# cd /usr/local/sbin/
# ls
haproxy haproxy-systemd-wrapper haproxy.cfg
接下来利用该配置文件来启动 HAProxy 代理,执行如下命令:
# haproxy -f haproxy.cfg

需要注意的是,如果修改了配置文件的内容,需要先结束所有的 HAProxy 进程,并重新启动代理。可以使用 killall 命令来结束进程,如果镜像中没有安装该命令,则需要先安装 psmisc 包,执行如下命令:

# apt-get install psmisc
# killall haproxy

至此,完成了 HAProxy 容器节点的全部部署,同时也完成了整个 Docker 应用栈的部署。

2.4.6 应用栈访问测试

整个应用栈部署完成后,就可以进行访问测试。参考应用栈搭建时的结构图可知,整个应用栈群的访问是通过 HAProxy 代理节点来进行的。在 HAProxy 容器节点启动时,通过 -p 6301:6301 参数,映射了容器访问的端口到主机上,因此可以在其他主机上,通过本地主机的 IP 地址和端口来访问搭建好的应用栈。

在应用栈启动后,先在本地主机上进行测试。在浏览器中访问 http:/172.17.0.9:6301/helloworld 可以查看 APP1 或 APP2 的页面内容,如下图所示,具体访问到的 APP 容器节点会由 HAProxy 代理进行均衡分配。同时,可以访问 http://172.17.0.9:6301/haproxy-stats 来查看 HAProxy 的后台管理页面。其中,172.17.0.9 为 HAProxy 容器的 IP 地址。

在这里插入图片描述
本地测试通过后,尝试在其他主机上通过应用栈入口主机的 IP 地址和暴露的 6301 端口来访问该应用栈的 APP,即访问http:/10.10.105.87:6301/helloworld,如下图所示。其中,10.10.105.87 为宿主机的IP地址。

在这里插入图片描述

3.开发、测试和发布一体化

从 Docker 集群的搭建过程不难看出,通过 Docker 提供的虚拟化方式,可以快速建立起一套可复用的开发环境,以镜像的形式将开发环境分发给所有开发成员,达到了简化开发环境搭建过程的目的。Docker 的优点在于可以简化 CI(持续集成)和 CD(持续交付)的构建流程,让开发者集中精力在应用开发上,同时运维和测试也可以并行进行,并保持整个开发、测试、发布和运维的一体化。

Docker 以镜像和在镜像基础上构建的容器为基础,以容器为开发、测试和发布的单元,将与应用相关的所有组件和环境进行封装,避免了应用在不同平台间迁移时所带来的依赖性问题,确保了应用在生产环境的各阶段达到高度一致的实际效果。

在开发阶段,镜像的使用使得构建开发环境变得简单和统一。随着 Docker 的发展,镜像资源也日益丰富,开发人员可以轻易地找到适合的镜像加以利用。同时,利用 Dockerfile 也可以将一切可代码化的东西进行自动化运行。Docker 最佳实践是将应用分割成大量彼此松散耦合的 Docker 容器,应用的不同组件在不同的容器中同步开发,互不影响,为实现持续集成和持续交付提供了先天的便利。

在测试阶段,可以直接使用开发所构建的镜像进行测试,直接免除了测试环境构建的烦恼,也消除了因为环境不一致所带来的漏洞问题。

在部署和运维阶段,与以往代码级别的部署不同,利用 Docker 可以进行容器级别的部署,把应用及其依赖环境打包成跨平台、轻量级、可移植的容器来进行部署。

Docker 已经逐渐发展成为一个构建、发布、运行分布式应用的开放平台,以轻量级容器为核心建立起了一套完整的生态系统,它重新定义了应用开发、测试、交付和部署的过程。在当前云计算飞速发展的背景下,Docker 将引领着云时代进入一个崭新的发展阶段。

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

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

相关文章

sql server查询结果:行转列、XML形式

1.普通查询 SELECT M.name From Menu M INNER JOIN MenuRoleRelation MRR ON M.idmrr.MenuId AND MRR.RoleId1; 结果&#xff1a; 2.做xml字符串返回 最后面加上&#xff1a;FOR XML PATH() 结果&#xff1a; 3.可以改为逗号分隔 SELECT ,M.name From Menu M INNER JOIN Me…

深度学习——深度学习计算一

深度学习——深度学习计算一 文章目录 前言一、层和块1.1. 自定义块1.2. 顺序块1.3. 在前向传播函数中执行代码1.4. 小结 二、参数管理2.1. 参数访问2.1.1. 目标参数2.1.2. 一次性访问所有参数2.1.3. 从嵌套块收集参数 2.2. 参数初始化2.2.1. 内置初始化2.2.2. 自定义初始化 2.…

常用Redis界面化软件

对于Redis的操作&#xff0c;前期有过介绍【Centos 下安装 Redis 及命令行操作】。而在Redis的日常开发调试中&#xff0c;可使用可视化软件方便进行操作。 本篇主要介绍Redis可视化的两款工具&#xff1a;Redis Desktop Manager和AnotherRedisDesktopManager。 1、Redis Desk…

unity 控制玩家物体

创建场景 放上一个plane&#xff0c;放上一个球 sphere&#xff0c;假定我们的球就是我们的玩家&#xff0c;使用控制键w a s d 来控制球也就是玩家移动。增加一个材质&#xff0c;把颜色改成绿色&#xff0c;把材质赋给plane&#xff0c;区分我们增加的白球。 增加组件和脚…

POJ 2104 K-th Number 平方分割 / 线段树

一、题目大意 长度为n&#xff08;n<100000&#xff09;的数组&#xff0c;进行m次查询&#xff08;m<5000&#xff09;&#xff0c;每次查询时&#xff0c;输入为 i j k&#xff0c;返回为数组 [i,j] 的分片里第k大数字&#xff08;1<i<j<n,k<j-i1) 二、解…

轻松实现视频、音频、文案批量合并,享受批量剪辑的便捷

在日常生活中&#xff0c;我们经常会需要将多个视频、音频和文案进行合并剪辑&#xff0c;以制作出符合我们需求的短视频。然而&#xff0c;这个过程通常需要花费大量的时间和精力。幸运的是&#xff0c;现在有一款名为“固乔智剪软件”的工具可以帮助我们轻松完成这个任务。 首…

mac怎么卸载软件没有叉的那种,别慌看这里

ac电脑对于很多人来说是一个高效、优雅的工作工具&#xff0c;但就像所有电子设备一样&#xff0c;有时候也需要进行软件的添加和删除以保持其最佳性能。然而&#xff0c;对于一些特殊类型的软件—也就是那些没有"叉"标志来直接卸载的—如何正确地从Mac上删除它们呢&…

RK3568笔记一:RKNN开发环境搭建

若该文为原创文章&#xff0c;转载请注明原文出处。 由于对AI的好奇&#xff0c;想要学习如何部署AI&#xff0c;所以从RV1126到RK3568中过渡。 一、介绍 RK3568开发板使用的是正点原子新出的ATK-DLRK3568 开发板&#xff0c;主要是学习从训练到部署的全过程&#xff0c;并记…

One Thread One Loop主从Reactor模型⾼并发服务器

One Thread One Loop主从Reactor模型⾼并发服务器 文章目录 One Thread One Loop主从Reactor模型⾼并发服务器一些补充HTTP服务器Reactor 模型eventfd通用类Any 目标功能模块划分&#xff1a;SERVER模块Buffer模块&#xff1a;编写思路&#xff1a;接口设计&#xff1a;具体实现…

Go Gin Gorm Casbin权限管理实现 - 3. 实现Gin鉴权中间件

文章目录 0. 背景1. 准备工作2. gin中间件2.1 中间件代码2.2 中间件使用2.3 测试中间件使用结果 3. 添加权限管理API3.1 获取所有用户3.2 获取所有角色组3.3 获取所有角色组的策略3.4 修改角色组策略3.5 删除角色组策略3.6 添加用户到组3.7 从组中删除用户3.8 测试API 4. 最终目…

FreeRTOS入门教程(队列的概念及相关函数介绍)

文章目录 前言一、队列概念二、队列的使用方法1.创建队列动态创建静态创建 2.复位队列3.删除队列4.写队列5.读队列6.查询队列7.覆盖/查看覆盖查看 总结 前言 本篇文章将带大家学习FreeRTOS中的队列&#xff0c;掌握什么是队列&#xff0c;并且学习如何使用队列&#xff0c;在什…

集成学习

集成学习&#xff08;Ensemble Learning) - 知乎 (zhihu.com)https://zhuanlan.zhihu.com/p/27689464集成学习就是组合这里的多个弱监督模型以期得到一个更好更全面的强监督模型&#xff0c;集成学习潜在的思想是即便某一个弱分类器得到了错误的预测&#xff0c;其他的弱分类器…

Pytorch基础:Tensor的permute方法

相关阅读 Pytorch基础https://blog.csdn.net/weixin_45791458/category_12457644.html 在Pytorch中&#xff0c;permute是Tensor的一个重要方法&#xff0c;同时它也是一个torch模块中的一个函数&#xff0c;它们的语法如下所示。 Tensor.permute(*dims) → Tensor torch.perm…

PbootCMS SQL注入漏洞

漏洞复现 访问漏洞url 数据库是mysql 构造payload&#xff0c;条件为假时&#xff0c;未查到任何数据 http://x.x.x/index.php?search 1select 0页面回显 构造payload&#xff0c;条件为真时&#xff0c;查询到数据 1select1文笔生疏&#xff0c;措辞浅薄&#xff0c;望各…

邮箱注册实现(二)注册接口实现

如果邮箱地址错误或非法&#xff0c;运行时会报错。因此需要增加校验&#xff1a; Validated RestController RequestMapping("/api/auth") public class AuthorizeController {ResourceAccountService service;GetMapping("/ask-code")public RestBean&l…

typescript 类型声明文件

typescript 类型声明文件概述 在今天几乎所有的JavaScript应用都会引入许多第三方库来完成任务需求。这些第三方库不管是否是用TS编写的&#xff0c;最终都要编译成JS代码&#xff0c;才能发布给开发者使用。6我们知道是TS提供了类型&#xff0c;才有了代码提示和类型保护等机…

R实现数据分布特征的视觉化——多笔数据之间的比较

大家好&#xff0c;我是带我去滑雪&#xff01; 如果要对两笔数据或者多笔数据的分布情况进行比较&#xff0c;Q-Q图、柱状图、星形图都是非常好的选择&#xff0c;下面开始实战。 &#xff08;1&#xff09;绘制Q-Q图 首先导入数据bankwage.csv文件&#xff0c;该数据集…

[MIT6.824] Lab 3: Fault-tolerant Key/Value Service

[MIT6.824] Lab 3: Fault-tolerant Key/Value Service 目标 通过在Lab2中实现的Raft库&#xff0c;构建一个可容灾的KV数据库。 需要实现的服务有三种操作: Put(key, value) key和value都是string&#xff0c;put设置指定key的value. Append(key, arg) 将arg append到key对…

『Linux』Linux环境搭建 | 阿里云云服务器白嫖 | Xshell环境配置

&#x1f525;博客主页&#xff1a; 小羊失眠啦 &#x1f516;系列专栏&#xff1a; C语言、Linux &#x1f325;️每日语录&#xff1a;时间&#xff0c;都是公平的&#xff0c;不公平的&#xff0c;只是现在的自己&#xff0c;对未来的自己。 ❤️感谢大家点赞&#x1f44d;收…

大华城市安防系统平台任意文件下载漏洞

一、漏洞描述 大华城市安防监控系统平台是一款集视频、报警、存储、管理于一体的综合安防解决方案。该平台支持多种接入方式&#xff0c;包括网络视频、模拟视频、数字视频、IP电话、对讲机等。此外&#xff0c;该平台还支持多种报警方式&#xff0c;包括移动侦测、区域入侵、…