java
2023-06-28 12:09:05 0 举报
AI智能生成
持续更新
作者其他创作
大纲/内容
Tomcat
Java基础
常用类
ArrayList
HashMap
初始大小为16,扩容:加载因子为0.75
数组+链表+红黑树 当产生hash碰撞的时候链表长度增加,当链表长度达到8时,转换成红黑树
当碰撞小于等于6时转换成链表
数组+链表+红黑树 当产生hash碰撞的时候链表长度增加,当链表长度达到8时,转换成红黑树
当碰撞小于等于6时转换成链表
IO
多线程
Java设计模式
设计模式的类型
创建型模式
单例模式
工厂模式
原型模式
建造者模式
结构型模式
代理模式
静态代理
代理类以及被代理类实现同一个接口
动态代理
行为型模式
观察者模式
对象之间是多对一依赖的设计方案
jvm
生命周期
JVM的启动
JVM通过引导类加载器(bootstrap class loader)创建一个初始类(initial class)来完成
JVM的执行
类加载
类加载过程
Loading
Linking
验证 verify
准备 prepare
解析 resolve
initialization
双亲委派机制
运行时数据区
图
程序计数器
PC寄存器 (Program Counter Register)
PC寄存器 (Program Counter Register)
虚拟机找
设置其大小:-Xss + 具体的大小
MQ
ActiveMQ
基本入门概述
是什么
能做什么
解耦
削峰
异步
下载
官网 https://activemq.apache.org/
基本操作
启动
./activemq start
带日志的启动
./activemq start > /home/activemq/run_activemq.log
结束
./activemq stop
查看是否启动 三种
ps -et|grep activemq|grep -v grep
netstat -anp|grep 61616
lsof -i:61616
Java- JMS操作步骤
图
JMS特点
JMS provider
实现JMS接口和规范的消息中间件,也就是MQ服务器
JMS producer
JMS consumer
JMS message
消息头
属性:
JMSDestination:消息目的地
JMSDeliveryMode:消息持久化模式
JMSExpiration:消息过期时间
JMSPriority:消息的优先级
JMSMessageID:消息的唯一标识符
JMSDestination:消息目的地
JMSDeliveryMode:消息持久化模式
JMSExpiration:消息过期时间
JMSPriority:消息的优先级
JMSMessageID:消息的唯一标识符
消息体
消息属性
什么是javaee
图
持久化
LevelDB
KahaDB
JDBC
RocketMQ
基本概念
1 消息模型(Message Model)
消息生产者(Producer)
存储消息 (Broker)
消息消费者(Consumer)
2 消息生产者(Producer)
1、使用nohup & 后台运行
nohup java -jar rocketmq-dashboard-1.0.1-SNAPSHOT.jar &
dashboard
2、服务化systemctl 配置自启动
cd /lib/systemd/system
vim rocketmq-dashboard.service
vim rocketmq-dashboard.service
#启动项目
systemctl start rocketmq-dashboard.service
#停止项目
systemctl stop rocketmq-dashboard.service
#重启项目
systemctl restart rocketmq-dashboard.service
#查看项目状态
systemctl status rocketmq-dashboard.service
设置项目自启动
systemctl enable rocketmq-dashboard.service
其他人的总结
https://bright-boy.gitee.io/technical-notes
broker.propertites 配置说明
https://bright-boy.gitee.io/technical-notes/#/rocketmq/index
其他
zookeeper
基于观察者模式的 文件存储+通知
特点
1)一个领导者(Leader),多个跟随者(Follower)
2)集群中只要有半数以上节点存活,Zookeeper集群就能正常服务
3)全局数据一致:每个Server保存一份相同的数据副本,Client无论连接到哪个Server,数据都是一致的。
4)更新请求顺序进行,来自同一个Client的更新请求按其发送顺序一次执行。
5)数据更新原子性,一次数据更新要么成功,要么失败。
6)实时性,在一定时间范围内,Client能读到最新数据。
2)集群中只要有半数以上节点存活,Zookeeper集群就能正常服务
3)全局数据一致:每个Server保存一份相同的数据副本,Client无论连接到哪个Server,数据都是一致的。
4)更新请求顺序进行,来自同一个Client的更新请求按其发送顺序一次执行。
5)数据更新原子性,一次数据更新要么成功,要么失败。
6)实时性,在一定时间范围内,Client能读到最新数据。
应用场景
统一命名服务
在分布式环境下,经常需要对应用/服务进行统一命名,便于识别。
统一配置管理
1)分布式环境下配置文件同步
1)一般要求一个集群,所有节点的配置信息是一致的
2)对配置文件修改后,希望能够快速的同步到各个节点上
2)对配置文件修改后,希望能够快速的同步到各个节点上
2)配置管理可交给Zookeeper实现
1)可将配置文件写入Zookeeper上的一个Znode。
2)各个客户端服务器监听这个Znode。
3)一旦Znode中的数据被修改,Zookeeper将通知各个客户端服务器
统一集群管理
1)分布式环境中,实时掌握每个节点的状态
服务器节点动态上下线
软负载均衡
数据库
MySql
索引
InnoDB
B+树
聚簇索引
二级索引
索引优化
事物
事物的隔离级别
Redis
基本数据类型
String
List
Set
Hash
Zset
持久化
RDB
AOF
主从复制
一主两从
从机第一次连上主机命令: SLAVEOF 127.0.0.1 6379
查看当前机器信息:info replication
去中心化,即不止一个主机
面试题
1、京东:Spring的循环依赖问题如何解决?
2、拼多多:Spring插件式扩展点开发如何做?
3、腾讯:DDD项目架构应该如何落地?
4、阿里:Nacos如何支撑阿里巴巴内部上百万服务实例的访问?
5、阿里:Nacos高并发异步注册架构知道如何设计的吗?
6、阿里:Sentinel高可用架构底层熔断降级如何实现的?
7、阿里:Sentinel底层滑动时间窗限流算法怎么实现的?
8、腾讯:如何用Redis高效实现12306的复杂售票业务?
9、微博:新浪微博突发事件如何做好Redis缓存的高可用?
10、微博:高并发场景缓存穿透&失效&雪崩如何解决?
11、京东:Redis缓存与数据库双写不一致如何解决?
12、京东:Redis底层ZSet跳表是如何设计与实现的?
13、腾讯:JVM的GC执行时机是任何时候都可以吗?安全点知道吗?
14、美团:CMS垃圾收集器的并发更新失败是怎么回事?如何优化?
15、阿里:高并发系统为何建议选择G1垃圾收集器?
16、拼多多:线上系统GC问题如何快速定位与分析?
17、阿里:阿里巴巴Arthas实现原理能大概说下吗?
18、百度:单机几十万并发的系统JVM如何优化?
19、阿里:解释下JVM垃圾收集底层的三色标记算法?
20、美团:Volatile底层的内存屏障是如何实现的?
21、springBean的生命周期
Spring
Spring5
Bean
Bean的生命周期
1、根据构造方法创建Bean实例
2、设置属性值 调用set方法
在初始化方法前执行的方法(后置处理器)
3、调用初始化方法
在初始化方法后执行的方法(后置处理器)
4、获得Bean实例
5、调用销毁方法
2、设置属性值 调用set方法
在初始化方法前执行的方法(后置处理器)
3、调用初始化方法
在初始化方法后执行的方法(后置处理器)
4、获得Bean实例
5、调用销毁方法
Bean的作用域
1、在spring里 设置创建的Bean是多实例还是单实例对象
2、Bean默认是单实例的对象
3、设置Bean是多实例还是单实例
1、在spring配置文件Bean 标签里有属性 (scope)用于设置单实例和多实例
BeanFactory
是获取Bean对象的工厂
在需要使用对象的时候才去创建对象
ApplicationContext 是其子接口
在配置文件加载时就创建对象
FactoryBean
可以返回不同类型的Bean
spring有两种类型的Bean
普通bean:在配置文件中定义Bean类型就是返回类型
工厂Bean:在配置文件中定义Bean类型可以和返回类型不一致
AOP
jdk动态代理
在有接口的情况下 使用jdk动态代理
通过实现 接口 在新的实现类中做功能的增强
创建接口实现类的代理对象(新的实现类),增强类的方法
创建接口实现类的代理对象(新的实现类),增强类的方法
CGlib动态代理
没有接口的情况想使用 CGlib动态代理
创建当前类的子类的代理对象,增强类的方法
术语
连接点
类里面 可以被增强的 方法 就叫连接点
切入点
实际被真正增强的方法,称为切入点
切入点表达式
作用:知道对哪个类里面的哪个方法进行增强
语法结构
execution([权限修饰符][返回类型][类全路径][方法名]([参数列表]))
通知(增强)
实际增强的 业务逻辑部分 称为通知(增强)
通知有多种类型
前置通知
@Before
后置通知(返回通知)
@AfterReturning
出现异常不会执行
环绕通知
@Around
环绕前通知 在 @Before 之前执行
环绕后通知 在 被增强的方法执行后 @After 之前执行
异常通知
@AfterThrowing
最终通知
@After
有无异常都会执行
切面
是一个动作
把通知应用到切入点的过程
事务
特性 ACID
原子性
一致性
隔离性
持久性
事务管理操作方式
编程式事务管理
声明式事务管理
底层使用AOP
基于注解方式
基于xml配置文件方式
事务管理API
PlatformTranscationManager (接口)
事务操作
声明式事务
事务的传播行为 propagation
REQUIRED
如果有事务在运行,当前的方法就在这个事务内运行,否则,就启动一个新的事务,并在自己的事务内运行
REQUIRED_NEW
当前的方法必须启动新的事务,并在它自己的事务内运行,如果有事务正在运行,应该将它挂起
SUPPORTS
如果有事务在运行,当前的方法就在这个事务内运行,否则它可以不运行在事务中
NOT_SUPPORTED
当前的方法不应该运行在事务中,如果有运行的事务,将它挂起
MANDATORY
当前的方法必须运行在事务内部,如果没有正在运行的事务,就抛出异常
NEVER
当前的方法不应该运行在事务中,如果有运行的事务,就抛出异常
NESTED
如果有事务在运行,当前的方法就应该在这个事务的嵌套事务内运行,否则就启动一个新的事务,并在它自己的事务内运行
事务的隔离级别
在不考虑隔离性产生的问题
脏读
不可重复读
幻读
日志框架
Log4j2
WebFlux
Spring6
AOT编译
Ahead-Of-Time,预先编译
SpringMVC
Nginx
基本命令
重启
从容的重启
安装
yum install nginx
内部结构
一个master进程
多个worker进程
多个worker进程
特点
反向代理
负载均衡
动静分离
功能特性
基本HTTP服务
高级HTTP服务
邮件服务
实用工具
安装tree 观察目录更清晰
yum install -y tree
tree [目录]
Linux
常用命令
防火墙
查看状态
service firewalld status
service iptables status
systemctl status firewalld
停止防火墙
service firewalld stop
service iptables stop
systemctl stop firewalld
开启防火墙
service firewalld start
service iptables start
systemctl start firewalld
重启防火墙
service firewalld restart
service iptables restart
systemctl restart firewalld
永久关闭防火墙
chkconfig iptables off
systemctl disable firewalld
# 查询端口是否开放
firewall-cmd --query-port=8080/tcp
# 开放80端口
firewall-cmd --permanent --add-port=80/tcp
# 移除端口
firewall-cmd --permanent --remove-port=8080/tcp
#重启防火墙(修改配置后要重启防火墙)
firewall-cmd --reload
查看版本
uname -a
设置主机名称
hostnamectl set-hostname [主机名称]
切换jdk版本
update-alternatives --config java
常见问题
启动 .sh文件
报错 坏的解释器
sed -i 's/\r$//' [ 要执行的sh文件 ]
报错 坏的解释器
sed -i 's/\r$//' [ 要执行的sh文件 ]
虚拟机网络
配置静态ip
vim /etc/sysconfig/network-scripts/ifcfg-enp0s
网络相关
IP
公网IP
查询公网IP
curl cip.cc
curl cip.cc
http工作原理
Docker
基础篇
镜像删除
docker rm 容器名
docker rmi 镜像名
创建命令
docker run -d -p 3306:3306 -v /home/mysql:/sql --privileged=true mysql
导入导出容器
export 导出容器的内容留作为一个tar归档文件[对应import命令]
import 从tar包中的内容创建一个新的文件系统再导入为镜像[对应export]
案例
docker export 容器ID > 文件名.tar
docker export 40ef0ee01654 > halotest.tar
cat 文件名.tar | docker import - 镜像用户/镜像名:镜像版本号
cat halotest.tar | docker import - wyx/halo:1.0
容器内安装
apt-get update
apt-get install net-tools
commit
创建本地新镜像
docekr commit -m="提交的描述信息" -a="作者" 容器ID 要创建的目标镜像名:[标签名]
发布到阿里云
镜像仓库
发布到docker hub
构建私服
一 下载私服镜像
docker pull registry
二 运行私有库 registry
docker run -d -p 5000:5000 -v /home/registry/:/tmp/registry --privileged=true registry
三 创建本地新镜像
四 查看本地私有库是否有镜像
curl -XGET http://192.168.56.10:5000/v2/_catalog
五 将本地新镜像推送到私服
将本地新镜像修改成符合私服规范的tag
docker tag [本地新镜像名]:[version] 192.168.56.10:5000/[镜像名]:[version]
修改配置文件使之支持http
vim /etc/docker/daemon.json
"insecure-registries": ["192.168.56.10:500"]
推送
docker push 192.168.56.10:5000/[镜像名]:[version]
六 再次验证私服是否有镜像
curl -XGET http://192.168.56.10:5000/v2/_catalog
七 验证是否能用
docker pull 192.168.56.10:5000/[镜像名]:[version]
容器卷
直接挂载
docker run -v /home/mysql:/sql --privileged=true mysql
查看挂载目录
docker inspect [容器ID]
找到 Mounts
权限配置
直接挂载是 rw 权限
docker run -v /home/mysql:/sql:ro --privileged=true mysql
卷的继承于共享
先完成第一个容器的映射
docker run -it --privileged=true --volumes-from [父类] --name [容器名] [镜像名]
安装常见的容器
总体步骤
搜索镜像
拉取镜像
查看镜像
启动镜像
服务端口映射
停止镜像
移除镜像
安装mysql
坑
插入数据时会出现中文乱码
SHOW VARIABLES LIKE 'character%';
实际工作
注意容器数据卷
docker run -d -p 3306:3306 --privileged=true -v /home/mysql/log:/var/log/mysql -v /home/mysql/data:/var/lib/mysql -v /home/mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWARD=123456 --name mysql mysql:5.7
修改 my.cnf
在 /home/mysql/conf 目录下新建my.cnf
安装redis
运行容器之前
1、在挂载目录下创建redis.conf
2、修改文件中的配置
1、开启redis密码验证
requirepass 123
2、允许外地连接
注释掉 #bind 127.0.0.1
3、yes 改为 no 解决docker 启动时 -d 命令的冲突问题
daemonize no
4、数据持久化
appendonly yes
启动
高级篇
1.Docker 复杂安装
安装MySQL主从复制
主从复制原理
主从搭建步骤
1.搭建主数据库
docker run -p 3307:3306 --name mysql-master \
-v /home/mydata/mysql-master/log:/var/log/mysql \
-v /home/mydata/mysql-master/data:/var/lib/mysql \
-v /home/mydata/mysql-master/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql:5.7
-v /home/mydata/mysql-master/log:/var/log/mysql \
-v /home/mydata/mysql-master/data:/var/lib/mysql \
-v /home/mydata/mysql-master/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql:5.7
2.进入 /home/mydata/mysql-master/conf 目录下新建 my.cnf
vim my.cnf
3.重启master实例
docker restart mysql-master
4.进入master容器
5.master容器实例内创建数据同步用户
配置可以连接master的用户
CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
授权
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
6.新建从服务器实例3308
docker run -p 3308:3306 --name mysql-slave \
-v /home/mydata/mysql-slave/log:/var/log/mysql \
-v /home/mydata/mysql-slave/data:/var/lib/mysql \
-v /home/mydata/mysql-slave/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql:5.7
-v /home/mydata/mysql-slave/log:/var/log/mysql \
-v /home/mydata/mysql-slave/data:/var/lib/mysql \
-v /home/mydata/mysql-slave/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql:5.7
7.进入 /home/mydata/mysql-slave/conf 目录下新建 my.cnf
vim my.cnf
8.重启slave
docker restart mysql-slave
9.在主数据库中查看主从同步状态
show master status;
10.进入mysql-slave 容器
docker exec -it mysql-slave /bin/bash
msyql -uroot -proot
11.在从数据库中配置主从复制
参数说明
12.在从数据库中查看主从同步状态
show slave status \G;
13.在从数据库中开启主从同步
start slave
14.查看从数据库状态是否已经同步
show slave status \G;
15.主从复制测试
主机建库建表写入数据
从机查看数据
安装redis集群
cluster模式-docker版
哈希槽分区进行亿级数据存储
哈希槽分区进行亿级数据存储
面试题
1-2亿数据需要缓存,如何设计存储案例
答
分布式存储
一般三种解决方案
哈希取余分区
优点
简单直接
缺点
容错不行
扩容,故障停机 算法要改变
扩容,故障停机 算法要改变
一致性哈希算法分区
解决了 普通哈希取余 服务器宕机、扩容问题
3大步骤
算法构建一致性哈希环
0-2^32-1
服务器IP节点映射
Key落到服务器的落键规则
优点
一致性哈希算法容错性
一致性哈希算法扩展性
缺点
一致性哈希算法的数据倾斜问题
节点少的时候,出现数据倾斜,导致其中某台服务数据量过大
小总结
哈希槽分区
是什么
解决一致性哈希算法的数据倾斜问题
哈希槽实质是一个数组,数组 [ 0-2^14-1 ] 形成hash slot空间
解决均匀分配的问题
在数据和节点之间加入一层,把这层称为哈希槽(slot),用于管理数据和节点之间的关系
槽解决的是粒度问题,把粒度变大,便于数据移动
哈希解决的是映射问题,使用key的哈希值来计算所在的槽,便于数据分配。
多少个hash槽
一个集群只能有16384个槽位,编号0-16383号
哈希槽计算
3主3从redis集群扩缩容配置案例架构说明
redis集群配置
3主3从redis集群配置
关闭防火墙+启动docker后台服务
systemctl start docker
新建6个docker容器实例
docker run -d --name redis-node-1 --net host --privileged=true -v /home/redis/share/redis-node-1:/data redis:6.0.8 --cluster-enable yes --appendonly yes --port 6381
docker run -d --name redis-node-2 --net host --privileged=true -v /home/redis/share/redis-node-2:/data redis:6.0.8 --cluster-enable yes --appendonly yes --port 6382
.....
docker run -d --name redis-node-6 --net host --privileged=true -v /home/redis/share/redis-node-6:/data redis:6.0.8 --cluster-enable yes --appendonly yes --port 6386
docker run -d --name redis-node-2 --net host --privileged=true -v /home/redis/share/redis-node-2:/data redis:6.0.8 --cluster-enable yes --appendonly yes --port 6382
.....
docker run -d --name redis-node-6 --net host --privileged=true -v /home/redis/share/redis-node-6:/data redis:6.0.8 --cluster-enable yes --appendonly yes --port 6386
进入容器 redis-node-1 并为6台机器构建集群关系
进入容器
docker exec -it redis-node-1 /bin/bash
构建主从关系
redis-cli --cluster create 192.168.56.10:6381 192.168.56.10:6382 192.168.56.10:6383 192.168.56.10:6384 192.168.56.10:6385 192.168.56.10:6386 --cluster-replicas 1
链接进入6381 作为切入点,查看集群状态
链接进入6381 作为切入点,查看节点状态
redis-cli -p 6381
cluster info
cluster nodes
主从容错切换迁移案例
数据读写存储
启动6台机器构成集群并通过exec进入容器
对6381新增key
redis-cli -p 6381
防止路由失效加参数 -c 并新增两个key
redis-cli -p 6381 -c
查看集群信息
redis-cli --cluster check 192.168.56.10:6381
容错切换迁移
主6381和从机切换,先停止主机6381
docker stop redis-node-1
再次查看集群信息
docker exec -it redis-node-2 /bin/bash
redis-cli -p 6382 -c
cluster nodes
先还原之前的3主3从
启动redis-node-1
查看主从关系
node-1 变为slave
还原
停掉node-4 (master)
此时node-1 上位为master
此时node-1 上位为master
再次启动 node-4
node-4 变为slave
node-4 变为slave
查看集群状态
redis-cli --cluster check 192.168.56.10:6381
主从扩容案例
新增服务时,哈希槽如何变化
新增master之后,原集群的master 分别匀相等的哈希槽给新加入的master
新建6387,6388两个节点+新建后启动+查看是否8节点
docker run -d --name redis-node-7 --net host --privileged=true -v /home/redis/share/redis-node-7:/data redis:6.0.8 --cluster-enable yes --appendonly yes --port 6387
docker run -d --name redis-node-8 --net host --privileged=true -v /home/redis/share/redis-node-8:/data redis:6.0.8 --cluster-enable yes --appendonly yes --port 6388
docker run -d --name redis-node-8 --net host --privileged=true -v /home/redis/share/redis-node-8:/data redis:6.0.8 --cluster-enable yes --appendonly yes --port 6388
进入6387容器实例内部
docker exec -it redis-node-7 /bin/bash
将新增的6387节点(空槽号)作为master 节点加入原集群
加入集群
redis-cli --cluster add-node 192.168.56.10:6387 192.168.56.10:6381
检查集群情况第一次
redis-cli --cluster check 192.168.56.10:6381
重新分派槽号
redis-cli --cluster reshard IP地址:端口号
redis-cli --cluster reshard 192.168.56.10:6381
根据实际master台数 进行哈希槽位分配
检查集群情况第二次
redis-cli --cluster check 192.168.56.10:6381
新增的master节点的槽位是 原集群的各个master的槽位 平均匀给新master的
优点,节省成本,全部重新分配节点成本太高了
为主节点6387分配从节点6388
redis-cli --cluster add-node [slave节点ip:端口] [master节点ip:端口] --cluster-slave --cluster-master-id [master容器ID]
redis-cli --cluster add-node 192.168.56.10:6388 192.168.56.10:6387 --cluster-slave --cluster-master-id [master容器ID]
检查集群情况第三次
redis-cli --cluster check 192.168.56.10:6381
主从缩容案例
问
清除的master多出的哈希槽位如何分配
可以自定义分配
分配给单个master
平均分配给多个master
应当如何缩容,即先删除master,还是先删除slave
先删除slave
删除6387/6388节点
检查集群情况,获得6388节点ID
redis-cli --cluster check 192.168.56.10:6381
删除6388
从集群中删除6388
从集群中删除6388
命令:redis-cli del-node ip:端口 从机6388节点ID
redis-cli del-node 192.168.56.10:6388 从机6388节点ID
清空6387的哈希槽号,重新分配
redis-cli --cluster reshard 192.168.56.10:6381
选择 哈希槽位数,先指定槽位接收节点,再指定槽位原节点
检查集群情况第二次
redis-cli --cluster check 192.168.56.10:6381
删除6387节点
命令:redis-cli del-node ip:端口 主机6387节点ID
redis-cli del-node 192.168.56.10:6388 主机6387节点ID
检查集群情况第三次
redis-cli --cluster check 192.168.56.10:6381
2.DockerFile 解析
是什么
DockerFile是用来构建Docker镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本
官网
https://docs.docker.com/engine/reference/builder/
步骤
编写docker文件
docker build 命令构建镜像
docker run 容器镜像
DockerFile构建过程解析
DockerFile基础知识
1、每条保留字指令 必须为大写字母 且后面要跟随至少一个参数
2、指令按照从上到下,顺序执行
3、#表示注释
4、每条指令都会创建一个新的镜像层并对镜像镜像提交
Docker执行DockerFile的大致流程
1、docker从基础镜像运行一个容器
2、执行一条指令并对容器作出修改
3、执行类似docker commit 的操作提交一个新的镜像层
4、docker再基于刚提交的镜像运行一个新容器
5、执行DockerFile中的下一条指令直到所有指令都执行完成
小总结
DockerFile常用保留字指令
参考tomcat8的DockerFile入门
https://github.com/docker-library/tomcat
FROM
基础镜像,当前新镜像是基于哪个镜像的,指定一个已经存在的镜像作为模板,第一条必须是FROM
MAINTAINER
镜像维护者的姓名,邮箱地址
RUN
容器构建时运行的命令
两种格式
shell格式
RUN yum -y install vim
exec格式
RUN ["可执行文件", "参数1", "参数2"]
RUN是在docker build 时运行
EXPOSE
当前容器暴露的端口
WORKDIR
指定创建容器后,默认终端登陆进容器的 工作目录。就是进入容器的默认位置
USER
指定改镜像以什么样的用户去执行,不指定则为 root
ENV
用来在构建镜像过程中设置环境变量
ADD
将宿主机目录下的文件拷贝进镜像且会自动处理URL和解压tar压缩包
COPY
类似ADD,拷贝文件和目录到镜像中
将从构建上下文目录中<源路径> 的文件/目录 复制到新的一层的镜像内的<目标路径>
将从构建上下文目录中<源路径> 的文件/目录 复制到新的一层的镜像内的<目标路径>
COPY src dest
COPY ["src","dest"]
<src源路径>:源文件或者源目录
<dest目标路径>:容器内的指定路径,该路径不用事先建好
VOLUME
容器数据卷,用于数据保存和持久化工作
CMD
指定容器启动后的要干的事情
两种格式
shell格式
CMD <命令>
exec格式
CMD ["可执行文件", "参数1", "参数2" ...]
参数列表格式
CMD [ "参数1", "参数2" ...] ,在指定了 ENTRYPOINT 指令后,用CMD指定具体的参数
注意
DockerFile中可以有多个CMD指令,只有最后一个生效,CMD 会被docker run 之后的参数替换
参考官网Tomcat的DockerFile演示讲解
官网最后
演示
docker run -it -p 8080:8080 /bin/bash
会替换 CMD catalina.sh 为 /bin/bash
会替换 CMD catalina.sh 为 /bin/bash
和RUN命令的区别
CMD 是在docker run时候运行
RUN 是在docker build 时运行
ENTRYPOINT
指定容器启动后的要干的事情
类似于CMD 但是 ENTRYPOINT 不会被docker run 后面的命令覆盖,
而且这些命令行参数 会被当做参数送给ENTRYPOINT 指令指定的程序
而且这些命令行参数 会被当做参数送给ENTRYPOINT 指令指定的程序
命令格式说明
优点
命令不会被覆盖
小总结
案例
自定义镜像mycentosjava8
要求
Centos7镜像具备 vim + ifconfig+ jdk8
JDK下载镜像地址
官网
x86 Compressed Archive
x86 Compressed Archive
https://www.oracle.com/java/technologies/downloads/#java8
mirror
mirrors.yangxingzhen.com/jdk/
编写
编写DockerFile文件
构建
docker build -t 新镜像名字:TAG .
注意,TAG 后面有个空格 有个点
运行
docker run -it 新镜像名字:TAG
再体会一下 UnionFS (联合文件系统)
虚悬镜像
是什么
仓库名、标签都是<none> 的镜像,俗称dangling image
Dockerfile 写一个
查看
docker image ls -f dangling=true
命令结果
删除
docker image prune
独立完成 自定义镜像myubuntu
编写
准备编写Dockerfile文件
构建
docker build -t 新镜像名:TAG .
运行
docker run -it 新镜像名:TAG
3.docker 微服务实战
通过idea新建一个微服务模块
建Module
改pom
写yml
主启动
业务类
通过Dockerfile发布微服务部署到docker容器
上传
先将项目打包,上传到服务器
编写Dockerfile
构建镜像
docker build -t 新镜像名字:TAG .
运行容器
docker run -it 新镜像名字:TAG
4.Docker网络
是什么
docker不启动,默认网络情况
docker启动后,网络情况
会出现一个 docker0 的虚拟网桥
常用基本命令
查看docker网络
docker network ls
docker network --help
删除docker网络
docker network rm [网络名称]
查看docker网络源数据
案例
能干嘛
容器间的互联和通信以及端口映射
容器IP变动时 可以通过服务名直接网络通信而不受影响
网络模式
总体介绍
bridge
host
none
container
容器实例内默认网络IP生产规则
说明
docker inspect [容器名称] | tail -n 20
结论
docker 容器内部的ip是有可能会发生改变的 在每次重启后都可能发生变化
案例
bridge
命令
docker run -d -p 8081:8080 --network bridge --name tomcat83 billygoo/tomcat8-jdk8
host
命令
警告
docker run -d -p 8083:8080 --network host --name tomcat83 billygoo/tomcat8-jdk8
正确
docker run -d --network host --name tomcat83 billygoo/tomcat8-jdk8
none
是什么
禁用网络功能,只有lo(localhost) 就是127.0.0.1 表示本地回环
命令
docker run -d -p 8084:8080 --network none --name tomcat84 billygoo/tomcat8-jdk8
container
是什么
案例1
docker run -d -p 8085:8080 --name tomcat85 billygoo/tomcat8-jdk8
docker run -d -p 8086:8080 --network container:tomcat85 --name tomcat86 billygoo/tomcat8-jdk8
这样会出现冲突
案例2
Alpine操作系统是一个面向安全的轻型Linux发型版
docker run -it --name alpine1 alpine /bin/sh
docekr run -it --network container:alpine1 --name alpine2 alpine /bin/sh
运行结果,验证共用搭桥
如果此时关闭alpine1,再看看alpine2
停掉 alpine1,alpine2 也没有网络了
自定义网络
过时的link
https://docs.docker.com/network/links/
是什么
案例
before
案例
docker run -d -p 8081:8080 --name tomcat81 billygoo/tomcat8-jdk8
docker run -d -p 8082:8080 --name tomcat82 billygoo/tomcat8-jdk8
在服务器内部ping IP地址可以ping通
通过服务名 ping 不能ping通
after
自定义桥接网络,自定义网络默认使用的是桥接网络bridge
新建自定义网络
docker network create zzyy_network
新建容器加入上一步新建的自定义网络
docker run -d -p 8081:8080 --network zzyy_network --name tomcat81 billygoo/tomcat8-jdk8
docker run -d -p 8082:8080 --network zzyy_network --name tomcat82 billygoo/tomcat8-jdk8
互相ping测试
Docker平台架构图解
5.Docker-compose容器编排
是什么
Docker-Compose是Docker官方的开源项目,负责实现对Docker容器集群的快速编排
能干嘛
去哪下
官网
https://docs.docker.com/compose/compose-file/compose-file-v3
官网下载
https://docs.docker.com/compose/install/
安装步骤
卸载
Compose核心概念
一文件
docker-compose.yml
两要素
服务(server)
一个个应用容器实例,比如订单微服务、mysql容器、redis容器
工程(project)
由一组关联的应用容器组成的一个完整业务单元,在docker-compose.yml 文件中定义
Compose使用的三个步骤
编写Dockerfile定义各个微服务应用并构建出对应的镜像文件
使用docker-compose.yml
定义一个完整业务单元,安排好整体应用中的各个容器服务
定义一个完整业务单元,安排好整体应用中的各个容器服务
最后,执行docker-compose up 命令来启动并运行整个应用程序,完成一键部署上线
Compose常用命令
Compose编排微服务
改造升级微服务工程docker_boot
以前的基础版
sql建表建库
一键生成说明
改pom
写yml
主启动
业务类
mvn package命令将微服务形成新的jar包 并上传到Linux服务器/mydocker目录下
编写Dockerfile
构建镜像
docker build -t 新镜像名:TAG .
不用compose
单独的mysql容器实例
新建mysql容器实例
进入mysql容器实例并新建库db2021+新建t_user
单独的redis容器实例
微服务工程
上面三个容器依次顺序启动
swagger测试
上面成功了,有哪些问题
先后启动顺序固定,先mysql+redis 才能启动微服务
多个run命令
容器间的启停或宕机,可能导致IP地址对应的容器实例变化,映射出错,要么生产ip写死(不推荐),要么通过服务调用
使用compose
编写docker-compose.yml文件
修改微服务的application.yml 配置文件
运行docker-compose.yml
docker-compose up
docker-compose up -d
6.Docker轻量级可视化工具Portainer
是什么
Portainer是一款轻量级的应用,提供了图形化界面,用于方便的管理docker环境,包括单机,集群
安装
官网
https://www.portainer.io/
https://docs.portainer.io/v/ce-2.11/start/install/server/docker/linux
命令
docker run -d -p 8000:8000 -p 9000:9000 --name portainer \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data \
portainer/portainer-ce
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data \
portainer/portainer-ce
docker run -d -p 8000:8000 -p 9000:9000 --name portainer \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data \
portainer/portainer-ce
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data \
portainer/portainer-ce
7.Docker容器监控之 CAdvisor+InfluxDB+Granfana
原生命令
docker stats
是什么
容器监控3剑客
一句话
CAdvisor监控收集+InfluxDB存储数据+Granfana展示图表
CAdvisor
InfluxDB
Granfana
8.总结
常用设置
容器自动重启 开启/关闭
docker update --restart=always <CONTAINER ID>
docker update --restart=no <CONTAINER ID>
Jenkins
centos
安装git
yum install git
生成秘钥
ssh-keygen -t rsa -C "youremail@abc.com"
其中 可以设置名称。密码
将生成的公钥 配置到github
点击 settings --》SSH AND GPG KEYS
安装maven
https://dlcdn.apache.org/maven/maven-3/3.6.3/binaries/
tar -zxvf apache-maven-3.6.3-src.tar.gz
配置环境变量
echo $PATH
查看环境变量
export MAVEN_HOME=/root/maven/apache-maven-3.6.3/apache-maven/src
export PATH=$PATH:$MAVEN_HOME/bin:.
cd /etc/profile.d/ 目录下新增 .sh 文件
安装java
1.查看云端目前支持安装的JDK版本
yum search java|grep jdk
2.选择JDK版本,并安装
yum install -y java-1.8.0-openjdk
3.检查是否安装成功
java -version
4.查看JDK的安装目录
find / -name 'java'
安装Jenkins
wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo --no-check-certificate
rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key
yum install -y jenkins
rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key
yum install -y jenkins
systemctl status jenkins // 查看 jenkins 运行状态
systemctl start jenkins // 启动 jenkins
systemctl start jenkins // 启动 jenkins
/var/lib/jenkins/secrets/initialAdminPassword // jenkins 密码
在登录配置界面时出现 No such plugin: cloudbees-folder 解决办法
https://updates.jenkins-ci.org/download/plugins/cloudbees-folder/ 下载一个插件
访问 IP:PORT/restart,越过配置插件的页面,直接访问
点击【系统管理】–【管理插件】–【高级】–【上传插件】,手动安装下载好的插件,即可
SpringCloud
漏桶算法
MySQL
子主题
正则
非空 非中文
^[^\u4e00-\u9fa5 ]+$
x-ui
第一阶段
安装xui:
bash <(curl -Ls https://raw.githubusercontent.com/vaxilu/x-ui/master/install.sh)
CF优选IP工具
https://github.com/XIU2/CloudflareSpeedTest/releases/latest
反代CF的IP
https://github.com/ip-scanner/cloudflare
合并txt文件
type *.txt>>all.txt
子主题
二阶段
OpenBullet2:
https://github.com/openbullet/OpenBullet2/releases/latest
CF节点信息:
/cdn-cgi/trace
机场三字码查询:
http://airport.anseo.cn/
loli脚本:
BLOCK:HttpRequest
url = $"http://<input.DATA>/cdn-cgi/trace"
maxNumberOfRedirects = 2
customHeaders = {("Host", "cf.nicename.tk")}
timeoutMilliseconds = 3000
TYPE:STANDARD
$""
"application/x-www-form-urlencoded"
ENDBLOCK
BLOCK:Keycheck
banIfNoMatch = False
KEYCHAIN SUCCESS OR
STRINGKEY @data.SOURCE Contains "h=cf.nicename.tk"
ENDBLOCK
url = $"http://<input.DATA>/cdn-cgi/trace"
maxNumberOfRedirects = 2
customHeaders = {("Host", "cf.nicename.tk")}
timeoutMilliseconds = 3000
TYPE:STANDARD
$""
"application/x-www-form-urlencoded"
ENDBLOCK
BLOCK:Keycheck
banIfNoMatch = False
KEYCHAIN SUCCESS OR
STRINGKEY @data.SOURCE Contains "h=cf.nicename.tk"
ENDBLOCK
程序运行
优选ip
.\CloudflareST.exe -tll 40
0 条评论
下一页