Spring Cloud

环境

  • IDEA 或 Eclipse(STS插件)

  • Lombok

  • Maven

    • 如果下载依赖有问题,更换阿里仓库和中央仓库
    <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                              https://maven.apache.org/xsd/settings-1.0.0.xsd">
    	<localRepository>D:\home\java\maven_repository</localRepository>
    
    	<mirrors>
    		<!--  打开阿里仓库,使用阿里仓库更新依赖
                  注释调用阿里仓库,使用中央仓库更新依赖
            -->
    		<mirror>
    			<id>alimaven</id>
    			<name>aliyun maven</name>
    			<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
    			<mirrorOf>central</mirrorOf>
    		</mirror>
    
    	</mirrors>
    </settings>
    

spring cloud是什么

  • spring cloud 是一个工具集

    • 集成多个工具,来解决微服务中的各种问题
    • 微服务全家桶
  • spring cloud 不是什么?

    • spring cloud 不是一个解决单一问题的工具
  • 远程调用 - RestTemplate

  • 负载均衡 - Ribbon

  • 重试 - Ribbon

  • 降级、熔断、限流 - Hystrix

  • 监控 - Hystrix Dashboard、Turbine、Sleuth、Zipkin

  • 配置中心 - Config server

  • 课程要求

    必须严格按照笔记做

    笔记中都是完整代码

    做的过程中不能直接 cv ,要自己手敲!!!

    如果遇到问题解决不了时,把前面做的一步代码cv一遍!!!

    业务模块

    02-item

    03-user

    04-order

    1. 工具类 - 不用自己写,在gitee或github搜索

      CookieUtil、JsonUtil、JsonResult

    2. TypeReference

      指定转换的类型: new TypeReference<List>() {}

    3. @RequestBody

      用来接收参数,从请求的协议体,完整接收协议体数据

    注册和发现

    注册中心产品:

    ​ zookeeper、eureka、nacos、consul、etcd…

    eureka

    1. 注册

    服务提供者启动时,向eureka一次次反复注册,直到注册成功为止

    1. 拉取注册表

    服务发现者每30秒拉取一次注册表(刷新注册表)

    1. 心跳

    服务提供者每30秒发送一次心跳数据

    eureka连续3次收不到一个服务的心跳,会删除这个服务

    1. 自我保护模式

    特殊情况

    如果由于网络不稳定或中断,15分钟内,85%以上服务器出现心跳异常,就会自动进入保护模式。

    在保护模式下,所有服务都不删除

    网络恢复后,可以自动退出保护模式,恢复正常

    开发期间很容易达到保护模式的条件,会影响测试,在开发期间可以关闭保护模式

    eureka 和 zookeeper 区别:

    • eureka:
      • 强调AP(可用性)
      • 集群结构:对等结构
    • zookeeper:
      • 强调CP(一致性)
      • 集群结构:主从结构

    搭建eureka服务器

    1. 新建 springboot 项目
    2. 添加 eureka server 依赖
    3. yml配置
      1. 主机名
      2. 禁用保护模式
      3. 针对单台服务器,配置不向自己注册,也不从自己拉取注册表
    4. 启动类注解 @EnableEurenaServer,通过注解触发自动配置

    单台 eureka 服务器启动后报错: Connect to localhost:8761 timed out

这是自动配置的一个默认集群服务器,但是这个默认服务器不存在,所以出错

后面自己搭建了集群服务,默认服务器就不会再自动配置

作业

  1. 提前下载最新依赖

课前资料\pom.xml

新建一个 maven 项目,把 pom.xml 代码粘进去,修改版本

  • springboot:2.4.0

  • springcloud: 2020.0.0-M5

    • pom.xml末尾添加
      <repositories>
            <repository>
              <id>spring-milestones</id>
                <name>Spring Milestones</name>
              <url>https://repo.spring.io/milestone</url>
            </repository>
      </repositories>
    

    然后更新依赖

    1. 安装新版 VMware

先卸载旧版本(江哥虚拟机镜像不会受影响)

再安装新版本

尽量用最新VMware,新版本对资源使用、运行效率都会有优化。

课前资料中提供了两个版本

  • 15.5.2
  • 12.x - 旧电脑cpu不支持虚拟化技术,可以使用12.x

官网还有有最新的 16 版本

Springboot 和 Springcloud 版本

  • springboot: 2.3.5.RELEASE
  • springcloud: Hoxton.SR9

02、03、04、05,都改

服务提供者

修改hosts文件,添加 eureka1 和 eureka2 的映射配置

C:\Windows\System32\drivers\etc\hosts

127.0.0.1  eureka1
127.0.0.1  eureka2

修改 02、03、04 这三个项目

  1. 添加 eureka client 依赖
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>
				spring-cloud-starter-netflix-eureka-client
			</artifactId>
		</dependency>
	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>Hoxton.SR9</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>
  1. yml配置eureka的注册连接地址: http://eureka1:2001/eureka
eureka:
  client:
    service-url:
      defaultZone: http://eureka1:2001/eureka

sp02商品,和 sp05 eureka 集群

在另一个端口上再启动一个商品服务

java -jar item.jar  # 根据application.yml的配置来启动

# 指定端口启动
java -jar item.jar --server.port=8002  # 命令行参数可以覆盖yml配置

远程调用

RestTemplate

springboot 提供的远程调用工具

类似于 HttpClient,可以发送 http 请求,并处理响应。RestTemplate简化了Rest API调用,只需要使用它的一个方法,就可以完成请求、响应、Json转换

方法:

  • getForObject(url, 转换的类型.class, 提交的参数)
  • postForObject(url, 协议体数据, 转换的类型.class)

RestTemplate 和 Dubbo 远程调用的区别:

  • RestTemplate:
    • http调用
    • 效率低
  • Dubbo:
    • RPC调用,Java的序列化
    • 效率高

Ribbon

Springcloud集成的工具,作用是负载均衡,和重试

负载均衡

Ribbon 对 RestTemplate 做了封装,增强了 RestTemplate 的功能

  1. 获得地址表
  2. 轮询一个服务的主机地址列表
  3. RestTemplate负责执行最终调用

添加负载均衡

  1. ribbon依赖
  2. @LoadBalanced 注解,对 RestTemplate 进行功能增强
  3. 修改调用地址,使用 服务id,而不是具体主机地址

Ribbon 重试

一种容错机制,当调用远程服务失败,可以自动重试调用

添加重试:

  1. 添加 spring-retry 依赖

  2. 配置重试参数

    1. 在yml中配置
    • MaxAutoRetries:单台服务器的
    • MaxAutoRetriesNextServer:更换服务器的次数
    1. 在java代码中设置
    • ConnectTimeout:与远程服务建立网络连接的超时时间
    • ReadTimeout:连接已建立,请求已发送,等待响应的超时时间

Hystrix

系统容错工具

  • 降级
    • 调用远程服务失败(宕机、500错、超时),可以降级执行当前服务中的一段代码,向客户端返回结果
    • 快速失败
  • 熔断
    • 当访问量过大,出现大量失败,可以做过热保护,断开远程服务不再调用
    • 限流
    • 防止故障传播、雪崩效应

降级

  1. hystrix依赖
  2. 启动类添加注解 @EnableCircuitBreaker
  3. 添加降级代码
// 当调用远程服务失败,跳转到指定的方法,执行降级代码
@HystrixCommand(fallbackMethod="方法名")
远程调用方法() {
	restTemplate.getForObject(url,......);
}

Hystrix超时

Hystrix有默认的超时时间:1秒

Hystrix超时要大于ribbon总的重试时间,否则,ribbon重试可能无效

Hystrix 熔断

短路器打开的条件:

  • 10秒内20次请求(必须首先满足)
  • 50%失败,执行了降级代码

短路器打开后,所有请求直接执行降级代码

断路器打开几秒后,会进入半开状态,客户端调用会尝试向后台服务发送一次调用,

如果调用成功,断路器可以自动关闭,恢复正常

如果调用仍然失败,继续保持打开状态几秒钟

Hystrix 故障监控 - Hystrix Dashboard

Hystrix 利用 Actuator 工具,来暴露 Hystrix 的故障日志

Actuator

springboot 提供的日志监控工具,可以暴露项目中多种监控信息

  • 健康状态
  • 系统环境变量
  • spring容器中所有的对象
  • spring mvc映射的所有路径

添加 actuator

  1. 添加 actuator 依赖
  2. yml 配置暴露监控数据
    • m.e.w.e.i="*" 暴露所有的监控
    • m.e.w.e.i=health 只暴露健康状态
    • m.e.w.e.i=[“health”, “beans”, “mappings”] 暴露指定的多个监控

搭建 Hystrix Dashboard

仪表盘项目可以是一个完全独立的项目,与其他项目都无关,也不用向注册表注册

  1. hystrix dashboard 依赖
  2. @EnableHystrixDashboard
  3. yml - 允许对哪台服务器开启监控
hystrix:
  dashboard:
    proxy-stream-allow-list: localhost

Feign

远程调用:RestTemplate

ribbon

hystrix

集成工具

  • 远程调用:声明式客户端
  • ribbon 负载均衡和重试
  • hystrix 降级和熔断

声明式客户端接口

只需要声明一个抽象接口,就可以通过接口做远程调用,不需要再使用 RestTemplate 来调用

// 调用远程的商品服务,获取订单的商品列表
// 通过注解,配置:
// 1. 调用哪个服务
// 2. 调用服务的哪个路径
// 3. 向路径提交什么参数数据
@FeignClient(name="item-service")
public interface ItemClient {
    @GetMapping("/{orderId}")
    JsonResult<List<Item>> getItems(@PathVariable String orderId);
}

在这里使用 @GetMapping("/{orderId}"), 指定的是向远程服务调用的路径

Feign 集成 Ribbon

0配置,已经启用了负载均衡和重试

默认重试参数:

  • MaxAutoRetries: 0
  • MaxAutoRetriesNextServer: 1
  • ReadTimeout: 1000

虚拟机

  1. 解压缩虚拟机

课前资料\虚拟机\

  • centos-7-1908.zip

    适用于 VMware 15 以上的虚拟机

  • centos-7-1908-vmware-12.zip

    使用与 VMware 12 或以上的虚拟机

  1. 双击 centos-7-1908.vmx 文件(三个窗口图标)

  2. 启动这个虚拟机

    按提示选择“已复制虚拟机”

  3. 登录

    username: root

    password: root (输入密码时没有人反应,实际已经输入成功,直接回车)

重置 VMware 虚拟网络

VMware 的虚拟网络非常不稳定,经常出现问题

  • 没有ip
  • 没有网卡
  • 一切正常,但ping不通

重置VMware虚拟网络环境:

删除所有的虚拟网卡,再重新创建,初始化网络

  1. 编辑 - 虚拟网络编辑器
  2. 点右下角“更改设置”获得管理员权限
  3. 左下角“还原默认设置”按钮

设置 NAT 网络网段: 192.168.64.0

编辑 - 虚拟网络编辑器

选择 VMnet8 网卡

下面网段设置成 192.168.64.0

设置 centos7-1908 的ip

# 在 /root/ 主目录下准备了两个脚本程序: ip-static 和 ip-dhcp
# 里面修改网卡的配置文件 /etc/sysconfig/network-scripts/ifcfg-ens33
ll

cat ip-static
cat ip-dhcp

# 动态分配ip
./ip-dhcp
ifconfig

# 指定固定ip
./ip-static
ip: 192.168.64.8

ifconfig

如果网络服务 network.service 服务无法启动,可能是和 NetworkManager 服务发生冲突,可以禁用 NetworkManager

# 停止 NetworkManager 服务
systemctl stop NetworkManager

# 禁用 NetworkManager
systemctl disable NetworkManager

Rabbitmq 虚拟机

  1. 从 centos-7-1908 克隆: rabbitmq
  2. 设置 ip
./ip-static
ip: 192.168.64.140
  1. 用 mobaxterm 连接 rabbitmq

  2. 上传rabbitmq的离线安装文件

    1. 解压 rabbitmq-install.zip
    2. 上传 rabbitmq-install 文件夹到 /root/

Feign 集成 Hystrix

Feign默认不启用Hystrix,不推荐启用Hystrix(后面再分析)

启用Hystrix基础配置:

  1. hystrix起步依赖
  2. yml中配置启用hystrix
feign.hystrix.enabled=true
  1. 启动类添加注解 @EnableCircuitBreaker

添加降级代码:

@FeignClient(name="item-service", fallback=降级类.class)
public interface ItemClient {
    @GetMapping("/{orderId}")
    JsonResult<List<Item>> getItems(@PathVariable String orderId);
}

降级类需要实现声明式客户端接口,在实现的抽象方法中添加降级代码,

降级类需要添加 @Component 注解

Feign 集成 Hystrix,添加监控

  1. 添加 actuator 依赖
  2. 暴露 hystrix.stream 监控端点
  3. 查看监控日志
    1. 重启09
    2. 访问 http://localhost:3001/actuator/

订单中添加 feign,调用商品和用户

  1. 添加依赖
    • feign
    • hystrix
    • actuator
  2. yml
    • feign.hystrix.enabled=true
    • m.e.w.e.i=hystrix.stream
  3. 启动类注解
    • @EnableFeignClients
    • @EnableCircuitBreaker

Turbine

聚合 Hystrix 监控数据

连接多台服务器,抓取日志数据,进行聚合,

交给仪表盘在同一个监控界面进行展现

搭建 Turbine 服务

  1. 添加 Turbine、eureka client 依赖
  2. yml 配置
    • 聚合的服务id:order-service, aa, bb, cc
    • 为聚合的监控数据命名: cluster-name=new String(“default”)
  3. 启动类添加注解 @EnableTurbine

消息服务器

分布式系统中广泛应用消息服务

消息服务器:

  • rabbitmq
  • activemq
  • rocketmq
  • tubemq

Zuul

API 网关

  • 微服务系统统一的调用入口
  • 统一的权限校验
  • 集成ribbon
  • 集成hystrix

统一的调用入口

  1. zuul 依赖、eureka client依赖、sp01

  2. yml

    # 配置调用转发规则
    # 下面是 zuul 默认的转发规则
    # 如果不手动配置,zuul可以根据注册表的注册信息进行自动配置
    zuul:
      routes:
        item-service: /item-service/**
        user-service: /user-service/**
        order-service: /order-service/**
    
  3. 启动类注解: @EnableZuulProxy

统一权限校验

通过 zuul 过滤器,可以判断用户是否有权限访问后台服务,如果没有权限可以阻止用户继续访问

判断用户是否登录,登录猜允许访问商品服务

http://localhost:3001/item-service/u45y45435 没有登录不允许访问

http://localhost:3001/item-service/u45y45435?token=y45343t4 有token认为登录过,允许访问

添加过滤器

  1. 继承 ZuulProxy
  2. 添加 @Component

zuul 会对过滤器进行自动配置

zuul 集成 ribbon

默认启用了 ribbon 的负载均衡

默认不启用重试,zuul不推荐启用重试

启用重试:

  1. spring-retry 依赖

  2. yml

    zuul.retryable=true
    
  3. 重试参数

    有默认参数,可以根据需要进行调整

zuul 集成 hystrix

0配置,已经启用了hystrix

添加降级代码

  1. 实现 FallbackProvider 接口,在子类中实现降级代码
  2. @Component

zuul的自动配置,会自动配置降级类

Zuul 和 Feign

  • 都可以调用后台服务
  • 都可以集成 ribbon
  • 都可集成 hystrix

zuul

  • 部署在所有微服务项目之前

  • 网关一般是一个独立的服务,与业务无关

  • 不推荐启用重试

    会造成后台服务压力翻倍

    重试尽量不部署在最前面,越往后越好

feign

  • 部署在微服务内部,服务和服务之间调用

  • 不推荐启用 hystrix

    一般在最前面进行降级和熔断,类似于电箱断路器,只在入户位置部署,

    不在微服务内部部署hystrix,否则会引起混乱

准备仓库

  1. 新建module: config,当做一个文件夹,用来存放配置文件
  2. 把 2,3,4,11 项目的配置文件,放到 config 文件夹
  3. springcloud1 工程目录创建本地仓库
    1. VCS - Import into version control - Create git repository
    2. 选择 springcloud1 工程目录设置成本地仓库
  4. 把本地仓库提交推送到gitee远程仓库
    1. ctrl + k 或 VCS - commit
    2. 勾选要提交的文件,填写提交信息,点击提交
    3. ctrl+shift+k 或 VCS - git - push
    4. 点击左上角 define remote

配置中心

  1. config server 依赖

  2. yml

    远程仓库 uri: https://gitee.com/ningning1599510557/springcloud1
    搜索的子目录: config
    
    如果是私有仓库,还要提供用户名和密码
    
  3. @EnableConfigServer

配置中心客户端

修改 2,3,4,11 项目

  1. config client 依赖

  2. 新建配置文件: bootstrap.yml

    bootstrap.yml 是引导配置文件,它先于application.yml加载

  3. bootstrap.yml 添加配置

    1. 连接eureka, 从注册表得到配置中心的地址
    2. 连接配置中心
    3. 从配置中心下载指定的配置文件

rabbitmq工作模式

合理分发消息

  1. 通过回执,通知服务器消息处理完成

    • 通过回执,服务器可以知道消费者有没有处理完消息
  2. qos=1

    每次只从服务器抓取一条消息,这条消息处理完成之前,不会抓取下一条,

    必须在手动ACK模式下 qos设置才有效

消息持久化

防止服务器崩溃、重启造成消息丢失,需要把消息保存在磁盘

  1. 队列持久化

    c.queueDeclare(“队列名”, true, …

  2. 消息持久化

    c.basicPublish("", “队列名”, MessageProperties.PERSISTENT_TEXT_PLAIN, 消息)

导入拼多商城项目

  1. 导入数据库
    1. sqlyog 右键点击连接
    2. 选择“从sql转储文件导入”
    3. 亿发课前资料\solr\04-拼多数据库\pd.sql
    4. 导入完成后,右键点击连接,刷新
  2. 新建 Empty Project:pd
  3. 导入模块
    1. D:\home\lesson\课前资料\亿发课前资料\solr\06-拼多项目\pd-web.zip
    2. 解压到 pd 工程目录
    3. 按两下shift,搜索 add maven(添加maven)
    4. 选择 pd-web 下的pom.xml 导入
  4. 数据库连接
    1. 如果用 oracle mysql 8 需要调整数据库驱动和连接参数
    2. 驱动用新版本 8.0.21
    3. yml 中驱动类改成 com.mysql.cj.jdbc.Driver
    4. 连接参数添加 &serverTimezone=GMT%2B8
  5. mapper.xml
    1. 项目中mapper.xml直接放在了java目录下
    2. 需要把xml文件移动到 resources 目录下
  6. 设置工程的jdk
  7. 启动配置,设置 working directory,设置成pd-web模块目录

链路跟踪

sleuth

生成链路跟踪日志的工具

A -> B -> C -> D

A,JF9308F895T,JF9308F895T,true

B,JF9308F895T,HUF92HR72,true

C,JF9308F895T,YT823R2TY4,true

D,JF9308F895T,YH43R23R22,true

服务id,链路id,服务跟踪id,是否发送到zipkin

默认10%的日志发送到zipkin

修改 2,3,4,11

  • 添加 sleuth 只需要添加它的依赖,它是自动配置的
  • 添加 zipkin 客户端依赖、amqp依赖
  • yml 添加rabbitmq的连接信息
  • yml配置日志发送方式:rabbitmq

solr

  1. 克隆 centos-7-1908:solr

  2. 设置ip

    ./ip-static
    ip: 192.168.64.170
    
  3. 两个文件上传到 /root/

    • jdk-8u212-linux-x64.tar.gz
    • solr-8.1.1.tgz
  4. 解压jdk

    tar -xf jdk-8u212-linux-x64.tar.gz -C /usr/local/
    
  5. 配置环境变量

    vim /etc/profile
    
    # 末尾添加下面两行:
    export JAVA_HOME=/usr/local/jdk1.8.0_212
    export PATH=$JAVA_HOME/bin:$PATH
    
  6. 让配置立即生效,并确认配置

    source /etc/profile
    
    java -version
    javac -version
    
  7. 解压 solr

    cd ~/
    tar -xf solr-8.1.1.tgz -C /usr/local/
    
  8. 启动 solr

    cd /usr/local/solr-8.1.1/
    
    bin/solr start -force
    
  9. 开方端口,访问测试

    firewall-cmd --zone=public --add-port=8983/tcp --permanent
    firewall-cmd --reload
    
    http://192.168.64.170:8983/
    

Docker 虚拟机

  1. 克隆 centos-7-1908: docker

  2. 设置ip

    ./ip-static
    ip: 192.168.64.150
    
  3. 上传离线安装文件

    DevOps课前资料\docker\docker课前资料.zip 解压缩

    docker-install 文件夹上传到 /root/

  4. 上传 docker 镜像文件

    5个 *-image.gz 文件,上传到 /root/

  5. 离线安装 docker

    cd ~/docker-install
    
    # 列出 rpm 安装包
    ls
    
    rpm -ivh *.rpm
    
    # 设置系统服务
    systemctl enable docker
    
    # 启动docker系统服务
    systemctl start docker
    

Docker

轻量的虚拟机

VMware

​ 完整虚拟一台计算机,所有的应将、底层系统资源都需要虚拟出来

Docker

充分利用宿主机的硬件和系统资源,自己虚拟的东西非常少

Docker 是开发运维一体化(DevOps)的核心工具

镜像

虚拟机的一组磁盘文件,可以任意分发、复制、下载

# 查看镜像列表
docker images

# 删除镜像
docker rmi hello-world
docker rmi aaaaa bbbbb cccccc dddd
docker rmi id1 id2 id3
# 如果存在容器,不能直接删除镜像,可以加 -f 参数强制删除镜像
docker rmi -f hello-world

镜像名称:

镜像名:标签

标签:一般是部署的应用的版本,或系统环境。如果不指定标签,默认标签是 latest

容器

从镜像运行启动的虚拟机

# 从 tomcat 镜像,运行启动容器
# 参数i: 交互  参数t: 终端
docker images

docker run -it tomcat

# 查看正在运行的容器
docker ps 
# 查看所有容器,包括已关闭的容器
docker ps -a

# 停止或重启容器
docker stop 0c6
docker start 0c6
docker restart 0c6

容器启动后运行的应用:

镜像中设置了默认启动的应用

# 查看镜像中设置的默认应用
docker history tomcat
docker history redis
docker history mariadb

如果不想执行镜像指定的默认命令,也可以自己指定任意命令

docker run -it tomcat ls
docker run -it tomcat top
docker run -it tomcat bash

docker ps -a

删除容器

docker rm 9aa f94

# 不能直接删除正在运行的容器,可以加 -f 强制删除
docker rm -f 0c6

# 清理所有已经退出的容器
docker container prune

启动容器的参数:-d、–name、–rm、–restart=always

# -d 后台运行,不占用控制台
# --name 给容器命名
docker run -d --name cat1 tomcat

docker ps

# 查看容器内部日志
docker logs cat1

# --rm 容器关闭时,自动删除容器
docker run -it --rm tomcat top
# ctrl+c 退出后,容器自动关闭,自动删除,查看容器列表是看不到容器的
docker ps -a

# --restart=always 容器总是自动启动
docker run -d --name cat2 --restart=always tomcat

docker ps

# 重启docker系统服务,cat2也会自动重启,cat1不会自动启动
systemctl restart docker

docker ps

进入容器,在容器内执行命令

docker exec -it cat2 pwd
docker exec -it cat2 ps
docker exec -it cat2 touch f1.txt
docker exec -it cat2 ls
docker exec -it cat2 bash

目录挂载

# -v /usr/app:/opt/app
# -v 宿主机目录:容器中的路径
# 宿主机目录不存在会自动创建
docker run \
-d \
--name cat1 \
-v /usr/app:/opt/app \
tomcat

# 进入cat1容器,在 /opt/app/ 目录下创建文件
docker exec -it cat1 bash
cd /opt/app/
echo 111111111111111 > f1.txt
ls
cat f1.txt

# 退回到宿主机,查看保存在宿主机的文件
exit

cd /usr/app/
ls
cat f1.txt

数据卷挂载

# 创建数据卷
docker volume create my-vol
# 查看数据卷
docker volume ls
# 查看数据卷详情 /var/lib/docker/volumes/my-vol/_data
docker inspect my-vol

# 把 my-vol 数据卷挂载到容器
docker run \
-d --name cat2 \
--rm \
-v my-vol:/opt/app \
tomcat

# 在容器 cat2 的 /opt/app/ 下创建文件
docker exec -it cat2 touch /opt/app/f2.txt
docker exec -it cat2 ls /opt/app/

# 在宿主机 my-vol 数据卷的目录下查看文件
cd /var/lib/docker/volumes/my-vol/_data
ls

端口映射

# 清理容器
docker rm -f cat1 cat2

# 创建 tomcat 容器,映射到宿主机的80端口
docker run \
-d --name cat1 \
--restart=always \
-p 80:8080 \
tomcat

# 访问 http://192.168.64.150
# 在宿主机创建 /opt/web/index.html
mkdir /opt/web/

cat <<EOF >/opt/web/index.html
<h1>Hello docker!!!</h1>
EOF

# 启动容器 cat2
docker run -d --name cat2 \
--restart=always \
-v /opt/web:/usr/local/tomcat/webapps/ROOT \
-p 8088:8080 \
tomcat

# 访问 http://192.168.64.150:8088

容器互联

# 创建网络
docker network create my-net
# 查看网络
docker network ls
# 查看网络详情
docker inspect my-net
# 查看宿主机上新建的虚拟网卡
ifconfig

# 启动容器 app1,连接到my-net网络
docker run -dit --name app1 \
--net my-net \
centos:7
# 启动容器 app2,连接到my-net网络
docker run -dit --name app2 \
--net my-net \
centos:7

# 查看容器描述,可以看到获得的ip地址
docker inspect app1
docker inspect app2

# 从宿主机ping app1和app2的ip
ping 172.18.0.2
ping 172.18.0.3

# 进入 app1,ping宿主机和app2
docker exec -it app1 ping 172.18.0.1
docker exec -it app1 ping 172.18.0.3
docker exec -it app1 ping app2

构建 tomcat:7 镜像

# 新建文件夹 tomcat7
cd ~/
mkdir tomcat7
# 生成 Dockerfile 文件
cd tomcat7

cat <<EOF >Dockerfile
FROM centos:7
ADD jdk-8u212-linux-x64.tar.gz /opt/
ADD apache-tomcat-7.0.96.tar.gz /usr/
RUN mv /usr/apache-tomcat-7.0.96 /usr/tomcat
ENV JAVA_HOME=/opt/jdk1.8.0_212 \
    CATALINA_HOME=/usr/tomcat \
    PATH=$PATH:/opt/jdk1.8.0_212/bin:/usr/tomcat/bin
EXPOSE 8080
ENTRYPOINT /usr/tomcat/bin/startup.sh && tail -F /usr/tomcat/logs/catalina.out
EOF

# 上传 jdk 和 tomcat7 的压缩文件到 /root/tomcat7/

# 完成构建,末尾的点,是当前目录(/root/tomcat7/)
docker build -t tomcat:7 .

# 查看镜像列表
docker images

# 从 tomcat:7 镜像,运行启动容器
docker run -d --name cat3 \
-p 8089:8080 \
tomcat:7

docker logs cat3

http://192.168.64.150:8089

构建 eureka 镜像

# 准备文件
cd ~/
mkdir eureka
cd eureka

# 上传文件 jdk 和 eureka 的 jar 文件到 /root/eureka/ 文件夹
# jdk文件: 课前资料/docker/tomcat7/

# java -jar /opt/sp05-eureka-0.0.1-SNAPSHOT.jar 
# --spring.profiles.active=eureka1 --server.port=2001

cat <<EOF >Dockerfile
FROM centos:7
ADD jdk-8u212-linux-x64.tar.gz /opt/
COPY sp05-eureka-0.0.1-SNAPSHOT.jar /opt/
ENV JAVA_HOME=/opt/jdk1.8.0_212 \
    PATH=$PATH:/opt/jdk1.8.0_212/bin
ENTRYPOINT ["java", "-jar", "/opt/sp05-eureka-0.0.1-SNAPSHOT.jar"]
CMD ["--spring.profiles.active=eureka1", "--server.port=2001"]
EOF

docker build -t eureka:v1 .

# 启动 eureka 容器
docker run -d --name eureka1 \
--restart=always \
-p 2001:2001 \
eureka:v1

docker logs eureka1

http://192.168.64.150:2001

redis

# 启动三个redis容器
docker run -d --name redis7000 -p 7000:6379 redis
docker run -d --name redis7001 -p 7001:6379 redis
docker run -d --name redis7002 -p 7002:6379 redis

# 查看容器
docker ps

# 访问redis服务
docker exec -it redis7000 redis-cli
docker exec -it redis7001 redis-cli
docker exec -it redis7002 redis-cli

web+mysql

网络

# 删除 my-net 网络
docker network rm my-net
# 创建 dockernet 网络
docker network create dockernet --subnet=172.18.0.0/24
# 查看网络
docker network ls
docker inspect dockernet
# 查看宿主机上创建的虚拟网络
ifconfig

启动mysql容器

# 创建数据局卷 mysql-data
docker volume create mysql-data
# 查看数据卷详情
docker inspect mysql-data

# 删除容器
docker rm -f mysql

# 启动mysql
docker run \
-d --name mysql \
-p 3306:3306 \
-v mysql-data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=root \
--restart=always \
--net dockernet \
--ip 172.18.0.11 \
mariadb

# 导入数据 课前资料\docker\EasyMall\easymall.sql

web应用

# 准备宿主机的文件夹和文件
mkdir /opt/webapps

# 上传 课前资料\docker\EasyMall\ROOT.war 到 /opt/webapps/

# 启动 tomcat 容器
docker run -d --name web \
-p 80:8080 \
-v /opt/webapps:/usr/tomcat/webapps \
--net dockernet \
--ip 172.18.0.12 \
tomcat:7

http://192.168.64.150

Kubernetes

全自动容器部署工具 - 持续部署

谷歌的开源工具,在谷歌内部已经运行几年,管理上千万容器

缺点:过于复杂

集群搭建的简化项目:

  • https://github.com/opsnull/follow-me-install-kubernetes-cluster

    手把手部署kubernetes

  • https://github.com/easzlab/kubeasz

    一键安装脚本

K8s 集群方案

  1. 单机 - 16G以上

    一个主控,两个工作节点

  2. 单机 - 8G以上

    一个主控+工作基点,一个工作节点

  3. 多台主机 - 4G

    一台主机启动一个虚拟机,用桥接网络

配置集群环境

  1. 克隆 centos-7-1908: k1

  2. 设置 cpu 和 内存

    cpu - 2

    内存 - 2G

    第三个方案,把网络设置成桥接网络

  3. 设置ip

    ./ip-static
    ip: 192.168.64.191
    
    第三个方案,用自动获取ip
    ./ip-dhcp
    
  4. 上传文件

    • easzup、images.gz 两个文件上传到 /root/
    • ansible 文件夹上传到 /etc/
  5. 执行以下命令

    # 对easzup文件设置执行权限
    chmod +x ./easzup
    
    # 下载离线安装文件,并安装配置docker,
    # 如果离线文件已经存在则不会重复下载,
    # 离线安装文件存放路径: /etc/ansible
    ./easzup -D
    
    # 启动kubeasz工具使用的临时容器
    ./easzup -S
    
    # 进入该容器
    docker exec -it kubeasz sh
    
    # 下面命令在容器内执行
    # 配置离线安装
    cd /etc/ansible
    sed -i 's/^INSTALL_SOURCE.*$/INSTALL_SOURCE: "offline"/g' roles/chrony/defaults/main.yml
    sed -i 's/^INSTALL_SOURCE.*$/INSTALL_SOURCE: "offline"/g' roles/ex-lb/defaults/main.yml
    sed -i 's/^INSTALL_SOURCE.*$/INSTALL_SOURCE: "offline"/g' roles/kube-node/defaults/main.yml
    sed -i 's/^INSTALL_SOURCE.*$/INSTALL_SOURCE: "offline"/g' roles/prepare/defaults/main.yml
    exit
    
  6. 导入镜像

    docker load -i images.gz
    
Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐