下载&安装 VirtualBox https://www.virtualbox.org/ 要开启 CPU 虚拟化
下载& 安装 Vagrant
https://app.vagrantup.com/boxes/search Vagrant 官方镜像仓库 https://www.vagrantup.com/downloads.html Vagrant下载
检查是否安装
vagrant vagrant -v
打开 window cmd 窗口,运行 Vagrant init centos/7,即可初始化一个 centos7 系统
vagrant init centos/7
运行 vagrant up 即可启动虚拟机。系统 root 用户的密码是 vagrant
vagrant up
vagrant 其他常用命令
- 自动使用 vagrant 用户连接虚拟机。
vagrant ssh //查看用户 whoami //退出连接 exit; //重启虚拟机 vagrant reload
- 上传文件
vagrant upload source [destination] [name|id]
- Vagrant 命令行
https://www.vagrantup.com/docs/cli/init.html
默认虚拟机的 ip 地址不是固定 ip,开发不方便
- C:Users29534下找:Vagrantfile 修改
config.vm.network "private_network", ip: "192.168.56.10"
这里的 ip 需要在物理机下使用 ipconfig 命令找到
改为这个指定的子网地址
config.vm.network "private_network", ip: "192.168.56.10"
重新使用 vagrant up 启动机器即可。然后再 vagrant ssh 连接机器
vagrant reload vagrant ssh //查看IP ip addr
查看是否ping通
ping 192.168.56.10
默认只允许 ssh 登录方式,为了后来操作方便,文件上传等,我们可以配置允许账号密码登录
Vagrant ssh 进去系统之后 vi /etc/ssh/sshd_config 修改 PasswordAuthentication yes/no 默认为no 改为 yes 重启服务 service sshd restart
以后可以使用提供的 ssh 连接工具直接连接
为了方便我们切换到root用户
su - root password:vagrant安装docker
1、卸载docker
sudo yum remove docker
docker-client
docker-client-latest
docker-common
docker-latest
docker-latest-logrotate
docker-logrotate
docker-engine
2、安装yum-utils;
sudo yum install -y yum-utils
3、为yum源添加docker仓库位置;
sudo yum-config-manager
--add-repo
https://download.docker.com/linux/centos/docker-ce.repo
4、安装docker服务;
sudo yum install docker-ce docker-ce-cli containerd.io
5、检查是否安装
docker -v //检查是否安装镜像 docker images
6、启动docker服务。
sudo systemctl start docker
7、设置开机自启
sudo systemctl enable docker
8、配置docker镜像加速
# 创建文件
sudo mkdir -p /etc/docker
# 修改配置, 设置镜像
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://b6490vol.mirror.aliyuncs.com"]
}
EOF
# 重启后台线程
sudo systemctl daemon-reload
# 重启docker
sudo systemctl restart docker
查看容器
//查看运行中的容器 docker ps //查看所有容器 docker ps -a //停止容器 docker stop 容器名称(names里面的) //重启 docker restart mysql(你的名称:names) //查看日志,错误信息 docker loge 容器名称删除容器
//查看 docker images //删除 docker rmi -f d1165f221234(IMAGE ID) //删除所有容器 docker image prune -a //删除所有停止运行的容器 docker container pruneDocker 安装 MySQL 1、下载镜像文件
sudo docker pull mysql:5.7 //检查是否安装成功 docker images2、创建实例并启动
docker run -p 3306:3306 --name mysql -v /mydata/mysql/log:/var/log/mysql -v /mydata/mysql/data:/var/lib/mysql -v /mydata/mysql/conf:/etc/mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7
参数说明:
-p 3306:3306 :将容器的3306端口映射到主机的3306端口
-v /mydata/mysql/conf:/etc/mysql :将配置文件夹挂载到主机
-v /mydata/mysql/log/mysql :将日志文件夹挂载到主机
-v /mydata/mysql/data:/var/lib/mysql/ :将配置文件夹挂载到主机
-e MYSQL_ROOT_PASSWORD=root :初始化root用户的密码
启动后,可以交互模式进入容器,查看mysql相关的目录命令: whereis mysql
资料报错表示:你的服务器3306端口已经被占用,把前面的3306改成3307
利用mysql客户端,进行测试:用户名root 密码 root
进入容器docker exec -it mysql /bin/bash
查看mysql应用结构
# ls / //退出 exit;
查看mysql目录结构
# cd /mydata/mysql/conf # 修改配置文件 my.cnf # vi my.conf //创建my.conf文件
配置my.conf文件
[client] default-character-set=utf8 [mysql] default-character-set=utf8 [mysqld] init_connect='SET collation_connection = utf8_unicode_ci' init_connect='SET NAMES utf8' character-set-server=utf8mb4 collation-server=utf8_unicode_ci skip-character-set-client-handshake skip-name-resolve 退出保存 # Esc # :wq
注意:解决MySQL连接慢的问题
在配置文件中加入如下,并重启MySQL
[mysqld] skip-name-resolve
解析:
skip-name-resolve :跳过域名解析
查看是否成功
# cd /etc/mysql # ls # cat my.conf //重启mysql docker restart mysql //设置开机自动启动 sudo docker update mysql --restart=always docker container update --restart=always mysql
这里你的MySQL已经安装成功了。
Docker 安装Redis 1、下载镜像文件docker pull redis2、创建实例并启动
mkdir -p /mydata/redis/conf touch /mydata/redis/conf/redis.conf docker run -p 6379:6379 --name redis -v /mydata/redis/data:/data -v /mydata/redis/conf/redis.conf:/etc/redis/redis.conf -d redis redis-server /etc/redis/redis.conf
redis 自描述文件:
https://raw.githubusercontent.com/antirez/redis/4.0/redis.conf
redis 官网配置文件 https://redis.io/topics/config
3、开启redis持久化# pwd # ls # vi redis.conf //一键创建 # vi /mydata/redis/conf/redis.conf //文件内容 appendonly yes4、使用 redis 镜像执行 redis-cli 命令连接
docker exec -it redis redis-cli //存放 key a value b set a b //得值 get a //退出 exit //重启redis docker restart redis //设置开机自动启动 sudo docker update redis --restart=alwaysDocker 安装 Elasticsearch、Kibana 1、下载镜像文件
# 存储和检索数据 docker pull elasticsearch:7.4.2 # 可视化检索数据 docker pull kibana:7.4.22、配置挂载数据文件夹
# 创建配置文件目录 mkdir -p /mydata/elasticsearch/config # 创建数据目录 mkdir -p /mydata/elasticsearch/data # 将/mydata/elasticsearch/文件夹中文件都可读可写 chmod -R 777 /mydata/elasticsearch/ # 进入config cd /mydata/elasticsearch/config/ # 配置任意机器可以访问 elasticsearch echo "http.host: 0.0.0.0" >/mydata/elasticsearch/config/elasticsearch.yml3、启动Elasticsearch
命令后面的 是换行符,注意前面有空格
docker run --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" -v /mydata/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml -v /mydata/elasticsearch/data:/usr/share/elasticsearch/data -v /mydata/elasticsearch/plugins:/usr/share/elasticsearch/plugins -d elasticsearch:7.4.2
- -p 9200:9200 -p 9300:9300:向外暴露两个端口,9200用于HTTP REST API请求,9300 ES 在分布式集群状态下 ES 之间的通信端口;
- -e "discovery.type=single-node":es 以单节点运行
- -e ES_JAVA_OPTS="-Xms64m -Xmx512m":设置启动占用内存,不设置可能会占用当前系统所有内存
- -v:挂载容器中的配置文件、数据文件、插件数据到本机的文件夹;
- -d elasticsearch:7.6.2:指定要启动的镜像
访问 IP:9200 看到返回的 json 数据说明启动成功。
http://192.168.56.10:92004、设置 Elasticsearch 随Docker启动
# 开启elasticsearch docker restart elasticsearch # 当前 Docker 开机自启,所以 ES 现在也是开机自启 docker update elasticsearch --restart=always5、启动可视化Kibana
docker run --name kibana -e ELASTICSEARCH_HOSTS=http://192.168.56.10:9200 -p 5601:5601 -d kibana:7.4.2 docker run --name kibana -e ELASTICSEARCH_HOSTS=http://47.115.143.129:9200 -p 5601:5601 -d kibana:7.4.2
-e ELASTICSEARCH_HOSTS=``http://192.168.56.10:9200: 这里要设置成自己的虚拟机IP地址
浏览器输入192.168.56.10:5601 测试:
6、设置 Kibana 随Docker启动# 当前 Docker 开机自启,所以 kibana 现在也是开机自启 docker update kibana --restart=always7、安装IK分词器
事前准备:
- IK 分词器属于 Elasticsearch 的插件,所以 IK 分词器的安装目录是 Elasticsearch 的 plugins 目录,在我们使用Docker启动 Elasticsearch 时,已经将该目录挂载到主机的 /mydata/elasticsearch/plugins 目录。
- IK 分词器的版本需要跟 Elasticsearch 的版本对应,当前选择的版本为 7.4.2,下载地址为:Github Release 或访问:镜像地址
# 进入挂载的插件目录 /mydata/elasticsearch/plugins cd /mydata/elasticsearch/plugins # 安装 wget 下载工具 yum install -y wget # 下载对应版本的 IK 分词器(这里是7.4.2) wget https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.4.2/elasticsearch-analysis-ik-7.4.2.zip
这里已经在挂载的 plugins 目录安装好了 IK分词器。现在我们进入到 es 容器内部检查是否成功安装
# 进入容器内部 docker exec -it elasticsearch /bin/bash # 查看 es 插件目录 ls /usr/share/elasticsearch/plugins # 可以看到 elasticsearch-analysis-ik-7.4.2.zip # 退出 exit;
所以我们之后只需要在挂载的目录/mydata/elasticsearch/plugins下进行操作即可。
7.1、解压# 进入到 es 的插件目录 cd /mydata/elasticsearch/plugins # 解压包 yum install -y unzip zip # 解压到 plugins 目录下的 ik 目录 unzip elasticsearch-analysis-ik-7.4.2.zip -d ik # 删除下载的压缩包 rm -f elasticsearch-analysis-ik-7.4.2.zip # 修改文件夹访问权限 chmod -R 777 ik/7.2、查看安装的ik插件
# 进入 es 容器内部 docker exec -it elasticsearch /bin/bash # 进入 es bin 目录 cd /usr/share/elasticsearch/bin # 执行查看命令 显示 ik elasticsearch-plugin list # 退出容器 exit # 重启 Elasticsearch docker restart elasticsearch7.3、测试
# 默认是不分词的
POST _analyze
{
"analyzer": "standard",
"text": "尚硅谷电商项目"
}
# 分词
POST _analyze
{
"analyzer": "ik_smart",
"text": "尚硅谷电商项目"
}
8、自定义扩展分词库
8.1、nginx 中自定义分词文件
echo "蔡徐坤" > /mydata/nginx/html/fenci.txt
nginx 默认请求地址为 ip:port/fenci.txt;本机为:192.168.56.10/fenci.txt
如果想要增加新的词语,只需要在该文件追加新的行并保存新的词语即可。
8.2、给 es 配置自定义词库# 1. 打开并编辑 ik 插件配置文件 vim /mydata/elasticsearch/plugins/ik/config/IKAnalyzer.cfg.xml
修改为以下内容:
8.3、重启 elasticsearch 容器IK Analyzer 扩展配置 http://192.168.56.10/fenci.txt
docker restart elasticsearch8.4、测试自定义词库
GET _analyze
{
"analyzer": "ik_max_word",
"text":"蔡徐坤你好"
}
Docker 安装 Nginx
1、创建要挂载的配置目录
mkdir -p /mydata/nginx/conf2、启动临时nginx容器
docker run -p 80:80 --name nginx -d nginx:1.10 docker run -p 80:80 --name nginx -d nginx:1.183、拷贝出 Nginx 容器的配置
# 将nginx容器中的nginx目录复制到本机的/mydata/nginx/conf目录
docker container cp nginx:/etc/nginx /mydata/nginx/conf
# 复制的是nginx目录,将该目录的所有文件移动到 conf 目录
mv /mydata/nginx/conf/nginx
@Test
public void contextLoads() {
// public DirectExchange(
// String name, 交换机的名字
// boolean durable, 是否持久
// boolean autoDelete, 是否自动删除
// Map arguments)
// {
DirectExchange directExchange = new DirectExchange("hello-java.exchange",true,false);
amqpAdmin.declareExchange(directExchange);
log.info("Exchange[{}]创建成功:","hello-java.exchange");
}
@Test
public void createQueue() {
// public Queue(String name, boolean durable, boolean exclusive, boolean autoDelete, Map arguments) {
Queue queue = new Queue("hello-java-queue",true,false,false);
amqpAdmin.declareQueue(queue);
log.info("Queue[{}]:","创建成功");
}
@Test
public void createBinding() {
// public Binding(String destination, 目的地
// DestinationType destinationType, 目的地类型
// String exchange,交换机
// String routingKey,//路由键
Binding binding = new Binding("hello-java-queue",
Binding.DestinationType.QUEUE,
"hello-java.exchange",
"hello.java",null);
amqpAdmin.declareBinding(binding);
log.info("Binding[{}]创建成功","hello-java-binding");
}
3.2、RabbitTemplate:消息发送处理组件
@Autowired
@Test
public void sendMessageTest() {
for(int i = 1; i <=5; i++) {
if(i%2==0) {
OrderReturnReasonEntity reasonEntity = new OrderReturnReasonEntity();
reasonEntity.setId(1l);
reasonEntity.setCreateTime(new java.util.Date());
reasonEntity.setName("哈哈");
//
String msg = "Hello World";
// 发送的对象类型的消息,可以是一个json
rabbitTemplate.convertAndSend("hello-java.exchange","hello.java",reasonEntity);
} else {
OrderEntity orderEntity = new OrderEntity();
orderEntity.setOrderSn(UUID.randomUUID().toString());
rabbitTemplate.convertAndSend("hello-java.exchange","hello.java",orderEntity);
}
log.info("消息发送完成{}");
}
}
4、RabbitMQ消息确认机制 - 可靠到达
- 保证消息不丢失,可靠抵达,可以使用事务消息,性能下降250倍,为此引入确认机制
- publisher confirmCallback 确认模式
- publisher returnCallback 未投递到 queue 退回
- consumer ack 机制
spring.rabbitmq.publisher-confirms=true
在创建 connectionFactory 的时候设置 PublisherConfirms(true) 选项,开启 /confirm/icallback。
CorrelationData 用来表示当前消息唯一性
消息只要被 broker 接收到就会执行 /confirm/iCallback,如果 cluster 模式,需要所有 broker 接收到才会调用 /confirm/iCallback
被 broker 接收到只能表示 message 已经到达服务器,并不能保证消息一定会被投递到目标 queue 里,所以需要用到接下来的 returnCallback
4.2、可靠抵达 - ReturnCallbackspring.rabbitmq.publisher-retuns=true
spring.rabbitmq.template.mandatory=true
confirm 模式只能保证消息到达 broker,不能保证消息准确投递到目标 queue 里。在有些模式业务场景下,我们需要保证消息一定要投递到目标 queue 里,此时就需要用到 return 退回模式
这样如果未能投递到目标 queue 里将调用 returnCallback,可以记录下详细到投递数据,定期的巡检或者自动纠错都需要这些数据
4.3、可靠抵达 - Ack 消息确认机制- 消费者获取到消息,成功处理,可以回复Ack给Broker
- basic.ack 用于肯定确认:broker 将移除此消息
- basic.nack 用于否定确认:可以指定 beoker 是否丢弃此消息,可以批量
- basic.reject用于否定确认,同上,但不能批量
- 默认,消息被消费者收到,就会从broker的queue中移除
- 消费者收到消息,默认自动ack,但是如果无法确定此消息是否被处理完成,或者成功处理,我们可以开启手动ack模式
- 消息处理成功,ack(),接受下一条消息,此消息broker就会移除
- 消息处理失败,nack()/reject() 重新发送给其他人进行处理,或者容错处理后ack
- 消息一直没有调用ack/nack方法,brocker认为此消息正在被处理,不会投递给别人,此时客户端断开,消息不会被broker移除,会投递给别人
设置发送端消息抵达Broker的确认
# 开启发送端确认,新版本 spring.rabbitmq.publisher-/confirm/i-type=correlated # 老版本 spring.rabbitmq.publisher-confirms=true
在配置类中定制RabbitTemplate设置/confirm/iCallback
package com.qrxm.gulimall.order.config;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
@Configuration
public class MyRabbitConfig {
@Autowired
RabbitTemplate rabbitTemplate;
@Bean
public MessageConverter messageConverter() {
return new Jackson2JsonMessageConverter();
}
@PostConstruct
public void initRabbitTemplate() {
//设置消息抵达Broker的确认回调
rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
@Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
System.out.println("/confirm/i...correlationData[" + correlationData + "],=>b[" + ack + "],=>s[" + cause + "]");
}
});
}
}
设置发送端抵达队列的确认
# 开启发送端消息抵达队列的确认 spring.rabbitmq.publisher-returns=true # 只要抵达队列,以异步发送优回调我们这个 spring.rabbitmq.template.mandatory=true
在配置类中定制RabbitTemplate设置ReturnCallback
//设置消息抵达队列的确认回调
rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
@Override
public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
System.out.println("Fail message[" + message + "] replyCode[" + replyCode + "] replyText[" + replyText + "] exchange[" + exchange + "] routingKey[" + routingKey + "]");
}
});
4.5、RabbitListener&RabbitHandler接收消息
监听消息:使用@RabbitListener 必须有 @EnableRabbit
@RabbitListener标注在业务逻辑组件上,且组件在容器中
在任意一个 service实现中 编写一个监听器,用Object 接收这个消息获取他的类型,发现类型为class org.springframework.amqp.core.Message
@RabbitListener能标注在类和方法上(监听哪些队列) @RabbitHandler能标注在方法上 (重载区分不同类型的消息) 直接重载了Docker 安装 Nacos Linux下安装Nacos
- 下载安装包
wget https://github.com/alibaba/nacos/releases/download/2.0.0-ALPHA.2/nacos-server-2.0.0-ALPHA.2.zip
- 如果 wget 不存在,则安装 wget
yum install wget
- 解压
unzip nacos-server-2.0.0-ALPHA.2.zip
- 如果unzip不存在,则安装unzip
yum install unzip zip
- 单机启动
sh startup.sh -m standlone
- 添加nacos.service文件
cd /lib/systemd/system vi nacos.service
[Unit] Description=nacos After=network.target [Service] Type=forking ExecStart=/home/nacos/nacos/bin/startup.sh -m standalone ExecReload=/home/nacos/nacos/bin/shutdown.sh ExecStop=/home/nacos/nacos/bin/shutdown.sh PrivateTmp=true [Install] WantedBy=multi-user.target
- 重新加载服务配置
systemctl daemon-reload
- 设置开机自启
systemctl enable nacos.service
- 设置nacos的java环境路径,如果不设置,手动启动nacos不会报错,但是开机自动启动nacos会报错找不到java环境变量,通过systemctl start nacos-service也会报错。编辑nacos的startup.sh文件
JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.275.b01-0.el7_9.x86_64/jre # 添加这行指定java的路径
cygwin=false
darwin=false
os400=false
case "`uname`" in
CYGWIN*) cygwin=true;;
Darwin*) darwin=true;;
OS400*) os400=true;;
esac
error_exit ()
{
echo "ERROR: $1 !!"
exit 1
}
[ ! -e "$JAVA_HOME/bin/java" ] && JAVA_HOME=$HOME/jdk/java
[ ! -e "$JAVA_HOME/bin/java" ] && JAVA_HOME=/usr/java
[ ! -e "$JAVA_HOME/bin/java" ] && JAVA_HOME=/opt/taobao/java
[ ! -e "$JAVA_HOME/bin/java" ] && unset JAVA_HOME
- 立即启动
systemctl start nacos.service
- 查看启动状态
systemctl status nacos.service



