正文共: 7284字 5图 

预计阅读时间: 19分钟

项目部署(三)_docker

每日分享

You cannot start the next chapter of your life if you keep re-reading the last one.

如果你不断阅读最后一章,你就无法开始人生的下一章。

小闫语录​:

不是你的生活无法改变,而是你一直沉浸于缅怀过去,纠结于过去,驻足不前。不是生活不放过你,而是你不放过你自己。无论过去多么辉煌还是不堪,都只是过去。不论下一步多么艰难,请勇敢的迈出去。艰难,有可能是不舍过去的辉煌,也有可能是前面被磨掉的信心。放下,舍得,前路尽是美好。


项目部署(三)_数据库_02


项目部署(三)

1.Docker进阶

1.1Dockerfile

1.1.1作用

类似于我们的python脚本,自动化的将我们的定制docker镜像创建出来。

注意​:

1.命令必须可执行。

2.目标需要响应的流程来配合。

在使用Dockerfile之前,手工执行一定要成功。

具体作用​:

1、找一个镜像:ubuntu

2、创建一个容器:

docker run  ubuntu

3、进入容器:

docker exec -it 容器 命令

4、操作:各种应用配置

....

5、构造新镜像:

docker commit

1.1.2使用准则

1.文件名 Dockerfile 首字母大写。

2.Dockerfile文件在一个空目录下(只存放和Dockerfile相关的内容)

3.构建后的docker镜像尽量只有一个功能。

4.Dockerfile里面的命令,越少越好,即使是5条命令实现一个目的,也要把这5条命令都放在一行来执行。

所有命令放在一行,命令间用 ​&&​来隔开。

1.1.3Dockerfile的指令类型

1.来源。

2.维护者。

3.定制命令。

4.容器启动时候的第一条命令。

1.1.4使用命令

docker build -t 镜像名称:镜像版本 Dockerfile文件所在路径


Dockerfile文件所在路径,可以是相对路径,也可以是绝对路径。

-t指定构建后的镜像信息。


1.1.5跨主机免密认证实践

场景​:跨主机免密码认证。

登录远程主机的时候,不需要输入密码或者用户名。

认证文件​:把用户名和密码加密成为了一套文件(公钥和私钥)。

步骤​:

1.主机1自己创建秘钥对。

2.主机2使用主机1上的公钥文件。

3.主机2使用公钥文件来进行用户登录的认证。

4.主机1登录一下主机2,测试一下公钥和私钥的认证是否成功。

代码实现​:

创建Dockerfile专用目录并切入目录:

mkdir /docker/images/ssh -p 
cd /docker/images/ssh

创建秘钥认证:

ssh-keygen -t rsa 
cat ~/.ssh/id_rsa.pub > authorized_keys

创建Dockerfile文件:

root@admina-virtual-machine:/docker/images/ssh# cat Dockerfile 

# 构建一个基于ubuntu的ssh定制镜像

# 基础镜像

FROM ubuntu

# 镜像作者

MAINTAINER President.Wang 000000@qq.com



# 执行命令

# 增加软件源

# ADD sources.list /etc/apt/sources.list

# 安装 ssh 服务

RUN apt-get update && apt-get install -y openssh-server curl vim net-tools && mkdir -p /var/run/sshd && mkdir -p /root/.ssh && sed -i "s/.*pam_loginuid.so/#&/" /etc/pam.d/sshd && apt-get autoclean && apt-get clean && apt-get autoremove

# 复制配置文件到相应位置,并赋予脚本可执行权限

ADD authorized_keys /root/.ssh/authorized_keys

# 对外端口

EXPOSE 22



# 启动ssh

ENTRYPOINT ["/usr/sbin/sshd","-D"]

构建镜像:

docker build -t ubuntu-ssh:v0.1 .

使用新镜像启动一个容器,查看效果:

docker run -d -p 10086:22 ubuntu-ssh:v0.1

ssh查看效果:

ssh 192.168.8.14 -p 10086

1.2基础指令详解

1.2.1 ​FORM

FROM 是 Dockerfile 里的第一条而且只能是除了首行注释之外的第一条指令

# 格式:
FROM <image>
FROM <image>:<tag>

1.2.2 ​MAINTAINER

指定该 dockerfile 文件的维护者信息。类似我们在 docker commit 的时候使用-a 参数指定的信息

# 格式:
MAINTAINER <name>

1.2.3 ​RUN

表示当前镜像构建时候运行的命令

# 格式:
RUN <command> # shell 模式
RUN["executable", "param1", "param2"] # exec 模式


shell 模式:类似于 /bin/bash -c command

  1. 举例: RUN echo hello

exec 模式:类似于 RUN ["/bin/bash", "-c", "command"]

  1. 举例: RUN ["echo", "hello"]


1.2.4 ​EXPOSE

设置 Docker 容器对外暴露的端口号,Docker 为了安全,不会自动对外打开端口,如果需要外部提供访问,还需要启动容器时增加-p 或者-P 参数对容器的端口进行分配。

# 格式:
EXPOSE <port> [<port>...]

1.2.5 ​ENTRYPOINT

每个 Dockerfile 中只能有一个 ENTRYPOINT,当指定多个时,只有最后一个起效。

# 格式:
ENTRYPOINT ["executable", "param1","param2"] # exec 模式
ENTRYPOINT command param1 param2 # shell 模式

1.3文件编辑指令详解

1.3.1 ​ADD

如果传输的是压缩包,会自动在容器里面解压

ADD yasuobao.tar.gz /test/

1.3.2 ​COPY

单纯的拷贝动作

COPY yasuobao.tar.gz /copy/
COPY authorized_keys /copy/

1.3.3 ​VOLUME

产生一个共享的目录

VOLUME ["VOLUMES"]

1.4环境指令详解

1.4.1需求

mysql镜像,设定好了登录用户名USERNAME和密码PASSWD,基于镜像创建的容器,我们想使用这两个变量来登录。

docker run -e

1.4.2 ​ENV

在构件镜像的时候,给他设定一个环境变量

ENV USERNAME=Ethanyan_note
ENV PASSWD=Ethanyan_note

1.4.3 ​WORKDIR

切换工作目录

注意:如果切换工作目录后,并没有执行回退的WORKDIR指令,那么就会一直在指定的目录下

WORKDIR ["/nihao/hah"]
RUN ["touch","itcast.txt"]

1.5Dockerfile构建过程

1.基于镜像创建容器1。

2.在容器1里执行Dockerfile指令1。

3.在提交容器为新镜像2的同时删除刚才的容器1。

4.重复1-3

我们的docker镜像的特点是只读的、分层的。

1.5.1构建过程镜像介绍

1.构建过程中,创建了很多镜像,这些中间镜像,我们可以直接使用,来启动容器。通过查看容器效果,从侧面能看到我们每次构建的效果。

2.提供了镜像调试的能力。

3.我们可以通过下面的指令来查看整个构建过程所产生的镜像:

docker history <镜像名>

1.5.2构建缓存

为了效率,能用缓存就用缓存。

我们第一次构建很慢,之后的构建都会很快,因为他们用到了构建的缓存。

不适用构建缓存方法常见两种:

1.全部不同缓存:

docker build --no-cache -t [镜像名]:[镜像版本] [Dockerfile位置]

2.部分使用缓存:

ENV REFRESH_DATE 2018-01-12

只要构建的缓存时间不变,就用缓存;时间一旦改变,就不用缓存了。

不使用缓存的方式​:

1.改一下命令

2.--no-cache

一些命令​:

查看构建过程:

docker history

清理构建缓存:

docker system prune
docker system prune --volumes

1.5.3Djangofile案例实现

如何在生产中定制标准的docker镜像?

1.标准的工作目录。

/docker/images/功能目录

2.标准的手工流程。


做出手工执行方案:

需求->方案分析->技术关键点->梳理出实施方案

在进入到Dockerfile步骤之前,一定要保证手工执行是成功的,而且必须把手工执行的命令梳理出来。


3.标准的Dockerfile转换。

3.1根据手工梳理出来的命令,准备Dockerfile所依赖的软件和文件,放到专用的Dockerfile目录里。

3.2分析手工命令,将其转换成Dockerfile指令。

3.3整理Dockerfile指令。

3.4执行Dockerfile文件。

3.5整体测试。

2.部署串讲

2.1项目架构

一般来说,一个项目至少有三层:web访问层、数据库层、存储层。

2.2初级阶段

2.2.1单体阶段

此阶段是刚开始的时候,还没有过多的用户访问,服务器无压力,所有应用服务都在一台主机上。

2.2.2应用/数据分离阶段

项目初期的时候,用户访问数据库有压力。我们可以将应用和数据库单独部署。这样用户体验好,我们的执行效率也高。

2.2.3页面动静分离阶段

项目初期的时候,web服务有压力,即用户访问页面有压力了,我们可以剥离用户读请求和写请求的操作,将动态请求和静态请求分别管理。web层多了一个代理层。

2.2.4页面/数据缓存阶段

采取数据缓存的策略,实现有限的资源创造更高的效益。在代理前加一个web缓存,在数据库前加一个数据缓存。

2.2.5扩展分析

1.网站项目的架构师一次性做出来的吗?

答:不是,一步一步演变过来的。

2.演变你的措施是一次性全部实现的吗?

答:不是,遇到了什么问题就解决什么问题。

3.每个阶段的措施是一次的吗?

答:不是,前面的措施,在后面也可以用,是一个选项。

2.3项目中期

应用集群阶段​:直接加机器。

keepalived + haproxy

数据库读写分离化​:数据读写有压力,需要单独来处理。


数据库读写分离 -- 主从同步。

主从复制(官方的)、主从同步、读写分离

前端应用 -- 共享存储。

nfs


存储分布式​:


数据库 -- 分库分表

存储单点 -- 分布式存储

fastdfs、glusterfs、ceph、swift、hdfs...


应用拆分

2.4项目中后期

业务拆分​:将相同或者相似的应用组合在一起,以统一的业务形式向外提供服务。

微服务​:

部署的角度​:将传统项目整体部署的方式,拆分成每一个子功能服务都可以单独来部署。

开发角度​:需求在开发前,进行更进一步的细化,细化成更详细的子功能,采用松耦合的形式来开发。

2.5架构部署

划分架构部分:

一级定位:存储层、数据库层、web层

部署原则:站在用户访问资源的角度从后向前来部署,后部署的内容正好验证

二级定位:web缓存、代理、数据库缓存(一级定位之外的部分)

部署原则:站在用户访问资源压力角度,需要部署到哪里,就部署到哪里,注意前后的信息交流。

2.6项目运营

2.6.1网站分析

2.6.1.1常见术语

我们在日常生活中经常会听说,XX网站日PV多少,日UV多少,每日访问峰值是多少之类的话,而这些名词都是项目 正常运营的过程中,为了更好的对项目的运行维护,我们对网站进行分析必须知道一些常用的网站分析术语。

IP: 独立IP数


指一天内使用不同IP地址的用户访问网站的数量。

特点:同一个IP无论访问多少网页,独立IP数均为1。


PV:Page view页面浏览量


指一天内网站的浏览次数,它是衡量网站用户访问页面的数量。

特点:用户每打开一个页面就记录一次,就算访问同一页面多次,就记录多次。


UV:Unique Visitor 访问网站的用户


指一天内访问某站点的人数,以cookie/客户端为依据。

特点:一天内,同一访问用户的多次访问只记录1次。


VV:Visit View 用户访问网站次数


指一天内某个用户访问了多少次网站。

特点:打开网页A,浏览完毕后关闭该页面,表示一次访问。


BR:Bounce Rate 跳出率


指一天内访问用户中,用户打开网站后没有做任何事情,一会就离开了的比例。

特点:如果跳出率很高,说明我们的网页没有什么吸引力,网页设计效果不怎么好。


CR:Conversion Rate 转化率


指一天内访问用户中,打开网站后,继续浏览该网站其他页面的比例

特点:转化率一般体现在项目的关键流程的部分,而它对网站的某些关键流程优化是一个很重要的直播


网站分析术语多如牛毛,每个公司的业务方向不一样,评判标准也不一样,上面只是举例了几种常见的术语,这些术语的常用场景如下:

口语描述​:

术语:IP、PV、UV

人员:所有岗位

网站质量​:

术语:跳出率和转化率

人员:产品、开发

2.6.1.2常见分析工具

服务器服务日志、公司内部监控平台等

互联网网站分析工具​:

站长工具、百度统计、云平台监控等

2.6.2网站优化

2.6.2.1网站优化思路

关于项目正常运行,就是网站运行过程中,不论遇到什么问题,我们都能应对下去。一般来说就是用户访问量变化的时候我们做的优化等工作。那么我们就站在开发的角度,从网站的分层上面来看一下常见问题及其解决方案。

2.6.2.2缓存层方面

问题描述​:怎么在现有的主机资源情况下,花最小的代价抗住大量的用户访问量?

解决思路​:很常见的就是自建Web缓存,或者购买CDN,将用户经常访问的、更新频率低的资源存放起来,这样用户再次请求相同资源的时候,就不会对后端的服务造成影响。当然防止互联网上的恶意访问/爬虫,我们应该做好相应的安全措施。缓存之类的措施一定要适合公司的当前业务,如果是项目的静态资源很多,只要我们购买的CDN够好,那么用户访问量随便。

2.6.2.3代理层方面

问题描述​:如何提高用户高质量的请求分发?

解决思路​:以Nginx代理为例,提高用户高质量的请求分发,最好的方法就是基于请求的关键字进行合理的分流。


基于请求的IP地址信息,封闭恶意IP访问,提高正常IP用户访问效率。

基于请求的浏览器信息,分发到相应的后端应用。

基于请求的协议方法,做好读写分离业务的精确分流。

基于请求的路径信息,做好指定业务的精确分流。

location+if指令。


问题描述​:对于前端使用nginx进行代理的项目,会随着功能的层层迭代逐渐增加数十个upstream,location规则的数量有可能达到数百个,这个时候偶尔有些 URL 会出现 404 的问题,对于这种情况怎么办?

解决思路​:

1 按照功能描述,将upstream拆分到不同的功能目录中。

2 对location的匹配规则尽量描述清楚,特别是匹配的location_match,最好使用^/$来锚定首尾字母。

2.6.2.4项目后端web访问

问题描述​:关于动态web请求过多,压力有些大,常见的解决方法有哪些?

解决思路​:可以根据架构演变的思路,我们合理的调整页面访问的关键流程,在技术方面我们可以这么做:分析动态的web请求主要的瓶颈点在哪里,是请求量大,还是数据访问大。

1.请求量大:Web缓存/CDN,或者动态web集群可以考虑一下。

2.数据库操作多:分析请求内容是否频繁/集中,是,页面静态化考虑一下;否,参看数据库的演变思路。

问题描述​:如何提高静态web资源的访问质量?

解决思路​:结合前段缓存的功能,在代码或者代理部分设置合理的资源缓存过期时间,定时/实时推送相关信息到前段的缓存层。

2.6.2.5数据层方面

问题描述​:用户访问数据有压力。

解决思路​:

1.对于热点数据读取频繁的话,可以考虑前端数据缓存、分部署数据缓存、优化查询搜索等方法。

2.对于数据频繁写入压力的话,可以考虑数据库集群、读写分离、分库分表、增加数据管理层等方法。

3.开发角度:关注数据库表的设计,表的索引合理、查询的时候,尽量使用条件查询。

2.6.2.6存储层方面

问题描述​:如何保证我们数据存储的质量?

解决思路​:存储设备的购买质量、分布式存储、备份策略。

2.6.2.7扩展

热备份​:在不停主机服务的情况下,备份数据。

冷备份​:在停止主机服务的情况下,备份数据。

全量备份​:就是对数据整体备份。

增量备份​:只对增量数据进行备份。

3.Django中MVC & MTV

Django中的MVT模式和程序设计模式MVC有区别吗?答案是肯定的。MVT是遵循MVC框架原则,在之前的基础上进行了很多的改变。

3.1详细解释

3.1.1MVC

M全拼为Model,主要封装对数据库层的访问,对数据库中的数据进行增、删、改、查操作。

V全拼为View,用于封装结果,生成页面展示的html内容。

C全拼为Controller,用于接收请求,处理业务逻辑,与Model和View交互,返回结果。

3.1.2MVT

M全拼为Model,与MVC中的M功能相同,负责和数据库交互,进行数据处理。

V全拼为View,与MVC中的C功能相同,接收请求,进行业务处理,返回应答。

T全拼为Template,与MVC中的V功能相同,负责封装构造要返回的html。

3.2区别

1、MVC的C(控制器)功能的大部分代码已经融合到了MVT框架中的代码里面了。

这是第一个区别,C基本上就没有了

2、将MVC的V(视图)功能和C(控制器)的部分功能进行了一个组合拆分,整合成MVT中的T(模板)和V(视图)

这是第二个区别,功能的整合和再次拆分



项目部署(三)_缓存_03


项目部署(三)_数据库_04