Docker Compose介绍

Docker Compose是一个定义和运行多容器应用的单机编排工具。通过Docker Compose你可以使用一个单一的YAML文件来配置多个应用服务,通过一条命令,就可以将所有配置的服务全部启动起来。

使用Docker Compose的三个步骤:

  • 使用Dockerfile定义环境,这样可以确保其在任意地方运行

  • 使用docker-compose.yml文件定义服务,这样它们就可以在独立环境中一起运行

  • 运行docker-compose up使用docker-compose启动所有应用

Docker Compose可以管理应用的整个生命周期:

  • 启动、停止、重建服务

  • 查看服务的运行状态

  • 流式输出服务日志

  • 对服务执行一次性命令

Docker Compose安装

二进制安装:

下载地址:https://github.com/docker/compose/releases

pip安装:

pip install docker-compose

Docker Compose基本示例

1、基本文件及目录设置

  1. 创建一个目录:
mkdir composetest
cd composetest
  1. 在上面的目录中创建一个app.py文件,内容如下:
import time

import redis
from flask import Flask app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379) def get_hit_count():
retries = 5
while True:
try:
return cache.incr('hits')
except redis.exceptions.ConnectionError as exc:
if retries == 0:
raise exc
retries -= 1
time.sleep(0.5) @app.route('/')
def hello():
count = get_hit_count()
return 'Hello World! I have been seen {} times.\n'.format(count) if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True)
  1. 再创建一个pip.conf文件,内容如下:
[global]
index-url = https://mirrors.aliyun.com/pypi/simple/ [install]
trusted-host=mirrors.aliyun.com

2、创建一个Dockerfile

仍然在composetest目录中创建一个Dockerfile,内容如下:

FROM python:3.4-alpine
ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt
CMD ["python", "app.py"]

3、通过docker-compose.yml定义服务

docker-compose.yml内容如下:

version: '3'
services:
web:
build: .
ports:
- "5000:5000"
redis:
image: "redis:alpine"

这个文件定义了两个服务:web和redis。

  • web服务使用当前目录的Dockerfile进行构建,并且映射web服务的5000端口到宿主机5000端口。
  • redis服务使用一个公共的redis镜像。

4、通过Docker Compose构建并启动服务

docker-compose up

这个时候可以通过http://127.0.0.1:5000来访问这个web服务。

5、 修改Compse文件,添加一个挂载点

修改docker-compose.yml,内容如下:

version: '3'
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
redis:
image: "redis:alpine"

添加了一个volumes配置项,将当前目录挂载至web容器的/code目录下。

然后我们通过docker-compose up重新构建应用,再次访问,会发现结果与上面完全相同。

7、 更新应用

我们修改本地的app.py,修改Hello World!Hello from Dokcer,如下:

return 'Hello from Docker! I have been seen {} times.\n'.format(count)

这个时候再次访问http://127.0.0.1:5000,发现访问内容也随之修改。

这是因为在上面我们将本地目录挂载进了容器,我们修改本地的app.py就相当于修改了容器内的文件。

Docker Compose常用命令说明

在上面的一个简单示例中,我们已经使用了docker-compose up来启动一个docker-compose.yml文件定义的服务。我们刚刚通过docker-compose up虽然启动了服务,当是docker-compose指令却在前台执行,如果需要将其放入后台运行,可以使用-d参数:

docker-compose up -d

docker-compose up还可以使用--scale参数实现服务的扩缩容:

[root@app composetest]# docker-compose up -d --scale web=2
Recreating composetest_web_1 ...
Recreating composetest_web_1 ... done
Creating composetest_web_2 ... done

还可以通过-f选项指定compose文件:

[root@app tranning]# docker-compose -f test-compose.yml up -d
Creating network "tranning_default" with the default driver
Creating network "tranning_frontend" with the default driver
Creating network "tranning_backend" with the default driver
Creating tranning_visualizer_1 ... done
Creating tranning_redis_1 ... done
Creating tranning_worker_1 ... done
Creating tranning_db_1 ... done
Creating tranning_result_1 ... done
Creating tranning_vote_1 ... done

需要说明的是,如果使用自动扩容,则web服务不能做端口映射,否则会出现端口冲突的情况

下面我们说一说其他常用的docker-compose命令:

  1. docker-compose ps
[root@app composetest]# docker-compose ps
Name Command State Ports
-------------------------------------------------------------------------------------
composetest_redis_1 docker-entrypoint.sh redis ... Up 6379/tcp
composetest_web_1 python app.py
  1. docker-compose stop
[root@app composetest]# docker-compose stop
Stopping composetest_redis_1 ... done
Stopping composetest_web_1 ... done [root@app composetest]# docker-compose stop web
Stopping composetest_web_1 ... done
  1. docker-compose start
[root@app composetest]# docker-compose start
Starting web ... done
Starting redis ... done [root@app composetest]# docker-compose start web
Starting web ... done
  1. docker-compose restart
[root@app composetest]# docker-compose restart
Restarting composetest_web_1 ... done
Restarting composetest_redis_1 ... done
  1. docker-compose run [command]
[root@app composetest]# docker-compose run web env
PATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=72ad8a0682b7
TERM=xterm
LANG=C.UTF-8
GPG_KEY=97FC712E4C024BBEA48A61ED3A5CA953F73C700D
PYTHON_VERSION=3.4.9
PYTHON_PIP_VERSION=18.0
HOME=/root
  1. docker-compose down
[root@app composetest]# docker-compose down
Stopping composetest_redis_1 ... done
Stopping composetest_web_1 ... done
Removing composetest_redis_1 ... done
Removing composetest_web_1 ... done
Removing network composetest_default

通过--volumes还要以删除自动挂载的容器卷

  1. docker-compose build

默认情况下,我们写好了Dockerfile,第一次通过docker-compose启动的时候,会自动完成构建,但如果随后Dockerfile发生了改动,再次通过docker-compose来启动实现更新的话,docker-compose不会再次自动构建镜像,而是复用第一次生成的镜像,如果希望镜像能够被重新构建,需要单独执行docker-compose build

  1. docker-compose top
[root@app composetest]# docker-compose top
composetest_redis_1
UID PID PPID C STIME TTY TIME CMD
---------------------------------------------------------------
100 89653 89634 0 23:26 ? 00:00:00 redis-server composetest_web_1
UID PID PPID C STIME TTY TIME CMD
--------------------------------------------------------------------------------
root 89635 89619 0 23:26 ? 00:00:00 python app.py
root 89742 89635 0 23:26 ? 00:00:00 /usr/local/bin/python app.py
  1. 其它
docker-compose rm       # 通过这种方式也能删除指定服务,但不会删除网络和volumes
docker-compose kill # 强制杀死一个服务
docker-compose logs # 用于查看日志

Docker Compose文件详解

通过之前的示例,其实我们可以看到,所有服务的管理,都是依靠docker-compose.yml文件来实现的。那么我们接下来就详细说一说docker-compose.yml文件中的常用指令。

compose文件使用yml格式,docker规定了一些指令,使用它们可以去设置对应的东西,主要分为了四个区域:

  • version:用于指定当前docker-compose.yml语法遵循哪个版本
  • services:服务,在它下面可以定义应用需要的一些服务,每个服务都有自己的名字、使用的镜像、挂载的数据卷、所属的网络、依赖哪些其他服务等等。
  • networks:应用的网络,在它下面可以定义应用的名字、使用的网络类型等。
  • volumes:数据卷,在它下面可以定义数据卷,然后挂载到不同的服务下去使用。

version

用于指定当前compose文件语法遵循哪个版本,下面这张表是不同的Compose文件版本兼容的Docker版本:

services

我们上面所说的所有服务的定义都是定义在services区域中,接下来,我们学习下services下常用的配置项

image

标明image的ID,这个image ID可以是本地也可以是远程的,如果本地不存在,compose会尝试pull下来

示例:

image: ubuntu
image: hub.dz11.com/library/tomcat:8

build

该参数指定Dockerfile文件的路径,compose会通过Dockerfile构建并生成镜像,然后使用该镜像

示例:

build: /path/to/build/dir

command

重写默认的命令,或者说指定启动容器的命令

示例:

command: "/run.sh"

links

链接到其他服务中的容器,可以指定服务名称和这个链接的别名,或者只指定服务名称

示例:

links:
- db
- db:database
- redis

此时,在容器内部,会在/etc/hosts文件中用别名创建几个条目,如下:

172.17.2.100 db
172.17.2.100 database
172.17.2.100 redis

external_links

链接到compose外部启动的容器,特别是对于提供共享和公共服务的容器。在指定容器名称和别名时,external_links遵循着和links相同的语义用法

示例:

external_links:
- redis_1
- project_db_1: mysql
- project_db_2: postgresql

ports

暴露端口,指定宿主机到容器的端口映射,或者只指定容器的端口,则表示映射到主机上的随机端口

注:当以 主机:容器 的形式来映射端口时,如果使容器的端口小于60,那可能会出现错误,因为YAML会将 xx:yy这样格式的数据解析为六十进制的数据,基于这个原因,时刻记得要将端口映射明确指定为字符串

示例:

ports:
- "3000"
- "8000:8000"
- "49100:22"
- "127.0.0.1:8001:8001"

expose

暴露端口,但不需要建立与宿主机的映射,只是会向链接的服务提供

示例:

expose:
- "3000"
- "8000"

environment

加入环境变量,可以使用数组或者字典,只有一个key的环境变量可以在运行compose的机器上找到对应的值

示例:

environment:
RACK_ENV: development
SESSION_SECRET: environment:
- RACK_ENV: development
- SESSION_SECRET:

env_file

从一个文件中引入环境变量,该文件可以是一个单独的值或者一个列表,如果同时定义了environment,则environment中的环境变量会重写这些值

示例:

env_file:
- env
cat env
RACK_ENV: development

depends_on

定义当前服务启动时,依赖的服务,当前服务会在依赖的服务启动后启动

depends_on:
- redis

deploy

该配置项在version 3里才引入,用于指定服务部署和运行时相关的参数

version: '3'
services:
redis:
image: redis:alpine
deploy:
replicas: 6
update_config:
parallelism: 2
delay: 10s
restart_policy:
condition: on-failure

下面是deploy中常用参数的说明

replicas

指定副本数:

version: '3'
services:
worker:
image: dockersamples/examplevotingapp_worker
deploy:
replicas: 6

restart_policy

指定重启策略:

version: "3"
services:
redis:
image: redis:alpine
deploy:
restart_policy:
condition: on-failure #重启条件:on-failure, none, any
delay: 5s # 等待多长时间尝试重启
max_attempts: 3 #尝试的次数
window: 120s # 在决定重启是否成功之前等待多长时间

update_config

定义更新服务的方式,常用于滚动更新

version: '3.4'
services:
vote:
image: dockersamples/examplevotingapp_vote:before
depends_on:
- redis
deploy:
replicas: 2
update_config:
parallelism: 2 # 一次更新2个容器
delay: 10s # 开始下一组更新之前,等待的时间
failure_action:pause # 如果更新失败,执行的动作:continue, rollback, pause,默认为pause
max_failure_ratio: 20 # 在更新过程中容忍的失败率
order: stop-first # 更新时的操作顺序,停止优先(stop-first,先停止旧容器,再启动新容器)还是开始优先(start-first,先启动新容器,再停止旧容器),默认为停止优先,从version 3.4才引入该配置项

resources

限制服务资源:

version: '3'
services:
redis:
image: redis:alpine
deploy:
resources:
limits:
cpus: '0.50'
memory: 50M
reservations:
cpus: '0.25'
memory: 20M

healthcheck

执行健康检查

healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"] # 用于健康检查的指令
interval: 1m30s # 间隔时间
timeout: 10s # 超时时间
retries: 3 # 重试次数
start_period: 40s # 启动多久后开始检查

network_mode

网络类型,可指定容器运行的网络类型

示例:

network_mode: "bridge"
network_mode: "host"
network_mode: "none"

dns

自定义dns服务

示例:

dns: 8.8.8

dns:
- 223.5.5.5
- 223.6.6.6

networks

网络决定了服务之间以及服务和外界之间如何去通信,在执行docker-compose up的时候,docker会默认创建一个默认网络,创建的服务也会默认的使用这个默认网络。服务和服务之间,可以使用服务的名字进行通信,也可以自己创建网络,并将服务加入到这个网络之中,这样服务之间可以相互通信,而外界不能够与这个网络中的服务通信,可以保持隔离性。

在networks中定义一个名为app_net,类型为driver的网络:

version: '2'

services:
app:
image: busybox
command: ifconfig
networks:
app_net:
ipv4_address: 172.16.238.10 networks:
app_net:
driver: bridge
enable_ipv6: true
ipam:
driver: default
config:
- subnet: 172.16.238.0/24
gateway: 172.168.238.254

volumes

version: "3.2"
services:
web:
image: nginx:alpine
volumes:
- type: volume
source: mydata
target: /data
volume:
nocopy: true
- type: bind
source: ./static
target: /opt/app/static db:
image: postgres:latest
volumes:
- "/var/run/postgres/postgres.sock:/var/run/postgres/postgres.sock"
- "dbdata:/var/lib/postgresql/data" volumes:
mydata:
dbdata:

Docker Compose案例实践

部署一个web集群

项目说明

这是一个典型的web项目,由一个haproxy容器加三个web容器组成。haproxy在前端充当负载均衡器,反向代理到后台三个服务服务。

基本目录结构

首先创建一个compose-haproxy-web的目录,然后在目录里面,创建两个子目录:haproxy和web。

在web目录里包含三个文件: Dockerfile、index.py、index.html

在haproxy目录里包含一个文件: haproxy.cfg

目录结构如下:

compose-haproxy-web/
├── docker-compose.yml
├── haproxy
│ └── haproxy.cfg
└── web
├── Dockerfile
├── index.html
└── index.py 2 directories, 5 files

web目录下的index.py提供一个简单的http服务,打印出访问者的ip和实际的本地IP,内容如下:

#!/usr/bin/python
#authors: yeasy.github.com
#date: 2013-07-05
import sys
import BaseHTTPServer
from SimpleHTTPServer import SimpleHTTPRequestHandler
import socket
import fcntl
import struct
import pickle
from datetime import datetime
from collections import OrderedDict class HandlerClass(SimpleHTTPRequestHandler):
def get_ip_address(self,ifname):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
return socket.inet_ntoa(fcntl.ioctl(
s.fileno(),
0x8915, # SIOCGIFADDR
struct.pack('256s', ifname[:15])
)[20:24])
def log_message(self, format, *args):
if len(args) < 3 or "200" not in args[1]:
return
try:
request = pickle.load(open("pickle_data.txt","r"))
except:
request=OrderedDict()
time_now = datetime.now()
ts = time_now.strftime('%Y-%m-%d %H:%M:%S')
server = self.get_ip_address('eth0')
host=self.address_string()
addr_pair = (host,server)
if addr_pair not in request:
request[addr_pair]=[1,ts]
else:
num = request[addr_pair][0]+1
del request[addr_pair]
request[addr_pair]=[num,ts]
file=open("index.html", "w")
file.write("<!DOCTYPE html> <html> <body><center><h1><font color=\"blue\" face=\"Georgia, Arial\" size=8><em>HA</em></font> Webpage Visit Results</h1></center>");
for pair in request:
if pair[0] == host:
guest = "LOCAL: "+pair[0]
else:
guest = pair[0]
if (time_now-datetime.strptime(request[pair][1],'%Y-%m-%d %H:%M:%S')).seconds < 3:
file.write("<p style=\"font-size:150%\" >#"+ str(request[pair][1]) +": <font color=\"red\">"+str(request[pair][0])+ "</font> requests " + "from &lt<font color=\"blue\">"+guest+"</font>&gt to WebServer &lt<font color=\"blue\">"+pair[1]+"</font>&gt</p>")
else:
file.write("<p style=\"font-size:150%\" >#"+ str(request[pair][1]) +": <font color=\"maroon\">"+str(request[pair][0])+ "</font> requests " + "from &lt<font color=\"navy\">"+guest+"</font>&gt to WebServer &lt<font color=\"navy\">"+pair[1]+"</font>&gt</p>")
file.write("</body> </html>");
file.close()
pickle.dump(request,open("pickle_data.txt","w")) if __name__ == '__main__':
try:
ServerClass = BaseHTTPServer.HTTPServer
Protocol = "HTTP/1.0"
addr = len(sys.argv) < 2 and "0.0.0.0" or sys.argv[1]
port = len(sys.argv) < 3 and 80 or int(sys.argv[2])
HandlerClass.protocol_version = Protocol
httpd = ServerClass((addr, port), HandlerClass)
sa = httpd.socket.getsockname()
print "Serving HTTP on", sa[0], "port", sa[1], "..."
httpd.serve_forever()
except:
exit()

web目录下index.html文件是一个空文件,在程序启动之后会用到。

web目录下Dockerfile内容如下:

FROM python:2.7
WORKDIR /code
ADD . /code
EXPOSE 80
CMD python index.py

haproxy目录下的haproxy.cfg内容如下:

global
log 127.0.0.1 local0
log 127.0.0.1 local1 notice defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms listen stats
bind 0.0.0.0:70
stats enable
stats uri / frontend balancer
bind 0.0.0.0:80
mode http
default_backend web_backends backend web_backends
mode http
option forwardfor
balance roundrobin
server weba weba:80 check
server webb webb:80 check
server webc webc:80 check
option httpchk GET /
http-check expect status 200

配置docker-compose

docker-compose.yml内容如下:

version: '3'
services:
weba:
build: ./web
expose:
- 80 webb:
build: ./web
expose:
- 80 webc:
build: ./web
expose:
- 80 haproxy:
image: haproxy:latest
volumes:
- ./haproxy:/haproxy-override
- ./haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
links:
- weba
- webb
- webc
ports:
- "80:80"
- "70:70"
expose:
- "80"
- "70"

启动docker-compose:

docker-compose up -d

通过验证,我们可以看到服务正常部署,访问http://127.0.0.1:80也可以完成服务的正常访问。但是在前面,我们讲过,weba和webb以及webc都是由同一个image创建而来,那么我们是否可以使用deploy配置项,直接配置三副本呢?

我们验证一下,修改docker-compose.yml内容如下:

version: '3'
services:
web:
build: ./web
expose:
- 80
deploy:
replicas: 3 haproxy:
image: haproxy:latest
volumes:
- ./haproxy:/haproxy-override
- ./haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
external_links:
- compose-haproxy-web_web_1
- compose-haproxy-web_web_2
- compose-haproxy-web_web_3
ports:
- "80:80"
- "70:70"
expose:
- "80"
- "70"

执行docker-compose up -d:

root@ubuntu:~/trainning/compose-haproxy-web# docker-compose up -d
WARNING: Some services (web) use the 'deploy' key, which will be ignored. Compose does not support 'deploy' configuration - use `docker stack deploy` to deploy to a swarm.
compose-haproxy-web_web_1 is up-to-date
compose-haproxy-web_haproxy_1 is up-to-date

上面提示deploy不被支持,然后web也只启动了一个。这是为什么呢?

因为deploy在使用的时候,有一些限制,但你的compose文件中出现如下配置项时,deploy就无法使用:

  • build
  • cgroup_parent
  • container_name
  • devices
  • tmpfs
  • external_links
  • links
  • network_mode
  • restart
  • security_opt
  • stop_signal
  • sysctls
  • userns_mode

使用Docker Compose一键部署zabbix

version: '3'
services:
mysql-server:
hostname: mysql-server
container_name: mysql-server
image: mysql:5.7
network_mode: host
volumes:
- /data/mysql5721/data:/var/lib/mysql
command: --character-set-server=utf8
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: zabbix
MYSQL_USER: zabbix
MYSQL_PASSWORD: zabbix zabbix-web-nginx-mysql:
hostname: zabbix-web-nginx-mysql
container_name: zabbix-web-nginx-mysql
image: zabbix/zabbix-web-nginx-mysql:alpine-3.4.11
network_mode: host
depends_on:
- mysql-server
- zabbix-server
ports:
- 80:80
environment:
DB_SERVER_HOST: 127.0.0.1
MYSQL_DATABASE: zabbix
MYSQL_USER: zabbix
MYSQL_PASSWORD: zabbix
MYSQL_ROOT_PASSWORD: 123456
ZBX_SERVER_HOST: 127.0.0.1
PHP_TZ: Asia/Shanghai zabbix-server:
hostname: zabbix-server-mysql
container_name: zabbix-server-mysql
image: zabbix/zabbix-server-mysql:alpine-3.4.11
depends_on:
- mysql-server
network_mode: host
ports:
- 10051:10051
environment:
DB_SERVER_HOST: 127.0.0.1
MYSQL_DATABASE: zabbix
MYSQL_USER: zabbix
MYSQL_PASSWORD: zabbix
MYSQL_ROOT_PASSWORD: 123456 zabbix-agent:
hostname: zabbix-agent
container_name: zabbix-agent
image: zabbix/zabbix-agent:alpine-3.4.11
network_mode: host
environment:
ZBX_HOSTNAME: monitor
ZBX_SERVER_HOST: 127.0.0.1

一文掌握Docker Compose的更多相关文章

  1. .NET遇上Docker - 使用Docker Compose组织Ngnix和.NETCore运行

    本文工具准备: Docker for Windows Visual Studio 2015 与 Visual Studio Tools for Docker 或 Visual Studio 2017 ...

  2. Docker系列10—容器编排工具Docker Compose详解

    本文收录在容器技术学习系列文章总目录 1.Docker Compose 概述 Compose是一个用于定义和运行多容器Docker应用程序的工具.使用Compose,您可以使用Compose文件来配置 ...

  3. Istio入门实战与架构原理——使用Docker Compose搭建Service Mesh

    本文将介绍如何使用Docker Compose搭建Istio.Istio号称支持多种平台(不仅仅Kubernetes).然而,官网上非基于Kubernetes的教程仿佛不是亲儿子,写得非常随便,不仅缺 ...

  4. 029.Docker Compose部署Zabbix实战

    一 前期规划 1.1 Zabbix架构图 1.2 其他规划 组件 类型 版本 备注 Zabbix Web zabbix-web-apache-mysql镜像 wordpress:latest 也可采用 ...

  5. Docker Compose 版本过高(Docker版本不匹配),降低docker-compose版本

    通过docker-compose启动容器,报错: ERROR: The Docker Engine version is less than the minimum required by Compo ...

  6. 19、Docker Compose

      编排(Orchestration)功能是复杂系统实现灵活可操作性的关键.特别是docker应用场景中,编排意味着用户可以灵活地对各种容器资源实现定义和管理.   在我们部署多容器的应用时: 要从D ...

  7. 阿里云上Docker Compose部署wordpress

    先上官方文档: https://docs.docker.com/compose/wordpress/ 我的环境: [root@xyjk1002 ~]# cat /etc/redhat-release ...

  8. Docker | 第七章:Docker Compose服务编排介绍及使用

    前言 前面章节,我们学习了如何构建自己的镜像文件,如何保存自己的镜像文件.大多都是一个镜像启动.当一个系统需要多个子系统进行配合时,若每个子系统也就是镜像需要一个个手动启动和停止的话,那估计实施人员也 ...

  9. 使用 Docker Compose 快速构建 TiDB 集群

    本文档介绍如何在单机上通过 Docker Compose 快速一键部署一套 TiDB 测试集群.Docker Compose 可以通过一个 YAML 文件定义多个容器的应用服务,然后一键启动或停止. ...

随机推荐

  1. 让Visual Studio载入Symbol(pdb)文件

    让Visual Studio载入Symbol(pdb)文件 让Visual Studio载入Symbol(pdb)文件 在VC编译工程的编译连接阶段,会产生Symbol文件,也就是常说的 pdb 文件 ...

  2. libgdx相关知识点

    Gdx.graphics.setContinuousRendering(false); 设置图像为非连续自动渲染. 设置Opengl的混合模式,支持alpha属性 Gdx.gl.glBlendFunc ...

  3. CS190.1x Scalable Machine Learning

    这门课是CS100.1x的后续课,看课程名字就知道这门课主要讲机器学习.难度也会比上一门课大一点.如果你对这门课感兴趣,可以看看我这篇博客,如果对PySpark感兴趣,可以看我分析作业的博客. Cou ...

  4. REST-framework快速构建API--四部曲

    代码目录结构: 一.使用原生APIView 使用rest-framework原生的APIView实现过程: 以url(r'^books/$', views.BookView.as_view(),nam ...

  5. NodeJS旅程 : express - nodejs MVC 中的王牌

    express 正如ASP.NET MVC 在作为.net平台下最佳的 Mvc框架的地位一样,express在 node.js 环境也有着相同的重要性.在百度上 "nodejs expres ...

  6. Unity协程Coroutine使用总结和一些坑

    原文摘自 Unity协程Coroutine使用总结和一些坑 MonoBehavior关于协程提供了下面几个接口: 可以使用函数或者函数名字符串来启动一个协程,同时可以用函数,函数名字符串,和Corou ...

  7. yocto-sumo源码解析(五): bitbake/lib/bb/main.py

    续前面分析,就该对bitbake_main()这个函数进行分析了,这个函数位于bitbake/lib/bb/main.py. 1. 检测主机操作系统是否为linux并且/dev/shm是否存在,pyt ...

  8. Final互评------《I do》---- 二次元梦之队

    一.基于NABCD评论作品,及改进建议 1.根据(不限于)NABCD评论作品的选题; N(Need,需求):该产品是一款休闲类的解密游戏,背景是编程知识.作为一款休闲游戏,有着基本的娱乐功能,可以给用 ...

  9. 【读书笔记】Linux内核设计与实现(第一章&第二章)

    http://pan.baidu.com/s/1hqYAZNQ OneNote做的笔记没法儿带着格式一起导进来.所以上传到百度云,麻烦老师下载一下了. 下次不再用OneNote.

  10. 用IDEA开发简单的Servlet

    最近学习java,主要是servlet相关的内容.IDEA和servlet之前都没有碰过,所以做了一下小实验,走了一些弯路:这里把一个完整的步骤写出来,加深一下印象. IDEA创建项目步骤 1. 在i ...