大觅网——微服务分布式项目
项目介绍
| 序号 | 名称 |
技术内容 |
| 1 | 项目架构 |
Vue、SpringBoot、Spring Cloud、Mybatis、Mysql |
| 2 | 微服务架构与项目设计 |
微服务、Git(版本管理)、SonarQube(代码规范检测)、Scrum(项目敏捷管理)、Maven(管理并解决jar包之间冲突) |
| 3 | Spring Cloud初体验 | Eureka/Nacos(注册中心)、Hystrix(容错处理)、Fegin(接口调用) |
| 4 | 虚拟化技术(实践Devops先进理念) | Docker(把服务器分隔成多个虚拟容器)+Jenkins(一键自动发布)、Docker Compose(通过一个配置文件来管理多个容器) |
| 5 | 分布式日志处理 | Sleuth(微服务追踪)、ELK+Kafka(日志收集) |
| 6 | 分布式业务实现 | RabbitMQ(实现分布式事务,解决高并发问题,消息队列)、Redis(缓存、分布式线程同步) |
| 7 | 分布式部署实现 | Ribbon(负载均衡)、Zuul(网关验证)、Config(分布式统一配置管理) |
| 8 | 分布式数据存储 | Elasticsearch(搜索)、Mycat(数据库中间件) |
| 9 | 分布式第三方接入 |
微信登录、微信支付、支付宝支付 |
| 10 | 集成测试 | JMeter(压力测试工具) |
大觅网项目类型
- 是基于微服务式分布式的票务类电商网站
大觅网业务
- 用户
- 商品
- 订单
- 排期
- 支付
微服务概念
- 把项目拆分成多个功能的模块,模块之间都注册到注册中心再通过接口互相访问,即使某些模块挂掉也不会影响别的模块正常运行,这就是微服务架构。
- 在实际项目运行时,可针对不同项目的需求进行一个集群配置
- 可以使用不同的技术来开发项目模块
单体式架构
概念:
- 把项目源码合规一处
缺点:
- 项目迭代不灵活
- 项目组改代码职责、权限不清
- 项目并发配置不灵活
- 项目部署扩展困难

单体式架构-图1
微服务架构
概念:
- 讲项目拆成几个独立的功能单元()架构
优点:
- 项目复杂度低
- 团队界限明确
- 部署灵活

微服务架构-图2
业务应用场景:
| 选项 | 传统行业 |
互联网行业 |
| 面向用户 | 企业内部用户 |
互联网线上用户 |
| 用户量 | 小 | 庞大 |
| 并发考虑 | 少/几乎不用考虑 |
必须考虑 |
| 项目代码量 | 代码量 |
少多 |
| 数据量 | 小 | 海量数据 |
| 架构方式 | 单体式架构 | 分布式微服务架构 |
| 开发团队 | 单个团队 |
多个团队 |
| 部署 | 单个服务器 |
集群服务器 |
| 运维复杂度 | 低 | 高 |
微服务架构-常见微服务框架:
Dubbo/Dubbox
- 阿里巴巴开发/当当改良
- 基于RPC(Remote Procedure Call)框架
SpringCloud
- Spring团队开发
- 基于RESTful(Representational State Transfer)架构
微服务架构-服务类型
把项目模块拆分开,对每个项目进行分类分为:
Provider
- 提供者,提供服务的一方
Consumer
- 消费者,调用服务的一方

架构拆分-图3
微服务架构-通信方式
RPC
- Remote Procedure Call
- 支持RPC的微服务框架:Dubbo/Dubbox
- 基于TCP、平台有关
RESTful
- Representational State Transfer
- 支持RESTful的微服务框架:Spring Cloud/Dubbox
- 基于HTTP、平台无关
分布式和集群
分布式
- 关注项目拆分
集群
- 关注项目部署
大觅网结构设计
- 业务架构
- 应用架构
- 技术架构
- 数据库架构
四个维度进行设计
架构设计-业务架构

业务架构-图4
架构设计-应用架构
应用类型
- 前端
- 网关
- 环境
- 消费者
- 基础
- 提供者

应用架构-图5
架构设计-技术架构
- 技术类型
- 数据库
- 搜索
- 缓存
- 提供者
- 注册中心
- 消费者
- 网管
- 。。。

设计架构-图6
架构设计-数据库架构

数据库设计-图7

订单表--排期表-节目表-剧院表-座位表-排期座位表的关系-图8
项目管理
- 版本管理-Git
- 代码规范管理-Sonar
- 项目敏捷管理-Scrum
项目管理-版本管理设计
- 分布式版本控制系统(DVCS)

Git版本管理设计-图9
根据服务分库
- 用户提供者
- 用户消费者
- 排期提供者
- 排期消费者
- 订单提供者
- 订单消费者
- 。。。

Git仓库分类-图10
项目管理-代码规范管理设计
框架
- SonarQube
作用
- 检查代码规范
- 检查代码缺陷
- 提高开发速度
支持语言
- Java、C、C++、JavaScript
服务器安装+本地安装
项目管理-团队管理设计
敏捷开发
- 以人为核心、遵循迭代、循序渐进的开发方式
敏捷的框架
- XP、Scrum
Scrum框架
- 将整个开发周期划分为若干个小的迭代周期的一种项目管理框架
Scrum框架运行流程:

Scrum框架运行流程-图11
Docker介绍

Docker概念
- 开源
- 容器
- 隔离
Docker和虚拟机
- 相似
- 虚拟机6层架构
- Docker5层架构

虚拟机架构-图12

Docker架构-图13
Docker相关概念
Docker Container(容器)
- 沙箱机制
- 容器和容器之间是相互独立的
Docker Image(镜像)
- 容器备份
Docker Registry(记录中心/仓库)
- 存储镜像
- 官方
- 第三方机构
Docker容器网络IP
- host模式
- container模式
- none模式
- bridge模式(默认)
Docker端口映射
- -p(Docker镜像映射到宿主机的某个端口)
Docker运行原理
Client
- 用户
Docker_Host
- Docker的宿主机
DockerRegistry
- 官方
- 第三方机构

Docker运行原理-图14
Linux环境搭建
1.安装Docker
sudo yum update -y #更新内核 sudo yum install docker -y #安装docker容器 sudo service docker start #启动服务 sudo docker --version #查看版本 sudo systemctl start docker #加入开机启动1步 sudo systemctl enable docker #加入开机启动2步 shutdown -r now #重新启动虚拟机 systemctl status docker #是否开启状态
2.下载镜像
语法:
docker pull [OPTIONS] NAME[:TAG|@DIGEST]
-
-a :拉取所有 tagged 镜像
-
--disable-content-trust :忽略镜像的校验,默认开启
TAG说明:
不同的镜像版本号标志
示例:
sudo docker pull centos:centos7
3.查看本地镜像
语法:
docker images [OPTIONS] [REPOSITORY[:TAG]]
OPTIONS说明:
-
-a :列出本地所有的镜像(含中间映像层,默认情况下,过滤掉中间映像层);
-
--digests :显示镜像的摘要信息;
-
-f :显示满足条件的镜像;
-
--format :指定返回值的模板文件;
-
-
-q :只显示镜像ID。
示例:
sudo docker images
各个列说明:
-
REPOSITORY:表示镜像的仓库源
-
TAG:镜像的标签
-
IMAGE ID:镜像ID
-
CREATED:镜像创建时间
-
SIZE:镜像大小
搜索镜像
语法:
docker search [OPTIONS] 镜像名称
OPTIONS说明:
-
--automated :只列出 automated build类型的镜像;
-
--no-trunc :显示完整的镜像描述;
-
-s :列出收藏数不小于指定值的镜像。
示例:
sudo docker search tomcat
各个选项说明:
-
NAME:镜像仓库源的名称
-
DESCRIPTION:镜像的描述
-
OFFICIAL:是否docker官方发布
修改镜像名称
语法:
docker tag IMAGEID NAME:TAG
示例:
sudo docker tag 9f38484d220f centos:latest #把镜像ID叫9f38484d220f的名称改为centos
sudo docker rmi docker.io/centos #删除原有的
删除镜像
语法:
docker rmi [OPTIONS] IMAGE [IMAGE...]
OPTIONS说明:
-
-f :
-
--no-prune :不移除该镜像的过程镜像,默认移除;
示例:
sudo docker rmi -f tomcat #删除tomcat镜像
sudo docker rmi $(sudo docker images |grep envdm) #删除多个镜像 镜像名包含envdm的
容器的操作
1、生成容器
语法:
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
OPTIONS常用说明:
-
-d: 后台运行容器,并返回容器ID;
-
-i: 以交互模式运行容器,通常与 -t 同时使用;
-
-p: 端口映射,格式为:主机(宿主)端口:容器端口
-
-t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用;
-
--name="nginx-lb": 为容器指定一个名称;
-
-h "mars": 指定容器的hostname;
-
-m :设置容器使用内存最大值;
-
--net="bridge": 指定容器的网络连接类型,支持 bridge/host/none/container: 四种类型;
none无网络,host宿主网络,bridge默认,每个容器独立网络,container容器共用一个网络
-
--expose=[]: 开放一个端口或一组端口;
-
--link=[]: 添加链接到另一个容器;
示例:
sudo docker run -it -d -p 8080:8080 --name tomcat 容器id
#生成启动容器,端口号8080,容器名称tomcat
2、容器网络操作
语法:
docker network create 网络名称 #创建网络
docker network ls #列出创建的网络
docker network rm 网络名称 #删除创建的网络
docker network disconnect 网络名称 #禁用连接网络
示例:
#创建一个envdm网络地址192.168.1.1 sudo docker network create --subnet=192.168.84.1/24 envdm #创建tomcat容器 指定IP192.168.1.8 sudo docker run -it -d --net envdm --ip 192.168.83.8 --name tomcat centos
3、查看容器
语法:
docker ps [OPTIONS]
OPTIONS常用说明:
-
-a :显示所有的容器,包括未运行的。
-
-f :根据条件过滤显示的内容。
-
-l :显示最近创建的容器。
-
-n :列出最近创建的n个容器。
-
-s :显示总的文件大小。
示例:
sudo docker ps -a | grep tomcat #查找tomcat容器运行和未运行的都显示
4、进入容器
语法:
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
OPTIONS常用说明:
-
-d :分离模式: 在后台运行
-
-i :即使没有附加也保持STDIN 打开
-
-t :分配一个伪终端
示例:
sudo docker exec -it tomcat /bin/bash #进入tomcat容器
5、退出容器
语法:
exit
6、停止容器
语法:
docker stop containerId/containerName
示例:
sudo docker stop tomcat #停止tomcat容器
7、启动容器
语法:
docker start containerId/containerName
示例:
sudo docker start tomcat #启动tomcat容器,此容器必须存在
8、删除容器
语法:
docker rm containerId/containerName
示例:
sudo docker rm tomcat #删除tomcat容器 sudo docker rm $(sudo docker container ls -f "status=exited" -q) #删除多个退出的容器 docker rm $(docker container ls -aq) #删除所有容器
9、拷贝文件到容器
语法:
docker cp 宿主机目录及文件 容器名称:容器目录
示例:
sudo docker cp jdk-8u201-linux-x64.tar.gz tomcat:/home/apps/jdk-8u201-linux-x64.tar.gz
#把宿主机当前目录下的jdk-8u201-linux-x64.tar.gz复制到容器tomcat的/home/apps文件夹下
10、查看日志
语法:
docker logs [OPTIONS] CONTAINER
OPTIONS常用说明:
-
--details :显示更多的信息
-
-f, --follow :跟踪实时日志
-
--since string :显示自某个timestamp之后的日志,或相对时间,如42m(即42分钟)
-
--tail string:从日志末尾显示多少行日志, 默认是all
-
-t, --timestamps :显示时间戳
-
--until string :显示自某个timestamp之前的日志,或相对时间,如42m(即42分钟)
示例:
#查看指定时间后的日志,只显示最后100行 sudo docker logs -f -t --since="2018-02-08" --tail=100 dm_zuul-gateway_1 #查看最近30分钟的日志 sudo docker logs --since 30m dm_zuul-gateway_1 #查看实时日志 sudo docker logs -f dm_zuul-gateway_1
11、容器打包镜像
语法:
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
OPTIONS常用说明:
-
-a :提交的镜像作者
-
-c :使用Dockerfile指令来创建镜像
-
-m :提交时的说明文字
-
-p :在commit时,将容器暂停
示例:
sudo docker commit -m "第一个版本" -p tomcat web-demo:latest #上传时登录失败 安装加密软件 sudo apt install gnupg2 pass -y
创建tomcat容器发布项目
1、下载centos镜像
sudo apt-get update #更新资源链接
sudo docker pull centos #下载centos镜像
2、运行容器
sudo docker run -it -p 8080:8080 --name tomcat centos
3、复制jdk到tomcat容器中去
sudo docker cp jdk-8u201-linux-x64.tar.gz tomcat:/home/jdk-8u201-linux-x64.tar.gz
4、复制tomcat到容器中去
sudo docker cp apache-tomcat-7.0.93.tar.gz tomcat:/home/apache-tomcat-7.0.93.tar.gz
5、进入到tomcat容器中
sudo docker exec -it tomcat /bin/bash
7、解压JDK和Tomcat
tar -zxvf jdk-8u201-linux-x64.tar.gz tar -zxvf apache-tomcat-7.0.93.tar.gz
8、删除压缩JDK和Tomcat文件
rm -f jdk-8u201-linux-x64.tar.gz rm -f apache-tomcat-7.0.93.tar.gz
9、配置JDK的环境变量(临时)
export JAVA_HOME=/home/jdk1.8.0_144 export PATH=$JAVA_HOME:$PATH
10、Tomcat给执行权限
chmod 777 apache-tomcat-7.0.93/bin
11、启动Tomcat
./apache-tomcat-7.0.93/bin/catalina.sh start
12、访问
http://虚拟机IP:8080
使用Dockerfile构建基础镜像
Dockerfile概念
1、什么是Dockerfile
Dockerfile是一个包含用于组合镜像的命令的文本文档。可以使用在命令行中调用任何命令。 Docker通过读取Dockerfile中的指令自动生成镜像。

生成镜像的几种方式-图15
2、基本结构
Dockerfile的文件介绍
1、FROM 指定基础镜像,必须是第一个指令
FROM <image> [AS <name>] FROM <image>:[<tag>] [AS <name>] FROM <image>[@<digest>] [AS <name>]
示例:
FROM centos:7 # 编译阶段 命名为 centos7 FROM centos:7 as centos7 ARG CODE_VERSION=7 FROM centos:${CODE_VERSION}
注:tag或digest是可选的,如果不使用这两个值时,会使用latest版本的基础镜像
2、MAINTAINER 指定作者
格式:
MAINTAINER <name>
示例:
MAINTAINER hary_lei
sudo docker inspect dmw_redis #查看作者信息
3、RUN构建镜像时执行的命令
RUN用于在镜像容器中执行命令,其有以下两种命令执行方式:
shell执行格式:
RUN <command>
exec执行格式:
RUN ["executable", "param1", "param2"]
示例:
RUN rm apache-tomcat-8.5.43.tar.gz #shell执行
4、ADD将本地文件添加到容器中
ADD将本地文件添加到容器中,tar类型文件会自动解压(网络压缩资源不会被解压),可以访问网络资源。
语法:
ADD <src>... <dest> ADD ["<src>",... "<dest>"] 用于支持包含空格的路径
示例:
ADD apache-tomcat-8.5.43.tar.gz /usr/local/ # apache-tomcat-8.5.43.tar.gz添加到 usr/local下 ,可以使用* ?,*表示任意,?表示一个
5、COPY将本地文件添加到容器中
COPY和ADD类似,但不会自动解压,也不能访问网络资源。
6、CMD容器启动时才进行调用
语法:
CMD ["executable","param1","param2"] CMD command param1 param2
示例:
CMD ["/usr/bin/supervisord"] CMD /usr/sbin/sshd -D
7、ENTRYPOINT配置容器使其可执行化
语法:
ENTRYPOINT ["executable", "param1", "param2"] ENTRYPOINT command param1 param2
示例:
ENTRYPOINT ["java","-server","-Xms64m","-Xmx128m","-jar","dm-base-consumer-1.0-SNAPSHOT.jar"]
注:ENTRYPOINT与CMD非常类似,不同的是通过docker run 命令中指定的任何参数,都会被当做参数再次传递给ENTRYPOINT
Dockerfile中只允许有一个ENTRYPOINT命令,多指定时会覆盖前面的设置,而只执行最后的ENTRYPOINT指令
8、ENV设置环境变量
语法:
ENV <key> <value>
ENV <key>=<value> ...
示例:
ENV JAVA_HOME=/usr/local/java/jdk1.8.0_212 ENV PATH=$JAVA_HOME/bin:$PATH
9、EXPOSE指定于外界交互的端口
语法:
EXPOSE <port> [<port>...]
示例:
EXPOSE 22 EXPOSE 8080
注:EXPOSE并不会让容器的端口访问到主机。要使其可访问,需要在docker run运行容器时通过-p来发布这些端口,或通过-P参数来发布EXPOSE导出的所有端口。
10、WORKDIR指定工作目录,类似于cd命令
语法:
WORKDIR /path/to/workdir
示例:
WORKDIR /usr/local/
注:通过WORKDIR设置工作目录后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT、ADD、COPY等命令都会在该目录下执行。
11、USER指定运行容器时的用户名或 UID,后续的 RUN 也会使用指定用户
语法:
USER user
USER user:group
USER uid
USER uid:gid
USER user:gid
USER uid:group
示例:
USER elsearch
注:使用USER指定用户后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT都将使用该用户。
语法:
sudo docker build [OPTIONS] PATH | URL | -
OPTIONS说明:
-
--tag, -t: 镜像的名字及标签,通常 name:tag 或者 name 格式
示例:
#进入centos7文件的目录下运行 sudo docker build -t yi/centos7-ssh . #.指的是当前目录下的Dockerfile文件 sudo docker build -t yi/centos7-jdk8u212 . sudo docker build -t yi/centos7-tomcat8 .
13、docker问题
问题1:容器中使用:ping www.baidu.com出现如下错误
ping: www.baidu.com: Name or service not known
解决办法:
vi /etc/resolv.conf #修改DNS #设置如下值 nameserver 8.8.8.8 nameserver 114.114.114.114

问题2:使用xshell登录不上容器
解决方法:使用如下命令创建容器
sudo docker run -it -p 8080:8080 -p 23:22 --privileged=true --name tomcat8 web-demo /usr/sbin/init
修改sshd_config文件
vi /etc/ssh/sshd_config #Port 22 此处注释去了 #PermitRootLogin yes 此处注释去了
重启ssh服务
systemctl start sshd.service #启动服务
systemctl restart sshd.service #重启动服务
使用docker-compose构建其它镜像服务
docker-compose概念
docker-compose 是 Docker 容器进行编排的工具,定义和运行多容器的应用,可以一条命令启动多个容器,使用docker-compose不再需要使用shell脚本来启动容器。
docker-compose使用介绍
1、安装docker-compose
centos7安装
#创建用户组docker sudo groupadd docker #把user用户分到docker用户组里面 sudo gpasswd -a user docker sudo service docker restart sudo yum -y install epel-release sudo yum -y install python-pip #安装pip sudo python -m pip install --upgrade pip #pip进行升级 sudo curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose #安装docker-compose sudo chmod +x /usr/local/bin/docker-compose #添加可执行权限 sudo docker-compose -version #查看版本
2、解析docker-compose.yml文件
version: '2' #表示该 Docker-Compose 文件使用的是 Version 2 file services: redis: # 指定服务名称 build: /home/px2/envdm/Redis/ #指定Dockerfile所在路径 environment: #定义环境变量 - TZ=Asia/Shanghai #指定时区 mem_limit: 300M # 指定限制内存大小 ports: # 指定端口映射 - "6379:6379" elasticsearch: # 指定服务名称 build: /home/px2/envdm/Elasticsearch/ #指定 Dockerfile所在路径 environment: - TZ=Asia/Shanghai mem_limit: 300M ports: # 暴露端口信息 - "宿主机端口:容器暴露端口" - "9200:9200" - "9300:9300" networks: default: external: name: envdm #使用已存在的网络 如果前面没有使用docker network create envdm网络此处则会报错
3、docker-compose命令使用
#ps sudo docker-compose ps #列出所有运行容器 #logs sudo docker-compose logs #查看服务日志输出 #build sudo docker-compose build #构建或者重新构建服务 #start sudo docker-compose start envdm_mysql_1 #启动指定服务已存在的容器 #stop sudo docker-compose stop envdm_mysql_1 #停止已运行的服务的容器 #rm sudo docker-compose rm envdm_mysql_1 #删除指定服务的容器 #up sudo docker-compose up envdm_mysql_1 #构建、启动容器envdm_mysql_1 sudo docker-compose up -d #把当前目录下的docker-compose.yml中的所有服务构建镜像、启动容器 #kill sudo docker-compose kill envdm_mysql_1 #通过发送 SIGKILL 信号来停止指定服务的容器
4、构建服务
把这些文件放到docker-compose.yml指定路径下,如下图:

在linux的此目录下使用如下命令构建基础服务:
sudo docker-compose up -d
可能会出现有些安装包网络连接异常,或者版本不存在问题。docker-compose.yml文件中指定的Dockfile文件路径不对问题也需要注意。
5、设置mysql远程登录
开启mysql服务
docker start service_mysql_1
1、进入容器
sudo docker exec -it service_mysql_1 /bin/bash
2、登录mysql数据库
mysql -uroot -p
3、切换数据库
use mysql
4、修改root密码为123456
update user set password=password('123456') where user='root' and host='localhost';
5、允许远程登录root用户
grant all privileges on *.* to root@'%' identified by '123456' with grant option;


浙公网安备 33010602011771号