克服自己
要克服自己的缺陷,打败自己, 这句话说起来容易做起来却是很难。
你会因为惯性去做使自己舒适的事,这样就容易在舒适的道路上越走越远,也就与你自己制定的目标相去甚远。
如此,要怎样克服自己?
我觉的有如下几点需要注意。
首先不要给自己过于遥远的目标,这样你是一定无法完成的,就会产生懈怠心理。
其次,对于目标一定要检验成果,并且记录下来,不要欺骗自己。
共勉之!
微服务架构中关于事务的一些思考
分布式事务 指的是当事务的操作分布在不同的节点上时, 需要保证事务的ACID特性。 其中最重要的一点是要保证在各个节点上的事务要么同时成功,要么同时失败。
分布式事务的解决方案有多种,下面对几种常见的进行一一说明。
2PC2PC, Two-phase Commit 。两阶段提交,通过引入协调者(Coordinator)来协调所有参与者的行为,并最终决定这些参与者是否要真正执行事务。
两个阶段分别如下:
第一阶段:准备阶段。由协调者询问各个参与节点事务是否执行成功,参与节点返回事务执行结果。参与节点收到通知之后,会进行准备操作,例如执行insert(此时并未commit),准备完成之后会告诉协调节点自己已经准备完成。
第二阶段:提交阶段。协调节点在收到所有参与节点都执行成功之后,就会通知所有节点进行提交操作。若任一节点执行失败,协调节点则会通知所有参与节点回滚数据。
主要缺点如下:
阻塞。 需要等待所有参与者确认OK之后才能commit, 其处理的时间取决于处理事务最慢的那个参与节点。所以不适合并发高的场景。
单点故障。 特别是对协调节点的依赖很大,若协调节点发生故障,则整个事务都 ...
drone和gitea集成以及hexo博客的自动部署
未完待续!
目的是为了实现hexo博客的自动部署, 每次push完之后, 触发drone ci自动进行部署。
选用drone的原因还是因为轻量, 且功能够用,如果用其他的CI工具,比如jenkins,我这小小的VPS部署服务一多,就扛不住了。
本文中drone是和gitea进行集成的, 如果要和其他仓库集成, 参考官方文档即可:https://docs.drone.io/
部署服务还是通过docker来进行。
准备工作登录gitea, 进入设置->应用, 新建一个给drone用的OAuth2授权
注意, 重定向URI(Redirect URI)是你的drone服务的域名加上login。
生成授权之后, 会得到一个客户端ID和客户端秘钥, 记下来, 后面会用到。
drone搭建本文在部署的时候, 是将drone和gitea进行集成,
drone的服务分为两部分:
drone-server
drone-runner-docker
本人将这两个服务都部署在同一个docker-compose.yml中,同时数据库还是连接的一个单独的mysql容器服务,所以需要先创建数据库, 命令 ...
记录服务异常重启导致clickhouse启动失败
测试环境中某个clickhouse实例由于意外断电而终止,重新启动报错,报错的关键信息 DB::ParsingException: Cannot parse input: expected ‘columns format version: 1\n’ at end of stream
其中报错的日志如下:
1{} <Error> auto DB::MergeTreeData::loadDataParts(bool)::(anonymous class)::operator()() const: Code: 27. DB::ParsingException: Cannot parse input: expected 'columns format version: 1\n' at end of stream. (CANNOT_PARSE_INPUT_ASSERTION_FAILED), Stack trace (when copying this message, always include the lines below):
可以搜 ...
mysql中undo、redo、binlog日志区别和说明
本文针对的都是MySQL的Innodb引擎。
1. binlog二进制日志。记录数据库的所有写操作。注意此处记录的是逻辑日志。
可用于主从复制、增量备份、监听binglog实现缓存一致性。
1.1 常用命令12345678-- 查看binlog配置信息show variables like '%log_bin%';-- 查看所有的binlog文件show binary logs;-- 查看当前正在使用的binlog文件show master status;
1.2 写入策略通过show binary logs命令可以看到当前数据库使用的哪些binlog文件, 如下图所示:
mysql会按照一定的规则,生成对应的日志文件,并按照编号从小到大依次生成。
binlog日志在写入时, 按照其日志记录类型不同, 分为如下三种情况:
statement: 记录的是sql原文, 每一条对数据的写操作都会记录在binlog中
优点: 不需要记录每一行的变化, 能够减少binlog日志量,提升性能。
缺点:由于记录的是sql原文,所以还需要记录一些额外的相关信息,用来确 ...
个人博客工具搭建
背景记录一下本人VPS上搭建的几个专门为个人博客使用的一些工具软件,为了方便, 都是使用docker进行部署,并且为了便于保存,使用docker-compose方式启动,方便后续修改。
因为vps的规格较低,所以在挑选工具时,会尽量偏向于内存占用小的。
下面介绍一下用到的一些工具, 都采用docker自建服务。
公用数据库搭建为了尽量减小资源,专门部署了一个mysql实例(docker方式),各个需要数据库的服务都会建立一个自己的库,然后都连接到这个实例上。
mysql实例的docker-compose.yml文件如下, 在这之前,需要创建一个docker网络,然后将所有需要连接到该数据库的docker服务都连接到该网络上即可,具体连接方法可参考下面的umami或waline中的配置。
此处创建的docker网络名为db-net,创建命令:docker network create db-net
mysql的docker-compose.yml文件
123456789101112131415161718192021222324version: "3"networks ...
个人笔记软件的选择
写这篇文章的目的, 主要是为了记录一下自己使用的笔记软件的过程以及最终选择(当然也只是目前的选择, 后续会不会变就不清楚了), 给其他同样有此问题的人一个参考。
先说一下本人选择笔记软件的一些原则:
数据要掌握在自己手上,放在云上的我感觉都不安全, 因为开发该软件的公司哪天收费或倒闭了, 你自己的数据就没了或者不好弄出来
要多端都能使用
方便同步
最好能自己部署
为知笔记推荐星级:★
这是我个人早起用的时间比较长的一个笔记软件, 是一个传统的笔记软件, 使用过程中陆陆续续出现过一些晓问题, 后来为知强制收费, 加上对其富文本格式的担心,花了一天的时间把数据都迁移出来了。
为知笔记有一个官方的docker镜像, 可以自己部署使用, 但是有些功能还是需要连接到官方使用, 所以不是很友好。
最终弃之。
typora + 坚果云推荐星级:★★★
在不使用为知笔记之后, 我一直在寻找替代品, 包括印象笔记,有道笔记等, 但都不符合预期, 且不符合数据掌握在自己手中的原则。在这个过程中,了解到了markdown这一文本格式, 就迅速的爱上他了。
再结合数据同步与备份, 便使用了 typora ...
ConcurrentHashMap源码分析
ConcurrentHashMap的实现机制是一直在变化的, 其中8的变化较大, 下面分别说明一下在Java7和Java8中他们的实现机制。
Java 7 实现原理主要是基于分离锁来实现的。这样做的目的是, 在进行并发操作的时候, 只需要锁住相应的Segment, 而不需要去锁住整个数据, 提高并发性能。
存储数据的是一个个的Segment,Segment是继承自ReentrantLock,所以它本质上就是一个锁。
每个Segment内部都有一个HashEntry的数组, 这个HashEntry数组存储方式和HashMap内部的table数组类似, 哈希相同的元素也是以链表形式存储。
get在并发的时候,get操作只要能保证可见性即可, 所以没有同步操作。
定位元素所属的segment
利用jdk提供的Unsafe方法保证以可见性的方式获取元素,UNSAFE.getObjectVolatile()
put
利用UNSAFE.getObject() 方法获取元素所属的segment
利用所属的segment获取可重入锁,从而将该segment锁住, 防止其他的线程进行并发写
会有一 ...
HashMap源码分析
基本原理HashMap是由数组Node<K,V>[] table 和链表(或者树)组成的一个复合结构。
数组被分成一个个的桶(buket),通过下面的这个算法决定元素在桶中的位置:
12// n为数组长度,hash为key的哈希值p = tab[i = (n - 1) & hash]
若p相同,则以链表形式存储。当链表长度超过阈值(TREEIFY_THRESHOLD=8)时,则将链表转换为红黑树。
此处为什么需要这么做?
主要是基于查询的效率考虑。链表查询元素的时间复杂度为O(n),随着链表长度的增大,查询时间也会递增。而红黑树的时间复杂度为O(logn),此处是一个以空间换时间的典型案例。
HashMap中几个特殊值说明:
initialCapacity:HashMap初始容量,默认为16
loadFactor:负载因子,默认0.75
threshold:键值对数量的最大值(不是table数组的长度),超过这个值,则需要扩容,会变为原先值的两倍
TREEIFY_THRESHOLD:链表转换红黑树阈值,默认为8, 当超过该值时, 链表就会转换为红黑树 ...
java大图片压缩与裁剪时防止oom
常规使用java进行图片裁剪或压缩的时候, 比如使用ImageIO.read()读取图片信息的时候, 或者使用Thumb nails框架进行压缩时, 都会调用DataBufferByte类的下面这个方法:
12345678910public DataBufferByte(int size, int numBanks) { super(STABLE, TYPE_BYTE, size, numBanks); bankdata = new byte[numBanks][]; for (int i= 0; i < numBanks; i++) { // 构造数组 bankdata[i] = new byte[size]; } data = bankdata[0];}
当图片像素很大时, size的值会很大, 此时构造这个数据就有可能会出现oom,比如当一张6.4M的图片, 宽高是5472*7296, size的值是114M。
基于此, ...