系统综合实践——第1次实践作业
一、课程调查
进入大三下学期的后半段,大学阶段的理论课程应该已经修得八九不离十了,在这个时间点迎来系统综合实践这门课,作为培养计划的一门新课程,我们非常希望了解你们对于课程的希望,请写下你对这门课的认识和你理想中的这门课程是怎么样的。
我感觉这门课应该是让我们去熟悉系统,通过自学来完成博客内容,面向百度实践
二、了解微服务
第一次作业我们将接触一种新型的软件架构——微服务(也许部分同学已经有所了解)。大家要做的是学习并了解该技术,微服务是什么,有什么特点,相较于传统的软件架构,它有什么优缺点,它是怎样部署的。
-
微服务是什么?
微服务是一个新兴的软件架构,就是把一个大型的单个应用程序和服务拆分为数十个的支持微服务。一个微服务的策略可以让工作变得更为简便,它可扩展单个组件而不是整个的应用程序堆栈,从而满足服务等级协议
-
微服务的特点
相比较于单体应用架构和SOA架构,微服务架构的主要特点是组件化、松耦合、自治、去中心化,体现在以下几个方面:用 4个字描述就是小 独 轻 松
- 小:体现每个微服务粒度要小,而每个服务是针对一个单一职责的业务能力的封装,专注做好一件事情。
- 独:独立部署运行和扩展。每个服务能够独立被部署并运行在一个进程内。这种运行和部署方式能够赋予系统灵活的代码组织方式和发布节奏,使得快速交付和应对变化成为可能。
- 轻:系统相比较复杂单体应用更为简洁轻量化,每个微服务因为独立部署,可以使用不同跨语言编写,这样使得微服务架构更为灵活.
- 松:低耦合性,符合面向对象设计高内聚低耦合特性。不同模块间依赖低,相互关联小(因为每个微服务设计的初衷是每个服务专注一个模块开发)
-
较于传统结构,微服务的优缺点
优点
传统的整体风格的架构在构建部署和扩展伸缩方面有很大的局限性,其服务端应用就像是一块铁板,笨重且不可拆分,系统中任何程序的改变都需要整个应用重新构建和部署新版本。在进行水平扩展时也只能整个系统扩展,而不能针对某一个功能模块进行扩展。
而微服务架构将系统以组件化的方式分解为多个服务,服务之间相对独立且松耦合,单一功能的改变只需要重新构建部署相应的服务即可。
1.每个微服务可由不同团队开发
传统的开发模式在分工时往往以技术为单位,比如UI团队、服务端团队和数据库团队,这样的分工可能会导致任何功能上的改变都需要跨团队沟通和协调。而微服务则倡导围绕服务来分工,不同的服务可以采用不同的技术来实现,一个团队中应该包含开发所需的所有技能,比如用户体验、数据库、项目管理。
2.微服务是松散耦合的
微服务架构抛弃了ESB复杂的业务规则编排、消息路由等功能,微服务架构中服务是高内聚的,每个服务都会处理相应的业务,所有的业务逻辑应该尽量在服务内部处理,且服务间的通信尽可能的轻量化,比如使用Restful的方式。
3.可用不同的编程语言与工具开发
传统的软件开发中经常会使用同一个技术平台来解决所有的问题,而经验表明使用合适的工具做合适的事情会让开发变得事半功倍。微服务架构天生就具有这样的特性,我们可以使用Node.js来开发一个简单的报表页面,使用C++来编写一个实时聊天组件。
缺点
1.运维开销
更多的服务也就意味着更多的运维,产品团队需要保证所有的相关服务都有完善的监控等基础设施,传统的架构开发者只需要保证一个应用正常运行,而现在却需要保证几十甚至上百道工序高效运转,这是一个艰巨的任务。
2.DevOps要求
使用微服务架构后,开发团队需要保证一个Tomcat集群可用,保证一个数据库可用,这就意味着团队需要高品质的DevOps和自动化技术。而现在,这样的全栈式人才很少。
3.隐式接口
服务和服务之间通过接口来“联系”,当某一个服务更改接口格式时,可能涉及到此接口的所有服务都需要做调整。
4.重复劳动
在很多服务中可能都会使用到同一个功能,而这一功能点没有足够大到提供一个服务的程度,这个时候可能不同的服务团队都会单独开发这一功能,重复的业务逻辑,这违背了良好的软件工程中的很多原则。
5.分布式系统的复杂性
微服务通过REST API或消息来将不同的服务联系起来,这在之前可能只是一个简单的远程过程调用。分布式系统也就意味着开发者需要考虑网络延迟、容错、消息序列化、不可靠的网络、异步、版本控制、负载等,而面对如此多的微服务都需要分布式时,整个产品需要有一整套完整的机制来保证各个服务可以正常运转。
6.事务、异步、测试面临挑战
跨进程之间的事务、大量的异步处理、多个微服务之间的整体测试都需要有一整套的解决方案,而现在看起来,这些技术并没有成熟。
-
如何部署微服务
基于主机(物理机或虚机)的多服务实例
基于主机(物理机或虚机)的服务实例
基于容器的服务实例
无服务器部署
三、学习docker技术
docker作为微服务的一种十分典型的代表技术,我们要做的是:
学习了解docker的相关概念(容器、镜像等),了解docker、docker compose、Dockerfile、docker machine、Swarm、k8s是什么,是做什么用的,心中有概念即可;
搭建你自己的docker环境,系统环境不限(主流的有Ubuntu/CentOS/Debian/Windows/MacOS等),完成docker的基本入门,包括但不限于:容器的创建、删除、更新和查询,创建并维护自己的镜像仓库,实现拉取和上传镜像等。
-
docker的相关概念
docker
docker compose
Dockerfile
docker machine
Swarm
k8s
-
搭建docker环境
-
更新Ubuntu的apt源索引
sudo apt-get update
-
安装包允许apt通过HTTPS使用仓库
sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
-
添加Docker官方GPG key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
-
设置Docker稳定版仓库
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
-
添加仓库后,更新apt源索引
sudo apt-get update
-
安装最新版Docker CE(社区版)
sudo apt-get install docker-ce
-
检查Docker CE是否安装正确
sudo docker run hello-world
-
使用阿里云加速器
接下来会涉及到拉取镜像等等,用到了国外的源,没有VPN会很慢,所以先设置为阿里云的源
登陆阿里云容器服务官网注册
点击控制台——>产品与服务——>弹性计算——>容器镜像管理,看到自己专有的镜像加速器
根据官方文档进行配置即可
-
docker容器使用
- 输出hello world
sudo docker run ubuntu:16.04 /bin/echo "Hello world"
各个参数解析:
docker: Docker 的二进制执行文件。
run: 与前面的 docker 组合来运行一个容器。
ubuntu:16.04 指定要运行的镜像,Docker 首先从本地主机上查找镜像是否存在,如果不存在,Docker 就会从镜像仓库 Docker Hub 下载公共镜像。
/bin/echo "Hello world": 在启动的容器里执行的命令
- 运行交互式的容器
我们通过 docker 的两个参数 -i -t,让 docker 运行的容器实现对话"的能力:
sudo docker run -i -t ubuntu:16.04 /bin/bash
- 启动容器(后台模式)
sudo docker run -d ubuntu:16.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"
这个长字符串叫做容器 ID,对每个容器来说都是唯一的,我们可以通过容器 ID 来查看对应的容器发生了什么。
首先,我们需要确认容器有在运行,可以通过 docker ps 来查看:
sudo docker ps
输出详情介绍:
CONTAINER ID: 容器 ID。
IMAGE: 使用的镜像。
COMMAND: 启动容器时运行的命令。
CREATED: 容器的创建时间。
STATUS: 容器状态。
状态有7种:
created(已创建)
restarting(重启中)
running(运行中)
removing(迁移中)
paused(暂停)
exited(停止)
dead(死亡)
PORTS: 容器的端口信息和使用的连接类型(tcp\udp)。
NAMES: 自动分配的容器名称。
在宿主主机内使用 docker logs 命令,查看容器内的标准输出:
sudo docker logs <容器 ID>
- 停止容器
使用 docker stop 命令来停止容器
sudo docker stop <容器 ID>
通过 docker ps 查看,容器已经停止工作:
- 进入容器
在使用 -d 参数时,容器启动后会进入后台。此时想要进入容器,可以通过以下指令进入:
docker attach
docker exec:推荐大家使用 docker exec 命令,因为此退出容器终端,不会导致容器的停止。
docker attach <容器 ID>
停止的容器可以通过 docker restart 重启:
docker restart <容器 ID>
下面演示了使用 docker exec 命令。
docker exec -it <容器 ID> /bin/bash
如果从这个容器退出,不会导致容器的停止,如下图,容器并未停止。
- 导出与导入容器
如果要导出本地某个容器,可以使用 docker export 命令。
可以使用 docker import 从容器快照文件中再导入为镜像,以下实例将快照文件 ubuntu.tar 导入到镜像 test/ubuntu:v1:
sudo docker export <容器 ID> > ubuntu.tar
cat ubuntu.tar | docker import - test/ubuntu:v1
-
删除容器
docker rm -f <容器 ID>
-
Docker 镜像使用
-
列出本地镜像列表
docker images
各个选项说明:
REPOSITORY:表示镜像的仓库源
TAG:镜像的标签
IMAGE ID:镜像ID
CREATED:镜像创建时间
SIZE:镜像大小
-
查找镜像
我们可以使用 docker search 命令来搜索镜像。比如我们需要一个 httpd 的镜像来作为我们的 web 服务。我们可以通过 docker search 命令搜索 httpd 来寻找适合我们的镜像。
docker search httpd
-
拖取镜像
docker pull httpd
-
删除镜像
第一步先停止所有的容器,第二步删除容器,最后删除指定镜像
docker stop $(docker ps -a -q)
docker rm $(docker ps -a -q)
docker rmi hello-world
-
Docker 仓库管理
-
登录Docker账号
登录需要输入用户名和密码,登录成功后,我们就可以从 docker hub 上拉取自己账号下的全部镜像。
docker login
-
推送镜像
用户登录后,可以通过 docker push 命令将自己的镜像推送到 Docker Hub。