回顾第三天知识:
Docker: c/s架构
Docker三个核心组件:
1、镜像(image)
2、容器(container):老师要谨记的命令(重要)
3、镜像中心(regiatry)
第四天开始之上午:
1、了解DockerCompose
== 看明白就成,无需练习 ==
DockerCompose可以基于Compose文件(文本文件)帮我们快速的部署分布式应用,无需一个个创建和运行容器
version: "3.8"
services:
mysql: //-- 镜像构建的容器
image: mysql:5.7.25
environment:
MYSQL_ROOT_PASSWORD: 123
volumes: //-- 目录挂载
- "/tmp/mysql/data:/var/lib/mysql"
web: //--又是一个容器java项目构建的
build: . //-- 基于Dockerfile脚本
ports:
- "8090:8090"
随心记住的东西:
cat docker-compose.yml //查看文本文件内容
<fileName>app<fileName> //定义名称
docker volume create html //--- 创建数据卷
docker volume ls //--- 查看所有数据
docker volume inspect html//--- 查看数据卷详细信息卷
自己理解:容器与容器的相互访问,是docker帮我们创建了虚拟网卡,开发运维部署是一体化的,容器化:[ Devps ,CICD(持续集成,持续部署的软件),容器编排 ]
2、了解搭建私人镜像中心,上传镜像
2.1、简化版镜像仓库
搭建方式比较简单,命令如下:
docker run -d \
--restart=always \
--name registry \
-p 5000:5000 \
-v registry-data:/var/lib/registry \
registry
2.2带有图形化界面版本
使用DockerCompose部署带有图象界面的DockerRegistry,命令如下
version: '3.0'
services:
registry:
image: registry
volumes:
- ./registry-data:/var/lib/registry
ui:
image: joxit/docker-registry-ui:static
ports:
- 8080:80
environment:
- REGISTRY_TITLE=传智教育私有仓库
- REGISTRY_URL=http://registry:5000
depends_on:
- registry
2.3把自己的镜像推送到镜像中心
2.3.1、配置Docker信任地址
# 打开要修改的文件
vi /etc/docker/daemon.json
# 添加内容:
"insecure-registries":["http://192.168.200.130:8080"]
# 重加载
systemctl daemon-reload
# 重启docker服务端
systemctl restart docker
docker-compose up -d : 要先-启动-两个容器
先构建一个镜像,考成压缩包,才能发送到镜像中心
//--创建镜像怎么弄的 忘记了....
//-- 复制镜像并创建一个别名
docker tag javaweb:1.0 192.168.200.130:8080/javaweb:1.0
//-- 向镜像中心推送镜像
docker push 192.168.200.130:8080/javaweb:1.0
//-- 向镜像中心拉去镜像
docker pull 192.168.200.130:8080/javaweb:1.0
//-- 检查是否成功
docker images
docker rmi -f 镜像名称: 这个是删除镜像
docker run —name eureka -p 10086:10086 -d 192.168.200.130:8080/eureka-server:1.0 这样容器就跑起来了
基于两种快捷部署方式要操作一下(小公司适用)
10:20 — 10:47分之间说的
服务异步通讯:MQ组件
同步通信与异步通讯
同步通信:时效性强,立刻得到结果 问题:耦合高
异步通信:吞吐量提示、故障隔离、流量削峰 缺点:依赖于Broker的可靠性、安全性、吞吐能力,,架构复制、没有明显流程线、不好追踪管理
什么是MQ?
事件驱动架构中的Broker,存放消息的队列
单机部署
docker pull rabbitmq:3.8-management //1、--在线拉取
//--安装MQ 执行下面的命令来运行MQ容器:
docker run \
-e RABBITMQ_DEFAULT_USER=itcast \
-e RABBITMQ_DEFAULT_PASS=123321 \
-v mq-plugins:/plugins \
--name mq \
--hostname mq \
-p 15672:15672 \
-p 5672:5672 \
-d \
rabbitmq:3.8-management
docker ps : 看一下容器启动没有
RabbitMQ概述:重要
MQ核心概念设计,遵循的协议:AMQP协议: 高级消息队列传输协议
1、消息发送者:Publisher
2、MQ服务端broker RabbitMQ Server:创建多个virtual Host虚拟主机,虚拟主机里创建:多个exchange交换机,然后创建多个queue消息队列
交换机:分发消息
队列:消息真正存储的地方
3、消费消息的:consumer
消费者消费的时候监听某个队列
4、连接对象:connection
channel //--连接的时候用这个来操作:操作MQ的工具
//--MQ天生处理高并发
//-- Publisher-->exchange-->consumer
常见的消息模型:
5种模式:发、收消息
psring调用对象:注入对象·
怎么修改发消息的转换器
第四天开始之下午:
消费消息
发消息
要看懂这个简单流程:14:50之前(不需要写)
SpringAMQP :
利用SpringAMQP实现HelloWorld中的基础消息队列功能
1、在父工程中引入spring-amqp的依赖
1.1再服务中yml,添加连接信息 :主机名、端口、虚拟主机、用户名、密码
2、在publisher服务中利用RabbitTemplate发送消息到simple.queue这个队列
3、在consumer服务中编写消费逻辑,绑定simple.queue这个队列
以下是两个简单的消费模式:
1、什么是AMQP?
应用间消息通信的一种协议,与语言和平台无关。
2、SpringAMQP如何//发送消息?
2.1 引入amqp的starter依赖
2.2 配置RabbitMQ地址
2.3 利用RabbitTemplate的convertAndSend方法
3、SpringAMQP如何//接收消息?
引入amqp的starter依赖
配置RabbitMQ地址
定义类,添加@Component注解
类中声明方法,添加//@RabbitListener注解,方法参数就时消息
注意:消息一旦消费就会从队列删除,RabbitMQ没有消息回溯功能
工作队列:两个消费者平均消费 多个消费者绑定到一个队列,同一条数据只会被一个消费者处理
为不让性能浪费,在消费者yml添加能者多劳:
listener:
simple:
prefetch: 1 #每次消费者都只能取1条消息消费,消费完毕确认后,在取下一条
生产者和消费者没有关系,消费者只和监听队列有关系(消费成功后会给MQ一个确认)
三种发布订阅绑定方式(交换机):Fanout 广播、Direct 路由、Topic 主题模式(支持通配符)
还有一个Headers头交换机:但性能不好、所以不讲
Fanout广播转换机的使用
1、在consumer服务中创建一个配置类,利用代码声明队列、交换机,并将两者绑定
2、然后再编写两个消费者方法,分别监听fanout.queue1和fanout.queue2
3、在publisher中编写测试方法,向itcast.fanout发送消息
MQ优化:在启动类里添加json序列化,发送和接收的序列化要一致
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
// 生产者和消费者两个启动类里都要加
@Bean //-- 配置json序列化
public MessageConverter messageConverter(){
return new Jackson2JsonMessageConverter();
}
SpringAMQP中消息的序列化和反序列化是怎么实现的?
利用MessageConverter实现的,默认是JDK的序列化
注意发送方与接收方必须使用相同的MessageConverter