一个人内耗,说明他活在过去;一个人焦虑,说明他活在未来。只有当一个人平静时,他才活在现在。
日常
1、起床6:00
2、健身2h
3、LeetCode刷了3题
- 加油站
- 局部最优:从start出发,如果curSum始终大于0,则说明可以继续,但当curSum小于0时,说明从start到curIndex上的所有点开始出发不会绕一圈,则从start+1开始出发,然后如果 total >= cost 则一定存在一个可以绕一圈的站,故遍历所有站,计算curSum,当小于0时更改start,结束后的start就是从当前可以到末尾的站,然后判断total 是否 > cost,如果是的则说明从start可以到达所有
- 局部最优:当前累
rest[i]
的和curSum一旦小于0,起始位置至少要是i+1,因为从i之前开始一定不行。全局最优:找到可以跑一圈的起始位置
- 分发糖果
- 必须单独一边遍历,无法同时满足两边,先满足左边,再满足右边,且要保证两边均满足,故在从右向左遍历时,要使得元素同时满足左右两边
- 先从前向后遍历,如果当前孩子评分大于左边则分发糖果数比左边+1,否则分发最少1个,此时保证了满足从前向后的遍历
- 然后从后向前遍历 ,如果当前评分大于右边时,则此时要满足左右两边 ,故 取当前分发(满足左边) 和 右边分发数+1 的最大值 ,从而满足左右两边 ;当小于右边时,只需要满足左边即可
- 账单找零
- 因为固定只可收5、10、20元 ,故只有三种情况 ,分别判断即可
- 只需要维护一个数组分别存放当前已经收到的零钱数 ,然后遍历bills ,当遇到5元时,直接收下,并记录5元+1 ;当遇到10元时,判断有没有5元,没有则直接返回false ,否则5元-1,10元+1 ;当遇到20元时 ,要优先判断是否有10和5元 ,没有时再判断是否有3个5元
- 关键是当遇到20元时,一定要优先使用10+5去找零 ,因为10元只可以找零20 ,而5元还可以找零10元 ,故优先使用10元去找零
- 遍历整个bills,三种情况分别判断,并记录当前的零钱数,5元直接收下,10元判断有没有5元零钱,20元时一定先用10元找零,然后再用5元找零,因为10只可以找零20,而5元还可以找零10元
4、复盘22:00
不复盘等于白学!!!
学习和感想
1、Docker学习
1. Docker-compose容器编排:NB!
- 是什么
- 负责实现对Docker容器集群(多个)的快速编排,即容器的启动顺序以及加载条件
- 需要定义一个YAML格式配置文件 docker-compose.yml ,写好多个容器之间的调用关系
- 此时通过执行该docker-compose.yml配置文件就可以快速 启动/关闭 容器集群
- 能干嘛:对Docker容器集群快速编排部署
- 通过配置docker-compose.yml配置文件,写好各个容器的调用关系 ,此时就可以一键 启动/关闭 容器集群 ,实现容器集群的快速编排部署
- 通过一个docker-compose.yml配置文件 对容器集群(一组管理容器定义为一个项目 )进行快速编排部署
- 在不使用docker-compose时 ,此时启动一个完整的业务可能要多个容器共同实现 ,而且各个容器之间也有依赖调用关系 ,要自己手动docker run 来运行各个容器 ,就会很麻烦,故引入了docker-compose来实现容器集群(工程)的快速编排
- 通过设置一个docker-compose.yml配置文件 ,在文件中配置各个容器镜像的调用关系以及启动顺序 ,然后通过docker-compose up 命令一键启动整个工程中的所有容器
- 去哪下
- 不是Docker自带的,要下载Docker-compose项目到Linux中,去官网自己下载,然后根据操作进行配置
- docker-compose不是docker自带的,要去官网下载到docker中才可以使用
- docker-compose官网
- Compose核心概念:一个文件+两个要素 (服务+工程)
- 一个文件:docker-compose.yml :配置各个容器的调用关系
- 两个要素:服务(一个个容器实例) 和工程(一组关联容器组成的完整业务单元,在yml文件中定义) ![[PastedImage/Pasted image 20241108184812.png]]
- Compose使用3步骤:构建容器镜像 、编写docker-compose.yml 、一键启动
- 先创建各个容器的镜像文件
- 编写docker-compose.yml文件对各个容器服务的调用关系进行编排形成一个工程
- 然后通过 docker-compose up 启动 docker-compose.yml 配置文件,实现容器集群的快速部署,等价于一次运行了多个docker run命令来开启docker容器集群,且在docker-compose.yml配置run的参数
- Compose常用命令
- Docker-compose可以在docker-compose.yml文件中对多个容器服务的调用关系和启动顺序进行配置,然后快速部署
- Compose编排复杂微服务
- docker-compose.yml文件
- 通过在docker-compose.yml目录下执行 docker-compose up 来一键启动同一个工程下的所有项目 ,通过docker-compose stop 来关闭所有服务
- 同一个docker-compose.yml文件中配置的服务会当作同一个工程 ,此时如果自定义了网络,则各个服务之间就可以直接通过服务名进行通信 ,**不需要通过容器名或者IP地址, 由自定义网络自动维护服务名与IP地址的映射
- 当写完docker-compose.yml文件后** 通过 docker-compose config -q 来检查是否存在语法问题**,如果没有输出说明没有问题
- 执行docker-compose命令时,必须在docker-compose.yml文件目录下执行 ,常用命令如下 ![[Pasted image 20241109095759.png]]
- DockerCompose工具可以实现项目工程容器集群的快速编排,通过在docker-compose.yml文件中编写各个服务的调用关系以及启动参数 ,然后直接docker-compose up docker-compose.yml 文件就可以实现容器的一键部署,或者使用 -d 使得全部容器后台运行 ![[PastedImage/Pasted image 20241109092518.png]]
- 在docker-compose.yml文件中,服务若不指定container-name ,则会默认生成一个容器名,且如果在docker-compose.yml中配置了自定义网络模式,则容器就可以通过配置文件中的服务名来进行通信
- 自定义网络自动维护了IP地址和容器名的映射 ,此时在容器内通过容器名就可以实现容器间的通信 ,此时就可以在微服务的配置文件中,设置通过容器名来访问对应的服务
- 用compose前
- 查找数据时,如果redis没有则双检加锁去MySQL中查找,然后回写到redis中;更新时先更新MySQL再删除redis,此时不需要回写 ;查找回写更新不回写
- 此时对于一个工程(同一个docker-compose.yml文件中的服务)中的所有容器服务 ,必须按照调用关系以及启动顺序分别使用docker run 启动各个容器以实现完整的业务
- 此时可以是工程正常运行 ,但容器的先后启动顺序是固定的 ,必须先启动Redis+MySQL才可以启动微服务,且每个容器服务都要使用docker run 进行启动,而且每次都要配置参数和端口映射 ,而且要在微服务中配置访问Redis和MySQL的IP地址 ,且是固定的,而bridge默认模式是为每个容器随机动态分配一个未被占用的IP地址 ,所以IP地址可能会变化导致无法成功部署 ![[PastedImage/Pasted image 20241109091315.png]]
- 让微服务容器以host模式启动使用宿主机的网络配置 ,然后Redis容器和MySQL容器均与宿主机实现端口映射 ,此时微服务就可以直接通过端口号访问启动的Redis和MySQL服务 ,或者MySQL和Redis与宿主机实现端口映射 ,此时微服务就直接访问宿主机的端口即可
- 用compose后
- 引入Compose之后,只需要在docker-compose.yml文件中编写各个容器服务的调用关系和启动参数配置 ,然后使用 docker-compose up 命令启动配置文件 ,就可以实现整个业务的运行
- 而且使用自定义网络模式 --network myBridge 来实现IP地址和容器名的自动映射
2. Docker轻量级可视化工具Portainer
- 是什么
- 是Docker轻量化可视化工具 ,是一个独立的工具 ,相当于把docker命令封装为可视化界面
- 将命令行操作通过图形化展示,Portainer是一个镜像,仍在Docker中以容器的方式运行,且设置为 --restart always 使得每次Docker启动时均会启动,从而实现Docker的监控
- 也就是将Docker的命令行操作通过图形化的方式进行实现,在Docker中运行对应的镜像后直接在浏览器访问网址即可进入图形化界面
- 安装
- Portainer工具也是一个Docker容器 ,要下载镜像然后在docker容器中运行 ,然后设置端口映射,通过访问宿主机的IP来访问服务 ,通过9000端口访问可视化界面
- 在运行docker镜像时,可以设置多个 -p 端口映射 ,且 --restart=always 表示每次docker重启时该容器均会重启
- 常用操作
- docker system df 可以查看当前docker中的所有容器和镜像等信息 ,图形化界面就是对命令和结果进行图形化展示
- --restart 参数是指当docker重启时该容器的操作 ,always表示该容器会随着docker重启
- 因为要使用Portainer实时监控Docker,故在启动Portainer时要使用 --restart always 表示随着Docker重新启动 ,此时就可以实现随时使用Portainer监控Docker
3. Docker重量级监控工具CIG
- Docker原生监控统计命令
- docker stats:查看各个容器占用内存和CPU等信息 ,但是当容器过多时使用命令行就很不直观 ,而且数据是实时的,无法进行持久化,也无法过线预警
- docker system df 可以查看Docker中所有镜像和容器的信息,以及docker stats可以查看Docker中CPU和内存占用信息,但信息都是实时的,且命令行方式很难观测且无法持久化和预警,故使用CIG实现Docker数据收集并持久化然后进行界面展示并进行预警
- CAdvisor实现Docker内存和CPU数据的收集,但只可以展示2分钟的数据,故使用InfluxDB时序数据库来保存CAdvisor收集到的数据,然后在Granfana中对InfulxDB存储的数据进行可视化界面展示
- 每一个都是镜像,都可以运行在Docker中,因为是相互配合,故可以使用docker-compose对其配置为同一个工程,然后在启动时一同启动,并且设置为 --restart always 每次重启时均会启动
- 是什么:重量级监控
- C Advisor+I nfluxDB+Granfana
- 可以对任何数据进行监控,相对于Portainer更加强大
- CAdvisor-监控收集 :收集docker容器信息,但默认只存储2分钟
- InfluxDB-存储数据 :持久化CAdvisor收集的数据,时序数据库
- Granfana-展示图表 :支持图表权限控制和预警
- Compose容器编排运行CIG
- 为CIG三个服务创建一个docker-compose.yml配置文件形成一个工程,一键启动三个服务
- 创建docker-compose.yml配置文件后,先使用 docker-compose config -q 查看语法是否有问题
- docker-compose命令必须在docker-compose.yml所在的目录下执行 ,否则找不到配置文件
- docker-compose命令启动的容器服务如果没有指定name ,则会自动使用 目录名+服务名-1 对其进行命名
- 测试
- C Advisor用来数据收集,其只会保持2分钟的数据,故要进行持久化,在配置时设置link到InfluxDB时序数据库上
- I nfluxDB对Cadvisor收集的数据进行持久化,配置时要设置保存的数据库为 cadvisor
- Granfana图形化展示界面 ,要进行配置 ,选择influxDB作为数据源并设置面板显示,因为三者使用Compose进行编排,故可以直接通过服务名进行访问
4. 总结
- Docker三要素:镜像、容器、仓库
- Docker五大网络模式:bridge(默认)、host、none、container、自定义
- 注意
- docker run 时可以使用 -v 实现容器数据卷挂载,此时宿主机是绝对路径 ,且不指定容器路径时,默认会挂载到 /var/lib/docker 目录下 ,此时可以实现两个目录的实时同步更新,且可以指定映射规则,默认是rw读写 ,而且数据卷不属于镜像,构建时不会将数据卷的更改构建进去 ;可以实现多个容器的共享;要指定宿主机的绝对路径 ;会一直维持到没有容器挂载;要开启权限才可以挂载--priviledge=true ;可以同时写多个 -v,且在Dockerfile中通过Volume保留字进行配置 ,且ADD保留字是拷贝+解压,而且要指定宿主机的相对路径
- 当某个镜像创建的容器正在运行,则此时不可以删除该镜像,因为容器是在镜像的基础上创建一个容器层进行操作,而且可能会commit提交为进行的镜像,此时要以原来的镜像为base镜像,故容器正在运行时不可删除镜像
- 使用redis进行缓存时,如果redis查不到数据,使用双检加锁去MySQL中查找 ,且一定要回写进入redis,否则永远都是查不到;更新时先更新MySQL,然后删除Redis即可,不用回写,否则可能导致最终数据不一致