第一次实践作业
第1次实践作业
(1)课程调查
因为教务处没有本课程的授课计划和教学大纲,所以不知道这是一门什么样的课。根据课程名来看,大概是要对前几年学到的知识,来一次综合实践运用,提升我们的综合能力吧
(2)了解微服务
什么是微服务
根据维基百科上的定义,微服务是一种软件开发技术,是面向服务的架构(SOA)结构风格的一种变体,将应用程序编排成一系列松耦合的服务。在微服务架构中,各个服务是细粒度的,协议是轻量级的。
业务发展中的不合理情况
- 网站和移动端应用有很多相同业务逻辑的重复代码。
- 数据有时候通过数据库共享,有时候通过接口调用传输。接口调用关系杂乱。
- 单个应用为了给其他应用提供接口,渐渐地越改越大,包含了很多本来就不属于它的逻辑。应用边界模糊,功能归属混乱。
- 管理后台在一开始的设计中保障级别较低。加入数据分析和促销管理相关功能后出现性能瓶颈,影响了其他应用。
- 数据库表结构被多个应用依赖,无法重构和优化。
- 所有应用都在一个数据库上操作,数据库出现性能瓶颈。特别是数据分析跑起来的时候,数据库性能急剧下降。
- 开发、测试、部署、维护愈发困难。即使只改动一个小功能,也需要整个应用一起发布。有时候发布会不小心带上了一些未经测试的代码,或者修改了一个功能后,另一个意想不到的地方出错了。为了减轻发布可能产生的问题的影响和线上业务停顿的影响,所有应用都要在凌晨三四点执行发布。发布后为了验证应用正常运行,还得盯到第二天白天的用户高峰期……
- 团队出现推诿扯皮现象。关于一些公用的功能应该建设在哪个应用上的问题常常要争论很久,最后要么干脆各做各的,或者随便放个地方但是都不维护。
微服务优点
- 提升开发交流,每个服务足够内聚,足够小,代码容易理解;
- 服务独立测试、部署、升级、发布;
- 按需定制的DFX,资源利用率,每个服务可以各自进行x扩展和z扩展,而且,每个服务可以根据自己的需要部署到合适的硬件服务器上;每个服务按
- 需要选择HA的模式,选择接受服务的实例个数;
- 容易扩大开发团队,可以针对每个服务(service)组件开发团队;
- 提高容错性(fault isolation),一个服务的内存泄露并不会让整个系统瘫痪;
- 新技术的应用,系统不会被长期限制在某个技术栈上;
微服务缺点
- 没有银弹,微服务提高了系统的复杂度;
- 开发人员要处理分布式系统的复杂性;
- 服务之间的分布式通信问题;
- 服务的注册与发现问题;
- 服务之间的分布式事务问题;
- 数据隔离再来的报表处理问题;
- 服务之间的分布式一致性问题;
- 服务管理的复杂性,服务的编排;
- 不同服务实例的管理。
(3)学习docker
Docker Engine是一种开源容器化技术,用于构建和容器化您的应用程序。Docker Engine通过以下方式充当客户端-服务器应用程序:
- 具有长时间运行的守护进程的服务器dockerd。
- API,用于指定程序可以用来与Docker守护程序进行通信的接口。
- 命令行界面(CLI)客户端docker。
CLI使用Docker API通过脚本或直接CLI命令控制或与Docker守护程序进行交互。许多其他Docker应用程序都使用基础API和CLI。守护程序创建和管理Docker对象,例如映像,容器,网络和卷。
相关概念
- Docker Engine:一个C/S应用,包含以下组件:长时间运行的守护进程daemon、一个REST API用于指挥守护进程、一个命令行接口
- Docker Daemon(dockerd):监听Docker API请求,也可以与其他Daemon交互来管理Docker服务
- Docker Client(docker):用于连接Daemon并与之交互,可以连接多个Daemon
- Image(镜像):容器的模板,可以根据不同的配置生成多个实例。
- Container(容器):镜像的实例,可以通过Docker API来开启/停止/删除,并且可以连接到多个网络,挂在多个存储,甚至可以在当前状态创建新镜像
- Docker Compose:一个定义和运行多容器Docker应用的工具,它的功能有开启/关闭服务、查看服务的运行状态输出服务的日志、运行一次性命令等。守护进程创建并管理Docker对象,例如镜像、容器、network、volumes
- Dockerfile:用于定义应用环境,使环境可以重复加载多次
- yml文件:用于定义组成应用的服务们的文件,使服务们可以在一个独立的环境中一起运行
- Docker Machine:用于安装Docker Engine到虚拟主机,并且可以使用相关命令来管理这些主机
- Swarm mode:用于编排部署多个Docker容器
- k8s:用于部署和管理容器
搭建环境
根据官方安装教程(debian)一步步安装完成后,执行docker run hello-world以运行官方的Hello World示例
- Docker客户端连接至Docker守护进程
- Docker守护进程从Docker Hub上拉取hello-world镜像
- Docker守护进程从拉取的镜像创建一个新容器,终端上显示的这段话就是从这个容器创建的
- Docker守护进程将输出流式传输到Docker客户端,显示到下图的终端上
image 文件生成的容器实例,本身也是一个文件,称为容器文件。也就是说,一旦容器生成,就会同时存在两个文件: image 文件和容器文件。而且关闭容器并不会删除容器文件,只是容器停止运行而已。
列出本机正在运行的容器
$ docker container ls
列出本机所有容器,包括终止运行的容器
$ docker container ls --all
终止运行的容器文件,依然会占据硬盘空间,可以使用docker container rm命令删除。
$ docker container rm [containerID]
Dockerfile 文件:它是一个文本文件,用来配置 image。Docker 根据 该文件生成二进制的 image 文件。
以 koa-demos 项目为例制作自己的 Docker 容器
$ git clone https://github.com/ruanyf/koa-demos.git
$ cd koa-demos
然后,在项目的根目录下,新建一个文本文件 Dockerfile,写入下面的内容。
FROM node:8.4
COPY . /app
WORKDIR /app
RUN npm install --registry=https://registry.npm.taobao.org
EXPOSE 3000
上面代码一共五行,含义如下:
FROM node:8.4:该 image 文件继承官方的 node image,冒号表示标签,这里标签是8.4,即8.4版本的 node。
COPY . /app:将当前目录下的所有文件(除了.dockerignore排除的路径),都拷贝进入 image 文件的/app目录。
WORKDIR /app:指定接下来的工作路径为/app。
RUN npm install:在/app目录下,运行npm install命令安装依赖。注意,安装后所有的依赖,都将打包进入 image 文件。
EXPOSE 3000:将容器 3000 端口暴露出来, 允许外部连接这个端口。
有了 Dockerfile 文件以后,就可以使用docker image build命令创建 image 文件了
$ docker image build -t koa-demo .
# 或者
$ docker image build -t koa-demo:0.0.1 .
如果运行成功,就可以看到新生成的 image 文件koa-demo了。
$ docker image ls
生成容器
$ docker container run -p 8000:3000 -it koa-demo /bin/bash
# 或者
$ docker container run -p 8000:3000 -it koa-demo:0.0.1 /bin/bash
上面命令的各个参数含义如下:
-p参数:容器的 3000 端口映射到本机的 8000 端口。
-it参数:容器的 Shell 映射到当前的 Shell,然后你在本机窗口输入的命令,就会传入容器。
koa-demo:0.0.1:image 文件的名字(如果有标签,还需要提供标签,默认是 latest 标签)。
/bin/bash:容器启动以后,内部第一个执行的命令。这里是启动 Bash,保证用户可以使用 Shell。
如果一切正常,运行上面的命令以后,就会返回一个命令行提示符。
root@66d80f4aaf1e:/app#
这表示你已经在容器里面了,返回的提示符就是容器内部的 Shell 提示符。执行下面的命令。
root@66d80f4aaf1e:/app# node demos/01.js
发布 image 文件
容器运行成功后,就确认了 image 文件的有效性。这时,我们就可以考虑把 image 文件分享到网上,让其他人使用。
首先,去 hub.docker.com 或 cloud.docker.com 注册一个账户。然后,用下面的命令登录。
$ docker login
接着,为本地的 image 标注用户名和版本。
$ docker image tag [imageName] [username]/[repository]:[tag]
$ docker image tag koa-demos:0.0.1 ruanyf/koa-demos:0.0.1
也可以不标注用户名,重新构建一下 image 文件。
$ docker image build -t [username]/[repository]:[tag] .
最后,发布 image 文件。
$ docker image push [username]/[repository]:[tag]
发布成功以后,登录 hub.docker.com,就可以看到已经发布的 image 文件。
感想: 浪费了我不少时间,主要是下载有点慢,想快点弄完博客就没有上传图片,之后有时间补上去。