正文共: 7284字 5图
预计阅读时间: 19分钟
每日分享
You cannot start the next chapter of your life if you keep re-reading the last one.
如果你不断阅读最后一章,你就无法开始人生的下一章。
小闫语录:
不是你的生活无法改变,而是你一直沉浸于缅怀过去,纠结于过去,驻足不前。不是生活不放过你,而是你不放过你自己。无论过去多么辉煌还是不堪,都只是过去。不论下一步多么艰难,请勇敢的迈出去。艰难,有可能是不舍过去的辉煌,也有可能是前面被磨掉的信心。放下,舍得,前路尽是美好。
项目部署(三)
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
举例: RUN echo hello
exec 模式:类似于 RUN ["/bin/bash", "-c", "command"]
举例: 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(视图)
这是第二个区别,功能的整合和再次拆分